| author | |
| committer | |
| log | cad75a7106cadd971f4cdc0ec4f3ee0fbe2adf09 |
| tree | 21c6cdcc1cfc63135e851e929882170032744bae |
| parent | ccbfd60e32be0412ed12f7d3bfd979dfc5c69e94 |
| parent | cb7c6e391872d2922a688c77def805883b69eba8 |
This commit also makes `pointer_stability` a non default init.
This was done initially to verify that methods like `toManaged` behave
properly with respect to pointer stability, but does require changes
outside of `array_list.zig`. Initialization with `init()` or
`.empty` appears to be preferred enough that this is minimally breaking.744 files changed, 31566 insertions(+), 20491 deletions(-)
.forgejo/workflows/ci.yaml+3-3| ... | @@ -153,7 +153,7 @@ jobs: | ... | @@ -153,7 +153,7 @@ jobs: |
| 153 | fetch-depth: 0 | 153 | fetch-depth: 0 |
| 154 | - name: Build and Test | 154 | - name: Build and Test |
| 155 | run: sh ci/s390x-linux-debug.sh | 155 | run: sh ci/s390x-linux-debug.sh |
| 156 | timeout-minutes: 420 | 156 | timeout-minutes: 480 |
| 157 | s390x-linux-release: | 157 | s390x-linux-release: |
| 158 | runs-on: [self-hosted, s390x-linux] | 158 | runs-on: [self-hosted, s390x-linux] |
| 159 | steps: | 159 | steps: |
| ... | @@ -174,7 +174,7 @@ jobs: | ... | @@ -174,7 +174,7 @@ jobs: |
| 174 | fetch-depth: 0 | 174 | fetch-depth: 0 |
| 175 | - name: Build and Test | 175 | - name: Build and Test |
| 176 | run: sh ci/x86_64-freebsd-debug.sh | 176 | run: sh ci/x86_64-freebsd-debug.sh |
| 177 | timeout-minutes: 120 | 177 | timeout-minutes: 1440 |
| 178 | x86_64-freebsd-release: | 178 | x86_64-freebsd-release: |
| 179 | runs-on: [self-hosted, x86_64-freebsd] | 179 | runs-on: [self-hosted, x86_64-freebsd] |
| 180 | steps: | 180 | steps: |
| ... | @@ -184,7 +184,7 @@ jobs: | ... | @@ -184,7 +184,7 @@ jobs: |
| 184 | fetch-depth: 0 | 184 | fetch-depth: 0 |
| 185 | - name: Build and Test | 185 | - name: Build and Test |
| 186 | run: sh ci/x86_64-freebsd-release.sh | 186 | run: sh ci/x86_64-freebsd-release.sh |
| 187 | timeout-minutes: 120 | 187 | timeout-minutes: 1440 |
| 188 | 188 | ||
| 189 | x86_64-linux-debug: | 189 | x86_64-linux-debug: |
| 190 | runs-on: [self-hosted, x86_64-linux] | 190 | runs-on: [self-hosted, x86_64-linux] |
CMakeLists.txt+8-13| ... | @@ -358,6 +358,8 @@ set(ZIG_STAGE2_SOURCES | ... | @@ -358,6 +358,8 @@ set(ZIG_STAGE2_SOURCES |
| 358 | src/codegen/c/type/render_defs.zig | 358 | src/codegen/c/type/render_defs.zig |
| 359 | src/codegen/llvm.zig | 359 | src/codegen/llvm.zig |
| 360 | src/codegen/llvm/bindings.zig | 360 | src/codegen/llvm/bindings.zig |
| 361 | src/codegen/loongarch/abi.zig | ||
| 362 | src/codegen/s390x/abi.zig | ||
| 361 | src/crash_report.zig | 363 | src/crash_report.zig |
| 362 | src/dev.zig | 364 | src/dev.zig |
| 363 | src/libs/freebsd.zig | 365 | src/libs/freebsd.zig |
| ... | @@ -600,24 +602,17 @@ if(MSVC) | ... | @@ -600,24 +602,17 @@ if(MSVC) |
| 600 | set(ZIG2_COMPILE_FLAGS "/Od") | 602 | set(ZIG2_COMPILE_FLAGS "/Od") |
| 601 | set(ZIG2_LINK_FLAGS "/STACK:16777216 /FORCE:MULTIPLE") | 603 | set(ZIG2_LINK_FLAGS "/STACK:16777216 /FORCE:MULTIPLE") |
| 602 | else() | 604 | else() |
| 603 | set(ZIG_WASM2C_COMPILE_FLAGS "-std=c99 -O2") | 605 | set(ZIG_WASM2C_COMPILE_FLAGS "-std=c99") |
| 604 | set(ZIG1_COMPILE_FLAGS "-std=c99 -Os -fno-strict-aliasing") | 606 | set(ZIG1_COMPILE_FLAGS "-std=c99 -Oz -fno-strict-aliasing") |
| 605 | set(ZIG2_COMPILE_FLAGS "-std=c99 -O0 -fno-sanitize=undefined -fno-stack-protector -fno-strict-aliasing") | 607 | set(ZIG2_COMPILE_FLAGS "-std=c99 -Oz -fno-sanitize=undefined -fno-stack-protector -fno-strict-aliasing") |
| 608 | if(CMAKE_C_COMPILER_ID STREQUAL "Clang" AND ZIG_HOST_TARGET_ARCH STREQUAL "s390x") | ||
| 609 | string(REPLACE -Oz -O0 ZIG2_COMPILE_FLAGS "${ZIG2_COMPILE_FLAGS}") # llvm 22 assertion failure | ||
| 610 | endif() | ||
| 606 | # Must match the condition in build.zig. | 611 | # Must match the condition in build.zig. |
| 607 | if(ZIG_HOST_TARGET_ARCH MATCHES "^(arm|thumb)(eb)?$" OR ZIG_HOST_TARGET_ARCH EQUAL "hexagon" OR ZIG_HOST_TARGET_ARCH MATCHES "^powerpc(64)?(le)?$") | 612 | if(ZIG_HOST_TARGET_ARCH MATCHES "^(arm|thumb)(eb)?$" OR ZIG_HOST_TARGET_ARCH EQUAL "hexagon" OR ZIG_HOST_TARGET_ARCH MATCHES "^powerpc(64)?(le)?$") |
| 608 | set(ZIG1_COMPILE_FLAGS "${ZIG1_COMPILE_FLAGS} -ffunction-sections -fdata-sections") | 613 | set(ZIG1_COMPILE_FLAGS "${ZIG1_COMPILE_FLAGS} -ffunction-sections -fdata-sections") |
| 609 | set(ZIG2_COMPILE_FLAGS "${ZIG2_COMPILE_FLAGS} -ffunction-sections -fdata-sections") | 614 | set(ZIG2_COMPILE_FLAGS "${ZIG2_COMPILE_FLAGS} -ffunction-sections -fdata-sections") |
| 610 | endif() | 615 | endif() |
| 611 | if(APPLE) | ||
| 612 | set(ZIG2_LINK_FLAGS "-Wl,-stack_size,0x10000000") | ||
| 613 | elseif(MINGW) | ||
| 614 | set(ZIG2_LINK_FLAGS "-Wl,--stack,0x10000000") | ||
| 615 | # Solaris/illumos ld(1) does not provide a --stack-size option. | ||
| 616 | elseif(CMAKE_HOST_SOLARIS) | ||
| 617 | unset(ZIG2_LINK_FLAGS) | ||
| 618 | else() | ||
| 619 | set(ZIG2_LINK_FLAGS "-Wl,-z,stack-size=0x10000000") | ||
| 620 | endif() | ||
| 621 | if (CMAKE_C_COMPILER_ID STREQUAL "GNU") | 616 | if (CMAKE_C_COMPILER_ID STREQUAL "GNU") |
| 622 | # Prevent GCC from miscompiling 'zig2.c'. See also 'GCC_BUG_119085_PRESENT' workaround details in 'bootstrap.c'. | 617 | # Prevent GCC from miscompiling 'zig2.c'. See also 'GCC_BUG_119085_PRESENT' workaround details in 'bootstrap.c'. |
| 623 | if ( | 618 | if ( |
bootstrap.c+2-2| ... | @@ -56,7 +56,7 @@ static void panic(const char *reason) { | ... | @@ -56,7 +56,7 @@ static void panic(const char *reason) { |
| 56 | #define GCC_BUG_119085_PRESENT 0 | 56 | #define GCC_BUG_119085_PRESENT 0 |
| 57 | #endif | 57 | #endif |
| 58 | 58 | ||
| 59 | #if defined(__WIN32__) | 59 | #if defined(_WIN32) |
| 60 | #error TODO write the functionality for executing child process into this build script | 60 | #error TODO write the functionality for executing child process into this build script |
| 61 | #else | 61 | #else |
| 62 | 62 | ||
| ... | @@ -99,7 +99,7 @@ static void print_and_run(const char **argv) { | ... | @@ -99,7 +99,7 @@ static void print_and_run(const char **argv) { |
| 99 | static const char *get_host_os(void) { | 99 | static const char *get_host_os(void) { |
| 100 | const char *host_os = getenv("ZIG_HOST_TARGET_OS"); | 100 | const char *host_os = getenv("ZIG_HOST_TARGET_OS"); |
| 101 | if (host_os != NULL) return host_os; | 101 | if (host_os != NULL) return host_os; |
| 102 | #if defined(__WIN32__) | 102 | #if defined(_WIN32) |
| 103 | return "windows"; | 103 | return "windows"; |
| 104 | #elif defined(__APPLE__) | 104 | #elif defined(__APPLE__) |
| 105 | return "macos"; | 105 | return "macos"; |
build.zig+11-11| ... | @@ -207,7 +207,7 @@ pub fn build(b: *std.Build) !void { | ... | @@ -207,7 +207,7 @@ pub fn build(b: *std.Build) !void { |
| 207 | 207 | ||
| 208 | const mem_leak_frames: u32 = b.option(u32, "mem-leak-frames", "How many stack frames to print when a memory leak occurs. Tests get 2x this amount.") orelse blk: { | 208 | const mem_leak_frames: u32 = b.option(u32, "mem-leak-frames", "How many stack frames to print when a memory leak occurs. Tests get 2x this amount.") orelse blk: { |
| 209 | if (strip == true) break :blk @as(u32, 0); | 209 | if (strip == true) break :blk @as(u32, 0); |
| 210 | if (optimize != .Debug) break :blk 0; | 210 | if (optimize != .debug) break :blk 0; |
| 211 | break :blk 4; | 211 | break :blk 4; |
| 212 | }; | 212 | }; |
| 213 | 213 | ||
| ... | @@ -256,7 +256,7 @@ pub fn build(b: *std.Build) !void { | ... | @@ -256,7 +256,7 @@ pub fn build(b: *std.Build) !void { |
| 256 | exe.root_module.link_libc = true; | 256 | exe.root_module.link_libc = true; |
| 257 | } | 257 | } |
| 258 | 258 | ||
| 259 | const is_debug = optimize == .Debug; | 259 | const is_debug = optimize == .debug; |
| 260 | const enable_debug_extensions = b.option(bool, "debug-extensions", "Enable commands and options useful for debugging the compiler") orelse is_debug; | 260 | const enable_debug_extensions = b.option(bool, "debug-extensions", "Enable commands and options useful for debugging the compiler") orelse is_debug; |
| 261 | const enable_logging = b.option(bool, "log", "Enable debug logging with --debug-log") orelse is_debug; | 261 | const enable_logging = b.option(bool, "log", "Enable debug logging with --debug-log") orelse is_debug; |
| 262 | 262 | ||
| ... | @@ -403,8 +403,8 @@ pub fn build(b: *std.Build) !void { | ... | @@ -403,8 +403,8 @@ pub fn build(b: *std.Build) !void { |
| 403 | if (tracy) |tracy_dir| { | 403 | if (tracy) |tracy_dir| { |
| 404 | const tracy_mod = b.createModule(.{ | 404 | const tracy_mod = b.createModule(.{ |
| 405 | .target = target, | 405 | .target = target, |
| 406 | // Always build Tracy in ReleaseFast so that it doesn't make Debug compiler builds unusable. | 406 | // Always build Tracy in ReleaseFast so that it doesn't make -Odebug compiler builds unusable. |
| 407 | .optimize = .ReleaseFast, | 407 | .optimize = .fast, |
| 408 | .root_source_file = null, | 408 | .root_source_file = null, |
| 409 | .link_libc = true, | 409 | .link_libc = true, |
| 410 | .link_libcpp = true, | 410 | .link_libcpp = true, |
| ... | @@ -434,19 +434,19 @@ pub fn build(b: *std.Build) !void { | ... | @@ -434,19 +434,19 @@ pub fn build(b: *std.Build) !void { |
| 434 | var chosen_opt_modes_buf: [4]std.lang.OptimizeMode = undefined; | 434 | var chosen_opt_modes_buf: [4]std.lang.OptimizeMode = undefined; |
| 435 | var chosen_mode_index: usize = 0; | 435 | var chosen_mode_index: usize = 0; |
| 436 | if (!skip_debug) { | 436 | if (!skip_debug) { |
| 437 | chosen_opt_modes_buf[chosen_mode_index] = .Debug; | 437 | chosen_opt_modes_buf[chosen_mode_index] = .debug; |
| 438 | chosen_mode_index += 1; | 438 | chosen_mode_index += 1; |
| 439 | } | 439 | } |
| 440 | if (!skip_release_safe) { | 440 | if (!skip_release_safe) { |
| 441 | chosen_opt_modes_buf[chosen_mode_index] = .ReleaseSafe; | 441 | chosen_opt_modes_buf[chosen_mode_index] = .safe; |
| 442 | chosen_mode_index += 1; | 442 | chosen_mode_index += 1; |
| 443 | } | 443 | } |
| 444 | if (!skip_release_fast) { | 444 | if (!skip_release_fast) { |
| 445 | chosen_opt_modes_buf[chosen_mode_index] = .ReleaseFast; | 445 | chosen_opt_modes_buf[chosen_mode_index] = .fast; |
| 446 | chosen_mode_index += 1; | 446 | chosen_mode_index += 1; |
| 447 | } | 447 | } |
| 448 | if (!skip_release_small) { | 448 | if (!skip_release_small) { |
| 449 | chosen_opt_modes_buf[chosen_mode_index] = .ReleaseSmall; | 449 | chosen_opt_modes_buf[chosen_mode_index] = .small; |
| 450 | chosen_mode_index += 1; | 450 | chosen_mode_index += 1; |
| 451 | } | 451 | } |
| 452 | const optimize_modes = chosen_opt_modes_buf[0..chosen_mode_index]; | 452 | const optimize_modes = chosen_opt_modes_buf[0..chosen_mode_index]; |
| ... | @@ -622,7 +622,7 @@ pub fn build(b: *std.Build) !void { | ... | @@ -622,7 +622,7 @@ pub fn build(b: *std.Build) !void { |
| 622 | .use_llvm = use_llvm, | 622 | .use_llvm = use_llvm, |
| 623 | .use_lld = use_llvm, | 623 | .use_lld = use_llvm, |
| 624 | .zig_lib_dir = b.path("lib"), | 624 | .zig_lib_dir = b.path("lib"), |
| 625 | .max_rss = 2_700_000_000, | 625 | .max_rss = 3_000_000_000, |
| 626 | }); | 626 | }); |
| 627 | if (link_libc) { | 627 | if (link_libc) { |
| 628 | unit_tests.root_module.link_libc = true; | 628 | unit_tests.root_module.link_libc = true; |
| ... | @@ -763,9 +763,8 @@ fn addWasiUpdateStep(b: *std.Build, version: [:0]const u8) !void { | ... | @@ -763,9 +763,8 @@ fn addWasiUpdateStep(b: *std.Build, version: [:0]const u8) !void { |
| 763 | .optimize = .ReleaseSmall, | 763 | .optimize = .ReleaseSmall, |
| 764 | .target = b.resolveTargetQuery(std.Target.Query.parse(.{ | 764 | .target = b.resolveTargetQuery(std.Target.Query.parse(.{ |
| 765 | .arch_os_abi = "wasm32-wasi", | 765 | .arch_os_abi = "wasm32-wasi", |
| 766 | // * `extended_const` is not supported by the `wasm-opt` version in CI. | ||
| 767 | // * `nontrapping_bulk_memory_len0` is supported by `wasm2c`. | 766 | // * `nontrapping_bulk_memory_len0` is supported by `wasm2c`. |
| 768 | .cpu_features = "baseline-extended_const+nontrapping_bulk_memory_len0", | 767 | .cpu_features = "baseline+nontrapping_bulk_memory_len0", |
| 769 | }) catch unreachable), | 768 | }) catch unreachable), |
| 770 | }); | 769 | }); |
| 771 | 770 | ||
| ... | @@ -809,6 +808,7 @@ fn addWasiUpdateStep(b: *std.Build, version: [:0]const u8) !void { | ... | @@ -809,6 +808,7 @@ fn addWasiUpdateStep(b: *std.Build, version: [:0]const u8) !void { |
| 809 | "-Oz", | 808 | "-Oz", |
| 810 | "--enable-bulk-memory", | 809 | "--enable-bulk-memory", |
| 811 | "--enable-mutable-globals", | 810 | "--enable-mutable-globals", |
| 811 | "--enable-extended-const", | ||
| 812 | "--enable-nontrapping-float-to-int", | 812 | "--enable-nontrapping-float-to-int", |
| 813 | "--enable-sign-ext", | 813 | "--enable-sign-ext", |
| 814 | }); | 814 | }); |
ci/x86_64-freebsd-debug.sh+1-7| ... | @@ -46,13 +46,7 @@ export ZIG_LIB_DIR="$PWD/../lib" | ... | @@ -46,13 +46,7 @@ export ZIG_LIB_DIR="$PWD/../lib" |
| 46 | stage3-debug/bin/zig build test docs \ | 46 | stage3-debug/bin/zig build test docs \ |
| 47 | --maxrss ${ZSF_MAX_RSS:-0} \ | 47 | --maxrss ${ZSF_MAX_RSS:-0} \ |
| 48 | -Dstatic-llvm \ | 48 | -Dstatic-llvm \ |
| 49 | -Dskip-spirv \ | 49 | -Dskip-non-native \ |
| 50 | -Dskip-wasm \ | ||
| 51 | -Dskip-linux \ | ||
| 52 | -Dskip-netbsd \ | ||
| 53 | -Dskip-openbsd \ | ||
| 54 | -Dskip-windows \ | ||
| 55 | -Dskip-darwin \ | ||
| 56 | --search-prefix "$PREFIX" \ | 50 | --search-prefix "$PREFIX" \ |
| 57 | --test-timeout 2m | 51 | --test-timeout 2m |
| 58 | 52 |
ci/x86_64-freebsd-release.sh+1-7| ... | @@ -46,13 +46,7 @@ export ZIG_LIB_DIR="$PWD/../lib" | ... | @@ -46,13 +46,7 @@ export ZIG_LIB_DIR="$PWD/../lib" |
| 46 | stage3-release/bin/zig build test docs \ | 46 | stage3-release/bin/zig build test docs \ |
| 47 | --maxrss ${ZSF_MAX_RSS:-0} \ | 47 | --maxrss ${ZSF_MAX_RSS:-0} \ |
| 48 | -Dstatic-llvm \ | 48 | -Dstatic-llvm \ |
| 49 | -Dskip-spirv \ | 49 | -Dskip-non-native \ |
| 50 | -Dskip-wasm \ | ||
| 51 | -Dskip-linux \ | ||
| 52 | -Dskip-netbsd \ | ||
| 53 | -Dskip-openbsd \ | ||
| 54 | -Dskip-windows \ | ||
| 55 | -Dskip-darwin \ | ||
| 56 | --search-prefix "$PREFIX" \ | 50 | --search-prefix "$PREFIX" \ |
| 57 | --test-timeout 2m | 51 | --test-timeout 2m |
| 58 | 52 |
ci/x86_64-linux-debug.sh+1-1| ... | @@ -44,7 +44,7 @@ ninja install | ... | @@ -44,7 +44,7 @@ ninja install |
| 44 | 44 | ||
| 45 | # Must be done after zig cc is finished. | 45 | # Must be done after zig cc is finished. |
| 46 | export ZIG_LIB_DIR="$PWD/../lib" | 46 | export ZIG_LIB_DIR="$PWD/../lib" |
| 47 | export ZIG_DEBUG_MAKER=1 | 47 | export ZIG_DEBUG_CMD=1 |
| 48 | 48 | ||
| 49 | # simultaneously test building self-hosted without LLVM and with 32-bit arm | 49 | # simultaneously test building self-hosted without LLVM and with 32-bit arm |
| 50 | stage3-debug/bin/zig build \ | 50 | stage3-debug/bin/zig build \ |
doc/langref.html.in+6-2| ... | @@ -1119,6 +1119,10 @@ | ... | @@ -1119,6 +1119,10 @@ |
| 1119 | otherwise the optimizer figures out all the values at compile-time, | 1119 | otherwise the optimizer figures out all the values at compile-time, |
| 1120 | which operates in strict mode.</p> | 1120 | which operates in strict mode.</p> |
| 1121 | {#code|float_mode_exe.zig#} | 1121 | {#code|float_mode_exe.zig#} |
| 1122 | {#shell_samp#}$ zig build-exe float_mode_exe.zig float_mode_obj.o -O fast | ||
| 1123 | $ ./float_mode_exe | ||
| 1124 | optimized = 0.001 | ||
| 1125 | strict = 0.0009765625{#end_shell_samp#} | ||
| 1122 | 1126 | ||
| 1123 | {#see_also|@setFloatMode|Division by Zero#} | 1127 | {#see_also|@setFloatMode|Division by Zero#} |
| 1124 | {#header_close#} | 1128 | {#header_close#} |
| ... | @@ -5848,7 +5852,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val | ... | @@ -5848,7 +5852,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val |
| 5848 | {#header_open|@Union#} | 5852 | {#header_open|@Union#} |
| 5849 | <pre>{#syntax#}@Union( | 5853 | <pre>{#syntax#}@Union( |
| 5850 | comptime layout: std.lang.Type.ContainerLayout, | 5854 | comptime layout: std.lang.Type.ContainerLayout, |
| 5851 | /// Either the integer tag type, or the integer backing type, depending on `layout`. | 5855 | /// Either the enum tag type, or the integer backing type, depending on `layout`. |
| 5852 | comptime ArgType: ?type, | 5856 | comptime ArgType: ?type, |
| 5853 | comptime field_names: []const []const u8, | 5857 | comptime field_names: []const []const u8, |
| 5854 | comptime field_types: *const [field_names.len]type, | 5858 | comptime field_types: *const [field_names.len]type, |
| ... | @@ -7499,7 +7503,7 @@ fn readU32Be() u32 {} | ... | @@ -7499,7 +7503,7 @@ fn readU32Be() u32 {} |
| 7499 | <pre>{#syntax#}errdefer{#endsyntax#}</pre> | 7503 | <pre>{#syntax#}errdefer{#endsyntax#}</pre> |
| 7500 | </th> | 7504 | </th> |
| 7501 | <td> | 7505 | <td> |
| 7502 | {#syntax#}errdefer{#endsyntax#} will execute an expression when control flow leaves the current block if the function returns an error, the errdefer expression can capture the unwrapped value. | 7506 | {#syntax#}errdefer{#endsyntax#} will execute an expression when control flow leaves the current block if the function returns an error. |
| 7503 | <ul> | 7507 | <ul> |
| 7504 | <li>See also {#link|errdefer#}</li> | 7508 | <li>See also {#link|errdefer#}</li> |
| 7505 | </ul> | 7509 | </ul> |
doc/langref/test_packed_structs.zig-1| ... | @@ -1,5 +1,4 @@ | ... | @@ -1,5 +1,4 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const native_endian = @import("builtin").target.cpu.arch.endian(); | ||
| 3 | const expectEqual = std.testing.expectEqual; | 2 | const expectEqual = std.testing.expectEqual; |
| 4 | 3 | ||
| 5 | const Full = packed struct { | 4 | const Full = packed struct { |
lib/build-web/time_report.zig+3-3| ... | @@ -84,7 +84,7 @@ pub fn compileResultMessage(msg_bytes: []u8) error{ OutOfMemory, WriteFailed }!v | ... | @@ -84,7 +84,7 @@ pub fn compileResultMessage(msg_bytes: []u8) error{ OutOfMemory, WriteFailed }!v |
| 84 | defer gpa.free(slowest_decls); | 84 | defer gpa.free(slowest_decls); |
| 85 | 85 | ||
| 86 | for (slowest_files) |*file_out| { | 86 | for (slowest_files) |*file_out| { |
| 87 | const i = std.mem.indexOfScalar(u8, trailing, 0) orelse @panic("malformed CompileResult message"); | 87 | const i = std.mem.findScalar(u8, trailing, 0) orelse @panic("malformed CompileResult message"); |
| 88 | file_out.* = .{ | 88 | file_out.* = .{ |
| 89 | .name = trailing[0..i], | 89 | .name = trailing[0..i], |
| 90 | .ns_sema = 0, | 90 | .ns_sema = 0, |
| ... | @@ -95,7 +95,7 @@ pub fn compileResultMessage(msg_bytes: []u8) error{ OutOfMemory, WriteFailed }!v | ... | @@ -95,7 +95,7 @@ pub fn compileResultMessage(msg_bytes: []u8) error{ OutOfMemory, WriteFailed }!v |
| 95 | } | 95 | } |
| 96 | 96 | ||
| 97 | for (slowest_decls) |*decl_out| { | 97 | for (slowest_decls) |*decl_out| { |
| 98 | const i = std.mem.indexOfScalar(u8, trailing, 0) orelse @panic("malformed CompileResult message"); | 98 | const i = std.mem.findScalar(u8, trailing, 0) orelse @panic("malformed CompileResult message"); |
| 99 | const file_idx = std.mem.readInt(u32, trailing[i..][1..5], .little); | 99 | const file_idx = std.mem.readInt(u32, trailing[i..][1..5], .little); |
| 100 | const sema_count = std.mem.readInt(u32, trailing[i..][5..9], .little); | 100 | const sema_count = std.mem.readInt(u32, trailing[i..][5..9], .little); |
| 101 | const sema_ns = std.mem.readInt(u64, trailing[i..][9..17], .little); | 101 | const sema_ns = std.mem.readInt(u64, trailing[i..][9..17], .little); |
| ... | @@ -258,7 +258,7 @@ pub fn runTestResultMessage(msg_bytes: []u8) error{OutOfMemory}!void { | ... | @@ -258,7 +258,7 @@ pub fn runTestResultMessage(msg_bytes: []u8) error{OutOfMemory}!void { |
| 258 | defer table_html.deinit(gpa); | 258 | defer table_html.deinit(gpa); |
| 259 | 259 | ||
| 260 | for (durations) |test_ns| { | 260 | for (durations) |test_ns| { |
| 261 | const test_name_len = std.mem.indexOfScalar(u8, trailing[offset..], 0) orelse @panic("malformed RunTestResult message"); | 261 | const test_name_len = std.mem.findScalar(u8, trailing[offset..], 0) orelse @panic("malformed RunTestResult message"); |
| 262 | const test_name = trailing[offset..][0..test_name_len]; | 262 | const test_name = trailing[offset..][0..test_name_len]; |
| 263 | offset += test_name_len + 1; | 263 | offset += test_name_len + 1; |
| 264 | try table_html.print(gpa, "<tr><th scope=\"row\"><code>{f}</code></th>", .{fmtEscapeHtml(test_name)}); | 264 | try table_html.print(gpa, "<tr><th scope=\"row\"><code>{f}</code></th>", .{fmtEscapeHtml(test_name)}); |
lib/c/malloc.zig+2-2| ... | @@ -59,8 +59,8 @@ const Header = packed struct(u64) { | ... | @@ -59,8 +59,8 @@ const Header = packed struct(u64) { |
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | const safety = switch (builtin.mode) { | 61 | const safety = switch (builtin.mode) { |
| 62 | .Debug, .ReleaseSafe => true, | 62 | .debug, .safe => true, |
| 63 | .ReleaseFast, .ReleaseSmall => false, | 63 | .fast, .small => false, |
| 64 | }; | 64 | }; |
| 65 | const max_addr_bits = switch (safety) { | 65 | const max_addr_bits = switch (safety) { |
| 66 | true => 48, // Ensures space for Canary bits. | 66 | true => 48, // Ensures space for Canary bits. |
lib/compiler/Maker.zig+339-78| ... | @@ -11,6 +11,7 @@ const File = std.Io.File; | ... | @@ -11,6 +11,7 @@ const File = std.Io.File; |
| 11 | const Io = std.Io; | 11 | const Io = std.Io; |
| 12 | const Dir = std.Io.Dir; | 12 | const Dir = std.Io.Dir; |
| 13 | const Path = std.Build.Cache.Path; | 13 | const Path = std.Build.Cache.Path; |
| 14 | const Reader = std.Io.Reader; | ||
| 14 | const Writer = std.Io.Writer; | 15 | const Writer = std.Io.Writer; |
| 15 | const assert = std.debug.assert; | 16 | const assert = std.debug.assert; |
| 16 | const fatal = std.process.fatal; | 17 | const fatal = std.process.fatal; |
| ... | @@ -19,6 +20,8 @@ const log = std.log; | ... | @@ -19,6 +20,8 @@ const log = std.log; |
| 19 | const mem = std.mem; | 20 | const mem = std.mem; |
| 20 | const process = std.process; | 21 | const process = std.process; |
| 21 | const Color = std.zig.Color; | 22 | const Color = std.zig.Color; |
| 23 | const Client = std.zig.Client; | ||
| 24 | const Server = std.zig.Server; | ||
| 22 | const EnvVar = std.zig.EnvVar; | 25 | const EnvVar = std.zig.EnvVar; |
| 23 | const default_local_zig_cache_basename = std.zig.default_local_zig_cache_basename; | 26 | const default_local_zig_cache_basename = std.zig.default_local_zig_cache_basename; |
| 24 | const stringToEnum = std.meta.stringToEnum; | 27 | const stringToEnum = std.meta.stringToEnum; |
| ... | @@ -51,10 +54,14 @@ max_rss_mutex: Io.Mutex, | ... | @@ -51,10 +54,14 @@ max_rss_mutex: Io.Mutex, |
| 51 | skip_oom_steps: bool, | 54 | skip_oom_steps: bool, |
| 52 | unit_test_timeout_ns: ?u64, | 55 | unit_test_timeout_ns: ?u64, |
| 53 | watch: bool, | 56 | watch: bool, |
| 57 | protocol_server: ?*AvoidableServer, | ||
| 58 | protocol_server_mutex: Io.Mutex, | ||
| 54 | web_server: ?*AvoidableWebServer, | 59 | web_server: ?*AvoidableWebServer, |
| 55 | /// Allocated into `gpa`. | 60 | /// Allocated into `gpa`. |
| 56 | memory_blocked_steps: std.ArrayList(Configuration.Step.Index), | 61 | memory_blocked_steps: std.ArrayList(Configuration.Step.Index), |
| 57 | /// Allocated into `gpa`. | 62 | /// Allocated into `gpa`. |
| 63 | initial_steps: std.array_hash_map.Auto(Configuration.Step.Index, void), | ||
| 64 | /// Allocated into `gpa`. | ||
| 58 | step_stack: std.array_hash_map.Auto(Configuration.Step.Index, void), | 65 | step_stack: std.array_hash_map.Auto(Configuration.Step.Index, void), |
| 59 | pkg_config: PkgConfig, | 66 | pkg_config: PkgConfig, |
| 60 | 67 | ||
| ... | @@ -67,12 +74,13 @@ var stdio_buffer_allocation: [256]u8 = undefined; | ... | @@ -67,12 +74,13 @@ var stdio_buffer_allocation: [256]u8 = undefined; |
| 67 | var stdout_writer_allocation: Io.File.Writer = undefined; | 74 | var stdout_writer_allocation: Io.File.Writer = undefined; |
| 68 | var debug_maker_leaks: bool = false; | 75 | var debug_maker_leaks: bool = false; |
| 69 | 76 | ||
| 77 | const AvoidableServer = if (builtin.single_threaded) void else Server; | ||
| 70 | const AvoidableWebServer = if (builtin.single_threaded) void else WebServer; | 78 | const AvoidableWebServer = if (builtin.single_threaded) void else WebServer; |
| 71 | 79 | ||
| 72 | const is_debug_mode = builtin.mode == .Debug; | 80 | const is_debug_mode = builtin.mode == .debug; |
| 73 | const use_safe_allocator = switch (builtin.mode) { | 81 | const use_safe_allocator = switch (builtin.mode) { |
| 74 | .Debug, .ReleaseSafe => true, | 82 | .debug, .safe => true, |
| 75 | .ReleaseFast, .ReleaseSmall => false, | 83 | .fast, .small => false, |
| 76 | }; | 84 | }; |
| 77 | 85 | ||
| 78 | const InstallPaths = struct { | 86 | const InstallPaths = struct { |
| ... | @@ -216,6 +224,7 @@ pub fn main(init: process.Init.Minimal) !void { | ... | @@ -216,6 +224,7 @@ pub fn main(init: process.Init.Minimal) !void { |
| 216 | var watch = false; | 224 | var watch = false; |
| 217 | var fuzz: ?Fuzz.Mode = null; | 225 | var fuzz: ?Fuzz.Mode = null; |
| 218 | var debounce_interval_ms: u16 = 50; | 226 | var debounce_interval_ms: u16 = 50; |
| 227 | var listen: bool = false; | ||
| 219 | var webui_listen: ?Io.net.IpAddress = null; | 228 | var webui_listen: ?Io.net.IpAddress = null; |
| 220 | var debug_pkg_config = false; | 229 | var debug_pkg_config = false; |
| 221 | var run_args: ?[]const []const u8 = null; | 230 | var run_args: ?[]const []const u8 = null; |
| ... | @@ -242,6 +251,12 @@ pub fn main(init: process.Init.Minimal) !void { | ... | @@ -242,6 +251,12 @@ pub fn main(init: process.Init.Minimal) !void { |
| 242 | } | 251 | } |
| 243 | } | 252 | } |
| 244 | 253 | ||
| 254 | if (EnvVar.ZIG_BUILD_SUMMARY.get(&graph.environ_map)) |str| { | ||
| 255 | if (stringToEnum(Summary, str)) |value| { | ||
| 256 | summary = value; | ||
| 257 | } | ||
| 258 | } | ||
| 259 | |||
| 245 | try configure_argv.ensureUnusedCapacity(arena, 16); | 260 | try configure_argv.ensureUnusedCapacity(arena, 16); |
| 246 | try cached_passthru_configure.ensureUnusedCapacity(arena, 16); | 261 | try cached_passthru_configure.ensureUnusedCapacity(arena, 16); |
| 247 | 262 | ||
| ... | @@ -416,6 +431,8 @@ pub fn main(init: process.Init.Minimal) !void { | ... | @@ -416,6 +431,8 @@ pub fn main(init: process.Init.Minimal) !void { |
| 416 | next_arg, err, | 431 | next_arg, err, |
| 417 | }); | 432 | }); |
| 418 | }; | 433 | }; |
| 434 | } else if (mem.eql(u8, arg, "--listen=-")) { | ||
| 435 | listen = true; | ||
| 419 | } else if (mem.eql(u8, arg, "--webui")) { | 436 | } else if (mem.eql(u8, arg, "--webui")) { |
| 420 | if (webui_listen == null) webui_listen = .{ .ip6 = .loopback(0) }; | 437 | if (webui_listen == null) webui_listen = .{ .ip6 = .loopback(0) }; |
| 421 | } else if (mem.startsWith(u8, arg, "--webui=")) { | 438 | } else if (mem.startsWith(u8, arg, "--webui=")) { |
| ... | @@ -553,7 +570,7 @@ pub fn main(init: process.Init.Minimal) !void { | ... | @@ -553,7 +570,7 @@ pub fn main(init: process.Init.Minimal) !void { |
| 553 | } | 570 | } |
| 554 | 571 | ||
| 555 | const early_exit_mode = fetch_only or help_menu or steps_menu or print_configuration != .none; | 572 | const early_exit_mode = fetch_only or help_menu or steps_menu or print_configuration != .none; |
| 556 | const server_mode = !early_exit_mode and (watch or webui_listen != null or fuzz != null); | 573 | const server_mode = !early_exit_mode and (watch or webui_listen != null or fuzz != null or listen); |
| 557 | 574 | ||
| 558 | process.raiseFileDescriptorLimit(); | 575 | process.raiseFileDescriptorLimit(); |
| 559 | 576 | ||
| ... | @@ -631,20 +648,31 @@ pub fn main(init: process.Init.Minimal) !void { | ... | @@ -631,20 +648,31 @@ pub fn main(init: process.Init.Minimal) !void { |
| 631 | .sub_path = "zig-out", | 648 | .sub_path = "zig-out", |
| 632 | }; | 649 | }; |
| 633 | 650 | ||
| 634 | const install_lib_path: Path = if (override_lib_dir) |cwd_relative| .{ | 651 | // These three overrides are meant to be relative to the install prefix, |
| 635 | .root_dir = .cwd(), | 652 | // not current working directory, unless absolute paths are used. |
| 636 | .sub_path = cwd_relative, | 653 | const install_lib_path: Path = if (override_lib_dir) |lib_dir| |
| 637 | } else try install_prefix_path.join(arena, "lib"); | 654 | if (Dir.path.isAbsolute(lib_dir)) .{ |
| 655 | .root_dir = .cwd(), | ||
| 656 | .sub_path = lib_dir, | ||
| 657 | } else try install_prefix_path.join(arena, lib_dir) | ||
| 658 | else | ||
| 659 | try install_prefix_path.join(arena, "lib"); | ||
| 638 | 660 | ||
| 639 | const install_bin_path: Path = if (override_bin_dir) |cwd_relative| .{ | 661 | const install_bin_path: Path = if (override_bin_dir) |bin_dir| |
| 640 | .root_dir = .cwd(), | 662 | if (Dir.path.isAbsolute(bin_dir)) .{ |
| 641 | .sub_path = cwd_relative, | 663 | .root_dir = .cwd(), |
| 642 | } else try install_prefix_path.join(arena, "bin"); | 664 | .sub_path = bin_dir, |
| 665 | } else try install_prefix_path.join(arena, bin_dir) | ||
| 666 | else | ||
| 667 | try install_prefix_path.join(arena, "bin"); | ||
| 643 | 668 | ||
| 644 | const install_include_path: Path = if (override_include_dir) |cwd_relative| .{ | 669 | const install_include_path: Path = if (override_include_dir) |include_dir| |
| 645 | .root_dir = .cwd(), | 670 | if (Dir.path.isAbsolute(include_dir)) .{ |
| 646 | .sub_path = cwd_relative, | 671 | .root_dir = .cwd(), |
| 647 | } else try install_prefix_path.join(arena, "include"); | 672 | .sub_path = include_dir, |
| 673 | } else try install_prefix_path.join(arena, include_dir) | ||
| 674 | else | ||
| 675 | try install_prefix_path.join(arena, "include"); | ||
| 648 | 676 | ||
| 649 | const now = Io.Clock.Timestamp.now(io, .awake); | 677 | const now = Io.Clock.Timestamp.now(io, .awake); |
| 650 | 678 | ||
| ... | @@ -661,6 +689,25 @@ pub fn main(init: process.Init.Minimal) !void { | ... | @@ -661,6 +689,25 @@ pub fn main(init: process.Init.Minimal) !void { |
| 661 | break :ws &web_server_allocation; | 689 | break :ws &web_server_allocation; |
| 662 | } else null; | 690 | } else null; |
| 663 | 691 | ||
| 692 | var stdin_buffer: [256]u8 = undefined; | ||
| 693 | var stdout_buffer: [256]u8 = undefined; | ||
| 694 | var stdin_reader = Io.File.stdin().reader(io, &stdin_buffer); | ||
| 695 | var stdout_writer = Io.File.stdout().writer(io, &stdout_buffer); | ||
| 696 | |||
| 697 | var protocol_server_allocation: AvoidableServer = undefined; | ||
| 698 | const protocol_server: ?*AvoidableServer = if (listen) s: { | ||
| 699 | if (builtin.single_threaded) fatal("--listen is not yet supported on single-threaded hosts", .{}); | ||
| 700 | if (watch) fatal("using '--watch' and '--listen' together is not supported", .{}); | ||
| 701 | if (fuzz != null) fatal("using '--fuzz' and '--listen' together is not supported", .{}); | ||
| 702 | if (step_names.items.len > 0) fatal("build steps must be provided over the protocol instead of using CLI arguments", .{}); | ||
| 703 | protocol_server_allocation = .{ | ||
| 704 | .in = &stdin_reader.interface, | ||
| 705 | .out = &stdout_writer.interface, | ||
| 706 | }; | ||
| 707 | try serveBSPHandshake(&protocol_server_allocation); | ||
| 708 | break :s &protocol_server_allocation; | ||
| 709 | } else null; | ||
| 710 | |||
| 664 | while (true) { | 711 | while (true) { |
| 665 | // If this fails, we can still start the server and wait for user | 712 | // If this fails, we can still start the server and wait for user |
| 666 | // to request a rebuild. If it returns error.FailedButCacheIntact | 713 | // to request a rebuild. If it returns error.FailedButCacheIntact |
| ... | @@ -731,16 +778,25 @@ pub fn main(init: process.Init.Minimal) !void { | ... | @@ -731,16 +778,25 @@ pub fn main(init: process.Init.Minimal) !void { |
| 731 | 778 | ||
| 732 | .watch = watch, | 779 | .watch = watch, |
| 733 | .web_server = web_server, | 780 | .web_server = web_server, |
| 781 | .protocol_server = protocol_server, | ||
| 782 | .protocol_server_mutex = .init, | ||
| 734 | .memory_blocked_steps = .empty, | 783 | .memory_blocked_steps = .empty, |
| 784 | .initial_steps = .empty, | ||
| 735 | .step_stack = .empty, | 785 | .step_stack = .empty, |
| 736 | .pkg_config = .{ .debug = debug_pkg_config }, | 786 | .pkg_config = .{ .debug = debug_pkg_config }, |
| 737 | 787 | ||
| 738 | .error_style = error_style, | 788 | .error_style = error_style, |
| 739 | .multiline_errors = multiline_errors, | 789 | .multiline_errors = multiline_errors, |
| 740 | .summary = summary orelse if (watch or webui_listen != null) .new else .failures, | 790 | .summary = summary orelse if (listen) |
| 791 | .none | ||
| 792 | else if (watch or webui_listen != null) | ||
| 793 | .new | ||
| 794 | else | ||
| 795 | .failures, | ||
| 741 | }; | 796 | }; |
| 742 | defer { | 797 | defer { |
| 743 | maker.memory_blocked_steps.deinit(gpa); | 798 | maker.memory_blocked_steps.deinit(gpa); |
| 799 | maker.initial_steps.deinit(gpa); | ||
| 744 | maker.step_stack.deinit(gpa); | 800 | maker.step_stack.deinit(gpa); |
| 745 | } | 801 | } |
| 746 | 802 | ||
| ... | @@ -749,7 +805,91 @@ pub fn main(init: process.Init.Minimal) !void { | ... | @@ -749,7 +805,91 @@ pub fn main(init: process.Init.Minimal) !void { |
| 749 | maker.max_rss_is_default = true; | 805 | maker.max_rss_is_default = true; |
| 750 | } | 806 | } |
| 751 | 807 | ||
| 752 | maker.prepare(step_names.items) catch |err| switch (err) { | 808 | if (protocol_server) |s| { |
| 809 | try s.serveStringMessage(.bsp_configuration, try arena.print("{f}", .{scanned_config.path})); | ||
| 810 | |||
| 811 | var w: ?Watch = null; | ||
| 812 | |||
| 813 | const Event = union(enum) { | ||
| 814 | message: Reader.Error!Client.Message.Header, | ||
| 815 | fs_event: if (Watch.have_impl) @typeInfo(@TypeOf(Watch.wait)).@"fn".return_type.? else noreturn, | ||
| 816 | }; | ||
| 817 | |||
| 818 | var select_buffer: [2]Event = undefined; | ||
| 819 | var select: Io.Select(Event) = .init(io, &select_buffer); | ||
| 820 | defer select.cancelDiscard(); | ||
| 821 | |||
| 822 | try select.concurrent(.message, Server.receiveMessage, .{s}); | ||
| 823 | |||
| 824 | var in_debounce = false; | ||
| 825 | loop: switch (try select.await()) { | ||
| 826 | .message => |payload| { | ||
| 827 | const header: Client.Message.Header = try payload; | ||
| 828 | switch (header.tag) { | ||
| 829 | .exit => { | ||
| 830 | cleanExit(io, &scanned_config); | ||
| 831 | process.exit(0); | ||
| 832 | }, | ||
| 833 | .bsp_build_steps => { | ||
| 834 | // Cancel existing file watching | ||
| 835 | select.cancelDiscard(); | ||
| 836 | in_debounce = false; | ||
| 837 | |||
| 838 | const body = try s.in.takeStruct(Client.Message.BuildSteps, .little); | ||
| 839 | const steps = try s.in.readSliceEndianAlloc(gpa, Configuration.Step.Index, body.step_count, .little); | ||
| 840 | defer gpa.free(steps); | ||
| 841 | if (body.flags.watch and !Watch.have_impl) fatal("file watching is unavailable", .{}); | ||
| 842 | |||
| 843 | try select.concurrent(.message, Server.receiveMessage, .{s}); | ||
| 844 | |||
| 845 | maker.watch = body.flags.watch; | ||
| 846 | maker.prepare(steps) catch |err| switch (err) { | ||
| 847 | error.DependencyLoopDetected, error.InsufficientMemory => { | ||
| 848 | // TODO handle DependencyLoopDetected as error.FailedButCacheIntact | ||
| 849 | // and handle InsufficientMemory as error.AlreadyReported | ||
| 850 | _ = io.lockStderr(&.{}, graph.stderr_mode) catch {}; | ||
| 851 | process.exit(1); | ||
| 852 | }, | ||
| 853 | else => |e| return e, | ||
| 854 | }; | ||
| 855 | |||
| 856 | try maker.makeSteps(main_progress_node, null); | ||
| 857 | |||
| 858 | if (body.flags.watch) { | ||
| 859 | if (!Watch.have_impl) unreachable; | ||
| 860 | if (w == null) w = try .init(&maker); | ||
| 861 | |||
| 862 | try w.?.update(maker.step_stack.keys()); | ||
| 863 | try select.concurrent(.fs_event, Watch.wait, .{ &w.?, if (in_debounce) .{ .ms = debounce_interval_ms } else .none }); | ||
| 864 | } | ||
| 865 | |||
| 866 | continue :loop try select.await(); | ||
| 867 | }, | ||
| 868 | else => fatal("unsupported message: {t}", .{header.tag}), | ||
| 869 | } | ||
| 870 | }, | ||
| 871 | .fs_event => |payload| { | ||
| 872 | if (!Watch.have_impl) unreachable; | ||
| 873 | switch (try payload) { | ||
| 874 | .timeout => { | ||
| 875 | assert(in_debounce); | ||
| 876 | markFailedStepsDirty(&maker); | ||
| 877 | try maker.makeSteps(main_progress_node, null); | ||
| 878 | in_debounce = false; | ||
| 879 | }, | ||
| 880 | .dirty => in_debounce = true, | ||
| 881 | .clean => {}, | ||
| 882 | } | ||
| 883 | try select.concurrent(.fs_event, Watch.wait, .{ &w.?, if (in_debounce) .{ .ms = debounce_interval_ms } else .none }); | ||
| 884 | continue :loop try select.await(); | ||
| 885 | }, | ||
| 886 | } | ||
| 887 | } | ||
| 888 | |||
| 889 | const initial_steps = try maker.resolveTopLevelSteps(step_names.items); | ||
| 890 | defer gpa.free(initial_steps); | ||
| 891 | |||
| 892 | maker.prepare(initial_steps) catch |err| switch (err) { | ||
| 753 | error.DependencyLoopDetected, error.InsufficientMemory => { | 893 | error.DependencyLoopDetected, error.InsufficientMemory => { |
| 754 | // TODO handle DependencyLoopDetected as error.FailedButCacheIntact | 894 | // TODO handle DependencyLoopDetected as error.FailedButCacheIntact |
| 755 | // and handle InsufficientMemory as error.AlreadyReported | 895 | // and handle InsufficientMemory as error.AlreadyReported |
| ... | @@ -774,18 +914,7 @@ pub fn main(init: process.Init.Minimal) !void { | ... | @@ -774,18 +914,7 @@ pub fn main(init: process.Init.Minimal) !void { |
| 774 | error.WriteFailed => return stderr.file_writer.err.?, | 914 | error.WriteFailed => return stderr.file_writer.err.?, |
| 775 | }; | 915 | }; |
| 776 | }) { | 916 | }) { |
| 777 | if (web_server) |ws| ws.startBuild(); | 917 | try maker.makeSteps(main_progress_node, fuzz); |
| 778 | |||
| 779 | try maker.makeStepNames(step_names.items, main_progress_node, fuzz); | ||
| 780 | |||
| 781 | if (web_server) |ws| { | ||
| 782 | if (fuzz) |mode| if (mode != .forever) fatal( | ||
| 783 | "error: limited fuzzing is not implemented yet for --webui", | ||
| 784 | .{}, | ||
| 785 | ); | ||
| 786 | |||
| 787 | ws.finishBuild(.{ .fuzz = fuzz != null }); | ||
| 788 | } | ||
| 789 | 918 | ||
| 790 | if (web_server) |ws| { | 919 | if (web_server) |ws| { |
| 791 | const c = &scanned_config.configuration; | 920 | const c = &scanned_config.configuration; |
| ... | @@ -850,6 +979,9 @@ pub fn main(init: process.Init.Minimal) !void { | ... | @@ -850,6 +979,9 @@ pub fn main(init: process.Init.Minimal) !void { |
| 850 | _ = io.lockStderr(&.{}, graph.stderr_mode) catch {}; | 979 | _ = io.lockStderr(&.{}, graph.stderr_mode) catch {}; |
| 851 | process.exit(1); | 980 | process.exit(1); |
| 852 | } | 981 | } |
| 982 | if (protocol_server != null) { | ||
| 983 | fatal("(zig build system) TODO send error messages to client when build.zig compilation fails", .{}); | ||
| 984 | } | ||
| 853 | if (watch and can_fs_watch) { | 985 | if (watch and can_fs_watch) { |
| 854 | fatal("(zig build system) TODO set up fs watching even when build.zig compilation fails", .{}); | 986 | fatal("(zig build system) TODO set up fs watching even when build.zig compilation fails", .{}); |
| 855 | } else { | 987 | } else { |
| ... | @@ -1330,7 +1462,7 @@ fn configure(graph: *Graph, options: ConfigureOptions) !ScannedConfig { | ... | @@ -1330,7 +1462,7 @@ fn configure(graph: *Graph, options: ConfigureOptions) !ScannedConfig { |
| 1330 | if (config_man) |man| for (configuration.path_deps) |path_dep| { | 1462 | if (config_man) |man| for (configuration.path_deps) |path_dep| { |
| 1331 | switch (path_dep.flags.mode) { | 1463 | switch (path_dep.flags.mode) { |
| 1332 | .directory => {}, // TODO | 1464 | .directory => {}, // TODO |
| 1333 | .contents => try man.addPathPost(confPathDepToCachePath(graph, &configuration, path_dep)), | 1465 | .contents => try man.addPathPost(try confPathDepToCachePath(arena, graph, &configuration, path_dep)), |
| 1334 | .metadata => {}, // TODO | 1466 | .metadata => {}, // TODO |
| 1335 | } | 1467 | } |
| 1336 | }; | 1468 | }; |
| ... | @@ -1433,7 +1565,6 @@ fn cmdFetch(gpa: Allocator, graph: *Graph, args: []const []const u8) !void { | ... | @@ -1433,7 +1565,6 @@ fn cmdFetch(gpa: Allocator, graph: *Graph, args: []const []const u8) !void { |
| 1433 | 1565 | ||
| 1434 | const color: Color = Color.settingFromEnvironment(environ_map); | 1566 | const color: Color = Color.settingFromEnvironment(environ_map); |
| 1435 | var opt_path_or_url: ?[]const u8 = null; | 1567 | var opt_path_or_url: ?[]const u8 = null; |
| 1436 | var override_global_cache_dir: ?[]const u8 = EnvVar.ZIG_GLOBAL_CACHE_DIR.get(environ_map); | ||
| 1437 | var override_local_cache_dir: ?[]const u8 = EnvVar.ZIG_LOCAL_CACHE_DIR.get(environ_map); | 1568 | var override_local_cache_dir: ?[]const u8 = EnvVar.ZIG_LOCAL_CACHE_DIR.get(environ_map); |
| 1438 | var override_pkg_dir: ?[]const u8 = EnvVar.ZIG_LOCAL_PKG_DIR.get(environ_map); | 1569 | var override_pkg_dir: ?[]const u8 = EnvVar.ZIG_LOCAL_PKG_DIR.get(environ_map); |
| 1439 | var debug_hash: bool = false; | 1570 | var debug_hash: bool = false; |
| ... | @@ -1449,8 +1580,6 @@ fn cmdFetch(gpa: Allocator, graph: *Graph, args: []const []const u8) !void { | ... | @@ -1449,8 +1580,6 @@ fn cmdFetch(gpa: Allocator, graph: *Graph, args: []const []const u8) !void { |
| 1449 | if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) { | 1580 | if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) { |
| 1450 | try Io.File.stdout().writeStreamingAll(io, usage_fetch); | 1581 | try Io.File.stdout().writeStreamingAll(io, usage_fetch); |
| 1451 | return process.cleanExit(io); | 1582 | return process.cleanExit(io); |
| 1452 | } else if (mem.eql(u8, arg, "--global-cache-dir")) { | ||
| 1453 | override_global_cache_dir = nextArgOrFatal(args, &arg_i); | ||
| 1454 | } else if (mem.eql(u8, arg, "--cache-dir")) { | 1583 | } else if (mem.eql(u8, arg, "--cache-dir")) { |
| 1455 | override_local_cache_dir = nextArgOrFatal(args, &arg_i); | 1584 | override_local_cache_dir = nextArgOrFatal(args, &arg_i); |
| 1456 | } else if (mem.eql(u8, arg, "--pkg-dir")) { | 1585 | } else if (mem.eql(u8, arg, "--pkg-dir")) { |
| ... | @@ -1730,7 +1859,6 @@ const usage_fetch = | ... | @@ -1730,7 +1859,6 @@ const usage_fetch = |
| 1730 | \\ | 1859 | \\ |
| 1731 | \\Options: | 1860 | \\Options: |
| 1732 | \\ -h, --help Print this help and exit | 1861 | \\ -h, --help Print this help and exit |
| 1733 | \\ --global-cache-dir [path] Override path to global Zig cache directory | ||
| 1734 | \\ --cache-dir [path] Override path to local cache directory | 1862 | \\ --cache-dir [path] Override path to local cache directory |
| 1735 | \\ --pkg-dir [path] Override path to local package directory | 1863 | \\ --pkg-dir [path] Override path to local package directory |
| 1736 | \\ --debug-hash Print verbose hash information to stdout | 1864 | \\ --debug-hash Print verbose hash information to stdout |
| ... | @@ -1991,7 +2119,7 @@ fn markFailedStepsDirty(maker: *Maker) void { | ... | @@ -1991,7 +2119,7 @@ fn markFailedStepsDirty(maker: *Maker) void { |
| 1991 | for (all_steps) |step_index| { | 2119 | for (all_steps) |step_index| { |
| 1992 | const step = maker.stepByIndex(step_index); | 2120 | const step = maker.stepByIndex(step_index); |
| 1993 | switch (step.state) { | 2121 | switch (step.state) { |
| 1994 | .dependency_failure, .failure, .skipped => _ = maker.invalidateResult(step), | 2122 | .dependency_failure, .dependency_skipped, .failure, .skipped => _ = maker.invalidateResult(step), |
| 1995 | else => continue, | 2123 | else => continue, |
| 1996 | } | 2124 | } |
| 1997 | } | 2125 | } |
| ... | @@ -2020,11 +2148,37 @@ pub fn stepByIndex(maker: *const Maker, i: Configuration.Step.Index) *Step { | ... | @@ -2020,11 +2148,37 @@ pub fn stepByIndex(maker: *const Maker, i: Configuration.Step.Index) *Step { |
| 2020 | return &maker.steps[@backingInt(i)]; | 2148 | return &maker.steps[@backingInt(i)]; |
| 2021 | } | 2149 | } |
| 2022 | 2150 | ||
| 2023 | fn prepare(maker: *Maker, step_names: []const []const u8) !void { | 2151 | fn resolveTopLevelSteps(maker: *Maker, step_names: []const []const u8) ![]const Configuration.Step.Index { |
| 2152 | const gpa = maker.gpa; | ||
| 2153 | const c = &maker.scanned_config.configuration; | ||
| 2154 | |||
| 2155 | if (step_names.len == 0) { | ||
| 2156 | return try gpa.dupe(Configuration.Step.Index, &.{c.default_step}); | ||
| 2157 | } | ||
| 2158 | |||
| 2159 | var result: std.array_hash_map.Auto(Configuration.Step.Index, void) = .empty; | ||
| 2160 | defer result.deinit(gpa); | ||
| 2161 | |||
| 2162 | try result.ensureTotalCapacity(gpa, step_names.len); | ||
| 2163 | |||
| 2164 | for (0..step_names.len) |i| { | ||
| 2165 | const step_name = step_names[step_names.len - i - 1]; | ||
| 2166 | const s = maker.scanned_config.top_level_steps.get(step_name) orelse { | ||
| 2167 | log.info("to list available steps: zig build -l", .{}); | ||
| 2168 | fatal("no such step: {s}", .{step_name}); | ||
| 2169 | }; | ||
| 2170 | result.putAssumeCapacity(s, {}); | ||
| 2171 | } | ||
| 2172 | |||
| 2173 | return try gpa.dupe(Configuration.Step.Index, result.keys()); | ||
| 2174 | } | ||
| 2175 | |||
| 2176 | fn prepare(maker: *Maker, step_indices: []const Configuration.Step.Index) !void { | ||
| 2024 | const gpa = maker.gpa; | 2177 | const gpa = maker.gpa; |
| 2025 | const graph = maker.graph; | 2178 | const graph = maker.graph; |
| 2026 | const arena = graph.arena; | 2179 | const arena = graph.arena; |
| 2027 | const seed: u32 = graph.random_seed; | 2180 | const seed: u32 = graph.random_seed; |
| 2181 | const initial_steps = &maker.initial_steps; | ||
| 2028 | const step_stack = &maker.step_stack; | 2182 | const step_stack = &maker.step_stack; |
| 2029 | const c = &maker.scanned_config.configuration; | 2183 | const c = &maker.scanned_config.configuration; |
| 2030 | 2184 | ||
| ... | @@ -2033,18 +2187,15 @@ fn prepare(maker: *Maker, step_names: []const []const u8) !void { | ... | @@ -2033,18 +2187,15 @@ fn prepare(maker: *Maker, step_names: []const []const u8) !void { |
| 2033 | step.* = .{ .extended = .init(step_index.ptr(c).flags(c).tag) }; | 2187 | step.* = .{ .extended = .init(step_index.ptr(c).flags(c).tag) }; |
| 2034 | } | 2188 | } |
| 2035 | 2189 | ||
| 2036 | if (step_names.len == 0) { | 2190 | try initial_steps.ensureUnusedCapacity(gpa, step_indices.len); |
| 2037 | try step_stack.put(gpa, c.default_step, {}); | 2191 | try step_stack.ensureUnusedCapacity(gpa, step_indices.len); |
| 2038 | } else { | 2192 | |
| 2039 | try step_stack.ensureUnusedCapacity(gpa, step_names.len); | 2193 | initial_steps.clearRetainingCapacity(); |
| 2040 | for (0..step_names.len) |i| { | 2194 | step_stack.clearRetainingCapacity(); |
| 2041 | const step_name = step_names[step_names.len - i - 1]; | 2195 | |
| 2042 | const s = maker.scanned_config.top_level_steps.get(step_name) orelse { | 2196 | for (step_indices) |step| { |
| 2043 | log.info("to list available steps: zig build -l", .{}); | 2197 | initial_steps.putAssumeCapacity(step, {}); |
| 2044 | fatal("no such step: {s}", .{step_name}); | 2198 | step_stack.putAssumeCapacity(step, {}); |
| 2045 | }; | ||
| 2046 | step_stack.putAssumeCapacity(s, {}); | ||
| 2047 | } | ||
| 2048 | } | 2199 | } |
| 2049 | 2200 | ||
| 2050 | const starting_steps = try arena.dupe(Configuration.Step.Index, step_stack.keys()); | 2201 | const starting_steps = try arena.dupe(Configuration.Step.Index, step_stack.keys()); |
| ... | @@ -2085,6 +2236,7 @@ fn prepare(maker: *Maker, step_names: []const []const u8) !void { | ... | @@ -2085,6 +2236,7 @@ fn prepare(maker: *Maker, step_names: []const []const u8) !void { |
| 2085 | } | 2236 | } |
| 2086 | } | 2237 | } |
| 2087 | if (any_problems) { | 2238 | if (any_problems) { |
| 2239 | log.info("use --skip-oom-steps to proceed, skipping memory limited steps", .{}); | ||
| 2088 | if (maker.max_rss_is_default) { | 2240 | if (maker.max_rss_is_default) { |
| 2089 | log.info("use --maxrss {d} to proceed, risking system memory exhaustion", .{max_needed}); | 2241 | log.info("use --maxrss {d} to proceed, risking system memory exhaustion", .{max_needed}); |
| 2090 | } | 2242 | } |
| ... | @@ -2093,9 +2245,8 @@ fn prepare(maker: *Maker, step_names: []const []const u8) !void { | ... | @@ -2093,9 +2245,8 @@ fn prepare(maker: *Maker, step_names: []const []const u8) !void { |
| 2093 | } | 2245 | } |
| 2094 | } | 2246 | } |
| 2095 | 2247 | ||
| 2096 | fn makeStepNames( | 2248 | fn makeSteps( |
| 2097 | maker: *Maker, | 2249 | maker: *Maker, |
| 2098 | step_names: []const []const u8, | ||
| 2099 | parent_progress_node: std.Progress.Node, | 2250 | parent_progress_node: std.Progress.Node, |
| 2100 | fuzz: ?Fuzz.Mode, | 2251 | fuzz: ?Fuzz.Mode, |
| 2101 | ) !void { | 2252 | ) !void { |
| ... | @@ -2106,6 +2257,12 @@ fn makeStepNames( | ... | @@ -2106,6 +2257,12 @@ fn makeStepNames( |
| 2106 | const top_level_steps = &maker.scanned_config.top_level_steps; | 2257 | const top_level_steps = &maker.scanned_config.top_level_steps; |
| 2107 | const c = &maker.scanned_config.configuration; | 2258 | const c = &maker.scanned_config.configuration; |
| 2108 | 2259 | ||
| 2260 | if (maker.web_server) |ws| ws.startBuild(); | ||
| 2261 | |||
| 2262 | if (maker.protocol_server) |s| { | ||
| 2263 | try s.serveBodylessMessage(.bsp_build_started); | ||
| 2264 | } | ||
| 2265 | |||
| 2109 | { | 2266 | { |
| 2110 | // Collect the initial set of tasks (those with no outstanding dependencies) into a buffer, | 2267 | // Collect the initial set of tasks (those with no outstanding dependencies) into a buffer, |
| 2111 | // then spawn them. The buffer is so that we don't race with `makeStep` and end up thinking | 2268 | // then spawn them. The buffer is so that we don't race with `makeStep` and end up thinking |
| ... | @@ -2131,6 +2288,19 @@ fn makeStepNames( | ... | @@ -2131,6 +2288,19 @@ fn makeStepNames( |
| 2131 | try group.await(io); | 2288 | try group.await(io); |
| 2132 | } | 2289 | } |
| 2133 | 2290 | ||
| 2291 | if (maker.web_server) |ws| { | ||
| 2292 | if (fuzz) |mode| if (mode != .forever) fatal( | ||
| 2293 | "error: limited fuzzing is not implemented yet for --webui", | ||
| 2294 | .{}, | ||
| 2295 | ); | ||
| 2296 | |||
| 2297 | ws.finishBuild(.{ .fuzz = fuzz != null }); | ||
| 2298 | } | ||
| 2299 | |||
| 2300 | if (maker.protocol_server) |s| { | ||
| 2301 | try s.serveBodylessMessage(.bsp_build_completed); | ||
| 2302 | } | ||
| 2303 | |||
| 2134 | assert(maker.memory_blocked_steps.items.len == 0); | 2304 | assert(maker.memory_blocked_steps.items.len == 0); |
| 2135 | 2305 | ||
| 2136 | var test_pass_count: usize = 0; | 2306 | var test_pass_count: usize = 0; |
| ... | @@ -2164,7 +2334,7 @@ fn makeStepNames( | ... | @@ -2164,7 +2334,7 @@ fn makeStepNames( |
| 2164 | .precheck_unstarted => unreachable, | 2334 | .precheck_unstarted => unreachable, |
| 2165 | .precheck_started => unreachable, | 2335 | .precheck_started => unreachable, |
| 2166 | .precheck_done => unreachable, | 2336 | .precheck_done => unreachable, |
| 2167 | .dependency_failure => pending_count += 1, | 2337 | .dependency_failure, .dependency_skipped => pending_count += 1, |
| 2168 | .success => success_count += 1, | 2338 | .success => success_count += 1, |
| 2169 | .skipped, .skipped_oom => skipped_count += 1, | 2339 | .skipped, .skipped_oom => skipped_count += 1, |
| 2170 | .failure => { | 2340 | .failure => { |
| ... | @@ -2283,7 +2453,7 @@ fn makeStepNames( | ... | @@ -2283,7 +2453,7 @@ fn makeStepNames( |
| 2283 | defer step_stack_copy.deinit(gpa); | 2453 | defer step_stack_copy.deinit(gpa); |
| 2284 | 2454 | ||
| 2285 | var print_node: PrintNode = .{ .parent = null }; | 2455 | var print_node: PrintNode = .{ .parent = null }; |
| 2286 | if (step_names.len == 0) { | 2456 | if (maker.initial_steps.count() == 0) { |
| 2287 | print_node.last = true; | 2457 | print_node.last = true; |
| 2288 | printTreeStep(maker, c.default_step, t, &print_node, &step_stack_copy) catch |err| switch (err) { | 2458 | printTreeStep(maker, c.default_step, t, &print_node, &step_stack_copy) catch |err| switch (err) { |
| 2289 | error.Canceled => |e| return e, | 2459 | error.Canceled => |e| return e, |
| ... | @@ -2291,10 +2461,10 @@ fn makeStepNames( | ... | @@ -2291,10 +2461,10 @@ fn makeStepNames( |
| 2291 | }; | 2461 | }; |
| 2292 | } else { | 2462 | } else { |
| 2293 | const last_index = if (maker.summary == .all) top_level_steps.count() else blk: { | 2463 | const last_index = if (maker.summary == .all) top_level_steps.count() else blk: { |
| 2294 | var i: usize = step_names.len; | 2464 | var i: usize = maker.initial_steps.count(); |
| 2295 | while (i > 0) { | 2465 | while (i > 0) { |
| 2296 | i -= 1; | 2466 | i -= 1; |
| 2297 | const step_index = top_level_steps.get(step_names[i]).?; | 2467 | const step_index = maker.initial_steps.keys()[i]; |
| 2298 | const step = maker.stepByIndex(step_index); | 2468 | const step = maker.stepByIndex(step_index); |
| 2299 | const found = switch (maker.summary) { | 2469 | const found = switch (maker.summary) { |
| 2300 | .all, .line, .none => unreachable, | 2470 | .all, .line, .none => unreachable, |
| ... | @@ -2305,8 +2475,7 @@ fn makeStepNames( | ... | @@ -2305,8 +2475,7 @@ fn makeStepNames( |
| 2305 | } | 2475 | } |
| 2306 | break :blk top_level_steps.count(); | 2476 | break :blk top_level_steps.count(); |
| 2307 | }; | 2477 | }; |
| 2308 | for (step_names, 0..) |step_name, i| { | 2478 | for (maker.initial_steps.keys(), 0..) |step_index, i| { |
| 2309 | const step_index = top_level_steps.get(step_name).?; | ||
| 2310 | print_node.last = i + 1 == last_index; | 2479 | print_node.last = i + 1 == last_index; |
| 2311 | printTreeStep(maker, step_index, t, &print_node, &step_stack_copy) catch |err| switch (err) { | 2480 | printTreeStep(maker, step_index, t, &print_node, &step_stack_copy) catch |err| switch (err) { |
| 2312 | error.Canceled => |e| return e, | 2481 | error.Canceled => |e| return e, |
| ... | @@ -2317,7 +2486,7 @@ fn makeStepNames( | ... | @@ -2317,7 +2486,7 @@ fn makeStepNames( |
| 2317 | w.writeByte('\n') catch {}; | 2486 | w.writeByte('\n') catch {}; |
| 2318 | } | 2487 | } |
| 2319 | 2488 | ||
| 2320 | if (maker.watch or maker.web_server != null) return; | 2489 | if (maker.watch or maker.web_server != null or maker.protocol_server != null) return; |
| 2321 | 2490 | ||
| 2322 | const code: u8 = code: { | 2491 | const code: u8 = code: { |
| 2323 | if (failure_count == 0) break :code 0; // success | 2492 | if (failure_count == 0) break :code 0; // success |
| ... | @@ -2392,6 +2561,15 @@ fn makeStep( | ... | @@ -2392,6 +2561,15 @@ fn makeStep( |
| 2392 | defer step_prog_node.end(); | 2561 | defer step_prog_node.end(); |
| 2393 | 2562 | ||
| 2394 | if (maker.web_server) |ws| ws.updateStepStatus(step_index, .wip); | 2563 | if (maker.web_server) |ws| ws.updateStepStatus(step_index, .wip); |
| 2564 | if (maker.protocol_server) |s| { | ||
| 2565 | maker.protocol_server_mutex.lockUncancelable(io); | ||
| 2566 | defer maker.protocol_server_mutex.unlock(io); | ||
| 2567 | |||
| 2568 | s.serveU32Message( | ||
| 2569 | .bsp_step_started, | ||
| 2570 | @backingInt(step_index), | ||
| 2571 | ) catch @panic("TODO propagate error when failing to send protocol message"); | ||
| 2572 | } | ||
| 2395 | 2573 | ||
| 2396 | const new_state: Step.State = for (deps) |dep_index| { | 2574 | const new_state: Step.State = for (deps) |dep_index| { |
| 2397 | const dep_make_step = maker.stepByIndex(dep_index); | 2575 | const dep_make_step = maker.stepByIndex(dep_index); |
| ... | @@ -2402,10 +2580,14 @@ fn makeStep( | ... | @@ -2402,10 +2580,14 @@ fn makeStep( |
| 2402 | 2580 | ||
| 2403 | .failure, | 2581 | .failure, |
| 2404 | .dependency_failure, | 2582 | .dependency_failure, |
| 2405 | .skipped_oom, | ||
| 2406 | => break .dependency_failure, | 2583 | => break .dependency_failure, |
| 2407 | 2584 | ||
| 2408 | .success, .skipped => {}, | 2585 | .dependency_skipped, |
| 2586 | .skipped_oom, | ||
| 2587 | .skipped, | ||
| 2588 | => break .dependency_skipped, | ||
| 2589 | |||
| 2590 | .success => {}, | ||
| 2409 | } | 2591 | } |
| 2410 | } else if (Step.make(step_index, maker, step_prog_node)) state: { | 2592 | } else if (Step.make(step_index, maker, step_prog_node)) state: { |
| 2411 | break :state .success; | 2593 | break :state .success; |
| ... | @@ -2417,25 +2599,46 @@ fn makeStep( | ... | @@ -2417,25 +2599,46 @@ fn makeStep( |
| 2417 | 2599 | ||
| 2418 | @atomicStore(Step.State, &make_step.state, new_state, .monotonic); | 2600 | @atomicStore(Step.State, &make_step.state, new_state, .monotonic); |
| 2419 | 2601 | ||
| 2420 | switch (new_state) { | 2602 | const success = switch (new_state) { |
| 2421 | .precheck_unstarted => unreachable, | 2603 | .precheck_unstarted => unreachable, |
| 2422 | .precheck_started => unreachable, | 2604 | .precheck_started => unreachable, |
| 2423 | .precheck_done => unreachable, | 2605 | .precheck_done => unreachable, |
| 2424 | 2606 | ||
| 2425 | .failure, | 2607 | .failure, |
| 2426 | .dependency_failure, | 2608 | .dependency_failure, |
| 2609 | .dependency_skipped, | ||
| 2427 | .skipped_oom, | 2610 | .skipped_oom, |
| 2428 | => { | 2611 | .skipped, |
| 2429 | if (maker.web_server) |ws| ws.updateStepStatus(step_index, .failure); | 2612 | => false, |
| 2430 | std.Progress.setStatus(.failure_working); | ||
| 2431 | }, | ||
| 2432 | 2613 | ||
| 2433 | .success, | 2614 | .success, |
| 2434 | .skipped, | 2615 | => true, |
| 2435 | => { | 2616 | }; |
| 2436 | if (maker.web_server) |ws| ws.updateStepStatus(step_index, .success); | 2617 | |
| 2437 | }, | 2618 | if (maker.web_server) |ws| { |
| 2619 | ws.updateStepStatus(step_index, if (success) .success else .failure); | ||
| 2438 | } | 2620 | } |
| 2621 | if (maker.protocol_server != null) { | ||
| 2622 | maker.protocol_server_mutex.lockUncancelable(io); | ||
| 2623 | defer maker.protocol_server_mutex.unlock(io); | ||
| 2624 | |||
| 2625 | const status: Server.Message.BuildStepCompleted.Status = switch (new_state) { | ||
| 2626 | .precheck_unstarted => unreachable, | ||
| 2627 | .precheck_started => unreachable, | ||
| 2628 | .precheck_done => unreachable, | ||
| 2629 | .success => .success, | ||
| 2630 | .failure, .dependency_failure => .failure, | ||
| 2631 | .dependency_skipped, .skipped => .skipped, | ||
| 2632 | .skipped_oom => .skipped_oom, | ||
| 2633 | }; | ||
| 2634 | serveBuildStepCompleted( | ||
| 2635 | maker, | ||
| 2636 | step_index, | ||
| 2637 | status, | ||
| 2638 | ) catch |err| std.debug.panic("TODO propagate error when failing to send protocol message: {t}", .{err}); | ||
| 2639 | } | ||
| 2640 | |||
| 2641 | if (!success) std.Progress.setStatus(.failure_working); | ||
| 2439 | } | 2642 | } |
| 2440 | 2643 | ||
| 2441 | // No matter the result, we want to display error/warning messages. | 2644 | // No matter the result, we want to display error/warning messages. |
| ... | @@ -2468,7 +2671,7 @@ fn makeStep( | ... | @@ -2468,7 +2671,7 @@ fn makeStep( |
| 2468 | maker.available_rss += max_rss; | 2671 | maker.available_rss += max_rss; |
| 2469 | dispatch_set.ensureUnusedCapacity(gpa, maker.memory_blocked_steps.items.len) catch | 2672 | dispatch_set.ensureUnusedCapacity(gpa, maker.memory_blocked_steps.items.len) catch |
| 2470 | @panic("TODO eliminate memory allocation here"); | 2673 | @panic("TODO eliminate memory allocation here"); |
| 2471 | while (maker.memory_blocked_steps.getLast()) |candidate_index| { | 2674 | while (maker.memory_blocked_steps.last()) |candidate_index| { |
| 2472 | const candidate_max_rss = candidate_index.ptr(c).max_rss.toBytes(); | 2675 | const candidate_max_rss = candidate_index.ptr(c).max_rss.toBytes(); |
| 2473 | if (maker.available_rss < candidate_max_rss) break; | 2676 | if (maker.available_rss < candidate_max_rss) break; |
| 2474 | assert(maker.memory_blocked_steps.pop() == candidate_index); | 2677 | assert(maker.memory_blocked_steps.pop() == candidate_index); |
| ... | @@ -2579,6 +2782,12 @@ fn printStepStatus(maker: *Maker, step_index: Configuration.Step.Index, stderr: | ... | @@ -2579,6 +2782,12 @@ fn printStepStatus(maker: *Maker, step_index: Configuration.Step.Index, stderr: |
| 2579 | try stderr.setColor(.reset); | 2782 | try stderr.setColor(.reset); |
| 2580 | }, | 2783 | }, |
| 2581 | 2784 | ||
| 2785 | .dependency_skipped => { | ||
| 2786 | try stderr.setColor(.dim); | ||
| 2787 | try writer.writeAll(" transitive skip\n"); | ||
| 2788 | try stderr.setColor(.reset); | ||
| 2789 | }, | ||
| 2790 | |||
| 2582 | .success => { | 2791 | .success => { |
| 2583 | try stderr.setColor(.green); | 2792 | try stderr.setColor(.green); |
| 2584 | if (s.result_cached) { | 2793 | if (s.result_cached) { |
| ... | @@ -2825,6 +3034,7 @@ fn constructGraphAndCheckForDependencyLoop( | ... | @@ -2825,6 +3034,7 @@ fn constructGraphAndCheckForDependencyLoop( |
| 2825 | 3034 | ||
| 2826 | // These don't happen until we actually run the step graph. | 3035 | // These don't happen until we actually run the step graph. |
| 2827 | .dependency_failure => unreachable, | 3036 | .dependency_failure => unreachable, |
| 3037 | .dependency_skipped => unreachable, | ||
| 2828 | .success => unreachable, | 3038 | .success => unreachable, |
| 2829 | .failure => unreachable, | 3039 | .failure => unreachable, |
| 2830 | .skipped => unreachable, | 3040 | .skipped => unreachable, |
| ... | @@ -2912,7 +3122,7 @@ pub fn printErrorMessages( | ... | @@ -2912,7 +3122,7 @@ pub fn printErrorMessages( |
| 2912 | try stderr.setColor(.red); | 3122 | try stderr.setColor(.red); |
| 2913 | try writer.writeAll("error:"); | 3123 | try writer.writeAll("error:"); |
| 2914 | try stderr.setColor(.reset); | 3124 | try stderr.setColor(.reset); |
| 2915 | if (std.mem.indexOfScalar(u8, msg, '\n') == null) { | 3125 | if (std.mem.findScalar(u8, msg, '\n') == null) { |
| 2916 | try writer.print(" {s}\n", .{msg}); | 3126 | try writer.print(" {s}\n", .{msg}); |
| 2917 | } else switch (multiline_errors) { | 3127 | } else switch (multiline_errors) { |
| 2918 | .indent => { | 3128 | .indent => { |
| ... | @@ -2990,6 +3200,50 @@ fn cleanTmpFiles(maker: *Maker, steps: []const Configuration.Step.Index) void { | ... | @@ -2990,6 +3200,50 @@ fn cleanTmpFiles(maker: *Maker, steps: []const Configuration.Step.Index) void { |
| 2990 | } | 3200 | } |
| 2991 | } | 3201 | } |
| 2992 | 3202 | ||
| 3203 | fn serveBSPHandshake(s: *const std.zig.Server) !void { | ||
| 3204 | const handshake_header: Server.Message.Handshake = .{ | ||
| 3205 | .version = Server.build_system_version, | ||
| 3206 | .flags = .{ | ||
| 3207 | .file_system_watch_supported = Watch.have_impl, | ||
| 3208 | }, | ||
| 3209 | }; | ||
| 3210 | try s.serveMessageHeader(.{ | ||
| 3211 | .tag = .bsp_handshake, | ||
| 3212 | .bytes_len = @sizeOf(Server.Message.Handshake), | ||
| 3213 | }); | ||
| 3214 | try s.out.writeStruct(handshake_header, .little); | ||
| 3215 | try s.out.flush(); | ||
| 3216 | } | ||
| 3217 | |||
| 3218 | fn serveBuildStepCompleted( | ||
| 3219 | maker: *Maker, | ||
| 3220 | step_index: Configuration.Step.Index, | ||
| 3221 | status: Server.Message.BuildStepCompleted.Status, | ||
| 3222 | ) !void { | ||
| 3223 | const s: *Server = maker.protocol_server.?; | ||
| 3224 | const step = maker.stepByIndex(step_index); | ||
| 3225 | const error_bundle = step.result_error_bundle; | ||
| 3226 | |||
| 3227 | const body: Server.Message.BuildStepCompleted = .{ | ||
| 3228 | .step_index = step_index, | ||
| 3229 | .status = status, | ||
| 3230 | .error_bundle = .{ | ||
| 3231 | .extra_len = @intCast(error_bundle.extra.len), | ||
| 3232 | .string_bytes_len = @intCast(error_bundle.string_bytes.len), | ||
| 3233 | }, | ||
| 3234 | }; | ||
| 3235 | const eb_bytes_len = @sizeOf(u32) * error_bundle.extra.len + error_bundle.string_bytes.len; | ||
| 3236 | const bytes_len = @sizeOf(Server.Message.BuildStepCompleted) + eb_bytes_len; | ||
| 3237 | try s.serveMessageHeader(.{ | ||
| 3238 | .tag = .bsp_step_completed, | ||
| 3239 | .bytes_len = @intCast(bytes_len), | ||
| 3240 | }); | ||
| 3241 | try s.out.writeStruct(body, .little); | ||
| 3242 | try s.out.writeSliceEndian(u32, error_bundle.extra, .little); | ||
| 3243 | try s.out.writeAll(error_bundle.string_bytes); | ||
| 3244 | try s.out.flush(); | ||
| 3245 | } | ||
| 3246 | |||
| 2993 | fn initStdoutWriter(io: Io) *Writer { | 3247 | fn initStdoutWriter(io: Io) *Writer { |
| 2994 | stdout_writer_allocation = Io.File.stdout().writerStreaming(io, &stdio_buffer_allocation); | 3248 | stdout_writer_allocation = Io.File.stdout().writerStreaming(io, &stdio_buffer_allocation); |
| 2995 | return &stdout_writer_allocation.interface; | 3249 | return &stdout_writer_allocation.interface; |
| ... | @@ -3071,17 +3325,19 @@ pub fn packagePath( | ... | @@ -3071,17 +3325,19 @@ pub fn packagePath( |
| 3071 | ) Allocator.Error!Path { | 3325 | ) Allocator.Error!Path { |
| 3072 | const c = &maker.scanned_config.configuration; | 3326 | const c = &maker.scanned_config.configuration; |
| 3073 | const graph = maker.graph; | 3327 | const graph = maker.graph; |
| 3074 | const package = package_index.get(c) orelse return .{ | 3328 | |
| 3329 | if (package_index == .root) return .{ | ||
| 3075 | .root_dir = graph.build_root_directory, | 3330 | .root_dir = graph.build_root_directory, |
| 3076 | .sub_path = sub_path, | 3331 | .sub_path = sub_path, |
| 3077 | }; | 3332 | }; |
| 3333 | |||
| 3078 | // Currently, neither configurer nor Maker is aware of the standard zig | 3334 | // Currently, neither configurer nor Maker is aware of the standard zig |
| 3079 | // package path, and the root path is stored as a bare string rather than | 3335 | // package path, and the root path is stored as a bare string rather than |
| 3080 | // relative to a known base directory. Without changing that, we must | 3336 | // relative to a known base directory. Without changing that, we must |
| 3081 | // construct a cwd relative path here. | 3337 | // construct a cwd relative path here. |
| 3082 | return .{ | 3338 | return .{ |
| 3083 | .root_dir = .cwd(), | 3339 | .root_dir = .cwd(), |
| 3084 | .sub_path = try Dir.path.join(arena, &.{ package.root_path.slice(c), sub_path }), | 3340 | .sub_path = try Dir.path.join(arena, &.{ package_index.ptr(c).root_path.slice(c), sub_path }), |
| 3085 | }; | 3341 | }; |
| 3086 | } | 3342 | } |
| 3087 | 3343 | ||
| ... | @@ -3687,7 +3943,12 @@ const Templates = struct { | ... | @@ -3687,7 +3943,12 @@ const Templates = struct { |
| 3687 | } | 3943 | } |
| 3688 | }; | 3944 | }; |
| 3689 | 3945 | ||
| 3690 | fn confPathDepToCachePath(graph: *const Graph, c: *const Configuration, path_dep: Configuration.PathDep) Path { | 3946 | fn confPathDepToCachePath( |
| 3947 | arena: Allocator, | ||
| 3948 | graph: *const Graph, | ||
| 3949 | c: *const Configuration, | ||
| 3950 | path_dep: Configuration.PathDep, | ||
| 3951 | ) Allocator.Error!Path { | ||
| 3691 | const sub_path = path_dep.sub.slice(c); | 3952 | const sub_path = path_dep.sub.slice(c); |
| 3692 | return switch (path_dep.flags.base) { | 3953 | return switch (path_dep.flags.base) { |
| 3693 | .cwd => .{ | 3954 | .cwd => .{ |
| ... | @@ -3703,11 +3964,11 @@ fn confPathDepToCachePath(graph: *const Graph, c: *const Configuration, path_dep | ... | @@ -3703,11 +3964,11 @@ fn confPathDepToCachePath(graph: *const Graph, c: *const Configuration, path_dep |
| 3703 | .sub_path = sub_path, | 3964 | .sub_path = sub_path, |
| 3704 | }, | 3965 | }, |
| 3705 | .build_root => .{ | 3966 | .build_root => .{ |
| 3706 | .root_dir = switch (path_dep.pkg.unwrap().?) { | 3967 | .root_dir = graph.build_root_directory, |
| 3707 | .root => graph.build_root_directory, | 3968 | .sub_path = switch (path_dep.pkg.unwrap().?) { |
| 3708 | _ => @panic("TODO"), | 3969 | .root => sub_path, |
| 3970 | else => |index| try Dir.path.join(arena, &.{ index.ptr(c).root_path.slice(c), sub_path }), | ||
| 3709 | }, | 3971 | }, |
| 3710 | .sub_path = sub_path, | ||
| 3711 | }, | 3972 | }, |
| 3712 | .zig_lib => .{ | 3973 | .zig_lib => .{ |
| 3713 | .root_dir = graph.zig_lib_directory, | 3974 | .root_dir = graph.zig_lib_directory, |
lib/compiler/Maker/Fetch.zig+3-3| ... | @@ -1164,7 +1164,7 @@ const FileType = enum { | ... | @@ -1164,7 +1164,7 @@ const FileType = enum { |
| 1164 | if (cd_header[value_start] != '=') return null; | 1164 | if (cd_header[value_start] != '=') return null; |
| 1165 | value_start += 1; | 1165 | value_start += 1; |
| 1166 | 1166 | ||
| 1167 | var value_end = std.mem.indexOfPos(u8, cd_header, value_start, ";") orelse cd_header.len; | 1167 | var value_end = std.mem.findPos(u8, cd_header, value_start, ";") orelse cd_header.len; |
| 1168 | if (cd_header[value_end - 1] == '\"') { | 1168 | if (cd_header[value_end - 1] == '\"') { |
| 1169 | value_end -= 1; | 1169 | value_end -= 1; |
| 1170 | } | 1170 | } |
| ... | @@ -1344,7 +1344,7 @@ fn unpackResource( | ... | @@ -1344,7 +1344,7 @@ fn unpackResource( |
| 1344 | return f.fail(f.location_tok, try eb.addString("missing 'Content-Type' header")); | 1344 | return f.fail(f.location_tok, try eb.addString("missing 'Content-Type' header")); |
| 1345 | 1345 | ||
| 1346 | // Extract the MIME type, ignoring charset and boundary directives | 1346 | // Extract the MIME type, ignoring charset and boundary directives |
| 1347 | const mime_type_end = std.mem.indexOf(u8, content_type, ";") orelse content_type.len; | 1347 | const mime_type_end = std.mem.find(u8, content_type, ";") orelse content_type.len; |
| 1348 | const mime_type = content_type[0..mime_type_end]; | 1348 | const mime_type = content_type[0..mime_type_end]; |
| 1349 | 1349 | ||
| 1350 | if (ascii.eqlIgnoreCase(mime_type, "application/x-tar")) | 1350 | if (ascii.eqlIgnoreCase(mime_type, "application/x-tar")) |
| ... | @@ -1455,7 +1455,7 @@ fn unpackTarball(f: *Fetch, out_dir: Io.Dir, reader: *Io.Reader) RunError!Unpack | ... | @@ -1455,7 +1455,7 @@ fn unpackTarball(f: *Fetch, out_dir: Io.Dir, reader: *Io.Reader) RunError!Unpack |
| 1455 | 1455 | ||
| 1456 | var diagnostics: std.tar.Diagnostics = .{ .allocator = arena }; | 1456 | var diagnostics: std.tar.Diagnostics = .{ .allocator = arena }; |
| 1457 | 1457 | ||
| 1458 | std.tar.pipeToFileSystem(io, out_dir, reader, .{ | 1458 | std.tar.extract(io, out_dir, reader, .{ |
| 1459 | .diagnostics = &diagnostics, | 1459 | .diagnostics = &diagnostics, |
| 1460 | .strip_components = 0, | 1460 | .strip_components = 0, |
| 1461 | .mode_mode = .ignore, | 1461 | .mode_mode = .ignore, |
lib/compiler/Maker/Fetch/git.zig+6-6| ... | @@ -336,7 +336,7 @@ pub const Repository = struct { | ... | @@ -336,7 +336,7 @@ pub const Repository = struct { |
| 336 | fn next(iterator: *TreeIterator) !?Entry { | 336 | fn next(iterator: *TreeIterator) !?Entry { |
| 337 | if (iterator.pos == iterator.data.len) return null; | 337 | if (iterator.pos == iterator.data.len) return null; |
| 338 | 338 | ||
| 339 | const mode_end = mem.indexOfScalarPos(u8, iterator.data, iterator.pos, ' ') orelse return error.InvalidTree; | 339 | const mode_end = mem.findScalarPos(u8, iterator.data, iterator.pos, ' ') orelse return error.InvalidTree; |
| 340 | const mode: packed struct { | 340 | const mode: packed struct { |
| 341 | permission: u9, | 341 | permission: u9, |
| 342 | unused: u3, | 342 | unused: u3, |
| ... | @@ -351,7 +351,7 @@ pub const Repository = struct { | ... | @@ -351,7 +351,7 @@ pub const Repository = struct { |
| 351 | }; | 351 | }; |
| 352 | iterator.pos = mode_end + 1; | 352 | iterator.pos = mode_end + 1; |
| 353 | 353 | ||
| 354 | const name_end = mem.indexOfScalarPos(u8, iterator.data, iterator.pos, 0) orelse return error.InvalidTree; | 354 | const name_end = mem.findScalarPos(u8, iterator.data, iterator.pos, 0) orelse return error.InvalidTree; |
| 355 | const name = iterator.data[iterator.pos..name_end :0]; | 355 | const name = iterator.data[iterator.pos..name_end :0]; |
| 356 | iterator.pos = name_end + 1; | 356 | iterator.pos = name_end + 1; |
| 357 | 357 | ||
| ... | @@ -823,7 +823,7 @@ pub const Session = struct { | ... | @@ -823,7 +823,7 @@ pub const Session = struct { |
| 823 | value: ?[]const u8 = null, | 823 | value: ?[]const u8 = null, |
| 824 | 824 | ||
| 825 | fn parse(data: []const u8) Capability { | 825 | fn parse(data: []const u8) Capability { |
| 826 | return if (mem.indexOfScalar(u8, data, '=')) |separator_pos| | 826 | return if (mem.findScalar(u8, data, '=')) |separator_pos| |
| 827 | .{ .key = data[0..separator_pos], .value = data[separator_pos + 1 ..] } | 827 | .{ .key = data[0..separator_pos], .value = data[separator_pos + 1 ..] } |
| 828 | else | 828 | else |
| 829 | .{ .key = data }; | 829 | .{ .key = data }; |
| ... | @@ -941,17 +941,17 @@ pub const Session = struct { | ... | @@ -941,17 +941,17 @@ pub const Session = struct { |
| 941 | .flush => return null, | 941 | .flush => return null, |
| 942 | .data => |data| { | 942 | .data => |data| { |
| 943 | const ref_data = Packet.normalizeText(data); | 943 | const ref_data = Packet.normalizeText(data); |
| 944 | const oid_sep_pos = mem.indexOfScalar(u8, ref_data, ' ') orelse return error.InvalidRefPacket; | 944 | const oid_sep_pos = mem.findScalar(u8, ref_data, ' ') orelse return error.InvalidRefPacket; |
| 945 | const oid = Oid.parse(it.format, data[0..oid_sep_pos]) catch return error.InvalidRefPacket; | 945 | const oid = Oid.parse(it.format, data[0..oid_sep_pos]) catch return error.InvalidRefPacket; |
| 946 | 946 | ||
| 947 | const name_sep_pos = mem.indexOfScalarPos(u8, ref_data, oid_sep_pos + 1, ' ') orelse ref_data.len; | 947 | const name_sep_pos = mem.findScalarPos(u8, ref_data, oid_sep_pos + 1, ' ') orelse ref_data.len; |
| 948 | const name = ref_data[oid_sep_pos + 1 .. name_sep_pos]; | 948 | const name = ref_data[oid_sep_pos + 1 .. name_sep_pos]; |
| 949 | 949 | ||
| 950 | var symref_target: ?[]const u8 = null; | 950 | var symref_target: ?[]const u8 = null; |
| 951 | var peeled: ?Oid = null; | 951 | var peeled: ?Oid = null; |
| 952 | var last_sep_pos = name_sep_pos; | 952 | var last_sep_pos = name_sep_pos; |
| 953 | while (last_sep_pos < ref_data.len) { | 953 | while (last_sep_pos < ref_data.len) { |
| 954 | const next_sep_pos = mem.indexOfScalarPos(u8, ref_data, last_sep_pos + 1, ' ') orelse ref_data.len; | 954 | const next_sep_pos = mem.findScalarPos(u8, ref_data, last_sep_pos + 1, ' ') orelse ref_data.len; |
| 955 | const attribute = ref_data[last_sep_pos + 1 .. next_sep_pos]; | 955 | const attribute = ref_data[last_sep_pos + 1 .. next_sep_pos]; |
| 956 | if (mem.startsWith(u8, attribute, "symref-target:")) { | 956 | if (mem.startsWith(u8, attribute, "symref-target:")) { |
| 957 | symref_target = attribute["symref-target:".len..]; | 957 | symref_target = attribute["symref-target:".len..]; |
lib/compiler/Maker/PkgConfig.zig+2| ... | @@ -63,6 +63,8 @@ pub fn run( | ... | @@ -63,6 +63,8 @@ pub fn run( |
| 63 | } | 63 | } |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | step.clearFailedCommand(maker.gpa); | ||
| 67 | |||
| 66 | return parsed; | 68 | return parsed; |
| 67 | } | 69 | } |
| 68 | 70 |
lib/compiler/Maker/ScannedConfig.zig+63-5| ... | @@ -12,10 +12,6 @@ top_level_steps: std.array_hash_map.String(Configuration.Step.Index), | ... | @@ -12,10 +12,6 @@ top_level_steps: std.array_hash_map.String(Configuration.Step.Index), |
| 12 | path: std.Build.Cache.Path, | 12 | path: std.Build.Cache.Path, |
| 13 | 13 | ||
| 14 | pub fn print(sc: *const ScannedConfig, w: *Writer) Writer.Error!void { | 14 | pub fn print(sc: *const ScannedConfig, w: *Writer) Writer.Error!void { |
| 15 | std.log.err("TODO also print paths", .{}); | ||
| 16 | std.log.err("TODO also print unlazy deps", .{}); | ||
| 17 | std.log.err("TODO also print system integrations", .{}); | ||
| 18 | std.log.err("TODO also print available options", .{}); | ||
| 19 | const c = &sc.configuration; | 15 | const c = &sc.configuration; |
| 20 | var serializer: Serializer = .{ .writer = w }; | 16 | var serializer: Serializer = .{ .writer = w }; |
| 21 | var s = try serializer.beginStruct(.{}); | 17 | var s = try serializer.beginStruct(.{}); |
| ... | @@ -45,6 +41,69 @@ pub fn print(sc: *const ScannedConfig, w: *Writer) Writer.Error!void { | ... | @@ -45,6 +41,69 @@ pub fn print(sc: *const ScannedConfig, w: *Writer) Writer.Error!void { |
| 45 | try tf.end(); | 41 | try tf.end(); |
| 46 | } | 42 | } |
| 47 | 43 | ||
| 44 | { | ||
| 45 | var tf = try s.beginTupleField("path_deps", .{}); | ||
| 46 | for (c.path_deps) |path_dep| { | ||
| 47 | var sf = try tf.beginStructField(.{}); | ||
| 48 | try sf.field("base", @tagName(path_dep.flags.base), .{}); | ||
| 49 | try sf.field("sub", path_dep.sub.slice(c), .{}); | ||
| 50 | try sf.end(); | ||
| 51 | } | ||
| 52 | try tf.end(); | ||
| 53 | } | ||
| 54 | |||
| 55 | { | ||
| 56 | var tf = try s.beginTupleField("unlazy_deps", .{}); | ||
| 57 | for (c.unlazy_deps) |dep| { | ||
| 58 | try tf.field(dep.slice(c), .{}); | ||
| 59 | } | ||
| 60 | try tf.end(); | ||
| 61 | } | ||
| 62 | |||
| 63 | { | ||
| 64 | var tf = try s.beginTupleField("system_integrations", .{}); | ||
| 65 | for (c.system_integrations) |opt| { | ||
| 66 | var sf = try tf.beginStructField(.{}); | ||
| 67 | try sf.field("name", opt.name.slice(c), .{}); | ||
| 68 | try sf.field("status", opt.status, .{}); | ||
| 69 | try sf.end(); | ||
| 70 | } | ||
| 71 | try tf.end(); | ||
| 72 | } | ||
| 73 | |||
| 74 | { | ||
| 75 | var tf = try s.beginTupleField("available_options", .{}); | ||
| 76 | for (c.available_options) |opt| { | ||
| 77 | var sf = try tf.beginStructField(.{}); | ||
| 78 | try sf.field("name", opt.name.slice(c), .{}); | ||
| 79 | try sf.field("description", opt.description.slice(c), .{}); | ||
| 80 | try sf.field("type", @tagName(opt.type), .{}); | ||
| 81 | try sf.end(); | ||
| 82 | } | ||
| 83 | try tf.end(); | ||
| 84 | } | ||
| 85 | |||
| 86 | { | ||
| 87 | var tf = try s.beginTupleField("packages", .{}); | ||
| 88 | for (c.packages) |package| { | ||
| 89 | var sf = try tf.beginStructField(.{}); | ||
| 90 | try sf.field("dep_prefix", package.dep_prefix.slice(c), .{}); | ||
| 91 | try sf.field("hash", package.hash.slice(c), .{}); | ||
| 92 | try sf.field("root_path", package.root_path.slice(c), .{}); | ||
| 93 | |||
| 94 | var dtf = try sf.beginTupleField("deps", .{}); | ||
| 95 | for (package.deps.slice(c)) |dep| { | ||
| 96 | var dsf = try dtf.beginStructField(.{}); | ||
| 97 | try sc.printStruct(&dsf, Configuration.Package.Dep, dep); | ||
| 98 | try dsf.end(); | ||
| 99 | } | ||
| 100 | try dtf.end(); | ||
| 101 | |||
| 102 | try sf.end(); | ||
| 103 | } | ||
| 104 | try tf.end(); | ||
| 105 | } | ||
| 106 | |||
| 48 | try s.end(); | 107 | try s.end(); |
| 49 | } | 108 | } |
| 50 | 109 | ||
| ... | @@ -341,7 +400,6 @@ pub fn printUsage(sc: *const ScannedConfig, graph: *Graph, w: *Writer) !void { | ... | @@ -341,7 +400,6 @@ pub fn printUsage(sc: *const ScannedConfig, graph: *Graph, w: *Writer) !void { |
| 341 | \\ --error-limit [num] Set the maximum amount of distinct error values | 400 | \\ --error-limit [num] Set the maximum amount of distinct error values |
| 342 | \\ --build-file [file] Override path to build.zig | 401 | \\ --build-file [file] Override path to build.zig |
| 343 | \\ --cache-dir [path] Override path to local Zig cache directory | 402 | \\ --cache-dir [path] Override path to local Zig cache directory |
| 344 | \\ --global-cache-dir [path] Override path to global Zig cache directory | ||
| 345 | \\ --zig-lib=[arg] Override path to Zig lib directory | 403 | \\ --zig-lib=[arg] Override path to Zig lib directory |
| 346 | \\ --seed [integer] For shuffling dependency traversal order (default: random) | 404 | \\ --seed [integer] For shuffling dependency traversal order (default: random) |
| 347 | \\ --cache-poison[=mode] Override configuration caching behavior | 405 | \\ --cache-poison[=mode] Override configuration caching behavior |
lib/compiler/Maker/Step.zig+13-8| ... | @@ -163,6 +163,9 @@ pub const State = enum { | ... | @@ -163,6 +163,9 @@ pub const State = enum { |
| 163 | /// be re-evaluated. | 163 | /// be re-evaluated. |
| 164 | precheck_done, | 164 | precheck_done, |
| 165 | dependency_failure, | 165 | dependency_failure, |
| 166 | /// Handled exactly the same as `dependency_failure` except communicates | ||
| 167 | /// that the dependency didn't fail but rather was skipped. | ||
| 168 | dependency_skipped, | ||
| 166 | success, | 169 | success, |
| 167 | failure, | 170 | failure, |
| 168 | /// This state indicates that the step did not complete, however, it also did not fail, | 171 | /// This state indicates that the step did not complete, however, it also did not fail, |
| ... | @@ -561,24 +564,26 @@ fn zigProcessUpdate(step_index: Configuration.Step.Index, maker: *Maker, zp: *Zi | ... | @@ -561,24 +564,26 @@ fn zigProcessUpdate(step_index: Configuration.Step.Index, maker: *Maker, zp: *Zi |
| 561 | var result: ?Path = null; | 564 | var result: ?Path = null; |
| 562 | var eos_err: error{EndOfStream}!void = {}; | 565 | var eos_err: error{EndOfStream}!void = {}; |
| 563 | 566 | ||
| 564 | const stdout = zp.multi_reader.fileReader(0); | 567 | var client: std.zig.Client = .{ |
| 568 | .in = zp.multi_reader.reader(0), | ||
| 569 | .out = undefined, | ||
| 570 | }; | ||
| 565 | 571 | ||
| 566 | while (true) { | 572 | while (true) { |
| 567 | const Header = std.zig.Server.Message.Header; | 573 | const header = client.receiveMessageWithMultiReader(&zp.multi_reader, .none) catch |err| switch (err) { |
| 568 | const header = stdout.interface.takeStruct(Header, .little) catch |err| switch (err) { | 574 | error.Timeout => unreachable, |
| 569 | error.EndOfStream => break, | ||
| 570 | error.ReadFailed => return stdout.err.?, | ||
| 571 | }; | ||
| 572 | const body = stdout.interface.take(header.bytes_len) catch |err| switch (err) { | ||
| 573 | error.EndOfStream => |e| { | 575 | error.EndOfStream => |e| { |
| 576 | if (client.in.bufferedLen() == 0) break; | ||
| 574 | // Better to report the crash with stderr below, but we set | 577 | // Better to report the crash with stderr below, but we set |
| 575 | // this in case the child exits successfully while violating | 578 | // this in case the child exits successfully while violating |
| 576 | // this protocol. | 579 | // this protocol. |
| 577 | eos_err = e; | 580 | eos_err = e; |
| 578 | break; | 581 | break; |
| 579 | }, | 582 | }, |
| 580 | error.ReadFailed => return stdout.err.?, | 583 | else => |e| return e, |
| 581 | }; | 584 | }; |
| 585 | const body = client.in.take(header.bytes_len) catch unreachable; | ||
| 586 | |||
| 582 | switch (header.tag) { | 587 | switch (header.tag) { |
| 583 | .zig_version => { | 588 | .zig_version => { |
| 584 | if (!std.mem.eql(u8, builtin.zig_version_string, body)) { | 589 | if (!std.mem.eql(u8, builtin.zig_version_string, body)) { |
lib/compiler/Maker/Step/Compile.zig+2-2| ... | @@ -215,8 +215,8 @@ fn lowerZigArgs( | ... | @@ -215,8 +215,8 @@ fn lowerZigArgs( |
| 215 | try addBool(gpa, zig_args, "-ffuzz", fuzz); | 215 | try addBool(gpa, zig_args, "-ffuzz", fuzz); |
| 216 | 216 | ||
| 217 | { | 217 | { |
| 218 | var is_linking_libc = conf_comp.flags3.is_linking_libc; | 218 | var is_linking_libc = false; |
| 219 | var is_linking_libcpp = conf_comp.flags3.is_linking_libcpp; | 219 | var is_linking_libcpp = false; |
| 220 | 220 | ||
| 221 | // Stores system libraries that have already been seen for at least one | 221 | // Stores system libraries that have already been seen for at least one |
| 222 | // module, along with any C compiler arguments that need to be passed | 222 | // module, along with any C compiler arguments that need to be passed |
lib/compiler/Maker/Step/ConfigHeader.zig+137| ... | @@ -93,6 +93,32 @@ pub fn make( | ... | @@ -93,6 +93,32 @@ pub fn make( |
| 93 | else => |e| return e, | 93 | else => |e| return e, |
| 94 | }; | 94 | }; |
| 95 | }, | 95 | }, |
| 96 | .meson => { | ||
| 97 | const tf = template_file.?; | ||
| 98 | const contents = tf.root_dir.handle.readFileAlloc( | ||
| 99 | io, | ||
| 100 | tf.sub_path, | ||
| 101 | arena, | ||
| 102 | input_size_limit, | ||
| 103 | ) catch |err| return step.fail( | ||
| 104 | maker, | ||
| 105 | "unable to read meson input file {f}: {t}", | ||
| 106 | .{ tf, err }, | ||
| 107 | ); | ||
| 108 | |||
| 109 | renderMeson( | ||
| 110 | maker, | ||
| 111 | step, | ||
| 112 | contents, | ||
| 113 | &aw, | ||
| 114 | value_pairs, | ||
| 115 | &value_map, | ||
| 116 | tf, | ||
| 117 | ) catch |err| switch (err) { | ||
| 118 | error.WriteFailed => return error.OutOfMemory, | ||
| 119 | else => |e| return e, | ||
| 120 | }; | ||
| 121 | }, | ||
| 96 | .blank => { | 122 | .blank => { |
| 97 | renderBlank(conf, &aw.writer, value_pairs, &value_map, include_path, include_guard_override) catch |err| switch (err) { | 123 | renderBlank(conf, &aw.writer, value_pairs, &value_map, include_path, include_guard_override) catch |err| switch (err) { |
| 98 | error.WriteFailed => return error.OutOfMemory, | 124 | error.WriteFailed => return error.OutOfMemory, |
| ... | @@ -370,6 +396,62 @@ fn renderCmake( | ... | @@ -370,6 +396,62 @@ fn renderCmake( |
| 370 | if (any_errors) return error.MakeFailed; | 396 | if (any_errors) return error.MakeFailed; |
| 371 | } | 397 | } |
| 372 | 398 | ||
| 399 | fn renderMeson( | ||
| 400 | maker: *Maker, | ||
| 401 | step: *Step, | ||
| 402 | contents: []const u8, | ||
| 403 | aw: *Writer.Allocating, | ||
| 404 | value_pairs: []const Value.Pair, | ||
| 405 | value_map: *const ValueMap, | ||
| 406 | src_path: Path, | ||
| 407 | ) !void { | ||
| 408 | const w = &aw.writer; | ||
| 409 | const conf = &maker.scanned_config.configuration; | ||
| 410 | const newline = detectNewline(contents); | ||
| 411 | |||
| 412 | try w.writeAll(c_generated_line); | ||
| 413 | try w.writeAll(newline); | ||
| 414 | |||
| 415 | var any_errors = false; | ||
| 416 | var line_index: u32 = 0; | ||
| 417 | var line_it = std.mem.splitScalar(u8, contents, '\n'); | ||
| 418 | // https://mesonbuild.com/Configuration.html | ||
| 419 | while (line_it.next()) |raw_line| : (line_index += 1) { | ||
| 420 | const last_line = line_it.index == line_it.buffer.len; | ||
| 421 | const line = std.mem.trimEnd(u8, raw_line, "\r"); | ||
| 422 | |||
| 423 | const old_len = aw.written().len; | ||
| 424 | expandVariablesMeson(w, conf, line, value_pairs, value_map) catch |err| switch (err) { | ||
| 425 | error.MissingToken => { | ||
| 426 | try step.addError(maker, "{f}:{d}: error: missing define name", .{ src_path, line_index + 1 }); | ||
| 427 | any_errors = true; | ||
| 428 | continue; | ||
| 429 | }, | ||
| 430 | error.MissingValue => { | ||
| 431 | const name = aw.written()[old_len..]; | ||
| 432 | defer aw.shrinkRetainingCapacity(old_len); | ||
| 433 | |||
| 434 | try step.addError(maker, "{f}:{d}: error: unspecified config header value: {q}", .{ | ||
| 435 | src_path, line_index + 1, name, | ||
| 436 | }); | ||
| 437 | any_errors = true; | ||
| 438 | continue; | ||
| 439 | }, | ||
| 440 | else => { | ||
| 441 | try step.addError(maker, "{f}:{d}: unable to substitute variable: error: {t}", .{ | ||
| 442 | src_path, line_index + 1, err, | ||
| 443 | }); | ||
| 444 | any_errors = true; | ||
| 445 | continue; | ||
| 446 | }, | ||
| 447 | }; | ||
| 448 | if (!last_line) try w.writeAll(newline); | ||
| 449 | } | ||
| 450 | |||
| 451 | try ensureAllValuesUsed(maker, step, value_map, src_path); | ||
| 452 | if (any_errors) return error.MakeFailed; | ||
| 453 | } | ||
| 454 | |||
| 373 | fn renderBlank( | 455 | fn renderBlank( |
| 374 | conf: *const Configuration, | 456 | conf: *const Configuration, |
| 375 | w: *Writer, | 457 | w: *Writer, |
| ... | @@ -432,6 +514,28 @@ fn renderValueC(conf: *const Configuration, w: *Writer, newline: []const u8, nam | ... | @@ -432,6 +514,28 @@ fn renderValueC(conf: *const Configuration, w: *Writer, newline: []const u8, nam |
| 432 | } | 514 | } |
| 433 | } | 515 | } |
| 434 | 516 | ||
| 517 | fn renderValueMeson( | ||
| 518 | conf: *const Configuration, | ||
| 519 | w: *Writer, | ||
| 520 | name: []const u8, | ||
| 521 | value: Value.Index, | ||
| 522 | ) !void { | ||
| 523 | switch (value.unpack(conf)) { | ||
| 524 | .undef => try w.print("/* #undef {s} */", .{name}), | ||
| 525 | .defined => try w.print("#define {s}", .{name}), | ||
| 526 | .bool => |b| { | ||
| 527 | if (b) { | ||
| 528 | try w.print("#define {s}", .{name}); | ||
| 529 | } else { | ||
| 530 | try w.print("#undef {s}", .{name}); | ||
| 531 | } | ||
| 532 | }, | ||
| 533 | inline .u64, .i64 => |int| try w.print("#define {s} {d}", .{ name, int }), | ||
| 534 | .ident => |ident| try w.print("#define {s} {s}", .{ name, ident }), | ||
| 535 | .string => |string| try w.print("#define {s} \"{f}\"", .{ name, std.zig.fmtString(string) }), | ||
| 536 | } | ||
| 537 | } | ||
| 538 | |||
| 435 | fn renderValueCIdent(w: *Writer, newline: []const u8, name: []const u8, ident: []const u8) Writer.Error!void { | 539 | fn renderValueCIdent(w: *Writer, newline: []const u8, name: []const u8, ident: []const u8) Writer.Error!void { |
| 436 | try w.print("#define {s}", .{name}); | 540 | try w.print("#define {s}", .{name}); |
| 437 | if (ident.len > 0) { | 541 | if (ident.len > 0) { |
| ... | @@ -628,3 +732,36 @@ fn expandVariablesCmake( | ... | @@ -628,3 +732,36 @@ fn expandVariablesCmake( |
| 628 | 732 | ||
| 629 | return result.toOwnedSliceAssert(); | 733 | return result.toOwnedSliceAssert(); |
| 630 | } | 734 | } |
| 735 | |||
| 736 | fn expandVariablesMeson( | ||
| 737 | w: *Writer, | ||
| 738 | conf: *const Configuration, | ||
| 739 | line: []const u8, | ||
| 740 | value_pairs: []const Value.Pair, | ||
| 741 | value_map: *const ValueMap, | ||
| 742 | ) !void { | ||
| 743 | const mesondefine = "#mesondefine"; | ||
| 744 | if (std.mem.startsWith(u8, line, mesondefine)) { | ||
| 745 | const line_offset = mesondefine.len + 1; | ||
| 746 | if (line_offset > line.len) return error.MissingToken; | ||
| 747 | |||
| 748 | var it = std.mem.tokenizeAny(u8, line[line_offset..], " \t\r"); | ||
| 749 | const name = it.next() orelse return error.MissingToken; | ||
| 750 | |||
| 751 | const index = value_map.getIndex(name) orelse { | ||
| 752 | // Report the missing key to the caller. | ||
| 753 | try w.writeAll(name); | ||
| 754 | return error.MissingValue; | ||
| 755 | }; | ||
| 756 | |||
| 757 | const value = value_pairs[index].index; | ||
| 758 | value_map.values()[index] = true; // Mark as used. | ||
| 759 | |||
| 760 | try renderValueMeson(conf, w, name, value); | ||
| 761 | |||
| 762 | // comments/any other text passthrough unaffected | ||
| 763 | return try w.writeAll(line[line_offset + name.len ..]); | ||
| 764 | } | ||
| 765 | |||
| 766 | try expandVariablesAutoconfAt(w, line, conf, value_pairs, value_map); | ||
| 767 | } |
lib/compiler/Maker/Step/Run.zig+93-134| ... | @@ -64,9 +64,9 @@ pub fn make( | ... | @@ -64,9 +64,9 @@ pub fn make( |
| 64 | } | 64 | } |
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | for (conf_run.preopen_names.slice, conf_run.preopen_paths.slice) |name, path| { | 67 | for (conf_run.preopens.slice) |preopen| { |
| 68 | man.hash.addBytesZ(name.slice(conf)); | 68 | man.hash.addBytesZ(preopen.name.slice(conf)); |
| 69 | const cwd_path = try maker.resolveLazyPathIndex(arena, path, run_index); | 69 | const cwd_path = try maker.resolveLazyPathIndex(arena, preopen.path, run_index); |
| 70 | man.hash.addBytes(try cwd_path.toString(arena)); | 70 | man.hash.addBytes(try cwd_path.toString(arena)); |
| 71 | } | 71 | } |
| 72 | 72 | ||
| ... | @@ -187,6 +187,11 @@ pub fn make( | ... | @@ -187,6 +187,11 @@ pub fn make( |
| 187 | man.hash.addListOfBytes(run_args); | 187 | man.hash.addListOfBytes(run_args); |
| 188 | } | 188 | } |
| 189 | }, | 189 | }, |
| 190 | .enable_darling => thirdPartyToggle(&man.hash, &argv_list, conf, graph.enable_darling, arg.prefix.value, arg.suffix.value), | ||
| 191 | .enable_qemu => thirdPartyToggle(&man.hash, &argv_list, conf, graph.enable_qemu, arg.prefix.value, arg.suffix.value), | ||
| 192 | .enable_rosetta => thirdPartyToggle(&man.hash, &argv_list, conf, graph.enable_rosetta, arg.prefix.value, arg.suffix.value), | ||
| 193 | .enable_wasmtime => thirdPartyToggle(&man.hash, &argv_list, conf, graph.enable_wasmtime, arg.prefix.value, arg.suffix.value), | ||
| 194 | .enable_wine => thirdPartyToggle(&man.hash, &argv_list, conf, graph.enable_wine, arg.prefix.value, arg.suffix.value), | ||
| 190 | } | 195 | } |
| 191 | } | 196 | } |
| 192 | 197 | ||
| ... | @@ -351,6 +356,29 @@ pub fn make( | ... | @@ -351,6 +356,29 @@ pub fn make( |
| 351 | step.clearFailedCommand(gpa); | 356 | step.clearFailedCommand(gpa); |
| 352 | } | 357 | } |
| 353 | 358 | ||
| 359 | fn thirdPartyToggle( | ||
| 360 | man_hash: ?*Cache.HashHelper, | ||
| 361 | argv_list: *std.ArrayList([]const u8), | ||
| 362 | conf: *const Configuration, | ||
| 363 | setting: bool, | ||
| 364 | enable: ?Configuration.String, | ||
| 365 | disable: ?Configuration.String, | ||
| 366 | ) void { | ||
| 367 | if (setting) { | ||
| 368 | if (enable) |string| { | ||
| 369 | const slice = string.slice(conf); | ||
| 370 | if (man_hash) |h| h.addBytesZ(slice); | ||
| 371 | argv_list.appendAssumeCapacity(slice); | ||
| 372 | } | ||
| 373 | } else { | ||
| 374 | if (disable) |string| { | ||
| 375 | const slice = string.slice(conf); | ||
| 376 | if (man_hash) |h| h.addBytesZ(slice); | ||
| 377 | argv_list.appendAssumeCapacity(slice); | ||
| 378 | } | ||
| 379 | } | ||
| 380 | } | ||
| 381 | |||
| 354 | /// Reads stdout of a Zig test process until a termination condition is reached: | 382 | /// Reads stdout of a Zig test process until a termination condition is reached: |
| 355 | /// * A write fails, indicating the child unexpectedly closed stdin | 383 | /// * A write fails, indicating the child unexpectedly closed stdin |
| 356 | /// * A test (or a response from the test runner) times out | 384 | /// * A test (or a response from the test runner) times out |
| ... | @@ -384,13 +412,23 @@ fn waitZigTest( | ... | @@ -384,13 +412,23 @@ fn waitZigTest( |
| 384 | var sub_prog_node: ?std.Progress.Node = null; | 412 | var sub_prog_node: ?std.Progress.Node = null; |
| 385 | defer if (sub_prog_node) |n| n.end(); | 413 | defer if (sub_prog_node) |n| n.end(); |
| 386 | 414 | ||
| 415 | const stdout = multi_reader.reader(0); | ||
| 416 | const stderr = multi_reader.reader(1); | ||
| 417 | |||
| 418 | var stdin_writer = child.stdin.?.writerStreaming(io, &.{}); | ||
| 419 | |||
| 420 | var client: std.zig.Client = .{ | ||
| 421 | .in = stdout, | ||
| 422 | .out = &stdin_writer.interface, | ||
| 423 | }; | ||
| 424 | |||
| 387 | if (opt_metadata.*) |*md| { | 425 | if (opt_metadata.*) |*md| { |
| 388 | // Previous unit test process died or was killed; we're continuing where it left off | 426 | // Previous unit test process died or was killed; we're continuing where it left off |
| 389 | requestNextTest(io, child.stdin.?, md, &sub_prog_node) catch |err| return .{ .write_failed = err }; | 427 | requestNextTest(&client, md, &sub_prog_node) catch |err| return .{ .write_failed = err }; |
| 390 | } else { | 428 | } else { |
| 391 | // Running unit tests normally | 429 | // Running unit tests normally |
| 392 | run.fuzz_tests.clearRetainingCapacity(); | 430 | run.fuzz_tests.clearRetainingCapacity(); |
| 393 | sendMessage(io, child.stdin.?, .query_test_metadata) catch |err| return .{ .write_failed = err }; | 431 | client.serveBodylessMessage(.query_test_metadata) catch |err| return .{ .write_failed = err }; |
| 394 | } | 432 | } |
| 395 | 433 | ||
| 396 | var active_test_index: ?u32 = null; | 434 | var active_test_index: ?u32 = null; |
| ... | @@ -410,10 +448,6 @@ fn waitZigTest( | ... | @@ -410,10 +448,6 @@ fn waitZigTest( |
| 410 | .raw = .fromNanoseconds(ns), | 448 | .raw = .fromNanoseconds(ns), |
| 411 | } else null; | 449 | } else null; |
| 412 | 450 | ||
| 413 | const stdout = multi_reader.reader(0); | ||
| 414 | const stderr = multi_reader.reader(1); | ||
| 415 | const Header = std.zig.Server.Message.Header; | ||
| 416 | |||
| 417 | while (true) { | 451 | while (true) { |
| 418 | const timeout: Io.Timeout = t: { | 452 | const timeout: Io.Timeout = t: { |
| 419 | const opt_duration = if (active_test_index == null) response_timeout else test_timeout; | 453 | const opt_duration = if (active_test_index == null) response_timeout else test_timeout; |
| ... | @@ -421,46 +455,20 @@ fn waitZigTest( | ... | @@ -421,46 +455,20 @@ fn waitZigTest( |
| 421 | break :t .{ .deadline = last_update.addDuration(duration) }; | 455 | break :t .{ .deadline = last_update.addDuration(duration) }; |
| 422 | }; | 456 | }; |
| 423 | 457 | ||
| 424 | // This block is exited when `stdout` contains enough bytes for a `Header`. | 458 | const header = client.receiveMessageWithMultiReader(multi_reader, timeout) catch |err| switch (err) { |
| 425 | header_ready: { | 459 | error.Timeout => return .{ .timeout = .{ |
| 426 | if (stdout.buffered().len >= @sizeOf(Header)) { | 460 | .active_test_index = active_test_index, |
| 427 | // We already have one, no need to poll! | 461 | .ns_elapsed = @intCast(last_update.untilNow(io).raw.nanoseconds), |
| 428 | break :header_ready; | 462 | } }, |
| 429 | } | 463 | error.EndOfStream => return .{ .no_poll = .{ |
| 430 | 464 | .active_test_index = active_test_index, | |
| 431 | multi_reader.fill(64, timeout) catch |err| switch (err) { | 465 | .ns_elapsed = @intCast(last_update.untilNow(io).raw.nanoseconds), |
| 432 | error.Timeout => return .{ .timeout = .{ | 466 | } }, |
| 433 | .active_test_index = active_test_index, | 467 | else => |e| return e, |
| 434 | .ns_elapsed = @intCast(last_update.untilNow(io).raw.nanoseconds), | 468 | }; |
| 435 | } }, | 469 | const body = client.in.take(header.bytes_len) catch unreachable; |
| 436 | error.EndOfStream => return .{ .no_poll = .{ | ||
| 437 | .active_test_index = active_test_index, | ||
| 438 | .ns_elapsed = @intCast(last_update.untilNow(io).raw.nanoseconds), | ||
| 439 | } }, | ||
| 440 | else => |e| return e, | ||
| 441 | }; | ||
| 442 | |||
| 443 | continue; | ||
| 444 | } | ||
| 445 | // There is definitely a header available now -- read it. | ||
| 446 | const header = stdout.takeStruct(Header, .little) catch unreachable; | ||
| 447 | |||
| 448 | while (stdout.buffered().len < header.bytes_len) { | ||
| 449 | multi_reader.fill(64, timeout) catch |err| switch (err) { | ||
| 450 | error.Timeout => return .{ .timeout = .{ | ||
| 451 | .active_test_index = active_test_index, | ||
| 452 | .ns_elapsed = @intCast(last_update.untilNow(io).raw.nanoseconds), | ||
| 453 | } }, | ||
| 454 | error.EndOfStream => return .{ .no_poll = .{ | ||
| 455 | .active_test_index = active_test_index, | ||
| 456 | .ns_elapsed = @intCast(last_update.untilNow(io).raw.nanoseconds), | ||
| 457 | } }, | ||
| 458 | else => |e| return e, | ||
| 459 | }; | ||
| 460 | } | ||
| 461 | |||
| 462 | const body = stdout.take(header.bytes_len) catch unreachable; | ||
| 463 | var body_r: std.Io.Reader = .fixed(body); | 470 | var body_r: std.Io.Reader = .fixed(body); |
| 471 | |||
| 464 | switch (header.tag) { | 472 | switch (header.tag) { |
| 465 | .zig_version => { | 473 | .zig_version => { |
| 466 | if (!std.mem.eql(u8, builtin.zig_version_string, body)) return step.fail( | 474 | if (!std.mem.eql(u8, builtin.zig_version_string, body)) return step.fail( |
| ... | @@ -500,7 +508,7 @@ fn waitZigTest( | ... | @@ -500,7 +508,7 @@ fn waitZigTest( |
| 500 | active_test_index = null; | 508 | active_test_index = null; |
| 501 | last_update = .now(io, .awake); | 509 | last_update = .now(io, .awake); |
| 502 | 510 | ||
| 503 | requestNextTest(io, child.stdin.?, &opt_metadata.*.?, &sub_prog_node) catch |err| return .{ .write_failed = err }; | 511 | requestNextTest(&client, &opt_metadata.*.?, &sub_prog_node) catch |err| return .{ .write_failed = err }; |
| 504 | }, | 512 | }, |
| 505 | .test_started => { | 513 | .test_started => { |
| 506 | active_test_index = opt_metadata.*.?.next_index - 1; | 514 | active_test_index = opt_metadata.*.?.next_index - 1; |
| ... | @@ -551,7 +559,7 @@ fn waitZigTest( | ... | @@ -551,7 +559,7 @@ fn waitZigTest( |
| 551 | md.ns_per_test[tr_hdr.index] = @intCast(last_update.durationTo(now).raw.nanoseconds); | 559 | md.ns_per_test[tr_hdr.index] = @intCast(last_update.durationTo(now).raw.nanoseconds); |
| 552 | last_update = now; | 560 | last_update = now; |
| 553 | 561 | ||
| 554 | requestNextTest(io, child.stdin.?, md, &sub_prog_node) catch |err| return .{ .write_failed = err }; | 562 | requestNextTest(&client, md, &sub_prog_node) catch |err| return .{ .write_failed = err }; |
| 555 | }, | 563 | }, |
| 556 | else => {}, // ignore other messages | 564 | else => {}, // ignore other messages |
| 557 | } | 565 | } |
| ... | @@ -575,7 +583,7 @@ const FuzzTestRunner = struct { | ... | @@ -575,7 +583,7 @@ const FuzzTestRunner = struct { |
| 575 | 583 | ||
| 576 | const Instance = struct { | 584 | const Instance = struct { |
| 577 | child: process.Child, | 585 | child: process.Child, |
| 578 | message: std.ArrayListAligned(u8, .@"4"), | 586 | message: std.array_list.Aligned(u8, .@"4"), |
| 579 | broadcast_written: usize, | 587 | broadcast_written: usize, |
| 580 | stderr: std.ArrayList(u8), | 588 | stderr: std.ArrayList(u8), |
| 581 | stdin_vec: [1][]u8, | 589 | stdin_vec: [1][]u8, |
| ... | @@ -697,17 +705,18 @@ const FuzzTestRunner = struct { | ... | @@ -697,17 +705,18 @@ const FuzzTestRunner = struct { |
| 697 | 705 | ||
| 698 | for (0.., f.instances) |id, *instance| { | 706 | for (0.., f.instances) |id, *instance| { |
| 699 | const id32: u32 = @intCast(id); | 707 | const id32: u32 = @intCast(id); |
| 708 | var writer = instance.child.stdin.?.writerStreaming(io, &.{}); | ||
| 709 | const client: std.zig.Client = .{ | ||
| 710 | .in = undefined, | ||
| 711 | .out = &writer.interface, | ||
| 712 | }; | ||
| 700 | (switch (f.ctx.fuzz.mode) { | 713 | (switch (f.ctx.fuzz.mode) { |
| 701 | .forever => sendRunFuzzTestMessage( | 714 | .forever => client.serveRunFuzzTestMessage( |
| 702 | io, | ||
| 703 | instance.child.stdin.?, | ||
| 704 | run.fuzz_tests.items, | 715 | run.fuzz_tests.items, |
| 705 | .forever, | 716 | .forever, |
| 706 | id32, | 717 | id32, |
| 707 | ), | 718 | ), |
| 708 | .limit => |limit| sendRunFuzzTestMessage( | 719 | .limit => |limit| client.serveRunFuzzTestMessage( |
| 709 | io, | ||
| 710 | instance.child.stdin.?, | ||
| 711 | run.fuzz_tests.items, | 720 | run.fuzz_tests.items, |
| 712 | .iterations, | 721 | .iterations, |
| 713 | limit.amount, | 722 | limit.amount, |
| ... | @@ -1315,7 +1324,7 @@ pub const CachedTestMetadata = struct { | ... | @@ -1315,7 +1324,7 @@ pub const CachedTestMetadata = struct { |
| 1315 | } | 1324 | } |
| 1316 | }; | 1325 | }; |
| 1317 | 1326 | ||
| 1318 | fn requestNextTest(io: Io, in: Io.File, metadata: *TestMetadata, sub_prog_node: *?std.Progress.Node) !void { | 1327 | fn requestNextTest(client: *std.zig.Client, metadata: *TestMetadata, sub_prog_node: *?std.Progress.Node) !void { |
| 1319 | while (metadata.next_index < metadata.names.len) { | 1328 | while (metadata.next_index < metadata.names.len) { |
| 1320 | const i = metadata.next_index; | 1329 | const i = metadata.next_index; |
| 1321 | metadata.next_index += 1; | 1330 | metadata.next_index += 1; |
| ... | @@ -1326,76 +1335,11 @@ fn requestNextTest(io: Io, in: Io.File, metadata: *TestMetadata, sub_prog_node: | ... | @@ -1326,76 +1335,11 @@ fn requestNextTest(io: Io, in: Io.File, metadata: *TestMetadata, sub_prog_node: |
| 1326 | if (sub_prog_node.*) |n| n.end(); | 1335 | if (sub_prog_node.*) |n| n.end(); |
| 1327 | sub_prog_node.* = metadata.prog_node.start(name, 0); | 1336 | sub_prog_node.* = metadata.prog_node.start(name, 0); |
| 1328 | 1337 | ||
| 1329 | try sendRunTestMessage(io, in, .run_test, i); | 1338 | try client.serveRunTest(i); |
| 1330 | return; | 1339 | return; |
| 1331 | } else { | 1340 | } else { |
| 1332 | metadata.next_index = std.math.maxInt(u32); // indicate that all tests are done | 1341 | metadata.next_index = std.math.maxInt(u32); // indicate that all tests are done |
| 1333 | try sendMessage(io, in, .exit); | 1342 | try client.serveBodylessMessage(.exit); |
| 1334 | } | ||
| 1335 | } | ||
| 1336 | |||
| 1337 | fn sendMessage(io: Io, file: Io.File, tag: std.zig.Client.Message.Tag) !void { | ||
| 1338 | const header: std.zig.Client.Message.Header = .{ | ||
| 1339 | .tag = tag, | ||
| 1340 | .bytes_len = 0, | ||
| 1341 | }; | ||
| 1342 | var w = file.writerStreaming(io, &.{}); | ||
| 1343 | w.interface.writeStruct(header, .little) catch |err| switch (err) { | ||
| 1344 | error.WriteFailed => return w.err.?, | ||
| 1345 | }; | ||
| 1346 | } | ||
| 1347 | |||
| 1348 | fn sendRunTestMessage(io: Io, file: Io.File, tag: std.zig.Client.Message.Tag, index: u32) !void { | ||
| 1349 | const header: std.zig.Client.Message.Header = .{ | ||
| 1350 | .tag = tag, | ||
| 1351 | .bytes_len = 4, | ||
| 1352 | }; | ||
| 1353 | var w = file.writerStreaming(io, &.{}); | ||
| 1354 | w.interface.writeStruct(header, .little) catch |err| switch (err) { | ||
| 1355 | error.WriteFailed => return w.err.?, | ||
| 1356 | }; | ||
| 1357 | w.interface.writeInt(u32, index, .little) catch |err| switch (err) { | ||
| 1358 | error.WriteFailed => return w.err.?, | ||
| 1359 | }; | ||
| 1360 | } | ||
| 1361 | |||
| 1362 | fn sendRunFuzzTestMessage( | ||
| 1363 | io: Io, | ||
| 1364 | file: Io.File, | ||
| 1365 | test_names: []const []const u8, | ||
| 1366 | kind: std.Build.abi.fuzz.LimitKind, | ||
| 1367 | amount_or_instance: u64, | ||
| 1368 | ) !void { | ||
| 1369 | const header: std.zig.Client.Message.Header = .{ | ||
| 1370 | .tag = .start_fuzzing, | ||
| 1371 | .bytes_len = 1 + 8 + 4 + count: { | ||
| 1372 | var c: u32 = @intCast(test_names.len * 4); | ||
| 1373 | for (test_names) |name| { | ||
| 1374 | c += @intCast(name.len); | ||
| 1375 | } | ||
| 1376 | break :count c; | ||
| 1377 | }, | ||
| 1378 | }; | ||
| 1379 | var w = file.writerStreaming(io, &.{}); | ||
| 1380 | w.interface.writeStruct(header, .little) catch |err| switch (err) { | ||
| 1381 | error.WriteFailed => return w.err.?, | ||
| 1382 | }; | ||
| 1383 | w.interface.writeByte(@backingInt(kind)) catch |err| switch (err) { | ||
| 1384 | error.WriteFailed => return w.err.?, | ||
| 1385 | }; | ||
| 1386 | w.interface.writeInt(u64, amount_or_instance, .little) catch |err| switch (err) { | ||
| 1387 | error.WriteFailed => return w.err.?, | ||
| 1388 | }; | ||
| 1389 | w.interface.writeInt(u32, @intCast(test_names.len), .little) catch |err| switch (err) { | ||
| 1390 | error.WriteFailed => return w.err.?, | ||
| 1391 | }; | ||
| 1392 | for (test_names) |test_name| { | ||
| 1393 | w.interface.writeInt(u32, @intCast(test_name.len), .little) catch |err| switch (err) { | ||
| 1394 | error.WriteFailed => return w.err.?, | ||
| 1395 | }; | ||
| 1396 | w.interface.writeAll(test_name) catch |err| switch (err) { | ||
| 1397 | error.WriteFailed => return w.err.?, | ||
| 1398 | }; | ||
| 1399 | } | 1343 | } |
| 1400 | } | 1344 | } |
| 1401 | 1345 | ||
| ... | @@ -1619,6 +1563,11 @@ pub fn rerunInFuzzMode( | ... | @@ -1619,6 +1563,11 @@ pub fn rerunInFuzzMode( |
| 1619 | .output_file => unreachable, | 1563 | .output_file => unreachable, |
| 1620 | .output_directory => unreachable, | 1564 | .output_directory => unreachable, |
| 1621 | .passthru => unreachable, | 1565 | .passthru => unreachable, |
| 1566 | .enable_darling => thirdPartyToggle(null, &argv_list, conf, graph.enable_darling, arg.prefix.value, arg.suffix.value), | ||
| 1567 | .enable_qemu => thirdPartyToggle(null, &argv_list, conf, graph.enable_qemu, arg.prefix.value, arg.suffix.value), | ||
| 1568 | .enable_rosetta => thirdPartyToggle(null, &argv_list, conf, graph.enable_rosetta, arg.prefix.value, arg.suffix.value), | ||
| 1569 | .enable_wasmtime => thirdPartyToggle(null, &argv_list, conf, graph.enable_wasmtime, arg.prefix.value, arg.suffix.value), | ||
| 1570 | .enable_wine => thirdPartyToggle(null, &argv_list, conf, graph.enable_wine, arg.prefix.value, arg.suffix.value), | ||
| 1622 | } | 1571 | } |
| 1623 | } | 1572 | } |
| 1624 | 1573 | ||
| ... | @@ -1917,14 +1866,14 @@ fn runCommand( | ... | @@ -1917,14 +1866,14 @@ fn runCommand( |
| 1917 | }, | 1866 | }, |
| 1918 | .wasmtime => |bin_name| { | 1867 | .wasmtime => |bin_name| { |
| 1919 | if (graph.enable_wasmtime) { | 1868 | if (graph.enable_wasmtime) { |
| 1920 | try interp_argv.ensureUnusedCapacity(arena, 3 + argv.len + conf_run.preopen_names.slice.len); | 1869 | try interp_argv.ensureUnusedCapacity(arena, 3 + argv.len + conf_run.preopens.slice.len); |
| 1921 | interp_argv.appendAssumeCapacity(bin_name); | 1870 | interp_argv.appendAssumeCapacity(bin_name); |
| 1922 | interp_argv.appendAssumeCapacity("--dir=."); | 1871 | interp_argv.appendAssumeCapacity("--dir=."); |
| 1923 | for (conf_run.preopen_names.slice, conf_run.preopen_paths.slice) |name, lazy_path| { | 1872 | for (conf_run.preopens.slice) |preopen| { |
| 1924 | const path = try maker.resolveLazyPath(arena, lazy_path.get(conf), run_index); | 1873 | const path = try maker.resolveLazyPath(arena, preopen.path.get(conf), run_index); |
| 1925 | path.root_dir.handle.createDirPath(io, path.subPathOrDot()) catch |e| | 1874 | path.root_dir.handle.createDirPath(io, path.subPathOrDot()) catch |e| |
| 1926 | return step.fail(maker, "failed creating directory {f}: {t}", .{ path, e }); | 1875 | return step.fail(maker, "failed creating directory {f}: {t}", .{ path, e }); |
| 1927 | interp_argv.appendAssumeCapacity(try arena.print("--dir={f}::{s}", .{ path, name.slice(conf) })); | 1876 | interp_argv.appendAssumeCapacity(try arena.print("--dir={f}::{s}", .{ path, preopen.name.slice(conf) })); |
| 1928 | } | 1877 | } |
| 1929 | // Wasmtime doeesn't inherit environment variables from the parent process | 1878 | // Wasmtime doeesn't inherit environment variables from the parent process |
| 1930 | // by default. '-S inherit-env' was added in Wasmtime version 20. | 1879 | // by default. '-S inherit-env' was added in Wasmtime version 20. |
| ... | @@ -2204,7 +2153,7 @@ fn fmtSnapshotIndicatorLine(buf: []const u8, index: usize) std.fmt.Alt( | ... | @@ -2204,7 +2153,7 @@ fn fmtSnapshotIndicatorLine(buf: []const u8, index: usize) std.fmt.Alt( |
| 2204 | } | 2153 | } |
| 2205 | 2154 | ||
| 2206 | fn snapshotIndicatorLine(line: FmtIndicatorLine, w: *std.Io.Writer) std.Io.Writer.Error!void { | 2155 | fn snapshotIndicatorLine(line: FmtIndicatorLine, w: *std.Io.Writer) std.Io.Writer.Error!void { |
| 2207 | const line_begin_index = if (std.mem.lastIndexOfScalar(u8, line.buf[0..line.index], '\n')) |line_begin| | 2156 | const line_begin_index = if (std.mem.findScalarLast(u8, line.buf[0..line.index], '\n')) |line_begin| |
| 2208 | line_begin + 1 | 2157 | line_begin + 1 |
| 2209 | else | 2158 | else |
| 2210 | 0; | 2159 | 0; |
| ... | @@ -2285,25 +2234,35 @@ fn spawnChildAndCollect( | ... | @@ -2285,25 +2234,35 @@ fn spawnChildAndCollect( |
| 2285 | assert(conf_run.flags.stdio != .inherit); | 2234 | assert(conf_run.flags.stdio != .inherit); |
| 2286 | break :s .pipe; | 2235 | break :s .pipe; |
| 2287 | } else switch (conf_run.flags.stdio) { | 2236 | } else switch (conf_run.flags.stdio) { |
| 2288 | .infer_from_args => if (has_side_effects) .inherit else .ignore, | 2237 | .infer_from_args => if (maker.protocol_server == null and has_side_effects) .inherit else .ignore, |
| 2289 | .inherit => .inherit, | 2238 | .inherit => .inherit, |
| 2290 | .check => .ignore, | 2239 | .check => .ignore, |
| 2291 | .zig_test => .pipe, | 2240 | .zig_test => .pipe, |
| 2292 | }, | 2241 | }, |
| 2293 | .stdout = if (conf_run.captured_stdout.value != null) .pipe else switch (conf_run.flags.stdio) { | 2242 | .stdout = if (conf_run.captured_stdout.value != null) .pipe else switch (conf_run.flags.stdio) { |
| 2294 | .infer_from_args => if (has_side_effects) .inherit else .ignore, | 2243 | .infer_from_args => if (maker.protocol_server == null and has_side_effects) .inherit else .ignore, |
| 2295 | .inherit => .inherit, | 2244 | .inherit => .inherit, |
| 2296 | .check => if (checksContainStdout(&conf_run)) .pipe else .ignore, | 2245 | .check => if (checksContainStdout(&conf_run)) .pipe else .ignore, |
| 2297 | .zig_test => .pipe, | 2246 | .zig_test => .pipe, |
| 2298 | }, | 2247 | }, |
| 2299 | .stderr = if (conf_run.captured_stderr.value != null) .pipe else switch (conf_run.flags.stdio) { | 2248 | .stderr = if (conf_run.captured_stderr.value != null) .pipe else switch (conf_run.flags.stdio) { |
| 2300 | .infer_from_args => if (has_side_effects) .inherit else .pipe, | 2249 | .infer_from_args => if (maker.protocol_server == null and has_side_effects) .inherit else .pipe, |
| 2301 | .inherit => .inherit, | 2250 | .inherit => if (maker.protocol_server == null) .inherit else .pipe, |
| 2302 | .check => .pipe, | 2251 | .check => .pipe, |
| 2303 | .zig_test => .pipe, | 2252 | .zig_test => .pipe, |
| 2304 | }, | 2253 | }, |
| 2305 | }; | 2254 | }; |
| 2306 | 2255 | ||
| 2256 | if (maker.protocol_server != null) { | ||
| 2257 | if (spawn_options.stdin == .inherit) { | ||
| 2258 | return step.fail(maker, "Cannot inherit stdin when running through over the build system protocol", .{}); | ||
| 2259 | } | ||
| 2260 | if (spawn_options.stdout == .inherit) { | ||
| 2261 | return step.fail(maker, "Cannot inherit stdout when running through over the build system protocol", .{}); | ||
| 2262 | } | ||
| 2263 | assert(spawn_options.stderr != .inherit); | ||
| 2264 | } | ||
| 2265 | |||
| 2307 | if (conf_run.flags.stdio == .zig_test) { | 2266 | if (conf_run.flags.stdio == .zig_test) { |
| 2308 | try setColorEnvironmentVariables(&conf_run, environ_map, graph.stderr_mode.?); | 2267 | try setColorEnvironmentVariables(&conf_run, environ_map, graph.stderr_mode.?); |
| 2309 | const started: Io.Clock.Timestamp = .now(io, .awake); | 2268 | const started: Io.Clock.Timestamp = .now(io, .awake); |
lib/compiler/Maker/Step/TranslateC.zig+3-3| ... | @@ -49,9 +49,9 @@ pub fn make( | ... | @@ -49,9 +49,9 @@ pub fn make( |
| 49 | 49 | ||
| 50 | const opt: ?OptimizeMode = switch (conf_tc.flags.optimize) { | 50 | const opt: ?OptimizeMode = switch (conf_tc.flags.optimize) { |
| 51 | .debug, .default => null, // Skip since it's the default | 51 | .debug, .default => null, // Skip since it's the default |
| 52 | .safe => .ReleaseSafe, | 52 | .safe => .safe, |
| 53 | .fast => .ReleaseFast, | 53 | .fast => .fast, |
| 54 | .small => .ReleaseSmall, | 54 | .small => .small, |
| 55 | }; | 55 | }; |
| 56 | if (opt) |o| argv.appendAssumeCapacity(try arena.print("-O{t}", .{o})); | 56 | if (opt) |o| argv.appendAssumeCapacity(try arena.print("-O{t}", .{o})); |
| 57 | 57 |
lib/compiler/Maker/WebServer.zig+1-1| ... | @@ -501,7 +501,7 @@ fn serveRequest(ws: *WebServer, req: *http.Server.Request) !void { | ... | @@ -501,7 +501,7 @@ fn serveRequest(ws: *WebServer, req: *http.Server.Request) !void { |
| 501 | if (mem.eql(u8, target, "/main.js")) return serveLibFile(ws, req, "build-web/main.js", "application/javascript"); | 501 | if (mem.eql(u8, target, "/main.js")) return serveLibFile(ws, req, "build-web/main.js", "application/javascript"); |
| 502 | if (mem.eql(u8, target, "/style.css")) return serveLibFile(ws, req, "build-web/style.css", "text/css"); | 502 | if (mem.eql(u8, target, "/style.css")) return serveLibFile(ws, req, "build-web/style.css", "text/css"); |
| 503 | if (mem.eql(u8, target, "/time_report.css")) return serveLibFile(ws, req, "build-web/time_report.css", "text/css"); | 503 | if (mem.eql(u8, target, "/time_report.css")) return serveLibFile(ws, req, "build-web/time_report.css", "text/css"); |
| 504 | if (mem.eql(u8, target, "/main.wasm")) return serveClientWasm(ws, req, if (debug) .Debug else .ReleaseFast); | 504 | if (mem.eql(u8, target, "/main.wasm")) return serveClientWasm(ws, req, if (debug) .debug else .fast); |
| 505 | 505 | ||
| 506 | if (ws.fuzz) |*fuzz| { | 506 | if (ws.fuzz) |*fuzz| { |
| 507 | if (mem.eql(u8, target, "/sources.tar")) return fuzz.serveSourcesTar(req); | 507 | if (mem.eql(u8, target, "/sources.tar")) return fuzz.serveSourcesTar(req); |
lib/compiler/aro/aro/Compilation.zig+1| ... | @@ -1601,6 +1601,7 @@ pub fn addSourceFromOwnedBuffer(comp: *Compilation, path: []const u8, buf: []u8, | ... | @@ -1601,6 +1601,7 @@ pub fn addSourceFromOwnedBuffer(comp: *Compilation, path: []const u8, buf: []u8, |
| 1601 | var list: std.ArrayList(u8) = .{ | 1601 | var list: std.ArrayList(u8) = .{ |
| 1602 | .items = contents[0..i], | 1602 | .items = contents[0..i], |
| 1603 | .capacity = contents.len, | 1603 | .capacity = contents.len, |
| 1604 | .pointer_stability = .{}, | ||
| 1604 | }; | 1605 | }; |
| 1605 | contents = try list.toOwnedSlice(comp.gpa); | 1606 | contents = try list.toOwnedSlice(comp.gpa); |
| 1606 | } | 1607 | } |
lib/compiler/aro/aro/Diagnostics.zig+1-1| ... | @@ -510,7 +510,7 @@ pub fn formatArgs(w: *std.Io.Writer, fmt: []const u8, args: anytype) std.Io.Writ | ... | @@ -510,7 +510,7 @@ pub fn formatArgs(w: *std.Io.Writer, fmt: []const u8, args: anytype) std.Io.Writ |
| 510 | 510 | ||
| 511 | pub fn templateIndex(w: *std.Io.Writer, fmt: []const u8, template: []const u8) std.Io.Writer.Error!usize { | 511 | pub fn templateIndex(w: *std.Io.Writer, fmt: []const u8, template: []const u8) std.Io.Writer.Error!usize { |
| 512 | const i = std.mem.indexOf(u8, fmt, template) orelse { | 512 | const i = std.mem.indexOf(u8, fmt, template) orelse { |
| 513 | if (@import("builtin").mode == .Debug) { | 513 | if (@import("builtin").mode == .debug) { |
| 514 | std.debug.panic("template `{s}` not found in format string `{s}`", .{ template, fmt }); | 514 | std.debug.panic("template `{s}` not found in format string `{s}`", .{ template, fmt }); |
| 515 | } | 515 | } |
| 516 | try w.print("template `{s}` not found in format string `{s}` (this is a bug in arocc)", .{ template, fmt }); | 516 | try w.print("template `{s}` not found in format string `{s}` (this is a bug in arocc)", .{ template, fmt }); |
lib/compiler/aro/aro/Target.zig+3-3| ... | @@ -1559,15 +1559,15 @@ pub fn ptrBitWidth(target: *const Target) u16 { | ... | @@ -1559,15 +1559,15 @@ pub fn ptrBitWidth(target: *const Target) u16 { |
| 1559 | } | 1559 | } |
| 1560 | 1560 | ||
| 1561 | pub fn cCharSignedness(target: *const Target) std.builtin.Signedness { | 1561 | pub fn cCharSignedness(target: *const Target) std.builtin.Signedness { |
| 1562 | return target.toZigTarget().cCharSignedness(); | 1562 | return target.toZigTarget().cCharSignedness().?; |
| 1563 | } | 1563 | } |
| 1564 | 1564 | ||
| 1565 | pub fn cTypeBitSize(target: *const Target, c_type: std.Target.CType) u16 { | 1565 | pub fn cTypeBitSize(target: *const Target, c_type: std.Target.CType) u16 { |
| 1566 | return target.toZigTarget().cTypeBitSize(c_type); | 1566 | return target.toZigTarget().cTypeBitSize(c_type).?; |
| 1567 | } | 1567 | } |
| 1568 | 1568 | ||
| 1569 | pub fn cTypeAlignment(target: *const Target, c_type: std.Target.CType) u16 { | 1569 | pub fn cTypeAlignment(target: *const Target, c_type: std.Target.CType) u16 { |
| 1570 | return target.toZigTarget().cTypeAlignment(c_type); | 1570 | return target.toZigTarget().cTypeAlignment(c_type).?; |
| 1571 | } | 1571 | } |
| 1572 | 1572 | ||
| 1573 | pub fn standardDynamicLinkerPath(target: *const Target) std.Target.DynamicLinker { | 1573 | pub fn standardDynamicLinkerPath(target: *const Target) std.Target.DynamicLinker { |
lib/compiler/aro/main.zig+1-1| ... | @@ -40,7 +40,7 @@ pub fn main(init: process.Init.Minimal) u8 { | ... | @@ -40,7 +40,7 @@ pub fn main(init: process.Init.Minimal) u8 { |
| 40 | defer threaded.deinit(); | 40 | defer threaded.deinit(); |
| 41 | const io = threaded.io(); | 41 | const io = threaded.io(); |
| 42 | 42 | ||
| 43 | const fast_exit = @import("builtin").mode != .Debug; | 43 | const fast_exit = @import("builtin").mode != .debug; |
| 44 | 44 | ||
| 45 | const args = init.args.toSlice(arena) catch { | 45 | const args = init.args.toSlice(arena) catch { |
| 46 | std.debug.print("out of memory\n", .{}); | 46 | std.debug.print("out of memory\n", .{}); |
lib/compiler/configurer.zig+1-1| ... | @@ -83,7 +83,7 @@ pub fn main(init: process.Init.Minimal) !void { | ... | @@ -83,7 +83,7 @@ pub fn main(init: process.Init.Minimal) !void { |
| 83 | if (mem.cutPrefix(u8, arg, "-D")) |option_contents| { | 83 | if (mem.cutPrefix(u8, arg, "-D")) |option_contents| { |
| 84 | if (option_contents.len == 0) | 84 | if (option_contents.len == 0) |
| 85 | fatalWithHint("expected option name after '-D'", .{}); | 85 | fatalWithHint("expected option name after '-D'", .{}); |
| 86 | if (mem.indexOfScalar(u8, option_contents, '=')) |name_end| { | 86 | if (mem.findScalar(u8, option_contents, '=')) |name_end| { |
| 87 | const option_name = option_contents[0..name_end]; | 87 | const option_name = option_contents[0..name_end]; |
| 88 | const option_value = option_contents[name_end + 1 ..]; | 88 | const option_value = option_contents[name_end + 1 ..]; |
| 89 | if (try builder.addUserInputOption(option_name, option_value)) | 89 | if (try builder.addUserInputOption(option_name, option_value)) |
lib/compiler/objcopy.zig+10-10| ... | @@ -214,11 +214,11 @@ fn cmdObjCopy(arena: Allocator, io: Io, args: []const []const u8) !void { | ... | @@ -214,11 +214,11 @@ fn cmdObjCopy(arena: Allocator, io: Io, args: []const []const u8) !void { |
| 214 | if (listen) { | 214 | if (listen) { |
| 215 | var stdin_reader = Io.File.stdin().reader(io, &stdin_buffer); | 215 | var stdin_reader = Io.File.stdin().reader(io, &stdin_buffer); |
| 216 | var stdout_writer = Io.File.stdout().writer(io, &stdout_buffer); | 216 | var stdout_writer = Io.File.stdout().writer(io, &stdout_buffer); |
| 217 | var server = try Server.init(.{ | 217 | var server: Server = .{ |
| 218 | .in = &stdin_reader.interface, | 218 | .in = &stdin_reader.interface, |
| 219 | .out = &stdout_writer.interface, | 219 | .out = &stdout_writer.interface, |
| 220 | .zig_version = builtin.zig_version_string, | 220 | }; |
| 221 | }); | 221 | try server.serveStringMessage(.zig_version, builtin.zig_version_string); |
| 222 | 222 | ||
| 223 | var seen_update = false; | 223 | var seen_update = false; |
| 224 | while (true) { | 224 | while (true) { |
| ... | @@ -435,13 +435,13 @@ const BinaryElfOutput = struct { | ... | @@ -435,13 +435,13 @@ const BinaryElfOutput = struct { |
| 435 | 435 | ||
| 436 | var program_headers = elf_hdr.iterateProgramHeaders(in); | 436 | var program_headers = elf_hdr.iterateProgramHeaders(in); |
| 437 | while (try program_headers.next()) |phdr| { | 437 | while (try program_headers.next()) |phdr| { |
| 438 | if (phdr.p_type == elf.PT_LOAD) { | 438 | if (phdr.type == .LOAD) { |
| 439 | const newSegment = try allocator.create(BinaryElfSegment); | 439 | const newSegment = try allocator.create(BinaryElfSegment); |
| 440 | 440 | ||
| 441 | newSegment.physicalAddress = phdr.p_paddr; | 441 | newSegment.physicalAddress = phdr.paddr; |
| 442 | newSegment.virtualAddress = phdr.p_vaddr; | 442 | newSegment.virtualAddress = phdr.vaddr; |
| 443 | newSegment.fileSize = @intCast(phdr.p_filesz); | 443 | newSegment.fileSize = @intCast(phdr.filesz); |
| 444 | newSegment.elfOffset = phdr.p_offset; | 444 | newSegment.elfOffset = phdr.offset; |
| 445 | newSegment.binaryOffset = 0; | 445 | newSegment.binaryOffset = 0; |
| 446 | newSegment.firstSection = null; | 446 | newSegment.firstSection = null; |
| 447 | 447 | ||
| ... | @@ -495,8 +495,8 @@ const BinaryElfOutput = struct { | ... | @@ -495,8 +495,8 @@ const BinaryElfOutput = struct { |
| 495 | return self; | 495 | return self; |
| 496 | } | 496 | } |
| 497 | 497 | ||
| 498 | fn sectionWithinSegment(section: *BinaryElfSection, segment: elf.Elf64_Phdr) bool { | 498 | fn sectionWithinSegment(section: *BinaryElfSection, segment: elf.Elf64.Phdr) bool { |
| 499 | return segment.p_offset <= section.elfOffset and (segment.p_offset + segment.p_filesz) >= (section.elfOffset + section.fileSize); | 499 | return segment.offset <= section.elfOffset and (segment.offset + segment.filesz) >= (section.elfOffset + section.fileSize); |
| 500 | } | 500 | } |
| 501 | 501 | ||
| 502 | fn sectionValidForOutput(shdr: anytype) bool { | 502 | fn sectionValidForOutput(shdr: anytype) bool { |
lib/compiler/reduce.zig+1-1| ... | @@ -400,7 +400,7 @@ fn parse(gpa: Allocator, io: Io, file_path: []const u8) !Ast { | ... | @@ -400,7 +400,7 @@ fn parse(gpa: Allocator, io: Io, file_path: []const u8) !Ast { |
| 400 | file_path, | 400 | file_path, |
| 401 | gpa, | 401 | gpa, |
| 402 | .limited(std.math.maxInt(u32)), | 402 | .limited(std.math.maxInt(u32)), |
| 403 | .fromByteUnits(1), | 403 | .@"1", |
| 404 | 0, | 404 | 0, |
| 405 | ) catch |err| { | 405 | ) catch |err| { |
| 406 | fatal("unable to open '{s}': {s}", .{ file_path, @errorName(err) }); | 406 | fatal("unable to open '{s}': {s}", .{ file_path, @errorName(err) }); |
lib/compiler/resinator/compile.zig+3-3| ... | @@ -540,7 +540,7 @@ pub const Compiler = struct { | ... | @@ -540,7 +540,7 @@ pub const Compiler = struct { |
| 540 | // This currently only checks for NUL bytes, but it should probably also check for | 540 | // This currently only checks for NUL bytes, but it should probably also check for |
| 541 | // platform-specific invalid characters like '*', '?', '"', '<', '>', '|' (Windows) | 541 | // platform-specific invalid characters like '*', '?', '"', '<', '>', '|' (Windows) |
| 542 | // Related: https://github.com/ziglang/zig/pull/14533#issuecomment-1416888193 | 542 | // Related: https://github.com/ziglang/zig/pull/14533#issuecomment-1416888193 |
| 543 | if (std.mem.indexOfScalar(u8, filename_utf8, 0) != null) { | 543 | if (std.mem.findScalar(u8, filename_utf8, 0) != null) { |
| 544 | return self.addErrorDetailsAndFail(.{ | 544 | return self.addErrorDetailsAndFail(.{ |
| 545 | .err = .invalid_filename, | 545 | .err = .invalid_filename, |
| 546 | .token = node.filename.getFirstToken(), | 546 | .token = node.filename.getFirstToken(), |
| ... | @@ -2919,11 +2919,11 @@ fn validateSearchPath(path: []const u8) error{BadPathName}!void { | ... | @@ -2919,11 +2919,11 @@ fn validateSearchPath(path: []const u8) error{BadPathName}!void { |
| 2919 | var component_iterator = std.fs.path.componentIterator(path); | 2919 | var component_iterator = std.fs.path.componentIterator(path); |
| 2920 | while (component_iterator.next()) |component| { | 2920 | while (component_iterator.next()) |component| { |
| 2921 | // https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file | 2921 | // https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file |
| 2922 | if (std.mem.indexOfAny(u8, component.name, "\x00<>:\"|?*") != null) return error.BadPathName; | 2922 | if (std.mem.findAny(u8, component.name, "\x00<>:\"|?*") != null) return error.BadPathName; |
| 2923 | } | 2923 | } |
| 2924 | }, | 2924 | }, |
| 2925 | else => { | 2925 | else => { |
| 2926 | if (std.mem.indexOfScalar(u8, path, 0) != null) return error.BadPathName; | 2926 | if (std.mem.findScalar(u8, path, 0) != null) return error.BadPathName; |
| 2927 | }, | 2927 | }, |
| 2928 | } | 2928 | } |
| 2929 | } | 2929 | } |
lib/compiler/resinator/cvtres.zig+1-1| ... | @@ -1056,7 +1056,7 @@ pub const supported_targets = struct { | ... | @@ -1056,7 +1056,7 @@ pub const supported_targets = struct { |
| 1056 | comptime { | 1056 | comptime { |
| 1057 | const info = @typeInfo(Arch).@"enum"; | 1057 | const info = @typeInfo(Arch).@"enum"; |
| 1058 | for (info.field_names, info.field_values) |field_name, field_value| { | 1058 | for (info.field_names, info.field_values) |field_name, field_value| { |
| 1059 | _ = std.mem.indexOfScalar(Arch, ordered_for_display, @fromBackingInt(@intCast(field_value))) orelse { | 1059 | _ = std.mem.findScalar(Arch, ordered_for_display, @fromBackingInt(@intCast(field_value))) orelse { |
| 1060 | @compileError(std.fmt.comptimePrint("'{s}' missing from ordered_for_display", .{field_name})); | 1060 | @compileError(std.fmt.comptimePrint("'{s}' missing from ordered_for_display", .{field_name})); |
| 1061 | }; | 1061 | }; |
| 1062 | } | 1062 | } |
lib/compiler/resinator/errors.zig+1-1| ... | @@ -506,7 +506,7 @@ pub const ErrorDetails = struct { | ... | @@ -506,7 +506,7 @@ pub const ErrorDetails = struct { |
| 506 | // We know that the token slice is a well-formed #pragma code_page(N), so | 506 | // We know that the token slice is a well-formed #pragma code_page(N), so |
| 507 | // we can skip to the first ( and then get the number that follows | 507 | // we can skip to the first ( and then get the number that follows |
| 508 | const token_slice = self.token.slice(source); | 508 | const token_slice = self.token.slice(source); |
| 509 | var number_start = std.mem.indexOfScalar(u8, token_slice, '(').? + 1; | 509 | var number_start = std.mem.findScalar(u8, token_slice, '(').? + 1; |
| 510 | while (std.ascii.isWhitespace(token_slice[number_start])) { | 510 | while (std.ascii.isWhitespace(token_slice[number_start])) { |
| 511 | number_start += 1; | 511 | number_start += 1; |
| 512 | } | 512 | } |
lib/compiler/resinator/parse.zig+1-1| ... | @@ -1277,7 +1277,7 @@ pub const Parser = struct { | ... | @@ -1277,7 +1277,7 @@ pub const Parser = struct { |
| 1277 | }, | 1277 | }, |
| 1278 | else => unreachable, | 1278 | else => unreachable, |
| 1279 | } | 1279 | } |
| 1280 | @compileError("unreachable"); | 1280 | comptime unreachable; |
| 1281 | } | 1281 | } |
| 1282 | 1282 | ||
| 1283 | pub const OptionalParamParser = struct { | 1283 | pub const OptionalParamParser = struct { |
lib/compiler/resinator/source_mapping.zig+1-1| ... | @@ -538,7 +538,7 @@ pub fn handleLineCommand(allocator: Allocator, line_command: []const u8, current | ... | @@ -538,7 +538,7 @@ pub fn handleLineCommand(allocator: Allocator, line_command: []const u8, current |
| 538 | defer allocator.free(filename); | 538 | defer allocator.free(filename); |
| 539 | 539 | ||
| 540 | // \x00 bytes in the filename is incompatible with how StringTable works | 540 | // \x00 bytes in the filename is incompatible with how StringTable works |
| 541 | if (std.mem.indexOfScalar(u8, filename, '\x00') != null) return error.InvalidLineCommand; | 541 | if (std.mem.findScalar(u8, filename, '\x00') != null) return error.InvalidLineCommand; |
| 542 | 542 | ||
| 543 | current_mapping.line_num = linenum; | 543 | current_mapping.line_num = linenum; |
| 544 | current_mapping.filename.clearRetainingCapacity(); | 544 | current_mapping.filename.clearRetainingCapacity(); |
lib/compiler/std-docs.zig+23-24| ... | @@ -142,9 +142,9 @@ fn serveRequest(request: *std.http.Server.Request, context: *Context) !void { | ... | @@ -142,9 +142,9 @@ fn serveRequest(request: *std.http.Server.Request, context: *Context) !void { |
| 142 | { | 142 | { |
| 143 | try serveDocsFile(request, context, "docs/main.js", "application/javascript"); | 143 | try serveDocsFile(request, context, "docs/main.js", "application/javascript"); |
| 144 | } else if (std.mem.eql(u8, request.head.target, "/main.wasm")) { | 144 | } else if (std.mem.eql(u8, request.head.target, "/main.wasm")) { |
| 145 | try serveWasm(request, context, .ReleaseFast); | 145 | try serveWasm(request, context, .fast); |
| 146 | } else if (std.mem.eql(u8, request.head.target, "/debug/main.wasm")) { | 146 | } else if (std.mem.eql(u8, request.head.target, "/debug/main.wasm")) { |
| 147 | try serveWasm(request, context, .Debug); | 147 | try serveWasm(request, context, .debug); |
| 148 | } else if (std.mem.eql(u8, request.head.target, "/sources.tar") or | 148 | } else if (std.mem.eql(u8, request.head.target, "/sources.tar") or |
| 149 | std.mem.eql(u8, request.head.target, "/debug/sources.tar")) | 149 | std.mem.eql(u8, request.head.target, "/debug/sources.tar")) |
| 150 | { | 150 | { |
| ... | @@ -346,29 +346,39 @@ fn buildWasmBinary( | ... | @@ -346,29 +346,39 @@ fn buildWasmBinary( |
| 346 | multi_reader.init(gpa, io, multi_reader_buffer.toStreams(), &.{ child.stdout.?, child.stderr.? }); | 346 | multi_reader.init(gpa, io, multi_reader_buffer.toStreams(), &.{ child.stdout.?, child.stderr.? }); |
| 347 | defer multi_reader.deinit(); | 347 | defer multi_reader.deinit(); |
| 348 | 348 | ||
| 349 | try sendMessage(io, child.stdin.?, .update); | 349 | const stdout = multi_reader.reader(0); |
| 350 | try sendMessage(io, child.stdin.?, .exit); | 350 | |
| 351 | var stdin_buffer: [256]u8 = undefined; | ||
| 352 | var stdin_writer = child.stdin.?.writerStreaming(io, &stdin_buffer); | ||
| 353 | |||
| 354 | var client: std.zig.Client = .{ | ||
| 355 | .in = stdout, | ||
| 356 | .out = &stdin_writer.interface, | ||
| 357 | }; | ||
| 358 | |||
| 359 | try client.serveMessageHeader(.{ .tag = .update, .bytes_len = 0 }); | ||
| 360 | try client.serveMessageHeader(.{ .tag = .exit, .bytes_len = 0 }); | ||
| 361 | try client.out.flush(); | ||
| 351 | 362 | ||
| 352 | var result: ?Cache.Path = null; | 363 | var result: ?Cache.Path = null; |
| 353 | var result_error_bundle = std.zig.ErrorBundle.empty; | 364 | var result_error_bundle = std.zig.ErrorBundle.empty; |
| 354 | 365 | ||
| 355 | const stdout = multi_reader.fileReader(0); | ||
| 356 | const MessageHeader = std.zig.Server.Message.Header; | ||
| 357 | |||
| 358 | var eos_err: error{EndOfStream}!void = {}; | 366 | var eos_err: error{EndOfStream}!void = {}; |
| 359 | 367 | ||
| 360 | while (true) { | 368 | while (true) { |
| 361 | const header = stdout.interface.takeStruct(MessageHeader, .little) catch |err| switch (err) { | 369 | const header = client.receiveMessageWithMultiReader(&multi_reader, .none) catch |err| switch (err) { |
| 362 | error.EndOfStream => break, | 370 | error.Timeout => unreachable, |
| 363 | error.ReadFailed => return stdout.err.?, | ||
| 364 | }; | ||
| 365 | const body = stdout.interface.take(header.bytes_len) catch |err| switch (err) { | ||
| 366 | error.EndOfStream => |e| { | 371 | error.EndOfStream => |e| { |
| 372 | if (client.in.bufferedLen() == 0) break; | ||
| 373 | // Better to report the crash with stderr below, but we set | ||
| 374 | // this in case the child exits successfully while violating | ||
| 375 | // this protocol. | ||
| 367 | eos_err = e; | 376 | eos_err = e; |
| 368 | break; | 377 | break; |
| 369 | }, | 378 | }, |
| 370 | error.ReadFailed => return stdout.err.?, | 379 | else => |e| return e, |
| 371 | }; | 380 | }; |
| 381 | const body = client.in.take(header.bytes_len) catch unreachable; | ||
| 372 | 382 | ||
| 373 | switch (header.tag) { | 383 | switch (header.tag) { |
| 374 | .zig_version => { | 384 | .zig_version => { |
| ... | @@ -435,17 +445,6 @@ fn buildWasmBinary( | ... | @@ -435,17 +445,6 @@ fn buildWasmBinary( |
| 435 | }; | 445 | }; |
| 436 | } | 446 | } |
| 437 | 447 | ||
| 438 | fn sendMessage(io: Io, file: Io.File, tag: std.zig.Client.Message.Tag) !void { | ||
| 439 | const header: std.zig.Client.Message.Header = .{ | ||
| 440 | .tag = tag, | ||
| 441 | .bytes_len = 0, | ||
| 442 | }; | ||
| 443 | var w = file.writer(io, &.{}); | ||
| 444 | w.interface.writeStruct(header, .little) catch |err| switch (err) { | ||
| 445 | error.WriteFailed => return w.err.?, | ||
| 446 | }; | ||
| 447 | } | ||
| 448 | |||
| 449 | fn openBrowserTab(io: Io, url: []const u8) !void { | 448 | fn openBrowserTab(io: Io, url: []const u8) !void { |
| 450 | // Until https://github.com/ziglang/zig/issues/19205 is implemented, we | 449 | // Until https://github.com/ziglang/zig/issues/19205 is implemented, we |
| 451 | // spawn and then leak a concurrent task for this child process. | 450 | // spawn and then leak a concurrent task for this child process. |
lib/compiler/test_runner.zig+14-14| ... | @@ -78,11 +78,11 @@ fn mainServer(init: std.process.Init.Minimal) !void { | ... | @@ -78,11 +78,11 @@ fn mainServer(init: std.process.Init.Minimal) !void { |
| 78 | @disableInstrumentation(); | 78 | @disableInstrumentation(); |
| 79 | stdin_reader = .initStreaming(.stdin(), runner_threaded_io, &stdin_buffer); | 79 | stdin_reader = .initStreaming(.stdin(), runner_threaded_io, &stdin_buffer); |
| 80 | stdout_writer = .initStreaming(.stdout(), runner_threaded_io, &stdout_buffer); | 80 | stdout_writer = .initStreaming(.stdout(), runner_threaded_io, &stdout_buffer); |
| 81 | var server = try std.zig.Server.init(.{ | 81 | var server: std.zig.Server = .{ |
| 82 | .in = &stdin_reader.interface, | 82 | .in = &stdin_reader.interface, |
| 83 | .out = &stdout_writer.interface, | 83 | .out = &stdout_writer.interface, |
| 84 | .zig_version = builtin.zig_version_string, | 84 | }; |
| 85 | }); | 85 | try server.serveStringMessage(.zig_version, builtin.zig_version_string); |
| 86 | 86 | ||
| 87 | while (true) { | 87 | while (true) { |
| 88 | const hdr = try server.receiveMessage(); | 88 | const hdr = try server.receiveMessage(); |
| ... | @@ -91,24 +91,23 @@ fn mainServer(init: std.process.Init.Minimal) !void { | ... | @@ -91,24 +91,23 @@ fn mainServer(init: std.process.Init.Minimal) !void { |
| 91 | return std.process.exit(0); | 91 | return std.process.exit(0); |
| 92 | }, | 92 | }, |
| 93 | .query_test_metadata => { | 93 | .query_test_metadata => { |
| 94 | testing.allocator_instance = .init(std.heap.page_allocator, .{}); | 94 | var sa: std.heap.SafeAllocator = .init(std.heap.page_allocator, .{}); |
| 95 | defer if (testing.allocator_instance.deinit() != 0) { | 95 | defer if (sa.deinit() != 0) @panic("internal test runner memory leak"); |
| 96 | @panic("internal test runner memory leak"); | 96 | const gpa = sa.allocator(); |
| 97 | }; | ||
| 98 | 97 | ||
| 99 | var string_bytes: std.ArrayList(u8) = .empty; | 98 | var string_bytes: std.ArrayList(u8) = .empty; |
| 100 | defer string_bytes.deinit(testing.allocator); | 99 | defer string_bytes.deinit(gpa); |
| 101 | try string_bytes.append(testing.allocator, 0); // Reserve 0 for null. | 100 | try string_bytes.append(gpa, 0); // Reserve 0 for null. |
| 102 | 101 | ||
| 103 | const test_fns = builtin.test_functions; | 102 | const test_fns = builtin.test_functions; |
| 104 | const names = try testing.allocator.alloc(u32, test_fns.len); | 103 | const names = try gpa.alloc(u32, test_fns.len); |
| 105 | defer testing.allocator.free(names); | 104 | defer gpa.free(names); |
| 106 | const expected_panic_msgs = try testing.allocator.alloc(u32, test_fns.len); | 105 | const expected_panic_msgs = try gpa.alloc(u32, test_fns.len); |
| 107 | defer testing.allocator.free(expected_panic_msgs); | 106 | defer gpa.free(expected_panic_msgs); |
| 108 | 107 | ||
| 109 | for (test_fns, names, expected_panic_msgs) |test_fn, *name, *expected_panic_msg| { | 108 | for (test_fns, names, expected_panic_msgs) |test_fn, *name, *expected_panic_msg| { |
| 110 | name.* = @intCast(string_bytes.items.len); | 109 | name.* = @intCast(string_bytes.items.len); |
| 111 | try string_bytes.ensureUnusedCapacity(testing.allocator, test_fn.name.len + 1); | 110 | try string_bytes.ensureUnusedCapacity(gpa, test_fn.name.len + 1); |
| 112 | string_bytes.appendSliceAssumeCapacity(test_fn.name); | 111 | string_bytes.appendSliceAssumeCapacity(test_fn.name); |
| 113 | string_bytes.appendAssumeCapacity(0); | 112 | string_bytes.appendAssumeCapacity(0); |
| 114 | expected_panic_msg.* = 0; | 113 | expected_panic_msg.* = 0; |
| ... | @@ -377,6 +376,7 @@ pub fn mainSimple() anyerror!void { | ... | @@ -377,6 +376,7 @@ pub fn mainSimple() anyerror!void { |
| 377 | else => false, | 376 | else => false, |
| 378 | }; | 377 | }; |
| 379 | 378 | ||
| 379 | testing.allocator_instance = .init(std.heap.page_allocator, .{}); | ||
| 380 | testing.io_instance = .init(testing.allocator, .{}); | 380 | testing.io_instance = .init(testing.allocator, .{}); |
| 381 | 381 | ||
| 382 | var passed: u64 = 0; | 382 | var passed: u64 = 0; |
lib/compiler/translate-c/MacroTranslator.zig+1-1| ... | @@ -361,7 +361,7 @@ fn parseCNumLit(mt: *MacroTranslator) ParseError!ZigNode { | ... | @@ -361,7 +361,7 @@ fn parseCNumLit(mt: *MacroTranslator) ParseError!ZigNode { |
| 361 | return error.ParseError; | 361 | return error.ParseError; |
| 362 | }, | 362 | }, |
| 363 | }); | 363 | }); |
| 364 | if (bytes.getLast().? == '.') { | 364 | if (bytes.last().? == '.') { |
| 365 | bytes.appendAssumeCapacity('0'); | 365 | bytes.appendAssumeCapacity('0'); |
| 366 | } else if (mem.findAny(u8, bytes.items, ".eEpP") == null) { | 366 | } else if (mem.findAny(u8, bytes.items, ".eEpP") == null) { |
| 367 | bytes.appendSliceAssumeCapacity(".0"); | 367 | bytes.appendSliceAssumeCapacity(".0"); |
lib/compiler/translate-c/main.zig+1-1| ... | @@ -9,7 +9,7 @@ const compiler_util = @import("../util.zig"); | ... | @@ -9,7 +9,7 @@ const compiler_util = @import("../util.zig"); |
| 9 | 9 | ||
| 10 | const Translator = @import("Translator.zig"); | 10 | const Translator = @import("Translator.zig"); |
| 11 | 11 | ||
| 12 | const fast_exit = @import("builtin").mode != .Debug; | 12 | const fast_exit = @import("builtin").mode != .debug; |
| 13 | 13 | ||
| 14 | pub fn main(init: process.Init) u8 { | 14 | pub fn main(init: process.Init) u8 { |
| 15 | const gpa = init.gpa; | 15 | const gpa = init.gpa; |
lib/compiler_rt.zig+193-177| ... | @@ -1,4 +1,5 @@ | ... | @@ -1,4 +1,5 @@ |
| 1 | const builtin = @import("builtin"); | 1 | const builtin = @import("builtin"); |
| 2 | const compiler_rt = @This(); | ||
| 2 | const ofmt_c = builtin.object_format == .c; | 3 | const ofmt_c = builtin.object_format == .c; |
| 3 | const native_endian = builtin.cpu.arch.endian(); | 4 | const native_endian = builtin.cpu.arch.endian(); |
| 4 | 5 | ||
| ... | @@ -84,144 +85,17 @@ comptime { | ... | @@ -84,144 +85,17 @@ comptime { |
| 84 | // Float routines | 85 | // Float routines |
| 85 | // conversion | 86 | // conversion |
| 86 | _ = @import("compiler_rt/extendf.zig"); | 87 | _ = @import("compiler_rt/extendf.zig"); |
| 87 | _ = @import("compiler_rt/extendhfsf2.zig"); | ||
| 88 | _ = @import("compiler_rt/extendhfdf2.zig"); | ||
| 89 | _ = @import("compiler_rt/extendhftf2.zig"); | ||
| 90 | _ = @import("compiler_rt/extendhfxf2.zig"); | ||
| 91 | _ = @import("compiler_rt/extendsfdf2.zig"); | ||
| 92 | _ = @import("compiler_rt/extendsftf2.zig"); | ||
| 93 | _ = @import("compiler_rt/extendsfxf2.zig"); | ||
| 94 | _ = @import("compiler_rt/extenddftf2.zig"); | ||
| 95 | _ = @import("compiler_rt/extenddfxf2.zig"); | ||
| 96 | _ = @import("compiler_rt/extendxftf2.zig"); | ||
| 97 | |||
| 98 | _ = @import("compiler_rt/truncf.zig"); | 88 | _ = @import("compiler_rt/truncf.zig"); |
| 99 | _ = @import("compiler_rt/truncsfhf2.zig"); | ||
| 100 | _ = @import("compiler_rt/truncdfhf2.zig"); | ||
| 101 | _ = @import("compiler_rt/truncdfsf2.zig"); | ||
| 102 | _ = @import("compiler_rt/truncxfhf2.zig"); | ||
| 103 | _ = @import("compiler_rt/truncxfsf2.zig"); | ||
| 104 | _ = @import("compiler_rt/truncxfdf2.zig"); | ||
| 105 | _ = @import("compiler_rt/trunctfhf2.zig"); | ||
| 106 | _ = @import("compiler_rt/trunctfsf2.zig"); | ||
| 107 | _ = @import("compiler_rt/trunctfdf2.zig"); | ||
| 108 | _ = @import("compiler_rt/trunctfxf2.zig"); | ||
| 109 | |||
| 110 | _ = @import("compiler_rt/int_from_float.zig"); | 89 | _ = @import("compiler_rt/int_from_float.zig"); |
| 111 | _ = @import("compiler_rt/fixhfei.zig"); | ||
| 112 | _ = @import("compiler_rt/fixsfsi.zig"); | ||
| 113 | _ = @import("compiler_rt/fixsfdi.zig"); | ||
| 114 | _ = @import("compiler_rt/fixsfti.zig"); | ||
| 115 | _ = @import("compiler_rt/fixsfei.zig"); | ||
| 116 | _ = @import("compiler_rt/fixdfsi.zig"); | ||
| 117 | _ = @import("compiler_rt/fixdfdi.zig"); | ||
| 118 | _ = @import("compiler_rt/fixdfti.zig"); | ||
| 119 | _ = @import("compiler_rt/fixdfei.zig"); | ||
| 120 | _ = @import("compiler_rt/fixtfsi.zig"); | ||
| 121 | _ = @import("compiler_rt/fixtfdi.zig"); | ||
| 122 | _ = @import("compiler_rt/fixtfti.zig"); | ||
| 123 | _ = @import("compiler_rt/fixtfei.zig"); | ||
| 124 | _ = @import("compiler_rt/fixxfsi.zig"); | ||
| 125 | _ = @import("compiler_rt/fixxfdi.zig"); | ||
| 126 | _ = @import("compiler_rt/fixxfei.zig"); | ||
| 127 | |||
| 128 | _ = @import("compiler_rt/fixunshfsi.zig"); | ||
| 129 | _ = @import("compiler_rt/fixunshfdi.zig"); | ||
| 130 | _ = @import("compiler_rt/fixunshfti.zig"); | ||
| 131 | _ = @import("compiler_rt/fixunshfei.zig"); | ||
| 132 | _ = @import("compiler_rt/fixunssfsi.zig"); | ||
| 133 | _ = @import("compiler_rt/fixunssfdi.zig"); | ||
| 134 | _ = @import("compiler_rt/fixunssfti.zig"); | ||
| 135 | _ = @import("compiler_rt/fixunssfei.zig"); | ||
| 136 | _ = @import("compiler_rt/fixunsdfsi.zig"); | ||
| 137 | _ = @import("compiler_rt/fixunsdfdi.zig"); | ||
| 138 | _ = @import("compiler_rt/fixunsdfti.zig"); | ||
| 139 | _ = @import("compiler_rt/fixunsdfei.zig"); | ||
| 140 | _ = @import("compiler_rt/fixunstfsi.zig"); | ||
| 141 | _ = @import("compiler_rt/fixunstfdi.zig"); | ||
| 142 | _ = @import("compiler_rt/fixunstfti.zig"); | ||
| 143 | _ = @import("compiler_rt/fixunstfei.zig"); | ||
| 144 | _ = @import("compiler_rt/fixunsxfsi.zig"); | ||
| 145 | _ = @import("compiler_rt/fixunsxfdi.zig"); | ||
| 146 | _ = @import("compiler_rt/fixunsxfti.zig"); | ||
| 147 | _ = @import("compiler_rt/fixunsxfei.zig"); | ||
| 148 | |||
| 149 | _ = @import("compiler_rt/float_from_int.zig"); | 90 | _ = @import("compiler_rt/float_from_int.zig"); |
| 150 | _ = @import("compiler_rt/floatsihf.zig"); | ||
| 151 | _ = @import("compiler_rt/floatsisf.zig"); | ||
| 152 | _ = @import("compiler_rt/floatsidf.zig"); | ||
| 153 | _ = @import("compiler_rt/floatsitf.zig"); | ||
| 154 | _ = @import("compiler_rt/floatsixf.zig"); | ||
| 155 | _ = @import("compiler_rt/floatdihf.zig"); | ||
| 156 | _ = @import("compiler_rt/floatdisf.zig"); | ||
| 157 | _ = @import("compiler_rt/floatdidf.zig"); | ||
| 158 | _ = @import("compiler_rt/floatditf.zig"); | ||
| 159 | _ = @import("compiler_rt/floatdixf.zig"); | ||
| 160 | _ = @import("compiler_rt/floattihf.zig"); | ||
| 161 | _ = @import("compiler_rt/floattisf.zig"); | ||
| 162 | _ = @import("compiler_rt/floattidf.zig"); | ||
| 163 | _ = @import("compiler_rt/floattitf.zig"); | ||
| 164 | _ = @import("compiler_rt/floattixf.zig"); | ||
| 165 | _ = @import("compiler_rt/floateihf.zig"); | ||
| 166 | _ = @import("compiler_rt/floateisf.zig"); | ||
| 167 | _ = @import("compiler_rt/floateidf.zig"); | ||
| 168 | _ = @import("compiler_rt/floateitf.zig"); | ||
| 169 | _ = @import("compiler_rt/floateixf.zig"); | ||
| 170 | _ = @import("compiler_rt/floatunsihf.zig"); | ||
| 171 | _ = @import("compiler_rt/floatunsisf.zig"); | ||
| 172 | _ = @import("compiler_rt/floatunsidf.zig"); | ||
| 173 | _ = @import("compiler_rt/floatunsitf.zig"); | ||
| 174 | _ = @import("compiler_rt/floatunsixf.zig"); | ||
| 175 | _ = @import("compiler_rt/floatundihf.zig"); | ||
| 176 | _ = @import("compiler_rt/floatundisf.zig"); | ||
| 177 | _ = @import("compiler_rt/floatundidf.zig"); | ||
| 178 | _ = @import("compiler_rt/floatunditf.zig"); | ||
| 179 | _ = @import("compiler_rt/floatundixf.zig"); | ||
| 180 | _ = @import("compiler_rt/floatuntihf.zig"); | ||
| 181 | _ = @import("compiler_rt/floatuntisf.zig"); | ||
| 182 | _ = @import("compiler_rt/floatuntidf.zig"); | ||
| 183 | _ = @import("compiler_rt/floatuntitf.zig"); | ||
| 184 | _ = @import("compiler_rt/floatuntixf.zig"); | ||
| 185 | _ = @import("compiler_rt/floatuneihf.zig"); | ||
| 186 | _ = @import("compiler_rt/floatuneisf.zig"); | ||
| 187 | _ = @import("compiler_rt/floatuneidf.zig"); | ||
| 188 | _ = @import("compiler_rt/floatuneitf.zig"); | ||
| 189 | _ = @import("compiler_rt/floatuneixf.zig"); | ||
| 190 | 91 | ||
| 191 | // comparison | 92 | // comparison |
| 192 | _ = @import("compiler_rt/comparef.zig"); | 93 | _ = @import("compiler_rt/comparef.zig"); |
| 193 | _ = @import("compiler_rt/cmpdf2.zig"); | ||
| 194 | _ = @import("compiler_rt/cmptf2.zig"); | ||
| 195 | _ = @import("compiler_rt/cmpxf2.zig"); | ||
| 196 | _ = @import("compiler_rt/unorddf2.zig"); | ||
| 197 | _ = @import("compiler_rt/gehf2.zig"); | ||
| 198 | _ = @import("compiler_rt/gesf2.zig"); | ||
| 199 | _ = @import("compiler_rt/gedf2.zig"); | ||
| 200 | _ = @import("compiler_rt/gexf2.zig"); | ||
| 201 | _ = @import("compiler_rt/getf2.zig"); | ||
| 202 | 94 | ||
| 203 | // arithmetic | 95 | // arithmetic |
| 204 | _ = @import("compiler_rt/addf3.zig"); | 96 | _ = @import("compiler_rt/addf3.zig"); |
| 205 | _ = @import("compiler_rt/addhf3.zig"); | ||
| 206 | _ = @import("compiler_rt/addsf3.zig"); | ||
| 207 | _ = @import("compiler_rt/adddf3.zig"); | ||
| 208 | _ = @import("compiler_rt/addtf3.zig"); | ||
| 209 | _ = @import("compiler_rt/addxf3.zig"); | ||
| 210 | |||
| 211 | _ = @import("compiler_rt/subhf3.zig"); | ||
| 212 | _ = @import("compiler_rt/subsf3.zig"); | ||
| 213 | _ = @import("compiler_rt/subdf3.zig"); | ||
| 214 | _ = @import("compiler_rt/subtf3.zig"); | ||
| 215 | _ = @import("compiler_rt/subxf3.zig"); | ||
| 216 | |||
| 217 | _ = @import("compiler_rt/mulf3.zig"); | 97 | _ = @import("compiler_rt/mulf3.zig"); |
| 218 | _ = @import("compiler_rt/mulhf3.zig"); | ||
| 219 | _ = @import("compiler_rt/mulsf3.zig"); | ||
| 220 | _ = @import("compiler_rt/muldf3.zig"); | ||
| 221 | _ = @import("compiler_rt/multf3.zig"); | ||
| 222 | _ = @import("compiler_rt/mulxf3.zig"); | ||
| 223 | 98 | ||
| 224 | _ = @import("compiler_rt/divhf3.zig"); | ||
| 225 | _ = @import("compiler_rt/divsf3.zig"); | 99 | _ = @import("compiler_rt/divsf3.zig"); |
| 226 | _ = @import("compiler_rt/divdf3.zig"); | 100 | _ = @import("compiler_rt/divdf3.zig"); |
| 227 | _ = @import("compiler_rt/divxf3.zig"); | 101 | _ = @import("compiler_rt/divxf3.zig"); |
| ... | @@ -235,25 +109,17 @@ comptime { | ... | @@ -235,25 +109,17 @@ comptime { |
| 235 | symbol(&__negsf2, "__negsf2"); | 109 | symbol(&__negsf2, "__negsf2"); |
| 236 | symbol(&__negdf2, "__negdf2"); | 110 | symbol(&__negdf2, "__negdf2"); |
| 237 | } | 111 | } |
| 238 | if (want_ppc_abi) symbol(&__negtf2, "__negkf2"); | 112 | if (want_ppc_abi) { |
| 239 | symbol(&__negtf2, "__negtf2"); | 113 | symbol(&__negtf2, "__negkf2"); |
| 114 | } else { | ||
| 115 | symbol(&__negtf2, "__negtf2"); | ||
| 116 | } | ||
| 240 | symbol(&__negxf2, "__negxf2"); | 117 | symbol(&__negxf2, "__negxf2"); |
| 241 | 118 | ||
| 242 | // other | 119 | // other |
| 243 | _ = @import("compiler_rt/powiXf2.zig"); | 120 | _ = @import("compiler_rt/powiXf2.zig"); |
| 244 | _ = @import("compiler_rt/mulc3.zig"); | 121 | _ = @import("compiler_rt/mulc3.zig"); |
| 245 | _ = @import("compiler_rt/mulhc3.zig"); | ||
| 246 | _ = @import("compiler_rt/mulsc3.zig"); | ||
| 247 | _ = @import("compiler_rt/muldc3.zig"); | ||
| 248 | _ = @import("compiler_rt/mulxc3.zig"); | ||
| 249 | _ = @import("compiler_rt/multc3.zig"); | ||
| 250 | |||
| 251 | _ = @import("compiler_rt/divc3.zig"); | 122 | _ = @import("compiler_rt/divc3.zig"); |
| 252 | _ = @import("compiler_rt/divhc3.zig"); | ||
| 253 | _ = @import("compiler_rt/divsc3.zig"); | ||
| 254 | _ = @import("compiler_rt/divdc3.zig"); | ||
| 255 | _ = @import("compiler_rt/divxc3.zig"); | ||
| 256 | _ = @import("compiler_rt/divtc3.zig"); | ||
| 257 | 123 | ||
| 258 | // Math routines. Alphabetically sorted. | 124 | // Math routines. Alphabetically sorted. |
| 259 | _ = @import("compiler_rt/cos.zig"); | 125 | _ = @import("compiler_rt/cos.zig"); |
| ... | @@ -279,7 +145,7 @@ comptime { | ... | @@ -279,7 +145,7 @@ comptime { |
| 279 | _ = @import("compiler_rt/divmodei4.zig"); | 145 | _ = @import("compiler_rt/divmodei4.zig"); |
| 280 | _ = @import("compiler_rt/udivmodei4.zig"); | 146 | _ = @import("compiler_rt/udivmodei4.zig"); |
| 281 | 147 | ||
| 282 | _ = @import("compiler_rt/limb64.zig"); | 148 | if (builtin.cpu.arch.isWasm()) _ = @import("compiler_rt/limb64.zig"); |
| 283 | 149 | ||
| 284 | // extra | 150 | // extra |
| 285 | _ = @import("compiler_rt/os_version_check.zig"); | 151 | _ = @import("compiler_rt/os_version_check.zig"); |
| ... | @@ -290,7 +156,7 @@ comptime { | ... | @@ -290,7 +156,7 @@ comptime { |
| 290 | _ = @import("compiler_rt/clear_cache.zig"); | 156 | _ = @import("compiler_rt/clear_cache.zig"); |
| 291 | _ = @import("compiler_rt/hexagon.zig"); | 157 | _ = @import("compiler_rt/hexagon.zig"); |
| 292 | 158 | ||
| 293 | if (@import("builtin").object_format != .c) { | 159 | if (builtin.object_format != .c) { |
| 294 | if (builtin.zig_backend != .stage2_aarch64) _ = @import("compiler_rt/atomics.zig"); | 160 | if (builtin.zig_backend != .stage2_aarch64) _ = @import("compiler_rt/atomics.zig"); |
| 295 | _ = @import("compiler_rt/stack_probe.zig"); | 161 | _ = @import("compiler_rt/stack_probe.zig"); |
| 296 | 162 | ||
| ... | @@ -302,7 +168,6 @@ comptime { | ... | @@ -302,7 +168,6 @@ comptime { |
| 302 | _ = @import("compiler_rt/memcpy.zig"); | 168 | _ = @import("compiler_rt/memcpy.zig"); |
| 303 | if (!ofmt_c) { | 169 | if (!ofmt_c) { |
| 304 | symbol(&memset, "memset"); | 170 | symbol(&memset, "memset"); |
| 305 | symbol(&__memset, "__memset"); | ||
| 306 | } | 171 | } |
| 307 | _ = @import("compiler_rt/memmove.zig"); | 172 | _ = @import("compiler_rt/memmove.zig"); |
| 308 | symbol(&memcmp, "memcmp"); | 173 | symbol(&memcmp, "memcmp"); |
| ... | @@ -367,10 +232,7 @@ pub const want_aeabi = switch (builtin.abi) { | ... | @@ -367,10 +232,7 @@ pub const want_aeabi = switch (builtin.abi) { |
| 367 | .gnueabihf, | 232 | .gnueabihf, |
| 368 | .android, | 233 | .android, |
| 369 | .androideabi, | 234 | .androideabi, |
| 370 | => switch (builtin.cpu.arch) { | 235 | => builtin.cpu.arch.isArm(), |
| 371 | .arm, .armeb, .thumb, .thumbeb => true, | ||
| 372 | else => false, | ||
| 373 | }, | ||
| 374 | else => false, | 236 | else => false, |
| 375 | }; | 237 | }; |
| 376 | 238 | ||
| ... | @@ -444,19 +306,108 @@ pub const gnu_f16_abi = switch (builtin.cpu.arch) { | ... | @@ -444,19 +306,108 @@ pub const gnu_f16_abi = switch (builtin.cpu.arch) { |
| 444 | pub const want_sparc64_abi = builtin.cpu.arch == .sparc64; | 306 | pub const want_sparc64_abi = builtin.cpu.arch == .sparc64; |
| 445 | pub const want_sparc32_abi = builtin.cpu.arch == .sparc; | 307 | pub const want_sparc32_abi = builtin.cpu.arch == .sparc; |
| 446 | 308 | ||
| 447 | pub fn F16T(comptime OtherType: type) type { | 309 | /// For operations converting between `f16` and another floating point type. |
| 448 | return switch (builtin.cpu.arch) { | 310 | pub fn f16Conv(comptime OtherType: type) type { |
| 449 | .x86, .x86_64 => if (builtin.target.os.tag.isDarwin()) switch (OtherType) { | 311 | switch (std.zig.target.compilerRtFloatAbi(&builtin.target, 16)) { |
| 450 | // Starting with LLVM 16, Darwin uses different abi for f16 | 312 | .hard => {}, |
| 451 | // depending on the type of the other return/argument..??? | 313 | .soft => return softFloatAbi(f16), |
| 452 | f32, f64 => u16, | 314 | } |
| 453 | f80, f128 => f16, | 315 | if (builtin.cpu.arch.isX86() and builtin.os.tag.isDarwin()) switch (OtherType) { |
| 454 | else => unreachable, | 316 | else => unreachable, |
| 455 | } else f16, | 317 | // Starting with LLVM 16, Darwin uses different abi for f16 |
| 456 | else => f16, | 318 | // depending on the type of the other return/argument..??? |
| 319 | f32, f64 => return softFloatAbi(f16), | ||
| 320 | f80, f128 => {}, | ||
| 321 | }; | ||
| 322 | return hardFloatAbi(f16); | ||
| 323 | } | ||
| 324 | pub const @"f16" = switch (std.zig.target.compilerRtFloatAbi(&builtin.target, 16)) { | ||
| 325 | .hard => hardFloatAbi(f16), | ||
| 326 | .soft => softFloatAbi(f16), | ||
| 327 | }; | ||
| 328 | pub const @"f32" = switch (std.zig.target.compilerRtFloatAbi(&builtin.target, 32)) { | ||
| 329 | .hard => hardFloatAbi(f32), | ||
| 330 | .soft => softFloatAbi(f32), | ||
| 331 | }; | ||
| 332 | pub const @"f64" = switch (std.zig.target.compilerRtFloatAbi(&builtin.target, 64)) { | ||
| 333 | .hard => hardFloatAbi(f64), | ||
| 334 | .soft => softFloatAbi(f64), | ||
| 335 | }; | ||
| 336 | pub const @"f80" = switch (std.zig.target.compilerRtFloatAbi(&builtin.target, 80)) { | ||
| 337 | .hard => hardFloatAbi(f80), | ||
| 338 | .soft => struct { | ||
| 339 | pub const Abi = extern struct { mantissa: u64, exponent: u16 }; | ||
| 340 | const Repr = packed struct { mantissa: u64, exponent: u16 }; | ||
| 341 | pub inline fn toAbi(raw: f80) Abi { | ||
| 342 | const repr: Repr = @bitCast(raw); | ||
| 343 | return .{ .mantissa = repr.mantissa, .exponent = repr.exponent }; | ||
| 344 | } | ||
| 345 | pub inline fn fromAbi(abi: Abi) f80 { | ||
| 346 | const repr: Repr = .{ .mantissa = abi.mantissa, .exponent = abi.exponent }; | ||
| 347 | return @bitCast(repr); | ||
| 348 | } | ||
| 349 | pub const complex = complexAbi(f80, @This()); | ||
| 350 | }, | ||
| 351 | }; | ||
| 352 | pub const @"f128" = switch (std.zig.target.compilerRtFloatAbi(&builtin.target, 128)) { | ||
| 353 | .hard => hardFloatAbi(f128), | ||
| 354 | .soft => struct { | ||
| 355 | pub const Abi = switch (builtin.cpu.arch.endian()) { | ||
| 356 | .big => extern struct { hi: u64, lo: u64 }, | ||
| 357 | .little => extern struct { lo: u64, hi: u64 }, | ||
| 358 | }; | ||
| 359 | const Repr = packed struct { lo: u64, hi: u64 }; | ||
| 360 | pub inline fn toAbi(raw: f128) Abi { | ||
| 361 | const repr: Repr = @bitCast(raw); | ||
| 362 | return .{ .lo = repr.lo, .hi = repr.hi }; | ||
| 363 | } | ||
| 364 | pub inline fn fromAbi(abi: Abi) f128 { | ||
| 365 | const repr: Repr = .{ .lo = abi.lo, .hi = abi.hi }; | ||
| 366 | return @bitCast(repr); | ||
| 367 | } | ||
| 368 | pub const complex = complexAbi(f128, @This()); | ||
| 369 | }, | ||
| 370 | }; | ||
| 371 | fn hardFloatAbi(comptime Float: type) type { | ||
| 372 | return struct { | ||
| 373 | pub const Abi = Float; | ||
| 374 | pub inline fn toAbi(raw: Float) Abi { | ||
| 375 | return raw; | ||
| 376 | } | ||
| 377 | pub inline fn fromAbi(abi: Abi) Float { | ||
| 378 | return abi; | ||
| 379 | } | ||
| 380 | pub const complex = complexAbi(Float, @This()); | ||
| 381 | }; | ||
| 382 | } | ||
| 383 | fn softFloatAbi(comptime Float: type) type { | ||
| 384 | return struct { | ||
| 385 | pub const Abi = @Int(.unsigned, @bitSizeOf(Float)); | ||
| 386 | pub inline fn toAbi(raw: Float) Abi { | ||
| 387 | return @bitCast(raw); | ||
| 388 | } | ||
| 389 | pub inline fn fromAbi(abi: Abi) Float { | ||
| 390 | return @bitCast(abi); | ||
| 391 | } | ||
| 392 | pub const complex = complexAbi(Float, @This()); | ||
| 393 | }; | ||
| 394 | } | ||
| 395 | fn complexAbi(comptime Float: type, comptime float: type) type { | ||
| 396 | return struct { | ||
| 397 | pub const Abi = extern struct { real: float.Abi, imag: float.Abi }; | ||
| 398 | pub inline fn toAbi(raw: Complex(Float)) Abi { | ||
| 399 | return .{ .real = float.toAbi(raw.real), .imag = float.toAbi(raw.imag) }; | ||
| 400 | } | ||
| 401 | pub inline fn fromAbi(abi: Abi) Complex(Float) { | ||
| 402 | return .{ .real = float.fromAbi(abi.real), .imag = float.fromAbi(abi.imag) }; | ||
| 403 | } | ||
| 457 | }; | 404 | }; |
| 458 | } | 405 | } |
| 459 | 406 | ||
| 407 | pub fn Complex(comptime Float: type) type { | ||
| 408 | return struct { real: Float, imag: Float }; | ||
| 409 | } | ||
| 410 | |||
| 460 | pub fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void { | 411 | pub fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void { |
| 461 | switch (Z) { | 412 | switch (Z) { |
| 462 | u16 => { | 413 | u16 => { |
| ... | @@ -589,31 +540,31 @@ pub inline fn fneg(a: anytype) @TypeOf(a) { | ... | @@ -589,31 +540,31 @@ pub inline fn fneg(a: anytype) @TypeOf(a) { |
| 589 | return @bitCast(negated); | 540 | return @bitCast(negated); |
| 590 | } | 541 | } |
| 591 | 542 | ||
| 592 | fn __negxf2(a: f80) callconv(.c) f80 { | 543 | fn __neghf2(a: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { |
| 593 | return fneg(a); | 544 | return compiler_rt.f16.toAbi(fneg(compiler_rt.f16.fromAbi(a))); |
| 594 | } | 545 | } |
| 595 | 546 | ||
| 596 | fn __neghf2(a: f16) callconv(.c) f16 { | 547 | fn __negsf2(a: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { |
| 597 | return fneg(a); | 548 | return compiler_rt.f32.toAbi(fneg(compiler_rt.f32.fromAbi(a))); |
| 598 | } | 549 | } |
| 599 | 550 | ||
| 600 | fn __negdf2(a: f64) callconv(.c) f64 { | 551 | fn __negdf2(a: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { |
| 601 | return fneg(a); | 552 | return compiler_rt.f64.toAbi(fneg(compiler_rt.f64.fromAbi(a))); |
| 602 | } | 553 | } |
| 603 | 554 | ||
| 604 | fn __aeabi_dneg(a: f64) callconv(.{ .arm_aapcs = .{} }) f64 { | 555 | fn __negxf2(a: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { |
| 605 | return fneg(a); | 556 | return compiler_rt.f80.toAbi(fneg(compiler_rt.f80.fromAbi(a))); |
| 606 | } | 557 | } |
| 607 | 558 | ||
| 608 | fn __negtf2(a: f128) callconv(.c) f128 { | 559 | fn __negtf2(a: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { |
| 609 | return fneg(a); | 560 | return compiler_rt.f128.toAbi(fneg(compiler_rt.f128.fromAbi(a))); |
| 610 | } | 561 | } |
| 611 | 562 | ||
| 612 | fn __negsf2(a: f32) callconv(.c) f32 { | 563 | fn __aeabi_fneg(a: f32) callconv(.{ .arm_aapcs = .{} }) f32 { |
| 613 | return fneg(a); | 564 | return fneg(a); |
| 614 | } | 565 | } |
| 615 | 566 | ||
| 616 | fn __aeabi_fneg(a: f32) callconv(.{ .arm_aapcs = .{} }) f32 { | 567 | fn __aeabi_dneg(a: f64) callconv(.{ .arm_aapcs = .{} }) f64 { |
| 617 | return fneg(a); | 568 | return fneg(a); |
| 618 | } | 569 | } |
| 619 | 570 | ||
| ... | @@ -650,14 +601,80 @@ inline fn negXi2(comptime T: type, a: T) T { | ... | @@ -650,14 +601,80 @@ inline fn negXi2(comptime T: type, a: T) T { |
| 650 | return -a; | 601 | return -a; |
| 651 | } | 602 | } |
| 652 | 603 | ||
| 653 | pub fn memset(dest: ?[*]u8, c: u8, len: usize) callconv(.c) ?[*]u8 { | 604 | fn memsetSmallPowerOf2(d: [*]u8, b: u8, comptime size: usize) void { |
| 654 | @setRuntimeSafety(false); | 605 | if (size > @sizeOf(usize)) { |
| 606 | d[0..size].* = @splat(b); | ||
| 607 | } else { | ||
| 608 | const T = @Int(.unsigned, 8 * size); | ||
| 609 | var splatted: T = 0; // Setting this to undefined causes a memset call and thus infinite recursion in Debug test-compiler-rt. | ||
| 610 | @as(*[size]u8, @ptrCast(&splatted)).* = @splat(b); | ||
| 611 | @as(*align(1) T, @ptrCast(d)).* = splatted; | ||
| 612 | } | ||
| 613 | } | ||
| 614 | |||
| 615 | fn shortMemset( | ||
| 616 | log_min: comptime_int, | ||
| 617 | log_max: comptime_int, | ||
| 618 | d: [*]u8, | ||
| 619 | b: u8, | ||
| 620 | len: usize, | ||
| 621 | ) void { | ||
| 622 | if (log_min + 1 != log_max) { | ||
| 623 | const mid = (log_min + log_max) / 2; | ||
| 624 | if (len > 1 << mid) { | ||
| 625 | shortMemset(mid, log_max, d, b, len); | ||
| 626 | } else { | ||
| 627 | shortMemset(log_min, mid, d, b, len); | ||
| 628 | } | ||
| 629 | } else { | ||
| 630 | const size = 1 << log_min; | ||
| 631 | |||
| 632 | memsetSmallPowerOf2(d, b, size); | ||
| 633 | memsetSmallPowerOf2(d + len - size, b, size); | ||
| 634 | } | ||
| 635 | } | ||
| 636 | |||
| 637 | fn fastMemset(dest: ?[*]u8, c: c_int, len: usize) callconv(.c) ?[*]u8 { | ||
| 638 | const b: u8 = @truncate(@as(c_uint, @bitCast(c))); | ||
| 639 | const n = std.simd.suggestVectorLength(u8) orelse @sizeOf(usize); | ||
| 640 | |||
| 641 | const d = dest.?; | ||
| 642 | |||
| 643 | if (len > 2 * n) { | ||
| 644 | memsetSmallPowerOf2(d, b, n); | ||
| 645 | |||
| 646 | const begin_aligned = std.mem.alignBackward(usize, @intFromPtr(d) + n, n); | ||
| 647 | const end_aligned = std.mem.alignForward(usize, @intFromPtr(d) + len - n, n); | ||
| 648 | |||
| 649 | const aligned_ptr: [*]align(n) u8 = @ptrFromInt(begin_aligned); | ||
| 650 | |||
| 651 | var i: usize = 0; | ||
| 652 | while (true) { | ||
| 653 | memsetSmallPowerOf2(aligned_ptr + n * i, b, n); | ||
| 654 | |||
| 655 | i += 1; | ||
| 656 | if (i == @divExact(end_aligned - begin_aligned, n)) | ||
| 657 | break; | ||
| 658 | } | ||
| 659 | |||
| 660 | memsetSmallPowerOf2(d + len - n, b, n); | ||
| 661 | } else { | ||
| 662 | if (len == 0) return dest; | ||
| 663 | |||
| 664 | shortMemset(0, @ctz(@as(usize, 2 * n)), d, b, len); | ||
| 665 | } | ||
| 666 | |||
| 667 | return dest; | ||
| 668 | } | ||
| 669 | |||
| 670 | fn smallMemset(dest: ?[*]u8, c: c_int, len: usize) callconv(.c) ?[*]u8 { | ||
| 671 | const b: u8 = @truncate(@as(c_uint, @bitCast(c))); | ||
| 655 | 672 | ||
| 656 | if (len != 0) { | 673 | if (len != 0) { |
| 657 | var d = dest.?; | 674 | var d = dest.?; |
| 658 | var n = len; | 675 | var n = len; |
| 659 | while (true) { | 676 | while (true) { |
| 660 | d[0] = c; | 677 | d[0] = b; |
| 661 | n -= 1; | 678 | n -= 1; |
| 662 | if (n == 0) break; | 679 | if (n == 0) break; |
| 663 | d += 1; | 680 | d += 1; |
| ... | @@ -667,11 +684,10 @@ pub fn memset(dest: ?[*]u8, c: u8, len: usize) callconv(.c) ?[*]u8 { | ... | @@ -667,11 +684,10 @@ pub fn memset(dest: ?[*]u8, c: u8, len: usize) callconv(.c) ?[*]u8 { |
| 667 | return dest; | 684 | return dest; |
| 668 | } | 685 | } |
| 669 | 686 | ||
| 670 | pub fn __memset(dest: ?[*]u8, c: u8, n: usize, dest_n: usize) callconv(.c) ?[*]u8 { | 687 | pub const memset = if (builtin.optimize == .small) |
| 671 | if (dest_n < n) | 688 | smallMemset |
| 672 | @panic("buffer overflow"); | 689 | else |
| 673 | return memset(dest, c, n); | 690 | fastMemset; |
| 674 | } | ||
| 675 | 691 | ||
| 676 | pub fn bcmp(vl: [*]allowzero const u8, vr: [*]allowzero const u8, n: usize) callconv(.c) c_int { | 692 | pub fn bcmp(vl: [*]allowzero const u8, vr: [*]allowzero const u8, n: usize) callconv(.c) c_int { |
| 677 | @setRuntimeSafety(false); | 693 | @setRuntimeSafety(false); |
lib/compiler_rt/absv.zig+1-2| ... | @@ -14,8 +14,7 @@ pub inline fn absv(comptime ST: type, a: ST) ST { | ... | @@ -14,8 +14,7 @@ pub inline fn absv(comptime ST: type, a: ST) ST { |
| 14 | const sign: ST = a >> N - 1; | 14 | const sign: ST = a >> N - 1; |
| 15 | x +%= sign; | 15 | x +%= sign; |
| 16 | x ^= sign; | 16 | x ^= sign; |
| 17 | if (x < 0) | 17 | if (x < 0) @panic("integer overflow"); |
| 18 | @panic("compiler_rt absv: overflow"); | ||
| 19 | return x; | 18 | return x; |
| 20 | } | 19 | } |
| 21 | 20 |
lib/compiler_rt/absvdi2.zig+3-2| ... | @@ -1,5 +1,6 @@ | ... | @@ -1,5 +1,6 @@ |
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | 1 | const compiler_rt = @import("../compiler_rt.zig"); |
| 2 | const absv = @import("./absv.zig").absv; | 2 | const symbol = compiler_rt.symbol; |
| 3 | const absv = @import("absv.zig").absv; | ||
| 3 | 4 | ||
| 4 | comptime { | 5 | comptime { |
| 5 | symbol(&__absvdi2, "__absvdi2"); | 6 | symbol(&__absvdi2, "__absvdi2"); |
lib/compiler_rt/absvsi2.zig+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | 1 | const compiler_rt = @import("../compiler_rt.zig"); |
| 2 | const symbol = compiler_rt.symbol; | 2 | const symbol = compiler_rt.symbol; |
| 3 | const absv = @import("./absv.zig").absv; | 3 | const absv = @import("absv.zig").absv; |
| 4 | 4 | ||
| 5 | comptime { | 5 | comptime { |
| 6 | symbol(&__absvsi2, "__absvsi2"); | 6 | symbol(&__absvsi2, "__absvsi2"); |
lib/compiler_rt/absvti2.zig+3-2| ... | @@ -1,5 +1,6 @@ | ... | @@ -1,5 +1,6 @@ |
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | 1 | const compiler_rt = @import("../compiler_rt.zig"); |
| 2 | const absv = @import("./absv.zig").absv; | 2 | const symbol = compiler_rt.symbol; |
| 3 | const absv = @import("absv.zig").absv; | ||
| 3 | 4 | ||
| 4 | comptime { | 5 | comptime { |
| 5 | symbol(&__absvti2, "__absvti2"); | 6 | symbol(&__absvti2, "__absvti2"); |
lib/compiler_rt/adddf3.zig deleted-19| ... | @@ -1,19 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const addf3 = @import("./addf3.zig").addf3; | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_aeabi) { | ||
| 7 | symbol(&__aeabi_dadd, "__aeabi_dadd"); | ||
| 8 | } else { | ||
| 9 | symbol(&__adddf3, "__adddf3"); | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | fn __adddf3(a: f64, b: f64) callconv(.c) f64 { | ||
| 14 | return addf3(f64, a, b); | ||
| 15 | } | ||
| 16 | |||
| 17 | fn __aeabi_dadd(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 { | ||
| 18 | return addf3(f64, a, b); | ||
| 19 | } | ||
lib/compiler_rt/addf3.zig+132-1| ... | @@ -1,12 +1,143 @@ | ... | @@ -1,12 +1,143 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const math = std.math; | 2 | const math = std.math; |
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | 3 | const compiler_rt = @import("../compiler_rt.zig"); |
| 4 | const symbol = compiler_rt.symbol; | ||
| 4 | const normalize = compiler_rt.normalize; | 5 | const normalize = compiler_rt.normalize; |
| 5 | 6 | ||
| 7 | comptime { | ||
| 8 | symbol(&__addhf3, "__addhf3"); | ||
| 9 | if (compiler_rt.want_aeabi) { | ||
| 10 | symbol(&__aeabi_fadd, "__aeabi_fadd"); | ||
| 11 | symbol(&__aeabi_dadd, "__aeabi_dadd"); | ||
| 12 | } else { | ||
| 13 | symbol(&__addsf3, "__addsf3"); | ||
| 14 | symbol(&__adddf3, "__adddf3"); | ||
| 15 | } | ||
| 16 | symbol(&__addxf3, "__addxf3"); | ||
| 17 | if (compiler_rt.want_ppc_abi) { | ||
| 18 | symbol(&__addtf3, "__addkf3"); | ||
| 19 | } else if (compiler_rt.want_sparc64_abi) { | ||
| 20 | symbol(&_Qp_add, "_Qp_add"); | ||
| 21 | } else if (compiler_rt.want_sparc32_abi) { | ||
| 22 | symbol(&__addtf3, "_Q_add"); | ||
| 23 | } else { | ||
| 24 | symbol(&__addtf3, "__addtf3"); | ||
| 25 | } | ||
| 26 | } | ||
| 27 | |||
| 28 | fn __addhf3(a: compiler_rt.f16.Abi, b: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { | ||
| 29 | return compiler_rt.f16.toAbi(add_f16(compiler_rt.f16.fromAbi(a), compiler_rt.f16.fromAbi(b))); | ||
| 30 | } | ||
| 31 | pub fn add_f16(a: f16, b: f16) f16 { | ||
| 32 | return addf3(f16, a, b); | ||
| 33 | } | ||
| 34 | |||
| 35 | fn __addsf3(a: compiler_rt.f32.Abi, b: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { | ||
| 36 | return compiler_rt.f32.toAbi(add_f32(compiler_rt.f32.fromAbi(a), compiler_rt.f32.fromAbi(b))); | ||
| 37 | } | ||
| 38 | fn __aeabi_fadd(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 { | ||
| 39 | return add_f32(a, b); | ||
| 40 | } | ||
| 41 | pub fn add_f32(a: f32, b: f32) f32 { | ||
| 42 | return addf3(f32, a, b); | ||
| 43 | } | ||
| 44 | |||
| 45 | fn __adddf3(a: compiler_rt.f64.Abi, b: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { | ||
| 46 | return compiler_rt.f64.toAbi(add_f64(compiler_rt.f64.fromAbi(a), compiler_rt.f64.fromAbi(b))); | ||
| 47 | } | ||
| 48 | fn __aeabi_dadd(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 { | ||
| 49 | return add_f64(a, b); | ||
| 50 | } | ||
| 51 | pub fn add_f64(a: f64, b: f64) f64 { | ||
| 52 | return addf3(f64, a, b); | ||
| 53 | } | ||
| 54 | |||
| 55 | fn __addxf3(a: compiler_rt.f80.Abi, b: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { | ||
| 56 | return compiler_rt.f80.toAbi(add_f80(compiler_rt.f80.fromAbi(a), compiler_rt.f80.fromAbi(b))); | ||
| 57 | } | ||
| 58 | pub fn add_f80(a: f80, b: f80) f80 { | ||
| 59 | return addf3(f80, a, b); | ||
| 60 | } | ||
| 61 | |||
| 62 | fn __addtf3(a: compiler_rt.f128.Abi, b: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { | ||
| 63 | return compiler_rt.f128.toAbi(add_f128(compiler_rt.f128.fromAbi(a), compiler_rt.f128.fromAbi(b))); | ||
| 64 | } | ||
| 65 | fn _Qp_add(c: *f128, a: *f128, b: *f128) callconv(.c) void { | ||
| 66 | c.* = add_f128(a.*, b.*); | ||
| 67 | } | ||
| 68 | pub fn add_f128(a: f128, b: f128) f128 { | ||
| 69 | return addf3(f128, a, b); | ||
| 70 | } | ||
| 71 | |||
| 72 | comptime { | ||
| 73 | symbol(&__subhf3, "__subhf3"); | ||
| 74 | if (compiler_rt.want_aeabi) { | ||
| 75 | symbol(&__aeabi_fsub, "__aeabi_fsub"); | ||
| 76 | symbol(&__aeabi_dsub, "__aeabi_dsub"); | ||
| 77 | } else { | ||
| 78 | symbol(&__subsf3, "__subsf3"); | ||
| 79 | symbol(&__subdf3, "__subdf3"); | ||
| 80 | } | ||
| 81 | symbol(&__subxf3, "__subxf3"); | ||
| 82 | if (compiler_rt.want_ppc_abi) { | ||
| 83 | symbol(&__subtf3, "__subkf3"); | ||
| 84 | } else if (compiler_rt.want_sparc64_abi) { | ||
| 85 | symbol(&_Qp_sub, "_Qp_sub"); | ||
| 86 | } else if (compiler_rt.want_sparc32_abi) { | ||
| 87 | symbol(&__subtf3, "_Q_sub"); | ||
| 88 | } else { | ||
| 89 | symbol(&__subtf3, "__subtf3"); | ||
| 90 | } | ||
| 91 | } | ||
| 92 | |||
| 93 | fn __subhf3(a: compiler_rt.f16.Abi, b: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { | ||
| 94 | return compiler_rt.f16.toAbi(sub_f16(compiler_rt.f16.fromAbi(a), compiler_rt.f16.fromAbi(b))); | ||
| 95 | } | ||
| 96 | pub fn sub_f16(a: f16, b: f16) f16 { | ||
| 97 | return add_f16(a, compiler_rt.fneg(b)); | ||
| 98 | } | ||
| 99 | |||
| 100 | fn __subsf3(a: compiler_rt.f32.Abi, b: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { | ||
| 101 | return compiler_rt.f32.toAbi(sub_f32(compiler_rt.f32.fromAbi(a), compiler_rt.f32.fromAbi(b))); | ||
| 102 | } | ||
| 103 | fn __aeabi_fsub(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 { | ||
| 104 | return sub_f32(a, b); | ||
| 105 | } | ||
| 106 | pub fn sub_f32(a: f32, b: f32) f32 { | ||
| 107 | return add_f32(a, compiler_rt.fneg(b)); | ||
| 108 | } | ||
| 109 | |||
| 110 | fn __subdf3(a: compiler_rt.f64.Abi, b: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { | ||
| 111 | return compiler_rt.f64.toAbi(sub_f64(compiler_rt.f64.fromAbi(a), compiler_rt.f64.fromAbi(b))); | ||
| 112 | } | ||
| 113 | fn __aeabi_dsub(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 { | ||
| 114 | return sub_f64(a, b); | ||
| 115 | } | ||
| 116 | pub fn sub_f64(a: f64, b: f64) f64 { | ||
| 117 | return add_f64(a, compiler_rt.fneg(b)); | ||
| 118 | } | ||
| 119 | |||
| 120 | fn __subxf3(a: compiler_rt.f80.Abi, b: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { | ||
| 121 | return compiler_rt.f80.toAbi(sub_f80(compiler_rt.f80.fromAbi(a), compiler_rt.f80.fromAbi(b))); | ||
| 122 | } | ||
| 123 | pub fn sub_f80(a: f80, b: f80) f80 { | ||
| 124 | return add_f80(a, compiler_rt.fneg(b)); | ||
| 125 | } | ||
| 126 | |||
| 127 | fn __subtf3(a: compiler_rt.f128.Abi, b: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { | ||
| 128 | return compiler_rt.f128.toAbi(sub_f128(compiler_rt.f128.fromAbi(a), compiler_rt.f128.fromAbi(b))); | ||
| 129 | } | ||
| 130 | fn _Qp_sub(c: *f128, a: *const f128, b: *const f128) callconv(.c) void { | ||
| 131 | c.* = sub_f128(a.*, b.*); | ||
| 132 | } | ||
| 133 | pub fn sub_f128(a: f128, b: f128) f128 { | ||
| 134 | return add_f128(a, compiler_rt.fneg(b)); | ||
| 135 | } | ||
| 136 | |||
| 6 | /// Ported from: | 137 | /// Ported from: |
| 7 | /// | 138 | /// |
| 8 | /// https://github.com/llvm/llvm-project/blob/02d85149a05cb1f6dc49f0ba7a2ceca53718ae17/compiler-rt/lib/builtins/fp_add_impl.inc | 139 | /// https://github.com/llvm/llvm-project/blob/02d85149a05cb1f6dc49f0ba7a2ceca53718ae17/compiler-rt/lib/builtins/fp_add_impl.inc |
| 9 | pub inline fn addf3(comptime T: type, a: T, b: T) T { | 140 | inline fn addf3(comptime T: type, a: T, b: T) T { |
| 10 | const bits = @typeInfo(T).float.bits; | 141 | const bits = @typeInfo(T).float.bits; |
| 11 | const Z = @Int(.unsigned, bits); | 142 | const Z = @Int(.unsigned, bits); |
| 12 | 143 |
lib/compiler_rt/addf3_test.zig+7-6| ... | @@ -8,12 +8,13 @@ const builtin = @import("builtin"); | ... | @@ -8,12 +8,13 @@ const builtin = @import("builtin"); |
| 8 | const math = std.math; | 8 | const math = std.math; |
| 9 | const qnan128: f128 = @bitCast(@as(u128, 0x7fff800000000000) << 64); | 9 | const qnan128: f128 = @bitCast(@as(u128, 0x7fff800000000000) << 64); |
| 10 | 10 | ||
| 11 | const __addtf3 = @import("addtf3.zig").__addtf3; | 11 | const impl = @import("addf3.zig"); |
| 12 | const __addxf3 = @import("addxf3.zig").__addxf3; | 12 | const add_f128 = impl.add_f128; |
| 13 | const __subtf3 = @import("subtf3.zig").__subtf3; | 13 | const add_f80 = impl.add_f80; |
| 14 | const sub_f128 = impl.sub_f128; | ||
| 14 | 15 | ||
| 15 | fn test__addtf3(a: f128, b: f128, expected_hi: u64, expected_lo: u64) !void { | 16 | fn test__addtf3(a: f128, b: f128, expected_hi: u64, expected_lo: u64) !void { |
| 16 | const x = __addtf3(a, b); | 17 | const x = add_f128(a, b); |
| 17 | 18 | ||
| 18 | const rep: u128 = @bitCast(x); | 19 | const rep: u128 = @bitCast(x); |
| 19 | const hi: u64 = @intCast(rep >> 64); | 20 | const hi: u64 = @intCast(rep >> 64); |
| ... | @@ -52,7 +53,7 @@ test "addtf3" { | ... | @@ -52,7 +53,7 @@ test "addtf3" { |
| 52 | } | 53 | } |
| 53 | 54 | ||
| 54 | fn test__subtf3(a: f128, b: f128, expected_hi: u64, expected_lo: u64) !void { | 55 | fn test__subtf3(a: f128, b: f128, expected_hi: u64, expected_lo: u64) !void { |
| 55 | const x = __subtf3(a, b); | 56 | const x = sub_f128(a, b); |
| 56 | 57 | ||
| 57 | const rep: u128 = @bitCast(x); | 58 | const rep: u128 = @bitCast(x); |
| 58 | const hi: u64 = @intCast(rep >> 64); | 59 | const hi: u64 = @intCast(rep >> 64); |
| ... | @@ -91,7 +92,7 @@ test "subtf3" { | ... | @@ -91,7 +92,7 @@ test "subtf3" { |
| 91 | const qnan80: f80 = @bitCast(@as(u80, @bitCast(math.nan(f80))) | (1 << (math.floatFractionalBits(f80) - 1))); | 92 | const qnan80: f80 = @bitCast(@as(u80, @bitCast(math.nan(f80))) | (1 << (math.floatFractionalBits(f80) - 1))); |
| 92 | 93 | ||
| 93 | fn test__addxf3(a: f80, b: f80, expected: u80) !void { | 94 | fn test__addxf3(a: f80, b: f80, expected: u80) !void { |
| 94 | const x = __addxf3(a, b); | 95 | const x = add_f80(a, b); |
| 95 | const rep: u80 = @bitCast(x); | 96 | const rep: u80 = @bitCast(x); |
| 96 | 97 | ||
| 97 | if (rep == expected) | 98 | if (rep == expected) |
lib/compiler_rt/addhf3.zig deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const addf3 = @import("./addf3.zig").addf3; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__addhf3, "__addhf3"); | ||
| 7 | } | ||
| 8 | |||
| 9 | fn __addhf3(a: f16, b: f16) callconv(.c) f16 { | ||
| 10 | return addf3(f16, a, b); | ||
| 11 | } | ||
lib/compiler_rt/addsf3.zig deleted-19| ... | @@ -1,19 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const addf3 = @import("./addf3.zig").addf3; | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_aeabi) { | ||
| 7 | symbol(&__aeabi_fadd, "__aeabi_fadd"); | ||
| 8 | } else { | ||
| 9 | symbol(&__addsf3, "__addsf3"); | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | fn __addsf3(a: f32, b: f32) callconv(.c) f32 { | ||
| 14 | return addf3(f32, a, b); | ||
| 15 | } | ||
| 16 | |||
| 17 | fn __aeabi_fadd(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 { | ||
| 18 | return addf3(f32, a, b); | ||
| 19 | } | ||
lib/compiler_rt/addtf3.zig deleted-22| ... | @@ -1,22 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const addf3 = @import("./addf3.zig").addf3; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_ppc_abi) { | ||
| 7 | symbol(&__addtf3, "__addkf3"); | ||
| 8 | } else if (compiler_rt.want_sparc64_abi) { | ||
| 9 | symbol(&_Qp_add, "_Qp_add"); | ||
| 10 | } else if (compiler_rt.want_sparc32_abi) { | ||
| 11 | symbol(&__addtf3, "_Q_add"); | ||
| 12 | } | ||
| 13 | symbol(&__addtf3, "__addtf3"); | ||
| 14 | } | ||
| 15 | |||
| 16 | pub fn __addtf3(a: f128, b: f128) callconv(.c) f128 { | ||
| 17 | return addf3(f128, a, b); | ||
| 18 | } | ||
| 19 | |||
| 20 | fn _Qp_add(c: *f128, a: *f128, b: *f128) callconv(.c) void { | ||
| 21 | c.* = addf3(f128, a.*, b.*); | ||
| 22 | } | ||
lib/compiler_rt/addvdi3.zig+3-2| ... | @@ -1,4 +1,5 @@ | ... | @@ -1,4 +1,5 @@ |
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | 1 | const compiler_rt = @import("../compiler_rt.zig"); |
| 2 | const symbol = compiler_rt.symbol; | ||
| 2 | const testing = @import("std").testing; | 3 | const testing = @import("std").testing; |
| 3 | 4 | ||
| 4 | comptime { | 5 | comptime { |
| ... | @@ -9,7 +10,7 @@ pub fn __addvdi3(a: i64, b: i64) callconv(.c) i64 { | ... | @@ -9,7 +10,7 @@ pub fn __addvdi3(a: i64, b: i64) callconv(.c) i64 { |
| 9 | const sum = a +% b; | 10 | const sum = a +% b; |
| 10 | // Overflow occurred iff both operands have the same sign, and the sign of the sum does | 11 | // Overflow occurred iff both operands have the same sign, and the sign of the sum does |
| 11 | // not match it. In other words, iff the sum sign is not the sign of either operand. | 12 | // not match it. In other words, iff the sum sign is not the sign of either operand. |
| 12 | if (((sum ^ a) & (sum ^ b)) < 0) @panic("compiler-rt: integer overflow"); | 13 | if (((sum ^ a) & (sum ^ b)) < 0) @panic("integer overflow"); |
| 13 | return sum; | 14 | return sum; |
| 14 | } | 15 | } |
| 15 | 16 |
lib/compiler_rt/addvsi3.zig+1-1| ... | @@ -10,7 +10,7 @@ pub fn __addvsi3(a: i32, b: i32) callconv(.c) i32 { | ... | @@ -10,7 +10,7 @@ pub fn __addvsi3(a: i32, b: i32) callconv(.c) i32 { |
| 10 | const sum = a +% b; | 10 | const sum = a +% b; |
| 11 | // Overflow occurred iff both operands have the same sign, and the sign of the sum does | 11 | // Overflow occurred iff both operands have the same sign, and the sign of the sum does |
| 12 | // not match it. In other words, iff the sum sign is not the sign of either operand. | 12 | // not match it. In other words, iff the sum sign is not the sign of either operand. |
| 13 | if (((sum ^ a) & (sum ^ b)) < 0) @panic("compiler-rt: integer overflow"); | 13 | if (((sum ^ a) & (sum ^ b)) < 0) @panic("integer overflow"); |
| 14 | return sum; | 14 | return sum; |
| 15 | } | 15 | } |
| 16 | 16 |
lib/compiler_rt/addxf3.zig deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const addf3 = @import("./addf3.zig").addf3; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__addxf3, "__addxf3"); | ||
| 7 | } | ||
| 8 | |||
| 9 | pub fn __addxf3(a: f80, b: f80) callconv(.c) f80 { | ||
| 10 | return addf3(f80, a, b); | ||
| 11 | } | ||
lib/compiler_rt/atomics.zig+1-1| ... | @@ -5,7 +5,7 @@ const arch = cpu.arch; | ... | @@ -5,7 +5,7 @@ const arch = cpu.arch; |
| 5 | const std = @import("std"); | 5 | const std = @import("std"); |
| 6 | 6 | ||
| 7 | const compiler_rt = @import("../compiler_rt.zig"); | 7 | const compiler_rt = @import("../compiler_rt.zig"); |
| 8 | const symbol = @import("../compiler_rt.zig").symbol; | 8 | const symbol = compiler_rt.symbol; |
| 9 | 9 | ||
| 10 | // This parameter is true iff the target architecture supports the bare minimum | 10 | // This parameter is true iff the target architecture supports the bare minimum |
| 11 | // to implement the atomic load/store intrinsics. | 11 | // to implement the atomic load/store intrinsics. |
lib/compiler_rt/aulldiv.zig+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | const builtin = @import("builtin"); | 1 | const builtin = @import("builtin"); |
| 2 | 2 | ||
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | 3 | const compiler_rt = @import("../compiler_rt.zig"); |
| 4 | const symbol = @import("../compiler_rt.zig").symbol; | 4 | const symbol = compiler_rt.symbol; |
| 5 | 5 | ||
| 6 | comptime { | 6 | comptime { |
| 7 | if (compiler_rt.want_windows_x86_msvc_abi) { | 7 | if (compiler_rt.want_windows_x86_msvc_abi) { |
lib/compiler_rt/cmpdf2.zig deleted-67| ... | @@ -1,67 +0,0 @@ | ||
| 1 | ///! The quoted behavior definitions are from | ||
| 2 | ///! https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gccint/Soft-float-library-routines.html#Soft-float-library-routines | ||
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 4 | const comparef = @import("./comparef.zig"); | ||
| 5 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 6 | |||
| 7 | comptime { | ||
| 8 | if (compiler_rt.want_aeabi) { | ||
| 9 | symbol(&__aeabi_dcmpeq, "__aeabi_dcmpeq"); | ||
| 10 | symbol(&__aeabi_dcmplt, "__aeabi_dcmplt"); | ||
| 11 | symbol(&__aeabi_dcmple, "__aeabi_dcmple"); | ||
| 12 | } else { | ||
| 13 | symbol(&__eqdf2, "__eqdf2"); | ||
| 14 | symbol(&__nedf2, "__nedf2"); | ||
| 15 | symbol(&__ledf2, "__ledf2"); | ||
| 16 | symbol(&__cmpdf2, "__cmpdf2"); | ||
| 17 | symbol(&__ltdf2, "__ltdf2"); | ||
| 18 | } | ||
| 19 | } | ||
| 20 | |||
| 21 | /// "These functions calculate a <=> b. That is, if a is less than b, they return -1; | ||
| 22 | /// if a is greater than b, they return 1; and if a and b are equal they return 0. | ||
| 23 | /// If either argument is NaN they return 1..." | ||
| 24 | /// | ||
| 25 | /// Note that this matches the definition of `__ledf2`, `__eqdf2`, `__nedf2`, `__cmpdf2`, | ||
| 26 | /// and `__ltdf2`. | ||
| 27 | fn __cmpdf2(a: f64, b: f64) callconv(.c) i32 { | ||
| 28 | return @backingInt(comparef.cmpf2(f64, comparef.LE, a, b)); | ||
| 29 | } | ||
| 30 | |||
| 31 | /// "These functions return a value less than or equal to zero if neither argument is NaN, | ||
| 32 | /// and a is less than or equal to b." | ||
| 33 | pub fn __ledf2(a: f64, b: f64) callconv(.c) i32 { | ||
| 34 | return __cmpdf2(a, b); | ||
| 35 | } | ||
| 36 | |||
| 37 | /// "These functions return zero if neither argument is NaN, and a and b are equal." | ||
| 38 | /// Note that due to some kind of historical accident, __eqdf2 and __nedf2 are defined | ||
| 39 | /// to have the same return value. | ||
| 40 | pub fn __eqdf2(a: f64, b: f64) callconv(.c) i32 { | ||
| 41 | return __cmpdf2(a, b); | ||
| 42 | } | ||
| 43 | |||
| 44 | /// "These functions return a nonzero value if either argument is NaN, or if a and b are unequal." | ||
| 45 | /// Note that due to some kind of historical accident, __eqdf2 and __nedf2 are defined | ||
| 46 | /// to have the same return value. | ||
| 47 | pub fn __nedf2(a: f64, b: f64) callconv(.c) i32 { | ||
| 48 | return __cmpdf2(a, b); | ||
| 49 | } | ||
| 50 | |||
| 51 | /// "These functions return a value less than zero if neither argument is NaN, and a | ||
| 52 | /// is strictly less than b." | ||
| 53 | pub fn __ltdf2(a: f64, b: f64) callconv(.c) i32 { | ||
| 54 | return __cmpdf2(a, b); | ||
| 55 | } | ||
| 56 | |||
| 57 | fn __aeabi_dcmpeq(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { | ||
| 58 | return @intFromBool(comparef.cmpf2(f64, comparef.LE, a, b) == .Equal); | ||
| 59 | } | ||
| 60 | |||
| 61 | fn __aeabi_dcmplt(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { | ||
| 62 | return @intFromBool(comparef.cmpf2(f64, comparef.LE, a, b) == .Less); | ||
| 63 | } | ||
| 64 | |||
| 65 | fn __aeabi_dcmple(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { | ||
| 66 | return @intFromBool(comparef.cmpf2(f64, comparef.LE, a, b) != .Greater); | ||
| 67 | } | ||
lib/compiler_rt/cmptf2.zig deleted-146| ... | @@ -1,146 +0,0 @@ | ||
| 1 | ///! The quoted behavior definitions are from | ||
| 2 | ///! https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gccint/Soft-float-library-routines.html#Soft-float-library-routines | ||
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 4 | const comparef = @import("./comparef.zig"); | ||
| 5 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 6 | |||
| 7 | comptime { | ||
| 8 | if (compiler_rt.want_ppc_abi) { | ||
| 9 | symbol(&__eqtf2, "__eqkf2"); | ||
| 10 | symbol(&__netf2, "__nekf2"); | ||
| 11 | symbol(&__lttf2, "__ltkf2"); | ||
| 12 | symbol(&__letf2, "__lekf2"); | ||
| 13 | } else if (compiler_rt.want_sparc64_abi) { | ||
| 14 | symbol(&_Qp_cmp, "_Qp_cmp"); | ||
| 15 | symbol(&_Qp_feq, "_Qp_feq"); | ||
| 16 | symbol(&_Qp_fne, "_Qp_fne"); | ||
| 17 | symbol(&_Qp_flt, "_Qp_flt"); | ||
| 18 | symbol(&_Qp_fle, "_Qp_fle"); | ||
| 19 | symbol(&_Qp_fgt, "_Qp_fgt"); | ||
| 20 | symbol(&_Qp_fge, "_Qp_fge"); | ||
| 21 | } else if (compiler_rt.want_sparc32_abi) { | ||
| 22 | symbol(&_Q_cmp, "_Q_cmp"); | ||
| 23 | symbol(&_Q_feq, "_Q_feq"); | ||
| 24 | symbol(&_Q_fne, "_Q_fne"); | ||
| 25 | symbol(&_Q_flt, "_Q_flt"); | ||
| 26 | symbol(&_Q_fle, "_Q_fle"); | ||
| 27 | symbol(&_Q_fgt, "_Q_fgt"); | ||
| 28 | symbol(&_Q_fge, "_Q_fge"); | ||
| 29 | } | ||
| 30 | symbol(&__eqtf2, "__eqtf2"); | ||
| 31 | symbol(&__netf2, "__netf2"); | ||
| 32 | symbol(&__letf2, "__letf2"); | ||
| 33 | symbol(&__cmptf2, "__cmptf2"); | ||
| 34 | symbol(&__lttf2, "__lttf2"); | ||
| 35 | } | ||
| 36 | |||
| 37 | /// "These functions calculate a <=> b. That is, if a is less than b, they return -1; | ||
| 38 | /// if a is greater than b, they return 1; and if a and b are equal they return 0. | ||
| 39 | /// If either argument is NaN they return 1..." | ||
| 40 | /// | ||
| 41 | /// Note that this matches the definition of `__letf2`, `__eqtf2`, `__netf2`, `__cmptf2`, | ||
| 42 | /// and `__lttf2`. | ||
| 43 | fn __cmptf2(a: f128, b: f128) callconv(.c) i32 { | ||
| 44 | return @backingInt(comparef.cmpf2(f128, comparef.LE, a, b)); | ||
| 45 | } | ||
| 46 | |||
| 47 | /// "These functions return a value less than or equal to zero if neither argument is NaN, | ||
| 48 | /// and a is less than or equal to b." | ||
| 49 | fn __letf2(a: f128, b: f128) callconv(.c) i32 { | ||
| 50 | return __cmptf2(a, b); | ||
| 51 | } | ||
| 52 | |||
| 53 | /// "These functions return zero if neither argument is NaN, and a and b are equal." | ||
| 54 | /// Note that due to some kind of historical accident, __eqtf2 and __netf2 are defined | ||
| 55 | /// to have the same return value. | ||
| 56 | fn __eqtf2(a: f128, b: f128) callconv(.c) i32 { | ||
| 57 | return __cmptf2(a, b); | ||
| 58 | } | ||
| 59 | |||
| 60 | /// "These functions return a nonzero value if either argument is NaN, or if a and b are unequal." | ||
| 61 | /// Note that due to some kind of historical accident, __eqtf2 and __netf2 are defined | ||
| 62 | /// to have the same return value. | ||
| 63 | fn __netf2(a: f128, b: f128) callconv(.c) i32 { | ||
| 64 | return __cmptf2(a, b); | ||
| 65 | } | ||
| 66 | |||
| 67 | /// "These functions return a value less than zero if neither argument is NaN, and a | ||
| 68 | /// is strictly less than b." | ||
| 69 | fn __lttf2(a: f128, b: f128) callconv(.c) i32 { | ||
| 70 | return __cmptf2(a, b); | ||
| 71 | } | ||
| 72 | |||
| 73 | const SparcFCMP = enum(i32) { | ||
| 74 | Equal = 0, | ||
| 75 | Less = 1, | ||
| 76 | Greater = 2, | ||
| 77 | Unordered = 3, | ||
| 78 | }; | ||
| 79 | |||
| 80 | fn _Qp_cmp(a: *const f128, b: *const f128) callconv(.c) i32 { | ||
| 81 | return @backingInt(comparef.cmpf2(f128, SparcFCMP, a.*, b.*)); | ||
| 82 | } | ||
| 83 | |||
| 84 | fn _Qp_feq(a: *const f128, b: *const f128) callconv(.c) bool { | ||
| 85 | return @as(SparcFCMP, @fromBackingInt(@intCast(_Qp_cmp(a, b)))) == .Equal; | ||
| 86 | } | ||
| 87 | |||
| 88 | fn _Qp_fne(a: *const f128, b: *const f128) callconv(.c) bool { | ||
| 89 | return @as(SparcFCMP, @fromBackingInt(@intCast(_Qp_cmp(a, b)))) != .Equal; | ||
| 90 | } | ||
| 91 | |||
| 92 | fn _Qp_flt(a: *const f128, b: *const f128) callconv(.c) bool { | ||
| 93 | return @as(SparcFCMP, @fromBackingInt(@intCast(_Qp_cmp(a, b)))) == .Less; | ||
| 94 | } | ||
| 95 | |||
| 96 | fn _Qp_fgt(a: *const f128, b: *const f128) callconv(.c) bool { | ||
| 97 | return @as(SparcFCMP, @fromBackingInt(@intCast(_Qp_cmp(a, b)))) == .Greater; | ||
| 98 | } | ||
| 99 | |||
| 100 | fn _Qp_fge(a: *const f128, b: *const f128) callconv(.c) bool { | ||
| 101 | return switch (@as(SparcFCMP, @fromBackingInt(@intCast(_Qp_cmp(a, b))))) { | ||
| 102 | .Equal, .Greater => true, | ||
| 103 | .Less, .Unordered => false, | ||
| 104 | }; | ||
| 105 | } | ||
| 106 | |||
| 107 | fn _Qp_fle(a: *const f128, b: *const f128) callconv(.c) bool { | ||
| 108 | return switch (@as(SparcFCMP, @fromBackingInt(@intCast(_Qp_cmp(a, b))))) { | ||
| 109 | .Equal, .Less => true, | ||
| 110 | .Greater, .Unordered => false, | ||
| 111 | }; | ||
| 112 | } | ||
| 113 | |||
| 114 | fn _Q_cmp(a: f128, b: f128) callconv(.c) i32 { | ||
| 115 | return @backingInt(comparef.cmpf2(f128, SparcFCMP, a, b)); | ||
| 116 | } | ||
| 117 | |||
| 118 | fn _Q_feq(a: f128, b: f128) callconv(.c) bool { | ||
| 119 | return @as(SparcFCMP, @fromBackingInt(@intCast(_Q_cmp(a, b)))) == .Equal; | ||
| 120 | } | ||
| 121 | |||
| 122 | fn _Q_fne(a: f128, b: f128) callconv(.c) bool { | ||
| 123 | return @as(SparcFCMP, @fromBackingInt(@intCast(_Q_cmp(a, b)))) != .Equal; | ||
| 124 | } | ||
| 125 | |||
| 126 | fn _Q_flt(a: f128, b: f128) callconv(.c) bool { | ||
| 127 | return @as(SparcFCMP, @fromBackingInt(@intCast(_Q_cmp(a, b)))) == .Less; | ||
| 128 | } | ||
| 129 | |||
| 130 | fn _Q_fgt(a: f128, b: f128) callconv(.c) bool { | ||
| 131 | return @as(SparcFCMP, @fromBackingInt(@intCast(_Q_cmp(a, b)))) == .Greater; | ||
| 132 | } | ||
| 133 | |||
| 134 | fn _Q_fge(a: f128, b: f128) callconv(.c) bool { | ||
| 135 | return switch (@as(SparcFCMP, @fromBackingInt(@intCast(_Q_cmp(a, b))))) { | ||
| 136 | .Equal, .Greater => true, | ||
| 137 | .Less, .Unordered => false, | ||
| 138 | }; | ||
| 139 | } | ||
| 140 | |||
| 141 | fn _Q_fle(a: f128, b: f128) callconv(.c) bool { | ||
| 142 | return switch (@as(SparcFCMP, @fromBackingInt(@intCast(_Q_cmp(a, b))))) { | ||
| 143 | .Equal, .Less => true, | ||
| 144 | .Greater, .Unordered => false, | ||
| 145 | }; | ||
| 146 | } | ||
lib/compiler_rt/cmpxf2.zig deleted-49| ... | @@ -1,49 +0,0 @@ | ||
| 1 | ///! The quoted behavior definitions are from | ||
| 2 | ///! https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gccint/Soft-float-library-routines.html#Soft-float-library-routines | ||
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 4 | const symbol = compiler_rt.symbol; | ||
| 5 | const comparef = @import("./comparef.zig"); | ||
| 6 | |||
| 7 | comptime { | ||
| 8 | symbol(&__eqxf2, "__eqxf2"); | ||
| 9 | symbol(&__nexf2, "__nexf2"); | ||
| 10 | symbol(&__lexf2, "__lexf2"); | ||
| 11 | symbol(&__cmpxf2, "__cmpxf2"); | ||
| 12 | symbol(&__ltxf2, "__ltxf2"); | ||
| 13 | } | ||
| 14 | |||
| 15 | /// "These functions calculate a <=> b. That is, if a is less than b, they return -1; | ||
| 16 | /// if a is greater than b, they return 1; and if a and b are equal they return 0. | ||
| 17 | /// If either argument is NaN they return 1..." | ||
| 18 | /// | ||
| 19 | /// Note that this matches the definition of `__lexf2`, `__eqxf2`, `__nexf2`, `__cmpxf2`, | ||
| 20 | /// and `__ltxf2`. | ||
| 21 | fn __cmpxf2(a: f80, b: f80) callconv(.c) i32 { | ||
| 22 | return @backingInt(comparef.cmp_f80(comparef.LE, a, b)); | ||
| 23 | } | ||
| 24 | |||
| 25 | /// "These functions return a value less than or equal to zero if neither argument is NaN, | ||
| 26 | /// and a is less than or equal to b." | ||
| 27 | fn __lexf2(a: f80, b: f80) callconv(.c) i32 { | ||
| 28 | return __cmpxf2(a, b); | ||
| 29 | } | ||
| 30 | |||
| 31 | /// "These functions return zero if neither argument is NaN, and a and b are equal." | ||
| 32 | /// Note that due to some kind of historical accident, __eqxf2 and __nexf2 are defined | ||
| 33 | /// to have the same return value. | ||
| 34 | fn __eqxf2(a: f80, b: f80) callconv(.c) i32 { | ||
| 35 | return __cmpxf2(a, b); | ||
| 36 | } | ||
| 37 | |||
| 38 | /// "These functions return a nonzero value if either argument is NaN, or if a and b are unequal." | ||
| 39 | /// Note that due to some kind of historical accident, __eqxf2 and __nexf2 are defined | ||
| 40 | /// to have the same return value. | ||
| 41 | fn __nexf2(a: f80, b: f80) callconv(.c) i32 { | ||
| 42 | return __cmpxf2(a, b); | ||
| 43 | } | ||
| 44 | |||
| 45 | /// "These functions return a value less than zero if neither argument is NaN, and a | ||
| 46 | /// is strictly less than b." | ||
| 47 | fn __ltxf2(a: f80, b: f80) callconv(.c) i32 { | ||
| 48 | return __cmpxf2(a, b); | ||
| 49 | } | ||
lib/compiler_rt/comparedf2_test.zig+17-73| ... | @@ -5,52 +5,12 @@ | ... | @@ -5,52 +5,12 @@ |
| 5 | const std = @import("std"); | 5 | const std = @import("std"); |
| 6 | const builtin = @import("builtin"); | 6 | const builtin = @import("builtin"); |
| 7 | 7 | ||
| 8 | const __eqdf2 = @import("./cmpdf2.zig").__eqdf2; | 8 | const compiler_rt = @import("../compiler_rt.zig"); |
| 9 | const __ledf2 = @import("./cmpdf2.zig").__ledf2; | ||
| 10 | const __ltdf2 = @import("./cmpdf2.zig").__ltdf2; | ||
| 11 | const __nedf2 = @import("./cmpdf2.zig").__nedf2; | ||
| 12 | 9 | ||
| 13 | const __gedf2 = @import("./gedf2.zig").__gedf2; | 10 | const impl = @import("comparef.zig"); |
| 14 | const __gtdf2 = @import("./gedf2.zig").__gtdf2; | 11 | const Order = impl.Order; |
| 15 | 12 | const cmp_f64 = impl.cmp_f64; | |
| 16 | const __unorddf2 = @import("./unorddf2.zig").__unorddf2; | 13 | const unord_f64 = impl.unord_f64; |
| 17 | |||
| 18 | const TestVector = struct { | ||
| 19 | a: f64, | ||
| 20 | b: f64, | ||
| 21 | eqReference: c_int, | ||
| 22 | geReference: c_int, | ||
| 23 | gtReference: c_int, | ||
| 24 | leReference: c_int, | ||
| 25 | ltReference: c_int, | ||
| 26 | neReference: c_int, | ||
| 27 | unReference: c_int, | ||
| 28 | }; | ||
| 29 | |||
| 30 | fn test__cmpdf2(vector: TestVector) bool { | ||
| 31 | if (__eqdf2(vector.a, vector.b) != vector.eqReference) { | ||
| 32 | return false; | ||
| 33 | } | ||
| 34 | if (__gedf2(vector.a, vector.b) != vector.geReference) { | ||
| 35 | return false; | ||
| 36 | } | ||
| 37 | if (__gtdf2(vector.a, vector.b) != vector.gtReference) { | ||
| 38 | return false; | ||
| 39 | } | ||
| 40 | if (__ledf2(vector.a, vector.b) != vector.leReference) { | ||
| 41 | return false; | ||
| 42 | } | ||
| 43 | if (__ltdf2(vector.a, vector.b) != vector.ltReference) { | ||
| 44 | return false; | ||
| 45 | } | ||
| 46 | if (__nedf2(vector.a, vector.b) != vector.neReference) { | ||
| 47 | return false; | ||
| 48 | } | ||
| 49 | if (__unorddf2(vector.a, vector.b) != vector.unReference) { | ||
| 50 | return false; | ||
| 51 | } | ||
| 52 | return true; | ||
| 53 | } | ||
| 54 | 14 | ||
| 55 | const arguments = [_]f64{ | 15 | const arguments = [_]f64{ |
| 56 | std.math.nan(f64), | 16 | std.math.nan(f64), |
| ... | @@ -73,36 +33,20 @@ const arguments = [_]f64{ | ... | @@ -73,36 +33,20 @@ const arguments = [_]f64{ |
| 73 | std.math.inf(f64), | 33 | std.math.inf(f64), |
| 74 | }; | 34 | }; |
| 75 | 35 | ||
| 76 | fn generateVector(comptime a: f64, comptime b: f64) TestVector { | 36 | test "compare f64" { |
| 77 | const leResult = if (a < b) -1 else if (a == b) 0 else 1; | ||
| 78 | const geResult = if (a > b) 1 else if (a == b) 0 else -1; | ||
| 79 | const unResult = if (a != a or b != b) 1 else 0; | ||
| 80 | return TestVector{ | ||
| 81 | .a = a, | ||
| 82 | .b = b, | ||
| 83 | .eqReference = leResult, | ||
| 84 | .geReference = geResult, | ||
| 85 | .gtReference = geResult, | ||
| 86 | .leReference = leResult, | ||
| 87 | .ltReference = leResult, | ||
| 88 | .neReference = leResult, | ||
| 89 | .unReference = unResult, | ||
| 90 | }; | ||
| 91 | } | ||
| 92 | |||
| 93 | const test_vectors = init: { | ||
| 94 | @setEvalBranchQuota(10000); | ||
| 95 | var vectors: [arguments.len * arguments.len]TestVector = undefined; | ||
| 96 | for (arguments[0..], 0..) |arg_i, i| { | 37 | for (arguments[0..], 0..) |arg_i, i| { |
| 97 | for (arguments[0..], 0..) |arg_j, j| { | 38 | for (arguments[0..], 0..) |arg_j, j| { |
| 98 | vectors[(i * arguments.len) + j] = generateVector(arg_i, arg_j); | 39 | const expected_unord = i == 0 or j == 0; |
| 40 | const expected_order: ?Order = if (expected_unord) null else switch (std.math.order( | ||
| 41 | if (i >= 9) i - 1 else i, | ||
| 42 | if (j >= 9) j - 1 else j, | ||
| 43 | )) { | ||
| 44 | .lt => .lt, | ||
| 45 | .eq => .eq, | ||
| 46 | .gt => .gt, | ||
| 47 | }; | ||
| 48 | try std.testing.expect(expected_order == cmp_f64(arg_i, arg_j)); | ||
| 49 | try std.testing.expect(expected_unord == unord_f64(arg_i, arg_j)); | ||
| 99 | } | 50 | } |
| 100 | } | 51 | } |
| 101 | break :init vectors; | ||
| 102 | }; | ||
| 103 | |||
| 104 | test "compare f64" { | ||
| 105 | for (test_vectors) |vector| { | ||
| 106 | try std.testing.expect(test__cmpdf2(vector)); | ||
| 107 | } | ||
| 108 | } | 52 | } |
lib/compiler_rt/comparef.zig+274-167| ... | @@ -1,163 +1,309 @@ | ... | @@ -1,163 +1,309 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 1 | const std = @import("std"); | 2 | const std = @import("std"); |
| 2 | 3 | ||
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | 4 | const compiler_rt = @import("../compiler_rt.zig"); |
| 4 | const symbol = compiler_rt.symbol; | 5 | const symbol = compiler_rt.symbol; |
| 5 | 6 | ||
| 6 | comptime { | 7 | const Unordered = if (builtin.cpu.arch == .avr) |
| 7 | if (compiler_rt.want_aeabi) { | 8 | i8 |
| 8 | symbol(&__aeabi_fcmpun, "__aeabi_fcmpun"); | 9 | else if (builtin.cpu.arch.isAARCH64()) |
| 9 | } else { | 10 | i32 |
| 10 | symbol(&__unordsf2, "__unordsf2"); | 11 | else if (builtin.target.cTypeBitSize(.long).? >= builtin.target.ptrBitWidth()) |
| 11 | } | 12 | c_long |
| 12 | 13 | else | |
| 13 | symbol(&__unordxf2, "__unordxf2"); | 14 | c_longlong; |
| 15 | pub const Order = enum(Unordered) { lt = -1, eq = 0, gt = 1 }; | ||
| 16 | const SparcOrder = enum(i32) { eq = 0, lt = 1, gt = 2, un = 3 }; | ||
| 14 | 17 | ||
| 15 | symbol(&__eqhf2, "__eqhf2"); | 18 | comptime { |
| 16 | symbol(&__nehf2, "__nehf2"); | ||
| 17 | symbol(&__lehf2, "__lehf2"); | ||
| 18 | symbol(&__cmphf2, "__cmphf2"); | 19 | symbol(&__cmphf2, "__cmphf2"); |
| 19 | symbol(&__lthf2, "__lthf2"); | 20 | symbol(&__cmphf2, "__eqhf2"); |
| 21 | symbol(&__cmphf2, "__nehf2"); | ||
| 22 | symbol(&__cmphf2, "__lthf2"); | ||
| 23 | symbol(&__cmphf2, "__lehf2"); | ||
| 24 | symbol(&__gehf2, "__gthf2"); | ||
| 25 | symbol(&__gehf2, "__gehf2"); | ||
| 26 | symbol(&__unordhf2, "__unordhf2"); | ||
| 20 | 27 | ||
| 21 | if (compiler_rt.want_aeabi) { | 28 | if (compiler_rt.want_aeabi) { |
| 22 | symbol(&__aeabi_fcmpeq, "__aeabi_fcmpeq"); | 29 | symbol(&__aeabi_fcmpeq, "__aeabi_fcmpeq"); |
| 23 | symbol(&__aeabi_fcmplt, "__aeabi_fcmplt"); | 30 | symbol(&__aeabi_fcmplt, "__aeabi_fcmplt"); |
| 24 | symbol(&__aeabi_fcmple, "__aeabi_fcmple"); | 31 | symbol(&__aeabi_fcmple, "__aeabi_fcmple"); |
| 32 | symbol(&__aeabi_fcmpgt, "__aeabi_fcmpgt"); | ||
| 33 | symbol(&__aeabi_fcmpge, "__aeabi_fcmpge"); | ||
| 34 | symbol(&__aeabi_fcmpun, "__aeabi_fcmpun"); | ||
| 35 | |||
| 36 | symbol(&__aeabi_dcmpeq, "__aeabi_dcmpeq"); | ||
| 37 | symbol(&__aeabi_dcmplt, "__aeabi_dcmplt"); | ||
| 38 | symbol(&__aeabi_dcmple, "__aeabi_dcmple"); | ||
| 39 | symbol(&__aeabi_dcmpgt, "__aeabi_dcmpgt"); | ||
| 40 | symbol(&__aeabi_dcmpge, "__aeabi_dcmpge"); | ||
| 41 | symbol(&__aeabi_dcmpun, "__aeabi_dcmpun"); | ||
| 25 | } else { | 42 | } else { |
| 26 | symbol(&__eqsf2, "__eqsf2"); | ||
| 27 | symbol(&__nesf2, "__nesf2"); | ||
| 28 | symbol(&__lesf2, "__lesf2"); | ||
| 29 | symbol(&__cmpsf2, "__cmpsf2"); | 43 | symbol(&__cmpsf2, "__cmpsf2"); |
| 30 | symbol(&__ltsf2, "__ltsf2"); | 44 | symbol(&__cmpsf2, "__eqsf2"); |
| 45 | symbol(&__cmpsf2, "__nesf2"); | ||
| 46 | symbol(&__cmpsf2, "__ltsf2"); | ||
| 47 | symbol(&__cmpsf2, "__lesf2"); | ||
| 48 | symbol(&__gesf2, "__gtsf2"); | ||
| 49 | symbol(&__gesf2, "__gesf2"); | ||
| 50 | symbol(&__unordsf2, "__unordsf2"); | ||
| 51 | |||
| 52 | symbol(&__cmpdf2, "__cmpdf2"); | ||
| 53 | symbol(&__cmpdf2, "__eqdf2"); | ||
| 54 | symbol(&__cmpdf2, "__nedf2"); | ||
| 55 | symbol(&__cmpdf2, "__ltdf2"); | ||
| 56 | symbol(&__cmpdf2, "__ledf2"); | ||
| 57 | symbol(&__gedf2, "__gtdf2"); | ||
| 58 | symbol(&__gedf2, "__gedf2"); | ||
| 59 | symbol(&__unorddf2, "__unorddf2"); | ||
| 31 | } | 60 | } |
| 32 | 61 | ||
| 62 | symbol(&__cmpxf2, "__cmpxf2"); | ||
| 63 | symbol(&__cmpxf2, "__eqxf2"); | ||
| 64 | symbol(&__cmpxf2, "__nexf2"); | ||
| 65 | symbol(&__cmpxf2, "__ltxf2"); | ||
| 66 | symbol(&__cmpxf2, "__lexf2"); | ||
| 67 | symbol(&__gexf2, "__gtxf2"); | ||
| 68 | symbol(&__gexf2, "__gexf2"); | ||
| 69 | symbol(&__unordxf2, "__unordxf2"); | ||
| 70 | |||
| 33 | if (compiler_rt.want_ppc_abi) { | 71 | if (compiler_rt.want_ppc_abi) { |
| 72 | symbol(&__cmptf2, "__eqkf2"); | ||
| 73 | symbol(&__cmptf2, "__nekf2"); | ||
| 74 | symbol(&__cmptf2, "__ltkf2"); | ||
| 75 | symbol(&__cmptf2, "__lekf2"); | ||
| 76 | symbol(&__getf2, "__gtkf2"); | ||
| 77 | symbol(&__getf2, "__gekf2"); | ||
| 34 | symbol(&__unordtf2, "__unordkf2"); | 78 | symbol(&__unordtf2, "__unordkf2"); |
| 79 | } else if (compiler_rt.want_sparc64_abi) { | ||
| 80 | symbol(&_Qp_cmp, "_Qp_cmp"); | ||
| 81 | symbol(&_Qp_feq, "_Qp_feq"); | ||
| 82 | symbol(&_Qp_fne, "_Qp_fne"); | ||
| 83 | symbol(&_Qp_flt, "_Qp_flt"); | ||
| 84 | symbol(&_Qp_fle, "_Qp_fle"); | ||
| 85 | symbol(&_Qp_fgt, "_Qp_fgt"); | ||
| 86 | symbol(&_Qp_fge, "_Qp_fge"); | ||
| 87 | } else if (compiler_rt.want_sparc32_abi) { | ||
| 88 | symbol(&_Q_cmp, "_Q_cmp"); | ||
| 89 | symbol(&_Q_feq, "_Q_feq"); | ||
| 90 | symbol(&_Q_fne, "_Q_fne"); | ||
| 91 | symbol(&_Q_flt, "_Q_flt"); | ||
| 92 | symbol(&_Q_fle, "_Q_fle"); | ||
| 93 | symbol(&_Q_fgt, "_Q_fgt"); | ||
| 94 | symbol(&_Q_fge, "_Q_fge"); | ||
| 95 | } else { | ||
| 96 | symbol(&__cmptf2, "__cmptf2"); | ||
| 97 | symbol(&__cmptf2, "__eqtf2"); | ||
| 98 | symbol(&__cmptf2, "__netf2"); | ||
| 99 | symbol(&__cmptf2, "__lttf2"); | ||
| 100 | symbol(&__cmptf2, "__letf2"); | ||
| 101 | symbol(&__getf2, "__gttf2"); | ||
| 102 | symbol(&__getf2, "__getf2"); | ||
| 103 | symbol(&__unordtf2, "__unordtf2"); | ||
| 35 | } | 104 | } |
| 36 | symbol(&__unordtf2, "__unordtf2"); | ||
| 37 | symbol(&__unordhf2, "__unordhf2"); | ||
| 38 | } | ||
| 39 | |||
| 40 | pub fn __unordhf2(a: f16, b: f16) callconv(.c) i32 { | ||
| 41 | return unordcmp(f16, a, b); | ||
| 42 | } | 105 | } |
| 43 | 106 | ||
| 44 | pub fn __unordtf2(a: f128, b: f128) callconv(.c) i32 { | 107 | fn __cmphf2(a: compiler_rt.f16.Abi, b: compiler_rt.f16.Abi) callconv(.c) Order { |
| 45 | return unordcmp(f128, a, b); | 108 | return cmp_f16(compiler_rt.f16.fromAbi(a), compiler_rt.f16.fromAbi(b)) orelse .gt; |
| 46 | } | 109 | } |
| 47 | 110 | fn __gehf2(a: compiler_rt.f16.Abi, b: compiler_rt.f16.Abi) callconv(.c) Order { | |
| 48 | /// "These functions calculate a <=> b. That is, if a is less than b, they return -1; | 111 | return cmp_f16(compiler_rt.f16.fromAbi(a), compiler_rt.f16.fromAbi(b)) orelse .lt; |
| 49 | /// if a is greater than b, they return 1; and if a and b are equal they return 0. | ||
| 50 | /// If either argument is NaN they return 1..." | ||
| 51 | /// | ||
| 52 | /// Note that this matches the definition of `__lesf2`, `__eqsf2`, `__nesf2`, `__cmpsf2`, | ||
| 53 | /// and `__ltsf2`. | ||
| 54 | fn __cmpsf2(a: f32, b: f32) callconv(.c) i32 { | ||
| 55 | return @backingInt(cmpf2(f32, LE, a, b)); | ||
| 56 | } | 112 | } |
| 57 | 113 | fn __unordhf2(a: compiler_rt.f16.Abi, b: compiler_rt.f16.Abi) callconv(.c) Unordered { | |
| 58 | /// "These functions return a value less than or equal to zero if neither argument is NaN, | 114 | return @intFromBool(unord_f16(compiler_rt.f16.fromAbi(a), compiler_rt.f16.fromAbi(b))); |
| 59 | /// and a is less than or equal to b." | ||
| 60 | pub fn __lesf2(a: f32, b: f32) callconv(.c) i32 { | ||
| 61 | return __cmpsf2(a, b); | ||
| 62 | } | 115 | } |
| 63 | 116 | pub fn cmp_f16(a: f16, b: f16) ?Order { | |
| 64 | /// "These functions return zero if neither argument is NaN, and a and b are equal." | 117 | return cmpf2(f16, a, b); |
| 65 | /// Note that due to some kind of historical accident, __eqsf2 and __nesf2 are defined | ||
| 66 | /// to have the same return value. | ||
| 67 | pub fn __eqsf2(a: f32, b: f32) callconv(.c) i32 { | ||
| 68 | return __cmpsf2(a, b); | ||
| 69 | } | 118 | } |
| 70 | 119 | pub fn unord_f16(a: f16, b: f16) bool { | |
| 71 | /// "These functions return a nonzero value if either argument is NaN, or if a and b are unequal." | 120 | return unord(f16, a, b); |
| 72 | /// Note that due to some kind of historical accident, __eqsf2 and __nesf2 are defined | ||
| 73 | /// to have the same return value. | ||
| 74 | pub fn __nesf2(a: f32, b: f32) callconv(.c) i32 { | ||
| 75 | return __cmpsf2(a, b); | ||
| 76 | } | 121 | } |
| 77 | 122 | ||
| 78 | /// "These functions return a value less than zero if neither argument is NaN, and a | 123 | fn __cmpsf2(a: compiler_rt.f32.Abi, b: compiler_rt.f32.Abi) callconv(.c) Order { |
| 79 | /// is strictly less than b." | 124 | return cmp_f32(compiler_rt.f32.fromAbi(a), compiler_rt.f32.fromAbi(b)) orelse .gt; |
| 80 | pub fn __ltsf2(a: f32, b: f32) callconv(.c) i32 { | ||
| 81 | return __cmpsf2(a, b); | ||
| 82 | } | 125 | } |
| 83 | |||
| 84 | fn __aeabi_fcmpeq(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 { | 126 | fn __aeabi_fcmpeq(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 { |
| 85 | return @intFromBool(cmpf2(f32, LE, a, b) == .Equal); | 127 | return @intFromBool(cmp_f32(a, b) == .eq); |
| 86 | } | 128 | } |
| 87 | |||
| 88 | fn __aeabi_fcmplt(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 { | 129 | fn __aeabi_fcmplt(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 { |
| 89 | return @intFromBool(cmpf2(f32, LE, a, b) == .Less); | 130 | return @intFromBool(cmp_f32(a, b) == .lt); |
| 90 | } | 131 | } |
| 91 | |||
| 92 | fn __aeabi_fcmple(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 { | 132 | fn __aeabi_fcmple(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 { |
| 93 | return @intFromBool(cmpf2(f32, LE, a, b) != .Greater); | 133 | return @intFromBool(cmp_f32(a, b) orelse .gt != .gt); |
| 94 | } | 134 | } |
| 95 | 135 | fn __gesf2(a: compiler_rt.f32.Abi, b: compiler_rt.f32.Abi) callconv(.c) Order { | |
| 96 | /// "These functions calculate a <=> b. That is, if a is less than b, they return -1; | 136 | return cmp_f32(compiler_rt.f32.fromAbi(a), compiler_rt.f32.fromAbi(b)) orelse .lt; |
| 97 | /// if a is greater than b, they return 1; and if a and b are equal they return 0. | ||
| 98 | /// If either argument is NaN they return 1..." | ||
| 99 | /// | ||
| 100 | /// Note that this matches the definition of `__lehf2`, `__eqhf2`, `__nehf2`, `__cmphf2`, | ||
| 101 | /// and `__lthf2`. | ||
| 102 | fn __cmphf2(a: f16, b: f16) callconv(.c) i32 { | ||
| 103 | return @backingInt(cmpf2(f16, LE, a, b)); | ||
| 104 | } | 137 | } |
| 105 | 138 | fn __aeabi_fcmpge(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 { | |
| 106 | /// "These functions return a value less than or equal to zero if neither argument is NaN, | 139 | return @intFromBool(cmp_f32(a, b) orelse .lt != .lt); |
| 107 | /// and a is less than or equal to b." | ||
| 108 | fn __lehf2(a: f16, b: f16) callconv(.c) i32 { | ||
| 109 | return __cmphf2(a, b); | ||
| 110 | } | 140 | } |
| 111 | 141 | fn __aeabi_fcmpgt(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 { | |
| 112 | /// "These functions return zero if neither argument is NaN, and a and b are equal." | 142 | return @intFromBool(cmp_f32(a, b) == .gt); |
| 113 | /// Note that due to some kind of historical accident, __eqhf2 and __nehf2 are defined | ||
| 114 | /// to have the same return value. | ||
| 115 | fn __eqhf2(a: f16, b: f16) callconv(.c) i32 { | ||
| 116 | return __cmphf2(a, b); | ||
| 117 | } | 143 | } |
| 118 | 144 | fn __unordsf2(a: compiler_rt.f32.Abi, b: compiler_rt.f32.Abi) callconv(.c) Unordered { | |
| 119 | /// "These functions return a nonzero value if either argument is NaN, or if a and b are unequal." | 145 | return @intFromBool(unord_f32(compiler_rt.f32.fromAbi(a), compiler_rt.f32.fromAbi(b))); |
| 120 | /// Note that due to some kind of historical accident, __eqhf2 and __nehf2 are defined | ||
| 121 | /// to have the same return value. | ||
| 122 | fn __nehf2(a: f16, b: f16) callconv(.c) i32 { | ||
| 123 | return __cmphf2(a, b); | ||
| 124 | } | 146 | } |
| 125 | 147 | fn __aeabi_fcmpun(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 { | |
| 126 | /// "These functions return a value less than zero if neither argument is NaN, and a | 148 | return @intFromBool(unord_f32(a, b)); |
| 127 | /// is strictly less than b." | ||
| 128 | fn __lthf2(a: f16, b: f16) callconv(.c) i32 { | ||
| 129 | return __cmphf2(a, b); | ||
| 130 | } | 149 | } |
| 131 | 150 | pub fn cmp_f32(a: f32, b: f32) ?Order { | |
| 132 | fn __unordxf2(a: f80, b: f80) callconv(.c) i32 { | 151 | return cmpf2(f32, a, b); |
| 133 | return unordcmp(f80, a, b); | 152 | } |
| 153 | pub fn unord_f32(a: f32, b: f32) bool { | ||
| 154 | return unord(f32, a, b); | ||
| 134 | } | 155 | } |
| 135 | 156 | ||
| 136 | pub fn __unordsf2(a: f32, b: f32) callconv(.c) i32 { | 157 | fn __cmpdf2(a: compiler_rt.f64.Abi, b: compiler_rt.f64.Abi) callconv(.c) Order { |
| 137 | return unordcmp(f32, a, b); | 158 | return cmp_f64(compiler_rt.f64.fromAbi(a), compiler_rt.f64.fromAbi(b)) orelse .gt; |
| 159 | } | ||
| 160 | fn __aeabi_dcmpeq(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { | ||
| 161 | return @intFromBool(cmp_f64(a, b) == .eq); | ||
| 162 | } | ||
| 163 | fn __aeabi_dcmplt(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { | ||
| 164 | return @intFromBool(cmp_f64(a, b) == .lt); | ||
| 165 | } | ||
| 166 | fn __aeabi_dcmple(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { | ||
| 167 | return @intFromBool(cmp_f64(a, b) orelse .gt != .gt); | ||
| 168 | } | ||
| 169 | fn __gedf2(a: compiler_rt.f64.Abi, b: compiler_rt.f64.Abi) callconv(.c) Order { | ||
| 170 | return cmp_f64(compiler_rt.f64.fromAbi(a), compiler_rt.f64.fromAbi(b)) orelse .lt; | ||
| 171 | } | ||
| 172 | fn __aeabi_dcmpge(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { | ||
| 173 | return @intFromBool(cmp_f64(a, b) orelse .lt != .lt); | ||
| 174 | } | ||
| 175 | fn __aeabi_dcmpgt(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { | ||
| 176 | return @intFromBool(cmp_f64(a, b) == .gt); | ||
| 177 | } | ||
| 178 | fn __unorddf2(a: compiler_rt.f64.Abi, b: compiler_rt.f64.Abi) callconv(.c) Unordered { | ||
| 179 | return @intFromBool(unord_f64(compiler_rt.f64.fromAbi(a), compiler_rt.f64.fromAbi(b))); | ||
| 180 | } | ||
| 181 | fn __aeabi_dcmpun(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { | ||
| 182 | return @intFromBool(unord_f64(a, b)); | ||
| 183 | } | ||
| 184 | pub fn cmp_f64(a: f64, b: f64) ?Order { | ||
| 185 | return cmpf2(f64, a, b); | ||
| 186 | } | ||
| 187 | pub fn unord_f64(a: f64, b: f64) bool { | ||
| 188 | return unord(f64, a, b); | ||
| 138 | } | 189 | } |
| 139 | 190 | ||
| 140 | fn __aeabi_fcmpun(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 { | 191 | fn __cmpxf2(a: compiler_rt.f80.Abi, b: compiler_rt.f80.Abi) callconv(.c) Order { |
| 141 | return unordcmp(f32, a, b); | 192 | return cmp_f80(compiler_rt.f80.fromAbi(a), compiler_rt.f80.fromAbi(b)) orelse .gt; |
| 193 | } | ||
| 194 | fn __gexf2(a: compiler_rt.f80.Abi, b: compiler_rt.f80.Abi) callconv(.c) Order { | ||
| 195 | return cmp_f80(compiler_rt.f80.fromAbi(a), compiler_rt.f80.fromAbi(b)) orelse .lt; | ||
| 142 | } | 196 | } |
| 197 | fn __unordxf2(a: compiler_rt.f80.Abi, b: compiler_rt.f80.Abi) callconv(.c) Unordered { | ||
| 198 | return @intFromBool(unord_f80(compiler_rt.f80.fromAbi(a), compiler_rt.f80.fromAbi(b))); | ||
| 199 | } | ||
| 200 | pub fn cmp_f80(a: f80, b: f80) ?Order { | ||
| 201 | const a_rep = std.math.F80.fromFloat(a); | ||
| 202 | const b_rep = std.math.F80.fromFloat(b); | ||
| 203 | const sig_bits = std.math.floatMantissaBits(f80); | ||
| 204 | const int_bit = 0x8000000000000000; | ||
| 205 | const sign_bit = 0x8000; | ||
| 206 | const special_exp = 0x7FFF; | ||
| 143 | 207 | ||
| 144 | pub const LE = enum(i32) { | 208 | // If either a or b is NaN, they are unordered. |
| 145 | Less = -1, | 209 | if ((a_rep.exp & special_exp == special_exp and a_rep.fraction ^ int_bit != 0) or |
| 146 | Equal = 0, | 210 | (b_rep.exp & special_exp == special_exp and b_rep.fraction ^ int_bit != 0)) |
| 147 | Greater = 1, | 211 | return null; |
| 148 | 212 | ||
| 149 | const Unordered: LE = .Greater; | 213 | // If a and b are both zeros, they are equal. |
| 150 | }; | 214 | if ((a_rep.fraction | b_rep.fraction) | ((a_rep.exp | b_rep.exp) & special_exp) == 0) |
| 215 | return .eq; | ||
| 151 | 216 | ||
| 152 | pub const GE = enum(i32) { | 217 | if (@intFromBool(a_rep.exp == b_rep.exp) & @intFromBool(a_rep.fraction == b_rep.fraction) != 0) { |
| 153 | Less = -1, | 218 | return .eq; |
| 154 | Equal = 0, | 219 | } else if (a_rep.exp & sign_bit != b_rep.exp & sign_bit) { |
| 155 | Greater = 1, | 220 | // signs are different |
| 221 | if (@as(i16, @bitCast(a_rep.exp)) < @as(i16, @bitCast(b_rep.exp))) { | ||
| 222 | return .lt; | ||
| 223 | } else { | ||
| 224 | return .gt; | ||
| 225 | } | ||
| 226 | } else { | ||
| 227 | const a_fraction = a_rep.fraction | (@as(u80, a_rep.exp) << sig_bits); | ||
| 228 | const b_fraction = b_rep.fraction | (@as(u80, b_rep.exp) << sig_bits); | ||
| 229 | if ((a_fraction < b_fraction) == (a_rep.exp & sign_bit == 0)) { | ||
| 230 | return .lt; | ||
| 231 | } else { | ||
| 232 | return .gt; | ||
| 233 | } | ||
| 234 | } | ||
| 235 | } | ||
| 236 | pub fn unord_f80(a: f80, b: f80) bool { | ||
| 237 | return unord(f80, a, b); | ||
| 238 | } | ||
| 156 | 239 | ||
| 157 | const Unordered: GE = .Less; | 240 | fn __cmptf2(a: compiler_rt.f128.Abi, b: compiler_rt.f128.Abi) callconv(.c) Order { |
| 158 | }; | 241 | return cmp_f128(compiler_rt.f128.fromAbi(a), compiler_rt.f128.fromAbi(b)) orelse .gt; |
| 242 | } | ||
| 243 | fn __getf2(a: compiler_rt.f128.Abi, b: compiler_rt.f128.Abi) callconv(.c) Order { | ||
| 244 | return cmp_f128(compiler_rt.f128.fromAbi(a), compiler_rt.f128.fromAbi(b)) orelse .lt; | ||
| 245 | } | ||
| 246 | fn __unordtf2(a: compiler_rt.f128.Abi, b: compiler_rt.f128.Abi) callconv(.c) Unordered { | ||
| 247 | return @intFromBool(unord_f128(compiler_rt.f128.fromAbi(a), compiler_rt.f128.fromAbi(b))); | ||
| 248 | } | ||
| 249 | fn _Qp_cmp(a: *const f128, b: *const f128) callconv(.c) SparcOrder { | ||
| 250 | return switch (cmp_f128(a.*, b.*) orelse return .un) { | ||
| 251 | .lt => .lt, | ||
| 252 | .eq => .eq, | ||
| 253 | .gt => .gt, | ||
| 254 | }; | ||
| 255 | } | ||
| 256 | fn _Qp_feq(a: *const f128, b: *const f128) callconv(.c) i32 { | ||
| 257 | return @intFromBool(cmp_f128(a.*, b.*) == .eq); | ||
| 258 | } | ||
| 259 | fn _Qp_fne(a: *const f128, b: *const f128) callconv(.c) i32 { | ||
| 260 | return @intFromBool(cmp_f128(a.*, b.*) != .eq); | ||
| 261 | } | ||
| 262 | fn _Qp_flt(a: *const f128, b: *const f128) callconv(.c) i32 { | ||
| 263 | return @intFromBool(cmp_f128(a.*, b.*) == .lt); | ||
| 264 | } | ||
| 265 | fn _Qp_fle(a: *const f128, b: *const f128) callconv(.c) i32 { | ||
| 266 | return @intFromBool((cmp_f128(a.*, b.*) orelse .gt) != .gt); | ||
| 267 | } | ||
| 268 | fn _Qp_fgt(a: *const f128, b: *const f128) callconv(.c) i32 { | ||
| 269 | return @intFromBool(cmp_f128(a.*, b.*) == .gt); | ||
| 270 | } | ||
| 271 | fn _Qp_fge(a: *const f128, b: *const f128) callconv(.c) i32 { | ||
| 272 | return @intFromBool((cmp_f128(a.*, b.*) orelse .lt) != .lt); | ||
| 273 | } | ||
| 274 | fn _Q_cmp(a: f128, b: f128) callconv(.c) SparcOrder { | ||
| 275 | return switch (cmp_f128(a, b) orelse return .un) { | ||
| 276 | .lt => .lt, | ||
| 277 | .eq => .eq, | ||
| 278 | .gt => .gt, | ||
| 279 | }; | ||
| 280 | } | ||
| 281 | fn _Q_feq(a: f128, b: f128) callconv(.c) i32 { | ||
| 282 | return @intFromBool(cmp_f128(a, b) == .eq); | ||
| 283 | } | ||
| 284 | fn _Q_fne(a: f128, b: f128) callconv(.c) i32 { | ||
| 285 | return @intFromBool(cmp_f128(a, b) != .eq); | ||
| 286 | } | ||
| 287 | fn _Q_flt(a: f128, b: f128) callconv(.c) i32 { | ||
| 288 | return @intFromBool(cmp_f128(a, b) == .lt); | ||
| 289 | } | ||
| 290 | fn _Q_fle(a: f128, b: f128) callconv(.c) i32 { | ||
| 291 | return @intFromBool((cmp_f128(a, b) orelse .gt) != .gt); | ||
| 292 | } | ||
| 293 | fn _Q_fgt(a: f128, b: f128) callconv(.c) i32 { | ||
| 294 | return @intFromBool(cmp_f128(a, b) == .gt); | ||
| 295 | } | ||
| 296 | fn _Q_fge(a: f128, b: f128) callconv(.c) i32 { | ||
| 297 | return @intFromBool((cmp_f128(a, b) orelse .lt) != .lt); | ||
| 298 | } | ||
| 299 | pub fn cmp_f128(a: f128, b: f128) ?Order { | ||
| 300 | return cmpf2(f128, a, b); | ||
| 301 | } | ||
| 302 | pub fn unord_f128(a: f128, b: f128) bool { | ||
| 303 | return unord(f128, a, b); | ||
| 304 | } | ||
| 159 | 305 | ||
| 160 | pub inline fn cmpf2(comptime T: type, comptime RT: type, a: T, b: T) RT { | 306 | inline fn cmpf2(comptime T: type, a: T, b: T) ?Order { |
| 161 | const bits = @typeInfo(T).float.bits; | 307 | const bits = @typeInfo(T).float.bits; |
| 162 | const srep_t = @Int(.signed, bits); | 308 | const srep_t = @Int(.signed, bits); |
| 163 | const rep_t = @Int(.unsigned, bits); | 309 | const rep_t = @Int(.unsigned, bits); |
| ... | @@ -175,81 +321,42 @@ pub inline fn cmpf2(comptime T: type, comptime RT: type, a: T, b: T) RT { | ... | @@ -175,81 +321,42 @@ pub inline fn cmpf2(comptime T: type, comptime RT: type, a: T, b: T) RT { |
| 175 | const bAbs = @as(rep_t, @bitCast(bInt)) & absMask; | 321 | const bAbs = @as(rep_t, @bitCast(bInt)) & absMask; |
| 176 | 322 | ||
| 177 | // If either a or b is NaN, they are unordered. | 323 | // If either a or b is NaN, they are unordered. |
| 178 | if (aAbs > infRep or bAbs > infRep) return RT.Unordered; | 324 | if (aAbs > infRep or bAbs > infRep) return null; |
| 179 | 325 | ||
| 180 | // If a and b are both zeros, they are equal. | 326 | // If a and b are both zeros, they are equal. |
| 181 | if ((aAbs | bAbs) == 0) return .Equal; | 327 | if ((aAbs | bAbs) == 0) return .eq; |
| 182 | 328 | ||
| 183 | // If at least one of a and b is positive, we get the same result comparing | 329 | // If at least one of a and b is positive, we get the same result comparing |
| 184 | // a and b as signed integers as we would with a floating-point compare. | 330 | // a and b as signed integers as we would with a floating-point compare. |
| 185 | if ((aInt & bInt) >= 0) { | 331 | if ((aInt & bInt) >= 0) { |
| 186 | if (aInt < bInt) { | 332 | if (aInt < bInt) { |
| 187 | return .Less; | 333 | return .lt; |
| 188 | } else if (aInt == bInt) { | 334 | } else if (aInt == bInt) { |
| 189 | return .Equal; | 335 | return .eq; |
| 190 | } else return .Greater; | 336 | } else return .gt; |
| 191 | } else { | 337 | } else { |
| 192 | // Otherwise, both are negative, so we need to flip the sense of the | 338 | // Otherwise, both are negative, so we need to flip the sense of the |
| 193 | // comparison to get the correct result. (This assumes a twos- or ones- | 339 | // comparison to get the correct result. (This assumes a twos- or ones- |
| 194 | // complement integer representation; if integers are represented in a | 340 | // complement integer representation; if integers are represented in a |
| 195 | // sign-magnitude representation, then this flip is incorrect). | 341 | // sign-magnitude representation, then this flip is incorrect). |
| 196 | if (aInt > bInt) { | 342 | if (aInt > bInt) { |
| 197 | return .Less; | 343 | return .lt; |
| 198 | } else if (aInt == bInt) { | 344 | } else if (aInt == bInt) { |
| 199 | return .Equal; | 345 | return .eq; |
| 200 | } else return .Greater; | 346 | } else return .gt; |
| 201 | } | 347 | } |
| 202 | } | 348 | } |
| 203 | 349 | ||
| 204 | pub inline fn cmp_f80(comptime RT: type, a: f80, b: f80) RT { | 350 | test cmp_f80 { |
| 205 | const a_rep = std.math.F80.fromFloat(a); | 351 | try std.testing.expect(cmp_f80(1.0, 1.0) == .eq); |
| 206 | const b_rep = std.math.F80.fromFloat(b); | 352 | try std.testing.expect(cmp_f80(0.0, -0.0) == .eq); |
| 207 | const sig_bits = std.math.floatMantissaBits(f80); | 353 | try std.testing.expect(cmp_f80(2.0, 4.0) == .lt); |
| 208 | const int_bit = 0x8000000000000000; | 354 | try std.testing.expect(cmp_f80(2.0, -4.0) == .gt); |
| 209 | const sign_bit = 0x8000; | 355 | try std.testing.expect(cmp_f80(-2.0, -4.0) == .gt); |
| 210 | const special_exp = 0x7FFF; | 356 | try std.testing.expect(cmp_f80(-2.0, 4.0) == .lt); |
| 211 | |||
| 212 | // If either a or b is NaN, they are unordered. | ||
| 213 | if ((a_rep.exp & special_exp == special_exp and a_rep.fraction ^ int_bit != 0) or | ||
| 214 | (b_rep.exp & special_exp == special_exp and b_rep.fraction ^ int_bit != 0)) | ||
| 215 | return RT.Unordered; | ||
| 216 | |||
| 217 | // If a and b are both zeros, they are equal. | ||
| 218 | if ((a_rep.fraction | b_rep.fraction) | ((a_rep.exp | b_rep.exp) & special_exp) == 0) | ||
| 219 | return .Equal; | ||
| 220 | |||
| 221 | if (@intFromBool(a_rep.exp == b_rep.exp) & @intFromBool(a_rep.fraction == b_rep.fraction) != 0) { | ||
| 222 | return .Equal; | ||
| 223 | } else if (a_rep.exp & sign_bit != b_rep.exp & sign_bit) { | ||
| 224 | // signs are different | ||
| 225 | if (@as(i16, @bitCast(a_rep.exp)) < @as(i16, @bitCast(b_rep.exp))) { | ||
| 226 | return .Less; | ||
| 227 | } else { | ||
| 228 | return .Greater; | ||
| 229 | } | ||
| 230 | } else { | ||
| 231 | const a_fraction = a_rep.fraction | (@as(u80, a_rep.exp) << sig_bits); | ||
| 232 | const b_fraction = b_rep.fraction | (@as(u80, b_rep.exp) << sig_bits); | ||
| 233 | if ((a_fraction < b_fraction) == (a_rep.exp & sign_bit == 0)) { | ||
| 234 | return .Less; | ||
| 235 | } else { | ||
| 236 | return .Greater; | ||
| 237 | } | ||
| 238 | } | ||
| 239 | } | ||
| 240 | |||
| 241 | test "cmp_f80" { | ||
| 242 | inline for (.{ LE, GE }) |RT| { | ||
| 243 | try std.testing.expect(cmp_f80(RT, 1.0, 1.0) == RT.Equal); | ||
| 244 | try std.testing.expect(cmp_f80(RT, 0.0, -0.0) == RT.Equal); | ||
| 245 | try std.testing.expect(cmp_f80(RT, 2.0, 4.0) == RT.Less); | ||
| 246 | try std.testing.expect(cmp_f80(RT, 2.0, -4.0) == RT.Greater); | ||
| 247 | try std.testing.expect(cmp_f80(RT, -2.0, -4.0) == RT.Greater); | ||
| 248 | try std.testing.expect(cmp_f80(RT, -2.0, 4.0) == RT.Less); | ||
| 249 | } | ||
| 250 | } | 357 | } |
| 251 | 358 | ||
| 252 | pub inline fn unordcmp(comptime T: type, a: T, b: T) i32 { | 359 | inline fn unord(comptime T: type, a: T, b: T) bool { |
| 253 | const rep_t = @Int(.unsigned, @typeInfo(T).float.bits); | 360 | const rep_t = @Int(.unsigned, @typeInfo(T).float.bits); |
| 254 | 361 | ||
| 255 | const significandBits = std.math.floatMantissaBits(T); | 362 | const significandBits = std.math.floatMantissaBits(T); |
| ... | @@ -261,7 +368,7 @@ pub inline fn unordcmp(comptime T: type, a: T, b: T) i32 { | ... | @@ -261,7 +368,7 @@ pub inline fn unordcmp(comptime T: type, a: T, b: T) i32 { |
| 261 | const aAbs: rep_t = @as(rep_t, @bitCast(a)) & absMask; | 368 | const aAbs: rep_t = @as(rep_t, @bitCast(a)) & absMask; |
| 262 | const bAbs: rep_t = @as(rep_t, @bitCast(b)) & absMask; | 369 | const bAbs: rep_t = @as(rep_t, @bitCast(b)) & absMask; |
| 263 | 370 | ||
| 264 | return @intFromBool(aAbs > infRep or bAbs > infRep); | 371 | return aAbs > infRep or bAbs > infRep; |
| 265 | } | 372 | } |
| 266 | 373 | ||
| 267 | test { | 374 | test { |
lib/compiler_rt/comparesf2_test.zig+17-73| ... | @@ -5,52 +5,12 @@ | ... | @@ -5,52 +5,12 @@ |
| 5 | const std = @import("std"); | 5 | const std = @import("std"); |
| 6 | const builtin = @import("builtin"); | 6 | const builtin = @import("builtin"); |
| 7 | 7 | ||
| 8 | const __eqsf2 = @import("./comparef.zig").__eqsf2; | 8 | const compiler_rt = @import("../compiler_rt.zig"); |
| 9 | const __lesf2 = @import("./comparef.zig").__lesf2; | ||
| 10 | const __ltsf2 = @import("./comparef.zig").__ltsf2; | ||
| 11 | const __nesf2 = @import("./comparef.zig").__nesf2; | ||
| 12 | 9 | ||
| 13 | const __gesf2 = @import("./gesf2.zig").__gesf2; | 10 | const impl = @import("comparef.zig"); |
| 14 | const __gtsf2 = @import("./gesf2.zig").__gtsf2; | 11 | const Order = impl.Order; |
| 15 | 12 | const cmp_f32 = impl.cmp_f32; | |
| 16 | const __unordsf2 = @import("./comparef.zig").__unordsf2; | 13 | const unord_f32 = impl.unord_f32; |
| 17 | |||
| 18 | const TestVector = struct { | ||
| 19 | a: f32, | ||
| 20 | b: f32, | ||
| 21 | eqReference: c_int, | ||
| 22 | geReference: c_int, | ||
| 23 | gtReference: c_int, | ||
| 24 | leReference: c_int, | ||
| 25 | ltReference: c_int, | ||
| 26 | neReference: c_int, | ||
| 27 | unReference: c_int, | ||
| 28 | }; | ||
| 29 | |||
| 30 | fn test__cmpsf2(vector: TestVector) bool { | ||
| 31 | if (__eqsf2(vector.a, vector.b) != vector.eqReference) { | ||
| 32 | return false; | ||
| 33 | } | ||
| 34 | if (__gesf2(vector.a, vector.b) != vector.geReference) { | ||
| 35 | return false; | ||
| 36 | } | ||
| 37 | if (__gtsf2(vector.a, vector.b) != vector.gtReference) { | ||
| 38 | return false; | ||
| 39 | } | ||
| 40 | if (__lesf2(vector.a, vector.b) != vector.leReference) { | ||
| 41 | return false; | ||
| 42 | } | ||
| 43 | if (__ltsf2(vector.a, vector.b) != vector.ltReference) { | ||
| 44 | return false; | ||
| 45 | } | ||
| 46 | if (__nesf2(vector.a, vector.b) != vector.neReference) { | ||
| 47 | return false; | ||
| 48 | } | ||
| 49 | if (__unordsf2(vector.a, vector.b) != vector.unReference) { | ||
| 50 | return false; | ||
| 51 | } | ||
| 52 | return true; | ||
| 53 | } | ||
| 54 | 14 | ||
| 55 | const arguments = [_]f32{ | 15 | const arguments = [_]f32{ |
| 56 | std.math.nan(f32), | 16 | std.math.nan(f32), |
| ... | @@ -73,36 +33,20 @@ const arguments = [_]f32{ | ... | @@ -73,36 +33,20 @@ const arguments = [_]f32{ |
| 73 | std.math.inf(f32), | 33 | std.math.inf(f32), |
| 74 | }; | 34 | }; |
| 75 | 35 | ||
| 76 | fn generateVector(comptime a: f32, comptime b: f32) TestVector { | 36 | test "compare f32" { |
| 77 | const leResult = if (a < b) -1 else if (a == b) 0 else 1; | ||
| 78 | const geResult = if (a > b) 1 else if (a == b) 0 else -1; | ||
| 79 | const unResult = if (a != a or b != b) 1 else 0; | ||
| 80 | return TestVector{ | ||
| 81 | .a = a, | ||
| 82 | .b = b, | ||
| 83 | .eqReference = leResult, | ||
| 84 | .geReference = geResult, | ||
| 85 | .gtReference = geResult, | ||
| 86 | .leReference = leResult, | ||
| 87 | .ltReference = leResult, | ||
| 88 | .neReference = leResult, | ||
| 89 | .unReference = unResult, | ||
| 90 | }; | ||
| 91 | } | ||
| 92 | |||
| 93 | const test_vectors = init: { | ||
| 94 | @setEvalBranchQuota(10000); | ||
| 95 | var vectors: [arguments.len * arguments.len]TestVector = undefined; | ||
| 96 | for (arguments[0..], 0..) |arg_i, i| { | 37 | for (arguments[0..], 0..) |arg_i, i| { |
| 97 | for (arguments[0..], 0..) |arg_j, j| { | 38 | for (arguments[0..], 0..) |arg_j, j| { |
| 98 | vectors[(i * arguments.len) + j] = generateVector(arg_i, arg_j); | 39 | const expected_unord = i == 0 or j == 0; |
| 40 | const expected_order: ?Order = if (expected_unord) null else switch (std.math.order( | ||
| 41 | i - @intFromBool(i >= 9), | ||
| 42 | j - @intFromBool(j >= 9), | ||
| 43 | )) { | ||
| 44 | .lt => .lt, | ||
| 45 | .eq => .eq, | ||
| 46 | .gt => .gt, | ||
| 47 | }; | ||
| 48 | try std.testing.expect(expected_order == cmp_f32(arg_i, arg_j)); | ||
| 49 | try std.testing.expect(expected_unord == unord_f32(arg_i, arg_j)); | ||
| 99 | } | 50 | } |
| 100 | } | 51 | } |
| 101 | break :init vectors; | ||
| 102 | }; | ||
| 103 | |||
| 104 | test "compare f32" { | ||
| 105 | for (test_vectors) |vector| { | ||
| 106 | try std.testing.expect(test__cmpsf2(vector)); | ||
| 107 | } | ||
| 108 | } | 52 | } |
lib/compiler_rt/cos.zig+64-51| ... | @@ -13,31 +13,34 @@ const expect = std.testing.expect; | ... | @@ -13,31 +13,34 @@ const expect = std.testing.expect; |
| 13 | const expectApproxEqAbs = std.testing.expectApproxEqAbs; | 13 | const expectApproxEqAbs = std.testing.expectApproxEqAbs; |
| 14 | 14 | ||
| 15 | const compiler_rt = @import("../compiler_rt.zig"); | 15 | const compiler_rt = @import("../compiler_rt.zig"); |
| 16 | const symbol = @import("../compiler_rt.zig").symbol; | 16 | const symbol = compiler_rt.symbol; |
| 17 | const trig = @import("trig.zig"); | 17 | const trig = @import("trig.zig"); |
| 18 | const rem_pio2 = @import("rem_pio2.zig").rem_pio2; | 18 | const rem_pio2 = @import("rem_pio2.zig").rem_pio2; |
| 19 | const rem_pio2f = @import("rem_pio2f.zig").rem_pio2f; | 19 | const rem_pio2f = @import("rem_pio2f.zig").rem_pio2f; |
| 20 | const rem_pio2l = @import("rem_pio2l.zig").rem_pio2l; | 20 | const rem_pio2l = @import("rem_pio2l.zig").rem_pio2l; |
| 21 | 21 | ||
| 22 | comptime { | 22 | comptime { |
| 23 | symbol(&cosh, "__cosh"); | 23 | symbol(&__cosh, "__cosh"); |
| 24 | symbol(&cosl, "__cosl"); | ||
| 25 | symbol(&cosf, "cosf"); | 24 | symbol(&cosf, "cosf"); |
| 26 | symbol(&cos, "cos"); | 25 | symbol(&cos, "cos"); |
| 27 | symbol(&cosx, "__cosx"); | 26 | symbol(&__cosx, "__cosx"); |
| 28 | if (compiler_rt.want_ppc_abi) { | 27 | symbol(&cosq, "cosf128"); |
| 29 | symbol(&cosq, "cosf128"); | ||
| 30 | } | ||
| 31 | symbol(&cosq, "cosq"); | ||
| 32 | symbol(&cosl, "cosl"); | 28 | symbol(&cosl, "cosl"); |
| 29 | symbol(&cosl, "__cosl"); // required by musl | ||
| 33 | } | 30 | } |
| 34 | 31 | ||
| 35 | pub fn cosh(a: f16) callconv(.c) f16 { | 32 | fn __cosh(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { |
| 33 | return compiler_rt.f16.toAbi(cos_f16(compiler_rt.f16.fromAbi(x))); | ||
| 34 | } | ||
| 35 | pub fn cos_f16(x: f16) f16 { | ||
| 36 | // TODO: more efficient implementation | 36 | // TODO: more efficient implementation |
| 37 | return @floatCast(cosf(a)); | 37 | return @floatCast(cos_f32(x)); |
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | pub fn cosf(x: f32) callconv(.c) f32 { | 40 | fn cosf(x: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { |
| 41 | return compiler_rt.f32.toAbi(cos_f32(compiler_rt.f32.fromAbi(x))); | ||
| 42 | } | ||
| 43 | pub fn cos_f32(x: f32) f32 { | ||
| 41 | // Small multiples of pi/2 rounded to double precision. | 44 | // Small multiples of pi/2 rounded to double precision. |
| 42 | const c1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D18 | 45 | const c1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D18 |
| 43 | const c2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D18 | 46 | const c2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D18 |
| ... | @@ -94,7 +97,10 @@ pub fn cosf(x: f32) callconv(.c) f32 { | ... | @@ -94,7 +97,10 @@ pub fn cosf(x: f32) callconv(.c) f32 { |
| 94 | }; | 97 | }; |
| 95 | } | 98 | } |
| 96 | 99 | ||
| 97 | pub fn cos(x: f64) callconv(.c) f64 { | 100 | fn cos(x: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { |
| 101 | return compiler_rt.f64.toAbi(cos_f64(compiler_rt.f64.fromAbi(x))); | ||
| 102 | } | ||
| 103 | pub fn cos_f64(x: f64) f64 { | ||
| 98 | var ix = @as(u64, @bitCast(x)) >> 32; | 104 | var ix = @as(u64, @bitCast(x)) >> 32; |
| 99 | ix &= 0x7fffffff; | 105 | ix &= 0x7fffffff; |
| 100 | 106 | ||
| ... | @@ -123,7 +129,10 @@ pub fn cos(x: f64) callconv(.c) f64 { | ... | @@ -123,7 +129,10 @@ pub fn cos(x: f64) callconv(.c) f64 { |
| 123 | }; | 129 | }; |
| 124 | } | 130 | } |
| 125 | 131 | ||
| 126 | pub fn cosx(x: f80) callconv(.c) f80 { | 132 | fn __cosx(x: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { |
| 133 | return compiler_rt.f80.toAbi(cos_f80(compiler_rt.f80.fromAbi(x))); | ||
| 134 | } | ||
| 135 | pub fn cos_f80(x: f80) f80 { | ||
| 127 | const se = ld.signExponent(x) & 0x7fff; | 136 | const se = ld.signExponent(x) & 0x7fff; |
| 128 | if (se == 0x7fff) { | 137 | if (se == 0x7fff) { |
| 129 | return x - x; | 138 | return x - x; |
| ... | @@ -147,7 +156,10 @@ pub fn cosx(x: f80) callconv(.c) f80 { | ... | @@ -147,7 +156,10 @@ pub fn cosx(x: f80) callconv(.c) f80 { |
| 147 | }; | 156 | }; |
| 148 | } | 157 | } |
| 149 | 158 | ||
| 150 | pub fn cosq(x: f128) callconv(.c) f128 { | 159 | fn cosq(x: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { |
| 160 | return compiler_rt.f128.toAbi(cos_f128(compiler_rt.f128.fromAbi(x))); | ||
| 161 | } | ||
| 162 | pub fn cos_f128(x: f128) f128 { | ||
| 151 | const se = ld.signExponent(x) & 0x7fff; | 163 | const se = ld.signExponent(x) & 0x7fff; |
| 152 | if (se == 0x7fff) { | 164 | if (se == 0x7fff) { |
| 153 | return x - x; | 165 | return x - x; |
| ... | @@ -173,20 +185,21 @@ pub fn cosq(x: f128) callconv(.c) f128 { | ... | @@ -173,20 +185,21 @@ pub fn cosq(x: f128) callconv(.c) f128 { |
| 173 | 185 | ||
| 174 | pub fn cosl(x: c_longdouble) callconv(.c) c_longdouble { | 186 | pub fn cosl(x: c_longdouble) callconv(.c) c_longdouble { |
| 175 | switch (@typeInfo(c_longdouble).float.bits) { | 187 | switch (@typeInfo(c_longdouble).float.bits) { |
| 176 | 64 => return cos(x), | 188 | 64 => return cos_f64(x), |
| 177 | 80 => return cosx(x), | 189 | 80 => return cos_f80(x), |
| 178 | 128 => return cosq(x), | 190 | 128 => return cos_f128(x), |
| 179 | else => @compileError("unreachable"), | 191 | else => comptime unreachable, |
| 180 | } | 192 | } |
| 181 | } | 193 | } |
| 182 | 194 | ||
| 183 | fn testCosSpecial(comptime T: type) !void { | 195 | fn testCosSpecial(comptime T: type) !void { |
| 184 | const f = switch (T) { | 196 | const f = switch (T) { |
| 185 | f32 => cosf, | 197 | f16 => cos_f16, |
| 186 | f64 => cos, | 198 | f32 => cos_f32, |
| 187 | f80 => cosx, | 199 | f64 => cos_f64, |
| 188 | f128 => cosq, | 200 | f80 => cos_f80, |
| 189 | else => @compileError("unimplemented"), | 201 | f128 => cos_f128, |
| 202 | else => comptime unreachable, | ||
| 190 | }; | 203 | }; |
| 191 | 204 | ||
| 192 | try expect(f(0.0) == 1.0); | 205 | try expect(f(0.0) == 1.0); |
| ... | @@ -198,13 +211,13 @@ fn testCosSpecial(comptime T: type) !void { | ... | @@ -198,13 +211,13 @@ fn testCosSpecial(comptime T: type) !void { |
| 198 | 211 | ||
| 199 | test "cos32.normal" { | 212 | test "cos32.normal" { |
| 200 | const epsilon = math.floatEps(f32); | 213 | const epsilon = math.floatEps(f32); |
| 201 | try expectApproxEqAbs(@as(f32, 1.0), cosf(0.0), epsilon); | 214 | try expectApproxEqAbs(@as(f32, 1.0), cos_f32(0.0), epsilon); |
| 202 | try expectApproxEqAbs(@as(f32, 0.9800666), cosf(0.2), epsilon); | 215 | try expectApproxEqAbs(@as(f32, 0.9800666), cos_f32(0.2), epsilon); |
| 203 | try expectApproxEqAbs(@as(f32, 0.6276231), cosf(0.8923), epsilon); | 216 | try expectApproxEqAbs(@as(f32, 0.6276231), cos_f32(0.8923), epsilon); |
| 204 | try expectApproxEqAbs(@as(f32, 0.0707372), cosf(1.5), epsilon); | 217 | try expectApproxEqAbs(@as(f32, 0.0707372), cos_f32(1.5), epsilon); |
| 205 | try expectApproxEqAbs(@as(f32, 0.0707372), cosf(-1.5), epsilon); | 218 | try expectApproxEqAbs(@as(f32, 0.0707372), cos_f32(-1.5), epsilon); |
| 206 | try expectApproxEqAbs(@as(f32, 0.96913195), cosf(37.45), epsilon); | 219 | try expectApproxEqAbs(@as(f32, 0.96913195), cos_f32(37.45), epsilon); |
| 207 | try expectApproxEqAbs(@as(f32, 0.40079966), cosf(89.123), epsilon); | 220 | try expectApproxEqAbs(@as(f32, 0.40079966), cos_f32(89.123), epsilon); |
| 208 | } | 221 | } |
| 209 | 222 | ||
| 210 | test "cos32.special" { | 223 | test "cos32.special" { |
| ... | @@ -213,13 +226,13 @@ test "cos32.special" { | ... | @@ -213,13 +226,13 @@ test "cos32.special" { |
| 213 | 226 | ||
| 214 | test "cos64.normal" { | 227 | test "cos64.normal" { |
| 215 | const epsilon = math.floatEps(f64); | 228 | const epsilon = math.floatEps(f64); |
| 216 | try expectApproxEqAbs(@as(f64, 1.0), cos(0.0), epsilon); | 229 | try expectApproxEqAbs(@as(f64, 1.0), cos_f64(0.0), epsilon); |
| 217 | try expectApproxEqAbs(@as(f64, 0.9800665778412416), cos(0.2), epsilon); | 230 | try expectApproxEqAbs(@as(f64, 0.9800665778412416), cos_f64(0.2), epsilon); |
| 218 | try expectApproxEqAbs(@as(f64, 0.6276230983360804), cos(0.8923), epsilon); | 231 | try expectApproxEqAbs(@as(f64, 0.6276230983360804), cos_f64(0.8923), epsilon); |
| 219 | try expectApproxEqAbs(@as(f64, 0.0707372016677029), cos(1.5), epsilon); | 232 | try expectApproxEqAbs(@as(f64, 0.0707372016677029), cos_f64(1.5), epsilon); |
| 220 | try expectApproxEqAbs(@as(f64, 0.0707372016677029), cos(-1.5), epsilon); | 233 | try expectApproxEqAbs(@as(f64, 0.0707372016677029), cos_f64(-1.5), epsilon); |
| 221 | try expectApproxEqAbs(@as(f64, 0.9691317730707778), cos(37.45), epsilon); | 234 | try expectApproxEqAbs(@as(f64, 0.9691317730707778), cos_f64(37.45), epsilon); |
| 222 | try expectApproxEqAbs(@as(f64, 0.4008006809354791), cos(89.123), epsilon); | 235 | try expectApproxEqAbs(@as(f64, 0.4008006809354791), cos_f64(89.123), epsilon); |
| 223 | } | 236 | } |
| 224 | 237 | ||
| 225 | test "cos64.special" { | 238 | test "cos64.special" { |
| ... | @@ -228,13 +241,13 @@ test "cos64.special" { | ... | @@ -228,13 +241,13 @@ test "cos64.special" { |
| 228 | 241 | ||
| 229 | test "cos80.normal" { | 242 | test "cos80.normal" { |
| 230 | const epsilon = math.floatEps(f80); | 243 | const epsilon = math.floatEps(f80); |
| 231 | try expectApproxEqAbs(@as(f80, 1.0), cosx(0.0), epsilon); | 244 | try expectApproxEqAbs(@as(f80, 1.0), cos_f80(0.0), epsilon); |
| 232 | try expectApproxEqAbs(@as(f80, 0.98006657784124163112419651674816888), cosx(0.2), epsilon); | 245 | try expectApproxEqAbs(@as(f80, 0.98006657784124163112419651674816888), cos_f80(0.2), epsilon); |
| 233 | try expectApproxEqAbs(@as(f80, 0.62762309833608037003563995939286067), cosx(0.8923), epsilon); | 246 | try expectApproxEqAbs(@as(f80, 0.62762309833608037003563995939286067), cos_f80(0.8923), epsilon); |
| 234 | try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), cosx(1.5), epsilon); | 247 | try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), cos_f80(1.5), epsilon); |
| 235 | try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), cosx(-1.5), epsilon); | 248 | try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), cos_f80(-1.5), epsilon); |
| 236 | try expectApproxEqAbs(@as(f80, 0.9691317730707771246), cosx(37.45), epsilon); | 249 | try expectApproxEqAbs(@as(f80, 0.9691317730707771246), cos_f80(37.45), epsilon); |
| 237 | try expectApproxEqAbs(@as(f80, 0.4008006809354834001), cosx(89.123), epsilon); | 250 | try expectApproxEqAbs(@as(f80, 0.4008006809354834001), cos_f80(89.123), epsilon); |
| 238 | } | 251 | } |
| 239 | 252 | ||
| 240 | test "cos80.special" { | 253 | test "cos80.special" { |
| ... | @@ -243,13 +256,13 @@ test "cos80.special" { | ... | @@ -243,13 +256,13 @@ test "cos80.special" { |
| 243 | 256 | ||
| 244 | test "cos128.normal" { | 257 | test "cos128.normal" { |
| 245 | const epsilon = math.floatEps(f128); | 258 | const epsilon = math.floatEps(f128); |
| 246 | try expectApproxEqAbs(@as(f128, 1.0), cosq(0.0), epsilon); | 259 | try expectApproxEqAbs(@as(f128, 1.0), cos_f128(0.0), epsilon); |
| 247 | try expectApproxEqAbs(@as(f128, 0.98006657784124163112419651674816888), cosq(0.2), epsilon); | 260 | try expectApproxEqAbs(@as(f128, 0.98006657784124163112419651674816888), cos_f128(0.2), epsilon); |
| 248 | try expectApproxEqAbs(@as(f128, 0.62762309833608037003563995939286067), cosq(0.8923), epsilon); | 261 | try expectApproxEqAbs(@as(f128, 0.62762309833608037003563995939286067), cos_f128(0.8923), epsilon); |
| 249 | try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), cosq(1.5), epsilon); | 262 | try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), cos_f128(1.5), epsilon); |
| 250 | try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), cosq(-1.5), epsilon); | 263 | try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), cos_f128(-1.5), epsilon); |
| 251 | try expectApproxEqAbs(@as(f128, 0.96913177307077712443149563847233230), cosq(37.45), epsilon); | 264 | try expectApproxEqAbs(@as(f128, 0.96913177307077712443149563847233230), cos_f128(37.45), epsilon); |
| 252 | try expectApproxEqAbs(@as(f128, 0.40080068093548339848199454493704702), cosq(89.123), epsilon); | 265 | try expectApproxEqAbs(@as(f128, 0.40080068093548339848199454493704702), cos_f128(89.123), epsilon); |
| 253 | } | 266 | } |
| 254 | 267 | ||
| 255 | test "cos128.special" { | 268 | test "cos128.special" { |
lib/compiler_rt/count0bits.zig+2-1| ... | @@ -1,6 +1,7 @@ | ... | @@ -1,6 +1,7 @@ |
| 1 | const builtin = @import("builtin"); | 1 | const builtin = @import("builtin"); |
| 2 | const std = @import("std"); | 2 | const std = @import("std"); |
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | 3 | const compiler_rt = @import("../compiler_rt.zig"); |
| 4 | const symbol = compiler_rt.symbol; | ||
| 4 | 5 | ||
| 5 | comptime { | 6 | comptime { |
| 6 | symbol(&__clzsi2, "__clzsi2"); | 7 | symbol(&__clzsi2, "__clzsi2"); |
lib/compiler_rt/divc3.zig+78-5| ... | @@ -7,12 +7,81 @@ const maxInt = std.math.maxInt; | ... | @@ -7,12 +7,81 @@ const maxInt = std.math.maxInt; |
| 7 | const minInt = std.math.minInt; | 7 | const minInt = std.math.minInt; |
| 8 | const isFinite = std.math.isFinite; | 8 | const isFinite = std.math.isFinite; |
| 9 | const copysign = std.math.copysign; | 9 | const copysign = std.math.copysign; |
| 10 | const Complex = @import("mulc3.zig").Complex; | 10 | |
| 11 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 12 | const symbol = compiler_rt.symbol; | ||
| 13 | const Complex = compiler_rt.Complex; | ||
| 14 | |||
| 15 | comptime { | ||
| 16 | if (@import("builtin").zig_backend != .stage2_c) { | ||
| 17 | symbol(&__divhc3, "__divhc3"); | ||
| 18 | symbol(&__divsc3, "__divsc3"); | ||
| 19 | symbol(&__divdc3, "__divdc3"); | ||
| 20 | symbol(&__divxc3, "__divxc3"); | ||
| 21 | if (compiler_rt.want_ppc_abi) { | ||
| 22 | symbol(&__divtc3, "__divkc3"); | ||
| 23 | } else { | ||
| 24 | symbol(&__divtc3, "__divtc3"); | ||
| 25 | } | ||
| 26 | } | ||
| 27 | } | ||
| 28 | |||
| 29 | fn __divhc3(lhs_real: compiler_rt.f16.Abi, lhs_imag: compiler_rt.f16.Abi, rhs_real: compiler_rt.f16.Abi, rhs_imag: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.complex.Abi { | ||
| 30 | return compiler_rt.f16.complex.toAbi(div_cf16( | ||
| 31 | compiler_rt.f16.complex.fromAbi(.{ .real = lhs_real, .imag = lhs_imag }), | ||
| 32 | compiler_rt.f16.complex.fromAbi(.{ .real = rhs_real, .imag = rhs_imag }), | ||
| 33 | )); | ||
| 34 | } | ||
| 35 | pub fn div_cf16(a: Complex(f16), b: Complex(f16)) Complex(f16) { | ||
| 36 | return divc3(f16, a, b); | ||
| 37 | } | ||
| 38 | |||
| 39 | fn __divsc3(lhs_real: compiler_rt.f32.Abi, lhs_imag: compiler_rt.f32.Abi, rhs_real: compiler_rt.f32.Abi, rhs_imag: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.complex.Abi { | ||
| 40 | return compiler_rt.f32.complex.toAbi(div_cf32( | ||
| 41 | compiler_rt.f32.complex.fromAbi(.{ .real = lhs_real, .imag = lhs_imag }), | ||
| 42 | compiler_rt.f32.complex.fromAbi(.{ .real = rhs_real, .imag = rhs_imag }), | ||
| 43 | )); | ||
| 44 | } | ||
| 45 | pub fn div_cf32(a: Complex(f32), b: Complex(f32)) Complex(f32) { | ||
| 46 | return divc3(f32, a, b); | ||
| 47 | } | ||
| 48 | |||
| 49 | fn __divdc3(lhs_real: compiler_rt.f64.Abi, lhs_imag: compiler_rt.f64.Abi, rhs_real: compiler_rt.f64.Abi, rhs_imag: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.complex.Abi { | ||
| 50 | return compiler_rt.f64.complex.toAbi(div_cf64( | ||
| 51 | compiler_rt.f64.complex.fromAbi(.{ .real = lhs_real, .imag = lhs_imag }), | ||
| 52 | compiler_rt.f64.complex.fromAbi(.{ .real = rhs_real, .imag = rhs_imag }), | ||
| 53 | )); | ||
| 54 | } | ||
| 55 | pub fn div_cf64(a: Complex(f64), b: Complex(f64)) Complex(f64) { | ||
| 56 | return divc3(f64, a, b); | ||
| 57 | } | ||
| 58 | |||
| 59 | fn __divxc3(lhs_real: compiler_rt.f80.Abi, lhs_imag: compiler_rt.f80.Abi, rhs_real: compiler_rt.f80.Abi, rhs_imag: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.complex.Abi { | ||
| 60 | return compiler_rt.f80.complex.toAbi(div_cf80( | ||
| 61 | compiler_rt.f80.complex.fromAbi(.{ .real = lhs_real, .imag = lhs_imag }), | ||
| 62 | compiler_rt.f80.complex.fromAbi(.{ .real = rhs_real, .imag = rhs_imag }), | ||
| 63 | )); | ||
| 64 | } | ||
| 65 | pub fn div_cf80(a: Complex(f80), b: Complex(f80)) Complex(f80) { | ||
| 66 | return divc3(f80, a, b); | ||
| 67 | } | ||
| 68 | |||
| 69 | fn __divtc3(lhs_real: compiler_rt.f128.Abi, lhs_imag: compiler_rt.f128.Abi, rhs_real: compiler_rt.f128.Abi, rhs_imag: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.complex.Abi { | ||
| 70 | return compiler_rt.f128.complex.toAbi(div_cf128( | ||
| 71 | compiler_rt.f128.complex.fromAbi(.{ .real = lhs_real, .imag = lhs_imag }), | ||
| 72 | compiler_rt.f128.complex.fromAbi(.{ .real = rhs_real, .imag = rhs_imag }), | ||
| 73 | )); | ||
| 74 | } | ||
| 75 | pub fn div_cf128(a: Complex(f128), b: Complex(f128)) Complex(f128) { | ||
| 76 | return divc3(f128, a, b); | ||
| 77 | } | ||
| 11 | 78 | ||
| 12 | /// Implementation based on Annex G of C17 Standard (N2176) | 79 | /// Implementation based on Annex G of C17 Standard (N2176) |
| 13 | pub inline fn divc3(comptime T: type, a: T, b: T, c_in: T, d_in: T) Complex(T) { | 80 | inline fn divc3(comptime T: type, lhs: Complex(T), rhs: Complex(T)) Complex(T) { |
| 14 | var c = c_in; | 81 | const a = lhs.real; |
| 15 | var d = d_in; | 82 | const b = lhs.imag; |
| 83 | var c = rhs.real; | ||
| 84 | var d = rhs.imag; | ||
| 16 | 85 | ||
| 17 | // logbw used to prevent under/over-flow | 86 | // logbw used to prevent under/over-flow |
| 18 | const logbw = ilogb(@max(@abs(c), @abs(d))); | 87 | const logbw = ilogb(@max(@abs(c), @abs(d))); |
| ... | @@ -23,7 +92,7 @@ pub inline fn divc3(comptime T: type, a: T, b: T, c_in: T, d_in: T) Complex(T) { | ... | @@ -23,7 +92,7 @@ pub inline fn divc3(comptime T: type, a: T, b: T, c_in: T, d_in: T) Complex(T) { |
| 23 | break :b logbw; | 92 | break :b logbw; |
| 24 | } else 0; | 93 | } else 0; |
| 25 | const denom = c * c + d * d; | 94 | const denom = c * c + d * d; |
| 26 | const result = Complex(T){ | 95 | const result: Complex(T) = .{ |
| 27 | .real = scalbn((a * c + b * d) / denom, -ilogbw), | 96 | .real = scalbn((a * c + b * d) / denom, -ilogbw), |
| 28 | .imag = scalbn((b * c - a * d) / denom, -ilogbw), | 97 | .imag = scalbn((b * c - a * d) / denom, -ilogbw), |
| 29 | }; | 98 | }; |
| ... | @@ -58,3 +127,7 @@ pub inline fn divc3(comptime T: type, a: T, b: T, c_in: T, d_in: T) Complex(T) { | ... | @@ -58,3 +127,7 @@ pub inline fn divc3(comptime T: type, a: T, b: T, c_in: T, d_in: T) Complex(T) { |
| 58 | 127 | ||
| 59 | return result; | 128 | return result; |
| 60 | } | 129 | } |
| 130 | |||
| 131 | test { | ||
| 132 | _ = @import("divc3_test.zig"); | ||
| 133 | } |
lib/compiler_rt/divc3_test.zig+28-51| ... | @@ -2,76 +2,53 @@ const std = @import("std"); | ... | @@ -2,76 +2,53 @@ const std = @import("std"); |
| 2 | const math = std.math; | 2 | const math = std.math; |
| 3 | const expect = std.testing.expect; | 3 | const expect = std.testing.expect; |
| 4 | 4 | ||
| 5 | const Complex = @import("./mulc3.zig").Complex; | 5 | const Complex = @import("../compiler_rt.zig").Complex; |
| 6 | const __divhc3 = @import("./divhc3.zig").__divhc3; | 6 | |
| 7 | const __divsc3 = @import("./divsc3.zig").__divsc3; | 7 | const impl = @import("divc3.zig"); |
| 8 | const __divdc3 = @import("./divdc3.zig").__divdc3; | 8 | const div_cf16 = impl.div_cf16; |
| 9 | const __divxc3 = @import("./divxc3.zig").__divxc3; | 9 | const div_cf32 = impl.div_cf32; |
| 10 | const __divtc3 = @import("./divtc3.zig").__divtc3; | 10 | const div_cf64 = impl.div_cf64; |
| 11 | const div_cf80 = impl.div_cf80; | ||
| 12 | const div_cf128 = impl.div_cf128; | ||
| 11 | 13 | ||
| 12 | test "divc3" { | 14 | test "divc3" { |
| 13 | try testDiv(f16, __divhc3); | 15 | try testDiv(f16, div_cf16); |
| 14 | try testDiv(f32, __divsc3); | 16 | try testDiv(f32, div_cf32); |
| 15 | try testDiv(f64, __divdc3); | 17 | try testDiv(f64, div_cf64); |
| 16 | try testDiv(f80, __divxc3); | 18 | try testDiv(f80, div_cf80); |
| 17 | try testDiv(f128, __divtc3); | 19 | try testDiv(f128, div_cf128); |
| 18 | } | 20 | } |
| 19 | 21 | ||
| 20 | fn testDiv(comptime T: type, comptime f: fn (T, T, T, T) callconv(.c) Complex(T)) !void { | 22 | fn testDiv(comptime T: type, comptime f: fn (Complex(T), Complex(T)) Complex(T)) !void { |
| 21 | { | 23 | { |
| 22 | const a: T = 1.0; | 24 | const result = f(.{ .real = 1.0, .imag = 0.0 }, .{ .real = -1.0, .imag = 0.0 }); |
| 23 | const b: T = 0.0; | ||
| 24 | const c: T = -1.0; | ||
| 25 | const d: T = 0.0; | ||
| 26 | |||
| 27 | const result = f(a, b, c, d); | ||
| 28 | try expect(result.real == -1.0); | 25 | try expect(result.real == -1.0); |
| 29 | try expect(result.imag == 0.0); | 26 | try expect(math.isNegativeZero(result.imag)); |
| 30 | } | 27 | } |
| 31 | { | 28 | { |
| 32 | const a: T = 1.0; | 29 | const result = f(.{ .real = 1.0, .imag = 0.0 }, .{ .real = -4.0, .imag = 0.0 }); |
| 33 | const b: T = 0.0; | ||
| 34 | const c: T = -4.0; | ||
| 35 | const d: T = 0.0; | ||
| 36 | |||
| 37 | const result = f(a, b, c, d); | ||
| 38 | try expect(result.real == -0.25); | 30 | try expect(result.real == -0.25); |
| 39 | try expect(result.imag == 0.0); | 31 | try expect(math.isNegativeZero(result.imag)); |
| 40 | } | 32 | } |
| 41 | { | 33 | { |
| 42 | // if the first operand is an infinity and the second operand is a finite number, then the | 34 | // if the first operand is an infinity and the second operand is a finite number, then the |
| 43 | // result of the / operator is an infinity; | 35 | // resultult of the / operator is an infinity; |
| 44 | const a: T = -math.inf(T); | 36 | const result = f(.{ .real = -math.inf(T), .imag = 0.0 }, .{ .real = -4.0, .imag = 1.0 }); |
| 45 | const b: T = 0.0; | 37 | try expect(math.isPositiveInf(result.real)); |
| 46 | const c: T = -4.0; | 38 | try expect(math.isPositiveInf(result.imag)); |
| 47 | const d: T = 1.0; | ||
| 48 | |||
| 49 | const result = f(a, b, c, d); | ||
| 50 | try expect(result.real == math.inf(T)); | ||
| 51 | try expect(result.imag == math.inf(T)); | ||
| 52 | } | 39 | } |
| 53 | { | 40 | { |
| 54 | // if the first operand is a finite number and the second operand is an infinity, then the | 41 | // if the first operand is a finite number and the second operand is an infinity, then the |
| 55 | // result of the / operator is a zero; | 42 | // result of the / operator is a zero; |
| 56 | const a: T = 17.2; | 43 | const result = f(.{ .real = 17.2, .imag = 0.0 }, .{ .real = -math.inf(T), .imag = 0.0 }); |
| 57 | const b: T = 0.0; | 44 | try expect(math.isNegativeZero(result.real)); |
| 58 | const c: T = -math.inf(T); | 45 | try expect(math.isNegativeZero(result.imag)); |
| 59 | const d: T = 0.0; | ||
| 60 | |||
| 61 | const result = f(a, b, c, d); | ||
| 62 | try expect(result.real == -0.0); | ||
| 63 | try expect(result.imag == 0.0); | ||
| 64 | } | 46 | } |
| 65 | { | 47 | { |
| 66 | // if the first operand is a nonzero finite number or an infinity and the second operand is | 48 | // if the first operand is a nonzero finite number or an infinity and the second operand is |
| 67 | // a zero, then the result of the / operator is an infinity | 49 | // a zero, then the result of the / operator is an infinity |
| 68 | const a: T = 1.1; | 50 | const result = f(.{ .real = 1.1, .imag = 0.1 }, .{ .real = 0.0, .imag = 0.0 }); |
| 69 | const b: T = 0.1; | 51 | try expect(math.isPositiveInf(result.real)); |
| 70 | const c: T = 0.0; | 52 | try expect(math.isPositiveInf(result.imag)); |
| 71 | const d: T = 0.0; | ||
| 72 | |||
| 73 | const result = f(a, b, c, d); | ||
| 74 | try expect(result.real == math.inf(T)); | ||
| 75 | try expect(result.imag == math.inf(T)); | ||
| 76 | } | 53 | } |
| 77 | } | 54 | } |
lib/compiler_rt/divdc3.zig deleted-13| ... | @@ -1,13 +0,0 @@ | ||
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 2 | const divc3 = @import("./divc3.zig"); | ||
| 3 | const Complex = @import("./mulc3.zig").Complex; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (@import("builtin").zig_backend != .stage2_c) { | ||
| 7 | symbol(&__divdc3, "__divdc3"); | ||
| 8 | } | ||
| 9 | } | ||
| 10 | |||
| 11 | pub fn __divdc3(a: f64, b: f64, c: f64, d: f64) callconv(.c) Complex(f64) { | ||
| 12 | return divc3.divc3(f64, a, b, c, d); | ||
| 13 | } | ||
lib/compiler_rt/divdf3.zig+4-4| ... | @@ -17,15 +17,15 @@ comptime { | ... | @@ -17,15 +17,15 @@ comptime { |
| 17 | } | 17 | } |
| 18 | } | 18 | } |
| 19 | 19 | ||
| 20 | pub fn __divdf3(a: f64, b: f64) callconv(.c) f64 { | 20 | fn __divdf3(a: compiler_rt.f64.Abi, b: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { |
| 21 | return div(a, b); | 21 | return compiler_rt.f64.toAbi(div_f64(compiler_rt.f64.fromAbi(a), compiler_rt.f64.fromAbi(b))); |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | fn __aeabi_ddiv(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 { | 24 | fn __aeabi_ddiv(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 { |
| 25 | return div(a, b); | 25 | return div_f64(a, b); |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | inline fn div(a: f64, b: f64) f64 { | 28 | pub fn div_f64(a: f64, b: f64) f64 { |
| 29 | const Z = @Int(.unsigned, 64); | 29 | const Z = @Int(.unsigned, 64); |
| 30 | const SignedZ = @Int(.signed, 64); | 30 | const SignedZ = @Int(.signed, 64); |
| 31 | 31 |
lib/compiler_rt/divdf3_test.zig+2-2| ... | @@ -6,7 +6,7 @@ const std = @import("std"); | ... | @@ -6,7 +6,7 @@ const std = @import("std"); |
| 6 | const math = std.math; | 6 | const math = std.math; |
| 7 | const testing = std.testing; | 7 | const testing = std.testing; |
| 8 | 8 | ||
| 9 | const __divdf3 = @import("divdf3.zig").__divdf3; | 9 | const div_f64 = @import("divdf3.zig").div_f64; |
| 10 | 10 | ||
| 11 | const nanRep: u64 = @as(u64, @bitCast(math.nan(f64))); | 11 | const nanRep: u64 = @as(u64, @bitCast(math.nan(f64))); |
| 12 | const infRep: u64 = @as(u64, @bitCast(math.inf(f64))); | 12 | const infRep: u64 = @as(u64, @bitCast(math.inf(f64))); |
| ... | @@ -30,7 +30,7 @@ fn compareResultD(result: f64, expected: u64) bool { | ... | @@ -30,7 +30,7 @@ fn compareResultD(result: f64, expected: u64) bool { |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | fn test__divdf3(a: f64, b: f64, expected: u64) !void { | 32 | fn test__divdf3(a: f64, b: f64, expected: u64) !void { |
| 33 | const x = __divdf3(a, b); | 33 | const x = div_f64(a, b); |
| 34 | const ret = compareResultD(x, expected); | 34 | const ret = compareResultD(x, expected); |
| 35 | try testing.expect(ret == true); | 35 | try testing.expect(ret == true); |
| 36 | } | 36 | } |
lib/compiler_rt/divhc3.zig deleted-14| ... | @@ -1,14 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const divc3 = @import("./divc3.zig"); | ||
| 4 | const Complex = @import("./mulc3.zig").Complex; | ||
| 5 | |||
| 6 | comptime { | ||
| 7 | if (@import("builtin").zig_backend != .stage2_c) { | ||
| 8 | symbol(&__divhc3, "__divhc3"); | ||
| 9 | } | ||
| 10 | } | ||
| 11 | |||
| 12 | pub fn __divhc3(a: f16, b: f16, c: f16, d: f16) callconv(.c) Complex(f16) { | ||
| 13 | return divc3.divc3(f16, a, b, c, d); | ||
| 14 | } | ||
lib/compiler_rt/divhf3.zig deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 2 | const divsf3 = @import("./divsf3.zig"); | ||
| 3 | |||
| 4 | comptime { | ||
| 5 | symbol(&__divhf3, "__divhf3"); | ||
| 6 | } | ||
| 7 | |||
| 8 | pub fn __divhf3(a: f16, b: f16) callconv(.c) f16 { | ||
| 9 | // TODO: more efficient implementation | ||
| 10 | return @floatCast(divsf3.__divsf3(a, b)); | ||
| 11 | } | ||
lib/compiler_rt/divmodei4.zig+1-1| ... | @@ -5,7 +5,7 @@ const std = @import("std"); | ... | @@ -5,7 +5,7 @@ const std = @import("std"); |
| 5 | 5 | ||
| 6 | const compiler_rt = @import("../compiler_rt.zig"); | 6 | const compiler_rt = @import("../compiler_rt.zig"); |
| 7 | const udivmod = @import("udivmodei4.zig").divmod; | 7 | const udivmod = @import("udivmodei4.zig").divmod; |
| 8 | const symbol = @import("../compiler_rt.zig").symbol; | 8 | const symbol = compiler_rt.symbol; |
| 9 | 9 | ||
| 10 | comptime { | 10 | comptime { |
| 11 | symbol(&__divei4, "__divei4"); | 11 | symbol(&__divei4, "__divei4"); |
lib/compiler_rt/divsc3.zig deleted-13| ... | @@ -1,13 +0,0 @@ | ||
| 1 | const divc3 = @import("./divc3.zig"); | ||
| 2 | const Complex = @import("./mulc3.zig").Complex; | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (@import("builtin").zig_backend != .stage2_c) { | ||
| 7 | symbol(&__divsc3, "__divsc3"); | ||
| 8 | } | ||
| 9 | } | ||
| 10 | |||
| 11 | pub fn __divsc3(a: f32, b: f32, c: f32, d: f32) callconv(.c) Complex(f32) { | ||
| 12 | return divc3.divc3(f32, a, b, c, d); | ||
| 13 | } | ||
lib/compiler_rt/divsf3.zig+13-4| ... | @@ -9,6 +9,7 @@ const symbol = compiler_rt.symbol; | ... | @@ -9,6 +9,7 @@ const symbol = compiler_rt.symbol; |
| 9 | const normalize = compiler_rt.normalize; | 9 | const normalize = compiler_rt.normalize; |
| 10 | 10 | ||
| 11 | comptime { | 11 | comptime { |
| 12 | symbol(&__divhf3, "__divhf3"); | ||
| 12 | if (compiler_rt.want_aeabi) { | 13 | if (compiler_rt.want_aeabi) { |
| 13 | symbol(&__aeabi_fdiv, "__aeabi_fdiv"); | 14 | symbol(&__aeabi_fdiv, "__aeabi_fdiv"); |
| 14 | } else { | 15 | } else { |
| ... | @@ -16,15 +17,23 @@ comptime { | ... | @@ -16,15 +17,23 @@ comptime { |
| 16 | } | 17 | } |
| 17 | } | 18 | } |
| 18 | 19 | ||
| 19 | pub fn __divsf3(a: f32, b: f32) callconv(.c) f32 { | 20 | fn __divhf3(a: compiler_rt.f16.Abi, b: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { |
| 20 | return div(a, b); | 21 | return compiler_rt.f16.toAbi(div_f16(compiler_rt.f16.fromAbi(a), compiler_rt.f16.fromAbi(b))); |
| 22 | } | ||
| 23 | pub fn div_f16(a: f16, b: f16) f16 { | ||
| 24 | // TODO: more efficient implementation | ||
| 25 | return @floatCast(div_f32(a, b)); | ||
| 26 | } | ||
| 27 | |||
| 28 | fn __divsf3(a: compiler_rt.f32.Abi, b: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { | ||
| 29 | return compiler_rt.f32.toAbi(div_f32(compiler_rt.f32.fromAbi(a), compiler_rt.f32.fromAbi(b))); | ||
| 21 | } | 30 | } |
| 22 | 31 | ||
| 23 | fn __aeabi_fdiv(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 { | 32 | fn __aeabi_fdiv(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 { |
| 24 | return div(a, b); | 33 | return div_f32(a, b); |
| 25 | } | 34 | } |
| 26 | 35 | ||
| 27 | inline fn div(a: f32, b: f32) f32 { | 36 | pub fn div_f32(a: f32, b: f32) f32 { |
| 28 | const Z = @Int(.unsigned, 32); | 37 | const Z = @Int(.unsigned, 32); |
| 29 | 38 | ||
| 30 | const significandBits = std.math.floatMantissaBits(f32); | 39 | const significandBits = std.math.floatMantissaBits(f32); |
lib/compiler_rt/divsf3_test.zig+2-2| ... | @@ -6,7 +6,7 @@ const std = @import("std"); | ... | @@ -6,7 +6,7 @@ const std = @import("std"); |
| 6 | const math = std.math; | 6 | const math = std.math; |
| 7 | const testing = std.testing; | 7 | const testing = std.testing; |
| 8 | 8 | ||
| 9 | const __divsf3 = @import("divsf3.zig").__divsf3; | 9 | const div_f32 = @import("divsf3.zig").div_f32; |
| 10 | 10 | ||
| 11 | const nanRep: u32 = @as(u32, @bitCast(math.nan(f32))); | 11 | const nanRep: u32 = @as(u32, @bitCast(math.nan(f32))); |
| 12 | const infRep: u32 = @as(u32, @bitCast(math.inf(f32))); | 12 | const infRep: u32 = @as(u32, @bitCast(math.inf(f32))); |
| ... | @@ -30,7 +30,7 @@ fn compareResultF(result: f32, expected: u32) bool { | ... | @@ -30,7 +30,7 @@ fn compareResultF(result: f32, expected: u32) bool { |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | fn test__divsf3(a: f32, b: f32, expected: u32) !void { | 32 | fn test__divsf3(a: f32, b: f32, expected: u32) !void { |
| 33 | const x = __divsf3(a, b); | 33 | const x = div_f32(a, b); |
| 34 | const ret = compareResultF(x, expected); | 34 | const ret = compareResultF(x, expected); |
| 35 | try testing.expect(ret == true); | 35 | try testing.expect(ret == true); |
| 36 | } | 36 | } |
lib/compiler_rt/divtc3.zig deleted-16| ... | @@ -1,16 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const divc3 = @import("./divc3.zig"); | ||
| 3 | const Complex = @import("./mulc3.zig").Complex; | ||
| 4 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 5 | |||
| 6 | comptime { | ||
| 7 | if (@import("builtin").zig_backend != .stage2_c) { | ||
| 8 | if (compiler_rt.want_ppc_abi) | ||
| 9 | symbol(&__divtc3, "__divkc3"); | ||
| 10 | symbol(&__divtc3, "__divtc3"); | ||
| 11 | } | ||
| 12 | } | ||
| 13 | |||
| 14 | pub fn __divtc3(a: f128, b: f128, c: f128, d: f128) callconv(.c) Complex(f128) { | ||
| 15 | return divc3.divc3(f128, a, b, c, d); | ||
| 16 | } | ||
lib/compiler_rt/divtf3.zig+6-5| ... | @@ -13,19 +13,20 @@ comptime { | ... | @@ -13,19 +13,20 @@ comptime { |
| 13 | symbol(&_Qp_div, "_Qp_div"); | 13 | symbol(&_Qp_div, "_Qp_div"); |
| 14 | } else if (compiler_rt.want_sparc32_abi) { | 14 | } else if (compiler_rt.want_sparc32_abi) { |
| 15 | symbol(&__divtf3, "_Q_div"); | 15 | symbol(&__divtf3, "_Q_div"); |
| 16 | } else { | ||
| 17 | symbol(&__divtf3, "__divtf3"); | ||
| 16 | } | 18 | } |
| 17 | symbol(&__divtf3, "__divtf3"); | ||
| 18 | } | 19 | } |
| 19 | 20 | ||
| 20 | pub fn __divtf3(a: f128, b: f128) callconv(.c) f128 { | 21 | fn __divtf3(a: compiler_rt.f128.Abi, b: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { |
| 21 | return div(a, b); | 22 | return compiler_rt.f128.toAbi(div_f128(compiler_rt.f128.fromAbi(a), compiler_rt.f128.fromAbi(b))); |
| 22 | } | 23 | } |
| 23 | 24 | ||
| 24 | fn _Qp_div(c: *f128, a: *const f128, b: *const f128) callconv(.c) void { | 25 | fn _Qp_div(c: *f128, a: *const f128, b: *const f128) callconv(.c) void { |
| 25 | c.* = div(a.*, b.*); | 26 | c.* = div_f128(a.*, b.*); |
| 26 | } | 27 | } |
| 27 | 28 | ||
| 28 | inline fn div(a: f128, b: f128) f128 { | 29 | pub fn div_f128(a: f128, b: f128) f128 { |
| 29 | const Z = @Int(.unsigned, 128); | 30 | const Z = @Int(.unsigned, 128); |
| 30 | 31 | ||
| 31 | const significandBits = std.math.floatMantissaBits(f128); | 32 | const significandBits = std.math.floatMantissaBits(f128); |
lib/compiler_rt/divtf3_test.zig+2-2| ... | @@ -2,7 +2,7 @@ const std = @import("std"); | ... | @@ -2,7 +2,7 @@ const std = @import("std"); |
| 2 | const math = std.math; | 2 | const math = std.math; |
| 3 | const testing = std.testing; | 3 | const testing = std.testing; |
| 4 | 4 | ||
| 5 | const __divtf3 = @import("divtf3.zig").__divtf3; | 5 | const div_f128 = @import("divtf3.zig").div_f128; |
| 6 | 6 | ||
| 7 | fn compareResultLD(result: f128, expectedHi: u64, expectedLo: u64) bool { | 7 | fn compareResultLD(result: f128, expectedHi: u64, expectedLo: u64) bool { |
| 8 | const rep: u128 = @bitCast(result); | 8 | const rep: u128 = @bitCast(result); |
| ... | @@ -24,7 +24,7 @@ fn compareResultLD(result: f128, expectedHi: u64, expectedLo: u64) bool { | ... | @@ -24,7 +24,7 @@ fn compareResultLD(result: f128, expectedHi: u64, expectedLo: u64) bool { |
| 24 | } | 24 | } |
| 25 | 25 | ||
| 26 | fn test__divtf3(a: f128, b: f128, expectedHi: u64, expectedLo: u64) !void { | 26 | fn test__divtf3(a: f128, b: f128, expectedHi: u64, expectedLo: u64) !void { |
| 27 | const x = __divtf3(a, b); | 27 | const x = div_f128(a, b); |
| 28 | const ret = compareResultLD(x, expectedHi, expectedLo); | 28 | const ret = compareResultLD(x, expectedHi, expectedLo); |
| 29 | try testing.expect(ret == true); | 29 | try testing.expect(ret == true); |
| 30 | } | 30 | } |
lib/compiler_rt/divxc3.zig deleted-13| ... | @@ -1,13 +0,0 @@ | ||
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 2 | const divc3 = @import("./divc3.zig"); | ||
| 3 | const Complex = @import("./mulc3.zig").Complex; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (@import("builtin").zig_backend != .stage2_c) { | ||
| 7 | symbol(&__divxc3, "__divxc3"); | ||
| 8 | } | ||
| 9 | } | ||
| 10 | |||
| 11 | pub fn __divxc3(a: f80, b: f80, c: f80, d: f80) callconv(.c) Complex(f80) { | ||
| 12 | return divc3.divc3(f80, a, b, c, d); | ||
| 13 | } | ||
lib/compiler_rt/divxf3.zig+4-1| ... | @@ -11,7 +11,10 @@ comptime { | ... | @@ -11,7 +11,10 @@ comptime { |
| 11 | symbol(&__divxf3, "__divxf3"); | 11 | symbol(&__divxf3, "__divxf3"); |
| 12 | } | 12 | } |
| 13 | 13 | ||
| 14 | pub fn __divxf3(a: f80, b: f80) callconv(.c) f80 { | 14 | fn __divxf3(a: compiler_rt.f80.Abi, b: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { |
| 15 | return compiler_rt.f80.toAbi(div_f80(compiler_rt.f80.fromAbi(a), compiler_rt.f80.fromAbi(b))); | ||
| 16 | } | ||
| 17 | pub fn div_f80(a: f80, b: f80) f80 { | ||
| 15 | const T = f80; | 18 | const T = f80; |
| 16 | const Z = @Int(.unsigned, @bitSizeOf(T)); | 19 | const Z = @Int(.unsigned, @bitSizeOf(T)); |
| 17 | 20 |
lib/compiler_rt/divxf3_test.zig+3-3| ... | @@ -2,7 +2,7 @@ const std = @import("std"); | ... | @@ -2,7 +2,7 @@ const std = @import("std"); |
| 2 | const math = std.math; | 2 | const math = std.math; |
| 3 | const testing = std.testing; | 3 | const testing = std.testing; |
| 4 | 4 | ||
| 5 | const __divxf3 = @import("divxf3.zig").__divxf3; | 5 | const div_f80 = @import("divxf3.zig").div_f80; |
| 6 | 6 | ||
| 7 | const nanRep: u80 = @as(u80, @bitCast(math.nan(f80))); | 7 | const nanRep: u80 = @as(u80, @bitCast(math.nan(f80))); |
| 8 | const infRep: u80 = @as(u80, @bitCast(math.inf(f80))); | 8 | const infRep: u80 = @as(u80, @bitCast(math.inf(f80))); |
| ... | @@ -19,14 +19,14 @@ fn compareResult(result: f80, expected: u80) bool { | ... | @@ -19,14 +19,14 @@ fn compareResult(result: f80, expected: u80) bool { |
| 19 | } | 19 | } |
| 20 | 20 | ||
| 21 | fn expect__divxf3_result(a: f80, b: f80, expected: u80) !void { | 21 | fn expect__divxf3_result(a: f80, b: f80, expected: u80) !void { |
| 22 | const x = __divxf3(a, b); | 22 | const x = div_f80(a, b); |
| 23 | const ret = compareResult(x, expected); | 23 | const ret = compareResult(x, expected); |
| 24 | try testing.expect(ret == true); | 24 | try testing.expect(ret == true); |
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | fn test__divxf3(a: f80, b: f80) !void { | 27 | fn test__divxf3(a: f80, b: f80) !void { |
| 28 | const integerBit = 1 << math.floatFractionalBits(f80); | 28 | const integerBit = 1 << math.floatFractionalBits(f80); |
| 29 | const x = __divxf3(a, b); | 29 | const x = div_f80(a, b); |
| 30 | 30 | ||
| 31 | // Next float (assuming normal, non-zero result) | 31 | // Next float (assuming normal, non-zero result) |
| 32 | const x_plus_eps: f80 = @bitCast((@as(u80, @bitCast(x)) + 1) | integerBit); | 32 | const x_plus_eps: f80 = @bitCast((@as(u80, @bitCast(x)) + 1) | integerBit); |
lib/compiler_rt/exp.zig+105-94| ... | @@ -14,26 +14,29 @@ const expect = std.testing.expect; | ... | @@ -14,26 +14,29 @@ const expect = std.testing.expect; |
| 14 | const expectEqual = std.testing.expectEqual; | 14 | const expectEqual = std.testing.expectEqual; |
| 15 | 15 | ||
| 16 | const compiler_rt = @import("../compiler_rt.zig"); | 16 | const compiler_rt = @import("../compiler_rt.zig"); |
| 17 | const symbol = @import("../compiler_rt.zig").symbol; | 17 | const symbol = compiler_rt.symbol; |
| 18 | 18 | ||
| 19 | comptime { | 19 | comptime { |
| 20 | symbol(&__exph, "__exph"); | 20 | symbol(&__exph, "__exph"); |
| 21 | symbol(&expf, "expf"); | 21 | symbol(&expf, "expf"); |
| 22 | symbol(&exp, "exp"); | 22 | symbol(&exp, "exp"); |
| 23 | symbol(&__expx, "__expx"); | 23 | symbol(&__expx, "__expx"); |
| 24 | if (compiler_rt.want_ppc_abi) { | 24 | symbol(&expq, "expf128"); |
| 25 | symbol(&expq, "expf128"); | ||
| 26 | } | ||
| 27 | symbol(&expq, "expq"); | ||
| 28 | symbol(&expl, "expl"); | 25 | symbol(&expl, "expl"); |
| 29 | } | 26 | } |
| 30 | 27 | ||
| 31 | pub fn __exph(a: f16) callconv(.c) f16 { | 28 | fn __exph(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { |
| 29 | return compiler_rt.f16.toAbi(exp_f16(compiler_rt.f16.fromAbi(x))); | ||
| 30 | } | ||
| 31 | pub fn exp_f16(x: f16) f16 { | ||
| 32 | // TODO: more efficient implementation | 32 | // TODO: more efficient implementation |
| 33 | return @floatCast(expf(a)); | 33 | return @floatCast(exp_f32(x)); |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | pub fn expf(x_: f32) callconv(.c) f32 { | 36 | fn expf(x: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { |
| 37 | return compiler_rt.f32.toAbi(exp_f32(compiler_rt.f32.fromAbi(x))); | ||
| 38 | } | ||
| 39 | pub fn exp_f32(x_: f32) f32 { | ||
| 37 | const half = [_]f32{ 0.5, -0.5 }; | 40 | const half = [_]f32{ 0.5, -0.5 }; |
| 38 | const ln2hi = 6.9314575195e-1; | 41 | const ln2hi = 6.9314575195e-1; |
| 39 | const ln2lo = 1.4286067653e-6; | 42 | const ln2lo = 1.4286067653e-6; |
| ... | @@ -108,7 +111,10 @@ pub fn expf(x_: f32) callconv(.c) f32 { | ... | @@ -108,7 +111,10 @@ pub fn expf(x_: f32) callconv(.c) f32 { |
| 108 | } | 111 | } |
| 109 | } | 112 | } |
| 110 | 113 | ||
| 111 | pub fn exp(x_: f64) callconv(.c) f64 { | 114 | fn exp(x: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { |
| 115 | return compiler_rt.f64.toAbi(exp_f64(compiler_rt.f64.fromAbi(x))); | ||
| 116 | } | ||
| 117 | pub fn exp_f64(x_: f64) f64 { | ||
| 112 | const half = [_]f64{ 0.5, -0.5 }; | 118 | const half = [_]f64{ 0.5, -0.5 }; |
| 113 | const ln2hi: f64 = 6.93147180369123816490e-01; | 119 | const ln2hi: f64 = 6.93147180369123816490e-01; |
| 114 | const ln2lo: f64 = 1.90821492927058770002e-10; | 120 | const ln2lo: f64 = 1.90821492927058770002e-10; |
| ... | @@ -189,116 +195,121 @@ pub fn exp(x_: f64) callconv(.c) f64 { | ... | @@ -189,116 +195,121 @@ pub fn exp(x_: f64) callconv(.c) f64 { |
| 189 | } | 195 | } |
| 190 | } | 196 | } |
| 191 | 197 | ||
| 192 | pub fn __expx(a: f80) callconv(.c) f80 { | 198 | fn __expx(x: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { |
| 199 | return compiler_rt.f80.toAbi(exp_f80(compiler_rt.f80.fromAbi(x))); | ||
| 200 | } | ||
| 201 | pub fn exp_f80(x: f80) f80 { | ||
| 193 | // TODO: more efficient implementation | 202 | // TODO: more efficient implementation |
| 194 | return @floatCast(expq(a)); | 203 | return @floatCast(exp_f128(x)); |
| 195 | } | 204 | } |
| 196 | 205 | ||
| 197 | const expq = @import("exp_f128.zig").exp; | 206 | fn expq(x: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { |
| 207 | return compiler_rt.f128.toAbi(exp_f128(compiler_rt.f128.fromAbi(x))); | ||
| 208 | } | ||
| 209 | pub const exp_f128 = @import("exp_f128.zig").exp; | ||
| 198 | 210 | ||
| 199 | pub fn expl(x: c_longdouble) callconv(.c) c_longdouble { | 211 | pub fn expl(x: c_longdouble) callconv(.c) c_longdouble { |
| 200 | switch (@typeInfo(c_longdouble).float.bits) { | 212 | switch (@typeInfo(c_longdouble).float.bits) { |
| 201 | 64 => return exp(x), | 213 | 64 => return exp_f64(x), |
| 202 | 80 => return __expx(x), | 214 | 80 => return exp_f80(x), |
| 203 | 128 => return expq(x), | 215 | 128 => return exp_f128(x), |
| 204 | else => @compileError("unreachable"), | 216 | else => comptime unreachable, |
| 205 | } | 217 | } |
| 206 | } | 218 | } |
| 207 | 219 | ||
| 208 | test "expf() special" { | 220 | test "expf() special" { |
| 209 | try expectEqual(expf(0.0), 1.0); | 221 | try expectEqual(exp_f32(0.0), 1.0); |
| 210 | try expectEqual(expf(-0.0), 1.0); | 222 | try expectEqual(exp_f32(-0.0), 1.0); |
| 211 | try expectEqual(expf(1.0), math.e); | 223 | try expectEqual(exp_f32(1.0), math.e); |
| 212 | try expectEqual(expf(math.ln2), 2.0); | 224 | try expectEqual(exp_f32(math.ln2), 2.0); |
| 213 | try expectEqual(expf(math.inf(f32)), math.inf(f32)); | 225 | try expectEqual(exp_f32(math.inf(f32)), math.inf(f32)); |
| 214 | try expect(math.isPositiveZero(expf(-math.inf(f32)))); | 226 | try expect(math.isPositiveZero(exp_f32(-math.inf(f32)))); |
| 215 | try expect(math.isNan(expf(math.nan(f32)))); | 227 | try expect(math.isNan(exp_f32(math.nan(f32)))); |
| 216 | try expect(math.isNan(expf(math.snan(f32)))); | 228 | try expect(math.isNan(exp_f32(math.snan(f32)))); |
| 217 | } | 229 | } |
| 218 | 230 | ||
| 219 | test "expf() sanity" { | 231 | test "expf() sanity" { |
| 220 | try expectEqual(expf(-0x1.0223a0p+3), 0x1.490320p-12); | 232 | try expectEqual(exp_f32(-0x1.0223a0p+3), 0x1.490320p-12); |
| 221 | try expectEqual(expf(0x1.161868p+2), 0x1.34712ap+6); | 233 | try expectEqual(exp_f32(0x1.161868p+2), 0x1.34712ap+6); |
| 222 | try expectEqual(expf(-0x1.0c34b4p+3), 0x1.e06b1ap-13); | 234 | try expectEqual(exp_f32(-0x1.0c34b4p+3), 0x1.e06b1ap-13); |
| 223 | try expectEqual(expf(-0x1.a206f0p+2), 0x1.7dd484p-10); | 235 | try expectEqual(exp_f32(-0x1.a206f0p+2), 0x1.7dd484p-10); |
| 224 | try expectEqual(expf(0x1.288bbcp+3), 0x1.4abc80p+13); | 236 | try expectEqual(exp_f32(0x1.288bbcp+3), 0x1.4abc80p+13); |
| 225 | try expectEqual(expf(0x1.52efd0p-1), 0x1.f04a9cp+0); | 237 | try expectEqual(exp_f32(0x1.52efd0p-1), 0x1.f04a9cp+0); |
| 226 | try expectEqual(expf(-0x1.a05cc8p-2), 0x1.54f1e0p-1); | 238 | try expectEqual(exp_f32(-0x1.a05cc8p-2), 0x1.54f1e0p-1); |
| 227 | try expectEqual(expf(0x1.1f9efap-1), 0x1.c0f628p+0); | 239 | try expectEqual(exp_f32(0x1.1f9efap-1), 0x1.c0f628p+0); |
| 228 | try expectEqual(expf(0x1.8c5db0p-1), 0x1.1599b2p+1); | 240 | try expectEqual(exp_f32(0x1.8c5db0p-1), 0x1.1599b2p+1); |
| 229 | try expectEqual(expf(-0x1.5b86eap-1), 0x1.03b572p-1); | 241 | try expectEqual(exp_f32(-0x1.5b86eap-1), 0x1.03b572p-1); |
| 230 | try expectEqual(expf(-0x1.57f25cp+2), 0x1.2fbea2p-8); | 242 | try expectEqual(exp_f32(-0x1.57f25cp+2), 0x1.2fbea2p-8); |
| 231 | try expectEqual(expf(0x1.c7d310p+3), 0x1.76eefp+20); | 243 | try expectEqual(exp_f32(0x1.c7d310p+3), 0x1.76eefp+20); |
| 232 | try expectEqual(expf(0x1.19be70p+4), 0x1.52d3dep+25); | 244 | try expectEqual(exp_f32(0x1.19be70p+4), 0x1.52d3dep+25); |
| 233 | try expectEqual(expf(-0x1.ab6d70p+3), 0x1.a88adep-20); | 245 | try expectEqual(exp_f32(-0x1.ab6d70p+3), 0x1.a88adep-20); |
| 234 | try expectEqual(expf(-0x1.5ac18ep+2), 0x1.22b328p-8); | 246 | try expectEqual(exp_f32(-0x1.5ac18ep+2), 0x1.22b328p-8); |
| 235 | try expectEqual(expf(-0x1.925982p-1), 0x1.d2acc0p-2); | 247 | try expectEqual(exp_f32(-0x1.925982p-1), 0x1.d2acc0p-2); |
| 236 | try expectEqual(expf(0x1.7221cep+3), 0x1.9c2ceap+16); | 248 | try expectEqual(exp_f32(0x1.7221cep+3), 0x1.9c2ceap+16); |
| 237 | try expectEqual(expf(0x1.11a0d4p+4), 0x1.980ee6p+24); | 249 | try expectEqual(exp_f32(0x1.11a0d4p+4), 0x1.980ee6p+24); |
| 238 | try expectEqual(expf(-0x1.ae41a2p+1), 0x1.1c28d0p-5); | 250 | try expectEqual(exp_f32(-0x1.ae41a2p+1), 0x1.1c28d0p-5); |
| 239 | try expectEqual(expf(-0x1.329154p+4), 0x1.47ef94p-28); | 251 | try expectEqual(exp_f32(-0x1.329154p+4), 0x1.47ef94p-28); |
| 240 | } | 252 | } |
| 241 | 253 | ||
| 242 | test "expf() boundary" { | 254 | test "expf() boundary" { |
| 243 | try expectEqual(expf(0x1.62e42ep+6), 0x1.ffff08p+127); // The last value before the result gets infinite | 255 | try expectEqual(exp_f32(0x1.62e42ep+6), 0x1.ffff08p+127); // The last value before the result gets infinite |
| 244 | try expectEqual(expf(0x1.62e430p+6), math.inf(f32)); // The first value that gives inf | 256 | try expectEqual(exp_f32(0x1.62e430p+6), math.inf(f32)); // The first value that gives inf |
| 245 | try expectEqual(expf(0x1.fffffep+127), math.inf(f32)); // Max input value | 257 | try expectEqual(exp_f32(0x1.fffffep+127), math.inf(f32)); // Max input value |
| 246 | try expectEqual(expf(0x1p-149), 1.0); // Min positive input value | 258 | try expectEqual(exp_f32(0x1p-149), 1.0); // Min positive input value |
| 247 | try expectEqual(expf(-0x1p-149), 1.0); // Min negative input value | 259 | try expectEqual(exp_f32(-0x1p-149), 1.0); // Min negative input value |
| 248 | try expectEqual(expf(0x1p-126), 1.0); // First positive subnormal input | 260 | try expectEqual(exp_f32(0x1p-126), 1.0); // First positive subnormal input |
| 249 | try expectEqual(expf(-0x1p-126), 1.0); // First negative subnormal input | 261 | try expectEqual(exp_f32(-0x1p-126), 1.0); // First negative subnormal input |
| 250 | try expectEqual(expf(-0x1.9fe368p+6), 0x1p-149); // The last value before the result flushes to zero | 262 | try expectEqual(exp_f32(-0x1.9fe368p+6), 0x1p-149); // The last value before the result flushes to zero |
| 251 | try expectEqual(expf(-0x1.9fe36ap+6), 0.0); // The first value at which the result flushes to zero | 263 | try expectEqual(exp_f32(-0x1.9fe36ap+6), 0.0); // The first value at which the result flushes to zero |
| 252 | try expectEqual(expf(-0x1.5d589ep+6), 0x1.00004cp-126); // The last value before the result flushes to subnormal | 264 | try expectEqual(exp_f32(-0x1.5d589ep+6), 0x1.00004cp-126); // The last value before the result flushes to subnormal |
| 253 | try expectEqual(expf(-0x1.5d58a0p+6), 0x1.ffff98p-127); // The first value for which the result flushes to subnormal | 265 | try expectEqual(exp_f32(-0x1.5d58a0p+6), 0x1.ffff98p-127); // The first value for which the result flushes to subnormal |
| 254 | |||
| 255 | } | 266 | } |
| 256 | 267 | ||
| 257 | test "exp() special" { | 268 | test "exp() special" { |
| 258 | try expectEqual(exp(0.0), 1.0); | 269 | try expectEqual(exp_f64(0.0), 1.0); |
| 259 | try expectEqual(exp(-0.0), 1.0); | 270 | try expectEqual(exp_f64(-0.0), 1.0); |
| 260 | // TODO: Accuracy error - off in the last bit in 64-bit, disagreeing with GCC | 271 | // TODO: Accuracy error - off in the last bit in 64-bit, disagreeing with GCC |
| 261 | // try expectEqual(exp(1.0), math.e); | 272 | // try expectEqual(exp(1.0), math.e); |
| 262 | try expectEqual(exp(math.ln2), 2.0); | 273 | try expectEqual(exp_f64(math.ln2), 2.0); |
| 263 | try expectEqual(exp(math.inf(f64)), math.inf(f64)); | 274 | try expectEqual(exp_f64(math.inf(f64)), math.inf(f64)); |
| 264 | try expect(math.isPositiveZero(exp(-math.inf(f64)))); | 275 | try expect(math.isPositiveZero(exp_f64(-math.inf(f64)))); |
| 265 | try expect(math.isNan(exp(math.nan(f64)))); | 276 | try expect(math.isNan(exp_f64(math.nan(f64)))); |
| 266 | try expect(math.isNan(exp(math.snan(f64)))); | 277 | try expect(math.isNan(exp_f64(math.snan(f64)))); |
| 267 | } | 278 | } |
| 268 | 279 | ||
| 269 | test "exp() sanity" { | 280 | test "exp() sanity" { |
| 270 | try expectEqual(exp(-0x1.02239f3c6a8f1p+3), 0x1.490327ea61235p-12); | 281 | try expectEqual(exp_f64(-0x1.02239f3c6a8f1p+3), 0x1.490327ea61235p-12); |
| 271 | try expectEqual(exp(0x1.161868e18bc67p+2), 0x1.34712ed238c04p+6); | 282 | try expectEqual(exp_f64(0x1.161868e18bc67p+2), 0x1.34712ed238c04p+6); |
| 272 | try expectEqual(exp(-0x1.0c34b3e01e6e7p+3), 0x1.e06b1b6c18e64p-13); | 283 | try expectEqual(exp_f64(-0x1.0c34b3e01e6e7p+3), 0x1.e06b1b6c18e64p-13); |
| 273 | try expectEqual(exp(-0x1.a206f0a19dcc4p+2), 0x1.7dd47f810e68cp-10); | 284 | try expectEqual(exp_f64(-0x1.a206f0a19dcc4p+2), 0x1.7dd47f810e68cp-10); |
| 274 | try expectEqual(exp(0x1.288bbb0d6a1e6p+3), 0x1.4abc77496e07ep+13); | 285 | try expectEqual(exp_f64(0x1.288bbb0d6a1e6p+3), 0x1.4abc77496e07ep+13); |
| 275 | try expectEqual(exp(0x1.52efd0cd80497p-1), 0x1.f04a9c1080500p+0); | 286 | try expectEqual(exp_f64(0x1.52efd0cd80497p-1), 0x1.f04a9c1080500p+0); |
| 276 | try expectEqual(exp(-0x1.a05cc754481d1p-2), 0x1.54f1e0fd3ea0dp-1); | 287 | try expectEqual(exp_f64(-0x1.a05cc754481d1p-2), 0x1.54f1e0fd3ea0dp-1); |
| 277 | try expectEqual(exp(0x1.1f9ef934745cbp-1), 0x1.c0f6266a6a547p+0); | 288 | try expectEqual(exp_f64(0x1.1f9ef934745cbp-1), 0x1.c0f6266a6a547p+0); |
| 278 | try expectEqual(exp(0x1.8c5db097f7442p-1), 0x1.1599b1d4a25fbp+1); | 289 | try expectEqual(exp_f64(0x1.8c5db097f7442p-1), 0x1.1599b1d4a25fbp+1); |
| 279 | try expectEqual(exp(-0x1.5b86ea8118a0ep-1), 0x1.03b5728a00229p-1); | 290 | try expectEqual(exp_f64(-0x1.5b86ea8118a0ep-1), 0x1.03b5728a00229p-1); |
| 280 | try expectEqual(exp(-0x1.57f25b2b5006dp+2), 0x1.2fbea6a01cab9p-8); | 291 | try expectEqual(exp_f64(-0x1.57f25b2b5006dp+2), 0x1.2fbea6a01cab9p-8); |
| 281 | try expectEqual(exp(0x1.c7d30fb825911p+3), 0x1.76eeed45a0634p+20); | 292 | try expectEqual(exp_f64(0x1.c7d30fb825911p+3), 0x1.76eeed45a0634p+20); |
| 282 | try expectEqual(exp(0x1.19be709de7505p+4), 0x1.52d3eb7be6844p+25); | 293 | try expectEqual(exp_f64(0x1.19be709de7505p+4), 0x1.52d3eb7be6844p+25); |
| 283 | try expectEqual(exp(-0x1.ab6d6fba96889p+3), 0x1.a88ae12f985d6p-20); | 294 | try expectEqual(exp_f64(-0x1.ab6d6fba96889p+3), 0x1.a88ae12f985d6p-20); |
| 284 | try expectEqual(exp(-0x1.5ac18e27084ddp+2), 0x1.22b327da9cca6p-8); | 295 | try expectEqual(exp_f64(-0x1.5ac18e27084ddp+2), 0x1.22b327da9cca6p-8); |
| 285 | try expectEqual(exp(-0x1.925981b093c41p-1), 0x1.d2acc046b55f7p-2); | 296 | try expectEqual(exp_f64(-0x1.925981b093c41p-1), 0x1.d2acc046b55f7p-2); |
| 286 | try expectEqual(exp(0x1.7221cd18455f5p+3), 0x1.9c2cde8699cfbp+16); | 297 | try expectEqual(exp_f64(0x1.7221cd18455f5p+3), 0x1.9c2cde8699cfbp+16); |
| 287 | try expectEqual(exp(0x1.11a0d4a51b239p+4), 0x1.980ef612ff182p+24); | 298 | try expectEqual(exp_f64(0x1.11a0d4a51b239p+4), 0x1.980ef612ff182p+24); |
| 288 | try expectEqual(exp(-0x1.ae41a1079de4dp+1), 0x1.1c28d16bb3222p-5); | 299 | try expectEqual(exp_f64(-0x1.ae41a1079de4dp+1), 0x1.1c28d16bb3222p-5); |
| 289 | try expectEqual(exp(-0x1.329153103b871p+4), 0x1.47efa6ddd0d22p-28); | 300 | try expectEqual(exp_f64(-0x1.329153103b871p+4), 0x1.47efa6ddd0d22p-28); |
| 290 | } | 301 | } |
| 291 | 302 | ||
| 292 | test "exp() boundary" { | 303 | test "exp() boundary" { |
| 293 | try expectEqual(exp(0x1.62e42fefa39efp+9), 0x1.fffffffffff2ap+1023); // The last value before the result gets infinite | 304 | try expectEqual(exp_f64(0x1.62e42fefa39efp+9), 0x1.fffffffffff2ap+1023); // The last value before the result gets infinite |
| 294 | try expectEqual(exp(0x1.62e42fefa39f0p+9), math.inf(f64)); // The first value that gives inf | 305 | try expectEqual(exp_f64(0x1.62e42fefa39f0p+9), math.inf(f64)); // The first value that gives inf |
| 295 | try expectEqual(exp(0x1.fffffffffffffp+1023), math.inf(f64)); // Max input value | 306 | try expectEqual(exp_f64(0x1.fffffffffffffp+1023), math.inf(f64)); // Max input value |
| 296 | try expectEqual(exp(0x1p-1074), 1.0); // Min positive input value | 307 | try expectEqual(exp_f64(0x1p-1074), 1.0); // Min positive input value |
| 297 | try expectEqual(exp(-0x1p-1074), 1.0); // Min negative input value | 308 | try expectEqual(exp_f64(-0x1p-1074), 1.0); // Min negative input value |
| 298 | try expectEqual(exp(0x1p-1022), 1.0); // First positive subnormal input | 309 | try expectEqual(exp_f64(0x1p-1022), 1.0); // First positive subnormal input |
| 299 | try expectEqual(exp(-0x1p-1022), 1.0); // First negative subnormal input | 310 | try expectEqual(exp_f64(-0x1p-1022), 1.0); // First negative subnormal input |
| 300 | try expectEqual(exp(-0x1.74910d52d3051p+9), 0x1p-1074); // The last value before the result flushes to zero | 311 | try expectEqual(exp_f64(-0x1.74910d52d3051p+9), 0x1p-1074); // The last value before the result flushes to zero |
| 301 | try expectEqual(exp(-0x1.74910d52d3052p+9), 0.0); // The first value at which the result flushes to zero | 312 | try expectEqual(exp_f64(-0x1.74910d52d3052p+9), 0.0); // The first value at which the result flushes to zero |
| 302 | try expectEqual(exp(-0x1.6232bdd7abcd2p+9), 0x1.000000000007cp-1022); // The last value before the result flushes to subnormal | 313 | try expectEqual(exp_f64(-0x1.6232bdd7abcd2p+9), 0x1.000000000007cp-1022); // The last value before the result flushes to subnormal |
| 303 | try expectEqual(exp(-0x1.6232bdd7abcd3p+9), 0x1.ffffffffffcf8p-1023); // The first value for which the result flushes to subnormal | 314 | try expectEqual(exp_f64(-0x1.6232bdd7abcd3p+9), 0x1.ffffffffffcf8p-1023); // The first value for which the result flushes to subnormal |
| 304 | } | 315 | } |
lib/compiler_rt/exp2.zig+85-73| ... | @@ -19,19 +19,22 @@ comptime { | ... | @@ -19,19 +19,22 @@ comptime { |
| 19 | symbol(&exp2f, "exp2f"); | 19 | symbol(&exp2f, "exp2f"); |
| 20 | symbol(&exp2, "exp2"); | 20 | symbol(&exp2, "exp2"); |
| 21 | symbol(&__exp2x, "__exp2x"); | 21 | symbol(&__exp2x, "__exp2x"); |
| 22 | if (compiler_rt.want_ppc_abi) { | 22 | symbol(&exp2q, "exp2f128"); |
| 23 | symbol(&exp2q, "exp2f128"); | ||
| 24 | } | ||
| 25 | symbol(&exp2q, "exp2q"); | ||
| 26 | symbol(&exp2l, "exp2l"); | 23 | symbol(&exp2l, "exp2l"); |
| 27 | } | 24 | } |
| 28 | 25 | ||
| 29 | pub fn __exp2h(x: f16) callconv(.c) f16 { | 26 | fn __exp2h(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { |
| 27 | return compiler_rt.f16.toAbi(exp2_f16(compiler_rt.f16.fromAbi(x))); | ||
| 28 | } | ||
| 29 | pub fn exp2_f16(x: f16) f16 { | ||
| 30 | // TODO: more efficient implementation | 30 | // TODO: more efficient implementation |
| 31 | return @floatCast(exp2f(x)); | 31 | return @floatCast(exp2_f32(x)); |
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | pub fn exp2f(x: f32) callconv(.c) f32 { | 34 | fn exp2f(x: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { |
| 35 | return compiler_rt.f32.toAbi(exp2_f32(compiler_rt.f32.fromAbi(x))); | ||
| 36 | } | ||
| 37 | pub fn exp2_f32(x: f32) f32 { | ||
| 35 | const tblsiz: u32 = @intCast(exp2ft.len); | 38 | const tblsiz: u32 = @intCast(exp2ft.len); |
| 36 | const redux: f32 = 0x1.8p23 / @as(f32, @floatFromInt(tblsiz)); | 39 | const redux: f32 = 0x1.8p23 / @as(f32, @floatFromInt(tblsiz)); |
| 37 | const P1: f32 = 0x1.62e430p-1; | 40 | const P1: f32 = 0x1.62e430p-1; |
| ... | @@ -88,7 +91,10 @@ pub fn exp2f(x: f32) callconv(.c) f32 { | ... | @@ -88,7 +91,10 @@ pub fn exp2f(x: f32) callconv(.c) f32 { |
| 88 | return @floatCast(r * uk); | 91 | return @floatCast(r * uk); |
| 89 | } | 92 | } |
| 90 | 93 | ||
| 91 | pub fn exp2(x: f64) callconv(.c) f64 { | 94 | fn exp2(x: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { |
| 95 | return compiler_rt.f64.toAbi(exp2_f64(compiler_rt.f64.fromAbi(x))); | ||
| 96 | } | ||
| 97 | pub fn exp2_f64(x: f64) f64 { | ||
| 92 | const tblsiz: u32 = @intCast(exp2dt.len / 2); | 98 | const tblsiz: u32 = @intCast(exp2dt.len / 2); |
| 93 | const redux: f64 = 0x1.8p52 / @as(f64, @floatFromInt(tblsiz)); | 99 | const redux: f64 = 0x1.8p52 / @as(f64, @floatFromInt(tblsiz)); |
| 94 | const P1: f64 = 0x1.62e42fefa39efp-1; | 100 | const P1: f64 = 0x1.62e42fefa39efp-1; |
| ... | @@ -156,19 +162,25 @@ pub fn exp2(x: f64) callconv(.c) f64 { | ... | @@ -156,19 +162,25 @@ pub fn exp2(x: f64) callconv(.c) f64 { |
| 156 | return math.scalbn(r, ik); | 162 | return math.scalbn(r, ik); |
| 157 | } | 163 | } |
| 158 | 164 | ||
| 159 | pub fn __exp2x(x: f80) callconv(.c) f80 { | 165 | fn __exp2x(x: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { |
| 166 | return compiler_rt.f80.toAbi(exp2_f80(compiler_rt.f80.fromAbi(x))); | ||
| 167 | } | ||
| 168 | pub fn exp2_f80(x: f80) f80 { | ||
| 160 | // TODO: more efficient implementation | 169 | // TODO: more efficient implementation |
| 161 | return @floatCast(exp2q(x)); | 170 | return @floatCast(exp2_f128(x)); |
| 162 | } | 171 | } |
| 163 | 172 | ||
| 164 | pub const exp2q = @import("exp_f128.zig").exp2; | 173 | fn exp2q(x: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { |
| 174 | return compiler_rt.f128.toAbi(exp2_f128(compiler_rt.f128.fromAbi(x))); | ||
| 175 | } | ||
| 176 | pub const exp2_f128 = @import("exp_f128.zig").exp2; | ||
| 165 | 177 | ||
| 166 | pub fn exp2l(x: c_longdouble) callconv(.c) c_longdouble { | 178 | pub fn exp2l(x: c_longdouble) callconv(.c) c_longdouble { |
| 167 | switch (@typeInfo(c_longdouble).float.bits) { | 179 | switch (@typeInfo(c_longdouble).float.bits) { |
| 168 | 64 => return exp2(x), | 180 | 64 => return exp2_f64(x), |
| 169 | 80 => return __exp2x(x), | 181 | 80 => return exp2_f80(x), |
| 170 | 128 => return exp2q(x), | 182 | 128 => return exp2_f128(x), |
| 171 | else => @compileError("unreachable"), | 183 | else => comptime unreachable, |
| 172 | } | 184 | } |
| 173 | } | 185 | } |
| 174 | 186 | ||
| ... | @@ -452,77 +464,77 @@ const exp2dt = [_]f64{ | ... | @@ -452,77 +464,77 @@ const exp2dt = [_]f64{ |
| 452 | }; | 464 | }; |
| 453 | 465 | ||
| 454 | test "exp2f() special" { | 466 | test "exp2f() special" { |
| 455 | try expectEqual(exp2f(0.0), 1.0); | 467 | try expectEqual(exp2_f32(0.0), 1.0); |
| 456 | try expectEqual(exp2f(-0.0), 1.0); | 468 | try expectEqual(exp2_f32(-0.0), 1.0); |
| 457 | try expectEqual(exp2f(1.0), 2.0); | 469 | try expectEqual(exp2_f32(1.0), 2.0); |
| 458 | try expectEqual(exp2f(-1.0), 0.5); | 470 | try expectEqual(exp2_f32(-1.0), 0.5); |
| 459 | try expectEqual(exp2f(math.inf(f32)), math.inf(f32)); | 471 | try expectEqual(exp2_f32(math.inf(f32)), math.inf(f32)); |
| 460 | try expect(math.isPositiveZero(exp2f(-math.inf(f32)))); | 472 | try expect(math.isPositiveZero(exp2_f32(-math.inf(f32)))); |
| 461 | try expect(math.isNan(exp2f(math.nan(f32)))); | 473 | try expect(math.isNan(exp2_f32(math.nan(f32)))); |
| 462 | try expect(math.isNan(exp2f(math.snan(f32)))); | 474 | try expect(math.isNan(exp2_f32(math.snan(f32)))); |
| 463 | } | 475 | } |
| 464 | 476 | ||
| 465 | test "exp2f() sanity" { | 477 | test "exp2f() sanity" { |
| 466 | try expectEqual(exp2f(-0x1.0223a0p+3), 0x1.e8d134p-9); | 478 | try expectEqual(exp2_f32(-0x1.0223a0p+3), 0x1.e8d134p-9); |
| 467 | try expectEqual(exp2f(0x1.161868p+2), 0x1.453672p+4); | 479 | try expectEqual(exp2_f32(0x1.161868p+2), 0x1.453672p+4); |
| 468 | try expectEqual(exp2f(-0x1.0c34b4p+3), 0x1.890ca0p-9); | 480 | try expectEqual(exp2_f32(-0x1.0c34b4p+3), 0x1.890ca0p-9); |
| 469 | try expectEqual(exp2f(-0x1.a206f0p+2), 0x1.622d4ep-7); | 481 | try expectEqual(exp2_f32(-0x1.a206f0p+2), 0x1.622d4ep-7); |
| 470 | try expectEqual(exp2f(0x1.288bbcp+3), 0x1.340ecep+9); | 482 | try expectEqual(exp2_f32(0x1.288bbcp+3), 0x1.340ecep+9); |
| 471 | try expectEqual(exp2f(0x1.52efd0p-1), 0x1.950eeep+0); | 483 | try expectEqual(exp2_f32(0x1.52efd0p-1), 0x1.950eeep+0); |
| 472 | try expectEqual(exp2f(-0x1.a05cc8p-2), 0x1.824056p-1); | 484 | try expectEqual(exp2_f32(-0x1.a05cc8p-2), 0x1.824056p-1); |
| 473 | try expectEqual(exp2f(0x1.1f9efap-1), 0x1.79dfa2p+0); | 485 | try expectEqual(exp2_f32(0x1.1f9efap-1), 0x1.79dfa2p+0); |
| 474 | try expectEqual(exp2f(0x1.8c5db0p-1), 0x1.b5ceacp+0); | 486 | try expectEqual(exp2_f32(0x1.8c5db0p-1), 0x1.b5ceacp+0); |
| 475 | try expectEqual(exp2f(-0x1.5b86eap-1), 0x1.3fd8bap-1); | 487 | try expectEqual(exp2_f32(-0x1.5b86eap-1), 0x1.3fd8bap-1); |
| 476 | } | 488 | } |
| 477 | 489 | ||
| 478 | test "exp2f() boundary" { | 490 | test "exp2f() boundary" { |
| 479 | try expectEqual(exp2f(0x1.fffffep+6), 0x1.ffff4ep+127); // The last value before the result gets infinite | 491 | try expectEqual(exp2_f32(0x1.fffffep+6), 0x1.ffff4ep+127); // The last value before the result gets infinite |
| 480 | try expectEqual(exp2f(0x1p+7), math.inf(f32)); // The first value that gives infinite result | 492 | try expectEqual(exp2_f32(0x1p+7), math.inf(f32)); // The first value that gives infinite result |
| 481 | try expectEqual(exp2f(-0x1.2bccccp+7), 0x1p-149); // The last value before the result flushes to zero | 493 | try expectEqual(exp2_f32(-0x1.2bccccp+7), 0x1p-149); // The last value before the result flushes to zero |
| 482 | try expectEqual(exp2f(-0x1.2cp+7), 0); // The first value at which the result flushes to zero | 494 | try expectEqual(exp2_f32(-0x1.2cp+7), 0); // The first value at which the result flushes to zero |
| 483 | try expectEqual(exp2f(-0x1.f8p+6), 0x1p-126); // The last value before the result flushes to subnormal | 495 | try expectEqual(exp2_f32(-0x1.f8p+6), 0x1p-126); // The last value before the result flushes to subnormal |
| 484 | try expectEqual(exp2f(-0x1.f80002p+6), 0x1.ffff50p-127); // The first value for which the result flushes to subnormal | 496 | try expectEqual(exp2_f32(-0x1.f80002p+6), 0x1.ffff50p-127); // The first value for which the result flushes to subnormal |
| 485 | try expectEqual(exp2f(0x1.fffffep+127), math.inf(f32)); // Max input value | 497 | try expectEqual(exp2_f32(0x1.fffffep+127), math.inf(f32)); // Max input value |
| 486 | try expectEqual(exp2f(0x1p-149), 1); // Min positive input value | 498 | try expectEqual(exp2_f32(0x1p-149), 1); // Min positive input value |
| 487 | try expectEqual(exp2f(-0x1p-149), 1); // Min negative input value | 499 | try expectEqual(exp2_f32(-0x1p-149), 1); // Min negative input value |
| 488 | try expectEqual(exp2f(0x1p-126), 1); // First positive subnormal input | 500 | try expectEqual(exp2_f32(0x1p-126), 1); // First positive subnormal input |
| 489 | try expectEqual(exp2f(-0x1p-126), 1); // First negative subnormal input | 501 | try expectEqual(exp2_f32(-0x1p-126), 1); // First negative subnormal input |
| 490 | } | 502 | } |
| 491 | 503 | ||
| 492 | test "exp2() special" { | 504 | test "exp2() special" { |
| 493 | try expectEqual(exp2(0.0), 1.0); | 505 | try expectEqual(exp2_f64(0.0), 1.0); |
| 494 | try expectEqual(exp2(-0.0), 1.0); | 506 | try expectEqual(exp2_f64(-0.0), 1.0); |
| 495 | try expectEqual(exp2(1.0), 2.0); | 507 | try expectEqual(exp2_f64(1.0), 2.0); |
| 496 | try expectEqual(exp2(-1.0), 0.5); | 508 | try expectEqual(exp2_f64(-1.0), 0.5); |
| 497 | try expectEqual(exp2(math.inf(f64)), math.inf(f64)); | 509 | try expectEqual(exp2_f64(math.inf(f64)), math.inf(f64)); |
| 498 | try expect(math.isPositiveZero(exp2(-math.inf(f64)))); | 510 | try expect(math.isPositiveZero(exp2_f64(-math.inf(f64)))); |
| 499 | try expect(math.isNan(exp2(math.nan(f64)))); | 511 | try expect(math.isNan(exp2_f64(math.nan(f64)))); |
| 500 | try expect(math.isNan(exp2(math.snan(f64)))); | 512 | try expect(math.isNan(exp2_f64(math.snan(f64)))); |
| 501 | } | 513 | } |
| 502 | 514 | ||
| 503 | test "exp2() sanity" { | 515 | test "exp2() sanity" { |
| 504 | try expectEqual(exp2(-0x1.02239f3c6a8f1p+3), 0x1.e8d13c396f452p-9); | 516 | try expectEqual(exp2_f64(-0x1.02239f3c6a8f1p+3), 0x1.e8d13c396f452p-9); |
| 505 | try expectEqual(exp2(0x1.161868e18bc67p+2), 0x1.4536746bb6f12p+4); | 517 | try expectEqual(exp2_f64(0x1.161868e18bc67p+2), 0x1.4536746bb6f12p+4); |
| 506 | try expectEqual(exp2(-0x1.0c34b3e01e6e7p+3), 0x1.890ca0c00b9a2p-9); | 518 | try expectEqual(exp2_f64(-0x1.0c34b3e01e6e7p+3), 0x1.890ca0c00b9a2p-9); |
| 507 | try expectEqual(exp2(-0x1.a206f0a19dcc4p+2), 0x1.622d4b0ebc6c1p-7); | 519 | try expectEqual(exp2_f64(-0x1.a206f0a19dcc4p+2), 0x1.622d4b0ebc6c1p-7); |
| 508 | try expectEqual(exp2(0x1.288bbb0d6a1e6p+3), 0x1.340ec7f3e607ep+9); | 520 | try expectEqual(exp2_f64(0x1.288bbb0d6a1e6p+3), 0x1.340ec7f3e607ep+9); |
| 509 | try expectEqual(exp2(0x1.52efd0cd80497p-1), 0x1.950eef4bc5451p+0); | 521 | try expectEqual(exp2_f64(0x1.52efd0cd80497p-1), 0x1.950eef4bc5451p+0); |
| 510 | try expectEqual(exp2(-0x1.a05cc754481d1p-2), 0x1.824056efc687cp-1); | 522 | try expectEqual(exp2_f64(-0x1.a05cc754481d1p-2), 0x1.824056efc687cp-1); |
| 511 | try expectEqual(exp2(0x1.1f9ef934745cbp-1), 0x1.79dfa14ab121ep+0); | 523 | try expectEqual(exp2_f64(0x1.1f9ef934745cbp-1), 0x1.79dfa14ab121ep+0); |
| 512 | try expectEqual(exp2(0x1.8c5db097f7442p-1), 0x1.b5cead2247372p+0); | 524 | try expectEqual(exp2_f64(0x1.8c5db097f7442p-1), 0x1.b5cead2247372p+0); |
| 513 | try expectEqual(exp2(-0x1.5b86ea8118a0ep-1), 0x1.3fd8ba33216b9p-1); | 525 | try expectEqual(exp2_f64(-0x1.5b86ea8118a0ep-1), 0x1.3fd8ba33216b9p-1); |
| 514 | } | 526 | } |
| 515 | 527 | ||
| 516 | test "exp2() boundary" { | 528 | test "exp2() boundary" { |
| 517 | try expectEqual(exp2(0x1.fffffffffffffp+9), 0x1.ffffffffffd3ap+1023); // The last value before the result gets infinite | 529 | try expectEqual(exp2_f64(0x1.fffffffffffffp+9), 0x1.ffffffffffd3ap+1023); // The last value before the result gets infinite |
| 518 | try expectEqual(exp2(0x1p+10), math.inf(f64)); // The first value that gives infinite result | 530 | try expectEqual(exp2_f64(0x1p+10), math.inf(f64)); // The first value that gives infinite result |
| 519 | try expectEqual(exp2(-0x1.0cbffffffffffp+10), 0x1p-1074); // The last value before the result flushes to zero | 531 | try expectEqual(exp2_f64(-0x1.0cbffffffffffp+10), 0x1p-1074); // The last value before the result flushes to zero |
| 520 | try expectEqual(exp2(-0x1.0ccp+10), 0); // The first value at which the result flushes to zero | 532 | try expectEqual(exp2_f64(-0x1.0ccp+10), 0); // The first value at which the result flushes to zero |
| 521 | try expectEqual(exp2(-0x1.ffp+9), 0x1p-1022); // The last value before the result flushes to subnormal | 533 | try expectEqual(exp2_f64(-0x1.ffp+9), 0x1p-1022); // The last value before the result flushes to subnormal |
| 522 | try expectEqual(exp2(-0x1.ff00000000001p+9), 0x1.ffffffffffd3ap-1023); // The first value for which the result flushes to subnormal | 534 | try expectEqual(exp2_f64(-0x1.ff00000000001p+9), 0x1.ffffffffffd3ap-1023); // The first value for which the result flushes to subnormal |
| 523 | try expectEqual(exp2(0x1.fffffffffffffp+1023), math.inf(f64)); // Max input value | 535 | try expectEqual(exp2_f64(0x1.fffffffffffffp+1023), math.inf(f64)); // Max input value |
| 524 | try expectEqual(exp2(0x1p-1074), 1); // Min positive input value | 536 | try expectEqual(exp2_f64(0x1p-1074), 1); // Min positive input value |
| 525 | try expectEqual(exp2(-0x1p-1074), 1); // Min negative input value | 537 | try expectEqual(exp2_f64(-0x1p-1074), 1); // Min negative input value |
| 526 | try expectEqual(exp2(0x1p-1022), 1); // First positive subnormal input | 538 | try expectEqual(exp2_f64(0x1p-1022), 1); // First positive subnormal input |
| 527 | try expectEqual(exp2(-0x1p-1022), 1); // First negative subnormal input | 539 | try expectEqual(exp2_f64(-0x1p-1022), 1); // First negative subnormal input |
| 528 | } | 540 | } |
lib/compiler_rt/exp_f128.zig+2-2| ... | @@ -26,7 +26,7 @@ const exp_f128 = @This(); | ... | @@ -26,7 +26,7 @@ const exp_f128 = @This(); |
| 26 | const std = @import("std"); | 26 | const std = @import("std"); |
| 27 | const math = std.math; | 27 | const math = std.math; |
| 28 | 28 | ||
| 29 | pub fn exp(x: f128) callconv(.c) f128 { | 29 | pub fn exp(x: f128) f128 { |
| 30 | if (!math.isFinite(x)) { | 30 | if (!math.isFinite(x)) { |
| 31 | if (math.isNan(x)) { | 31 | if (math.isNan(x)) { |
| 32 | if (math.isSignalNan(x)) math.raiseInvalid(); | 32 | if (math.isSignalNan(x)) math.raiseInvalid(); |
| ... | @@ -91,7 +91,7 @@ fn expPoly(r_hi: f128, r_lo: f128) f128 { | ... | @@ -91,7 +91,7 @@ fn expPoly(r_hi: f128, r_lo: f128) f128 { |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | /// Computes 2^x | 93 | /// Computes 2^x |
| 94 | pub fn exp2(x: f128) callconv(.c) f128 { | 94 | pub fn exp2(x: f128) f128 { |
| 95 | if (!math.isFinite(x)) { | 95 | if (!math.isFinite(x)) { |
| 96 | if (math.isNan(x)) { | 96 | if (math.isNan(x)) { |
| 97 | if (math.isSignalNan(x)) math.raiseInvalid(); | 97 | if (math.isSignalNan(x)) math.raiseInvalid(); |
lib/compiler_rt/extenddftf2.zig deleted-22| ... | @@ -1,22 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const extendf = @import("./extendf.zig").extendf; | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_ppc_abi) { | ||
| 7 | symbol(&__extenddftf2, "__extenddfkf2"); | ||
| 8 | } else if (compiler_rt.want_sparc64_abi) { | ||
| 9 | symbol(&_Qp_dtoq, "_Qp_dtoq"); | ||
| 10 | } else if (compiler_rt.want_sparc32_abi) { | ||
| 11 | symbol(&__extenddftf2, "_Q_dtoq"); | ||
| 12 | } | ||
| 13 | symbol(&__extenddftf2, "__extenddftf2"); | ||
| 14 | } | ||
| 15 | |||
| 16 | pub fn __extenddftf2(a: f64) callconv(.c) f128 { | ||
| 17 | return extendf(f128, f64, @as(u64, @bitCast(a))); | ||
| 18 | } | ||
| 19 | |||
| 20 | fn _Qp_dtoq(c: *f128, a: f64) callconv(.c) void { | ||
| 21 | c.* = extendf(f128, f64, @as(u64, @bitCast(a))); | ||
| 22 | } | ||
lib/compiler_rt/extenddfxf2.zig deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const extend_f80 = @import("./extendf.zig").extend_f80; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__extenddfxf2, "__extenddfxf2"); | ||
| 7 | } | ||
| 8 | |||
| 9 | pub fn __extenddfxf2(a: f64) callconv(.c) f80 { | ||
| 10 | return extend_f80(f64, @as(u64, @bitCast(a))); | ||
| 11 | } | ||
lib/compiler_rt/extendf.zig+174-7| ... | @@ -1,10 +1,175 @@ | ... | @@ -1,10 +1,175 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | 2 | ||
| 3 | pub inline fn extendf( | 3 | const compiler_rt = @import("../compiler_rt.zig"); |
| 4 | comptime dst_t: type, | 4 | const symbol = compiler_rt.symbol; |
| 5 | comptime src_t: type, | 5 | |
| 6 | a: @Int(.unsigned, @typeInfo(src_t).float.bits), | 6 | comptime { |
| 7 | ) dst_t { | 7 | if (compiler_rt.want_aeabi) { |
| 8 | if (compiler_rt.gnu_f16_abi) { | ||
| 9 | symbol(&__aeabi_h2f, "__gnu_h2f_ieee"); | ||
| 10 | } else { | ||
| 11 | symbol(&__aeabi_h2f, "__aeabi_h2f"); | ||
| 12 | } | ||
| 13 | } else if (compiler_rt.gnu_f16_abi) { | ||
| 14 | symbol(&__extendhfsf2, "__gnu_h2f_ieee"); | ||
| 15 | } | ||
| 16 | symbol(&__extendhfsf2, "__extendhfsf2"); | ||
| 17 | symbol(&__extendhfdf2, "__extendhfdf2"); | ||
| 18 | symbol(&__extendhfxf2, "__extendhfxf2"); | ||
| 19 | if (compiler_rt.want_ppc_abi) { | ||
| 20 | symbol(&__extendhftf2, "__extendhfkf2"); | ||
| 21 | } else { | ||
| 22 | symbol(&__extendhftf2, "__extendhftf2"); | ||
| 23 | } | ||
| 24 | |||
| 25 | if (compiler_rt.want_aeabi) { | ||
| 26 | symbol(&__aeabi_f2d, "__aeabi_f2d"); | ||
| 27 | } else { | ||
| 28 | symbol(&__extendsfdf2, "__extendsfdf2"); | ||
| 29 | } | ||
| 30 | symbol(&__extendsfxf2, "__extendsfxf2"); | ||
| 31 | if (compiler_rt.want_ppc_abi) { | ||
| 32 | symbol(&__extendsftf2, "__extendsfkf2"); | ||
| 33 | } else if (compiler_rt.want_sparc64_abi) { | ||
| 34 | symbol(&_Qp_stoq, "_Qp_stoq"); | ||
| 35 | } else if (compiler_rt.want_sparc32_abi) { | ||
| 36 | symbol(&__extendsftf2, "_Q_stoq"); | ||
| 37 | } else { | ||
| 38 | symbol(&__extendsftf2, "__extendsftf2"); | ||
| 39 | } | ||
| 40 | |||
| 41 | symbol(&__extenddfxf2, "__extenddfxf2"); | ||
| 42 | if (compiler_rt.want_ppc_abi) { | ||
| 43 | symbol(&__extenddftf2, "__extenddfkf2"); | ||
| 44 | } else if (compiler_rt.want_sparc64_abi) { | ||
| 45 | symbol(&_Qp_dtoq, "_Qp_dtoq"); | ||
| 46 | } else if (compiler_rt.want_sparc32_abi) { | ||
| 47 | symbol(&__extenddftf2, "_Q_dtoq"); | ||
| 48 | } else { | ||
| 49 | symbol(&__extenddftf2, "__extenddftf2"); | ||
| 50 | } | ||
| 51 | |||
| 52 | if (compiler_rt.want_ppc_abi) { | ||
| 53 | symbol(&__extendxftf2, "__extendxfkf2"); | ||
| 54 | } else { | ||
| 55 | symbol(&__extendxftf2, "__extendxftf2"); | ||
| 56 | } | ||
| 57 | } | ||
| 58 | |||
| 59 | fn __extendhfsf2(a: compiler_rt.f16Conv(f32).Abi) callconv(.c) compiler_rt.f32.Abi { | ||
| 60 | return compiler_rt.f32.toAbi(f32_floatCast_f16(compiler_rt.f16Conv(f32).fromAbi(a))); | ||
| 61 | } | ||
| 62 | fn __aeabi_h2f(a: u16) callconv(.{ .arm_aapcs = .{} }) u32 { | ||
| 63 | return @bitCast(f32_floatCast_f16(@bitCast(a))); | ||
| 64 | } | ||
| 65 | pub fn f32_floatCast_f16(a: f16) f32 { | ||
| 66 | return extendf(f32, f16, a); | ||
| 67 | } | ||
| 68 | |||
| 69 | fn __extendhfdf2(a: compiler_rt.f16Conv(f64).Abi) callconv(.c) compiler_rt.f64.Abi { | ||
| 70 | return compiler_rt.f64.toAbi(f64_floatCast_f16(compiler_rt.f16Conv(f64).fromAbi(a))); | ||
| 71 | } | ||
| 72 | pub fn f64_floatCast_f16(a: f16) f64 { | ||
| 73 | return extendf(f64, f16, a); | ||
| 74 | } | ||
| 75 | |||
| 76 | fn __extendhfxf2(a: compiler_rt.f16Conv(f80).Abi) callconv(.c) compiler_rt.f80.Abi { | ||
| 77 | return compiler_rt.f80.toAbi(f80_floatCast_f16(compiler_rt.f16Conv(f80).fromAbi(a))); | ||
| 78 | } | ||
| 79 | pub fn f80_floatCast_f16(a: f16) f80 { | ||
| 80 | return extend_f80(f16, a); | ||
| 81 | } | ||
| 82 | |||
| 83 | fn __extendhftf2(a: compiler_rt.f16Conv(f128).Abi) callconv(.c) compiler_rt.f128.Abi { | ||
| 84 | return compiler_rt.f128.toAbi(f128_floatCast_f16(compiler_rt.f16Conv(f128).fromAbi(a))); | ||
| 85 | } | ||
| 86 | pub fn f128_floatCast_f16(a: f16) f128 { | ||
| 87 | return extendf(f128, f16, a); | ||
| 88 | } | ||
| 89 | |||
| 90 | fn __extendsfdf2(a: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f64.Abi { | ||
| 91 | return compiler_rt.f64.toAbi(f64_floatCast_f32(compiler_rt.f32.fromAbi(a))); | ||
| 92 | } | ||
| 93 | fn __aeabi_f2d(a: f32) callconv(.{ .arm_aapcs = .{} }) f64 { | ||
| 94 | return f64_floatCast_f32(a); | ||
| 95 | } | ||
| 96 | pub fn f64_floatCast_f32(a: f32) f64 { | ||
| 97 | return extendf(f64, f32, a); | ||
| 98 | } | ||
| 99 | |||
| 100 | fn __extendsfxf2(a: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f80.Abi { | ||
| 101 | return compiler_rt.f80.toAbi(f80_floatCast_f32(compiler_rt.f32.fromAbi(a))); | ||
| 102 | } | ||
| 103 | pub fn f80_floatCast_f32(a: f32) f80 { | ||
| 104 | return extend_f80(f32, a); | ||
| 105 | } | ||
| 106 | |||
| 107 | pub fn __extendsftf2(a: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f128.Abi { | ||
| 108 | return compiler_rt.f128.toAbi(f128_floatCast_f32(compiler_rt.f32.fromAbi(a))); | ||
| 109 | } | ||
| 110 | fn _Qp_stoq(c: *f128, a: f32) callconv(.c) void { | ||
| 111 | c.* = f128_floatCast_f32(a); | ||
| 112 | } | ||
| 113 | pub fn f128_floatCast_f32(a: f32) f128 { | ||
| 114 | return extendf(f128, f32, a); | ||
| 115 | } | ||
| 116 | |||
| 117 | fn __extenddfxf2(a: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f80.Abi { | ||
| 118 | return compiler_rt.f80.toAbi(f80_floatCast_f64(compiler_rt.f64.fromAbi(a))); | ||
| 119 | } | ||
| 120 | pub fn f80_floatCast_f64(a: f64) f80 { | ||
| 121 | return extend_f80(f64, a); | ||
| 122 | } | ||
| 123 | |||
| 124 | fn __extenddftf2(a: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f128.Abi { | ||
| 125 | return compiler_rt.f128.toAbi(f128_floatCast_f64(compiler_rt.f64.fromAbi(a))); | ||
| 126 | } | ||
| 127 | fn _Qp_dtoq(c: *f128, a: f64) callconv(.c) void { | ||
| 128 | c.* = f128_floatCast_f64(a); | ||
| 129 | } | ||
| 130 | pub fn f128_floatCast_f64(a: f64) f128 { | ||
| 131 | return extendf(f128, f64, a); | ||
| 132 | } | ||
| 133 | |||
| 134 | fn __extendxftf2(a: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f128.Abi { | ||
| 135 | return compiler_rt.f128.toAbi(f128_floatCast_f80(compiler_rt.f80.fromAbi(a))); | ||
| 136 | } | ||
| 137 | pub fn f128_floatCast_f80(a: f80) f128 { | ||
| 138 | const src_int_bit: u64 = 0x8000000000000000; | ||
| 139 | const src_sig_mask = ~src_int_bit; | ||
| 140 | const src_sig_bits = std.math.floatMantissaBits(f80) - 1; // -1 for the integer bit | ||
| 141 | const dst_sig_bits = std.math.floatMantissaBits(f128); | ||
| 142 | |||
| 143 | const dst_bits = @bitSizeOf(f128); | ||
| 144 | |||
| 145 | // Break a into a sign and representation of the absolute value | ||
| 146 | var a_rep: std.math.F80 = .fromFloat(a); | ||
| 147 | const sign = a_rep.exp & 0x8000; | ||
| 148 | a_rep.exp &= 0x7FFF; | ||
| 149 | var abs_result: u128 = undefined; | ||
| 150 | |||
| 151 | if (a_rep.exp == 0 and a_rep.fraction == 0) { | ||
| 152 | // zero | ||
| 153 | abs_result = 0; | ||
| 154 | } else if (a_rep.exp == 0x7FFF) { | ||
| 155 | // a is nan or infinite | ||
| 156 | abs_result = @as(u128, a_rep.fraction) << (dst_sig_bits - src_sig_bits); | ||
| 157 | abs_result |= @as(u128, a_rep.exp) << dst_sig_bits; | ||
| 158 | } else if (a_rep.fraction & src_int_bit != 0) { | ||
| 159 | // a is a normal value | ||
| 160 | abs_result = @as(u128, a_rep.fraction & src_sig_mask) << (dst_sig_bits - src_sig_bits); | ||
| 161 | abs_result |= @as(u128, a_rep.exp) << dst_sig_bits; | ||
| 162 | } else { | ||
| 163 | // a is denormal | ||
| 164 | abs_result = @as(u128, a_rep.fraction) << (dst_sig_bits - src_sig_bits); | ||
| 165 | } | ||
| 166 | |||
| 167 | // Apply the signbit to (dst_t)abs(a). | ||
| 168 | const result: u128 = abs_result | @as(u128, sign) << (dst_bits - 16); | ||
| 169 | return @bitCast(result); | ||
| 170 | } | ||
| 171 | |||
| 172 | inline fn extendf(comptime dst_t: type, comptime src_t: type, f: src_t) dst_t { | ||
| 8 | const src_rep_t = @Int(.unsigned, @typeInfo(src_t).float.bits); | 173 | const src_rep_t = @Int(.unsigned, @typeInfo(src_t).float.bits); |
| 9 | const dst_rep_t = @Int(.unsigned, @typeInfo(dst_t).float.bits); | 174 | const dst_rep_t = @Int(.unsigned, @typeInfo(dst_t).float.bits); |
| 10 | const srcSigBits = std.math.floatMantissaBits(src_t); | 175 | const srcSigBits = std.math.floatMantissaBits(src_t); |
| ... | @@ -31,6 +196,7 @@ pub inline fn extendf( | ... | @@ -31,6 +196,7 @@ pub inline fn extendf( |
| 31 | 196 | ||
| 32 | const dstMinNormal: dst_rep_t = @as(dst_rep_t, 1) << dstSigBits; | 197 | const dstMinNormal: dst_rep_t = @as(dst_rep_t, 1) << dstSigBits; |
| 33 | 198 | ||
| 199 | const a: src_rep_t = @bitCast(f); | ||
| 34 | // Break a into a sign and representation of the absolute value | 200 | // Break a into a sign and representation of the absolute value |
| 35 | const aRep: src_rep_t = @bitCast(a); | 201 | const aRep: src_rep_t = @bitCast(a); |
| 36 | const aAbs: src_rep_t = aRep & srcAbsMask; | 202 | const aAbs: src_rep_t = aRep & srcAbsMask; |
| ... | @@ -66,11 +232,11 @@ pub inline fn extendf( | ... | @@ -66,11 +232,11 @@ pub inline fn extendf( |
| 66 | } | 232 | } |
| 67 | 233 | ||
| 68 | // Apply the signbit to (dst_t)abs(a). | 234 | // Apply the signbit to (dst_t)abs(a). |
| 69 | const result: dst_rep_t align(@alignOf(dst_t)) = absResult | @as(dst_rep_t, sign) << (dstBits - srcBits); | 235 | const result: dst_rep_t = absResult | @as(dst_rep_t, sign) << (dstBits - srcBits); |
| 70 | return @bitCast(result); | 236 | return @bitCast(result); |
| 71 | } | 237 | } |
| 72 | 238 | ||
| 73 | pub inline fn extend_f80(comptime src_t: type, a: @Int(.unsigned, @typeInfo(src_t).float.bits)) f80 { | 239 | inline fn extend_f80(comptime src_t: type, f: src_t) f80 { |
| 74 | const src_rep_t = @Int(.unsigned, @typeInfo(src_t).float.bits); | 240 | const src_rep_t = @Int(.unsigned, @typeInfo(src_t).float.bits); |
| 75 | const src_sig_bits = std.math.floatMantissaBits(src_t); | 241 | const src_sig_bits = std.math.floatMantissaBits(src_t); |
| 76 | const dst_int_bit = 0x8000000000000000; | 242 | const dst_int_bit = 0x8000000000000000; |
| ... | @@ -92,6 +258,7 @@ pub inline fn extend_f80(comptime src_t: type, a: @Int(.unsigned, @typeInfo(src_ | ... | @@ -92,6 +258,7 @@ pub inline fn extend_f80(comptime src_t: type, a: @Int(.unsigned, @typeInfo(src_ |
| 92 | 258 | ||
| 93 | var dst: std.math.F80 = undefined; | 259 | var dst: std.math.F80 = undefined; |
| 94 | 260 | ||
| 261 | const a: src_rep_t = @bitCast(f); | ||
| 95 | // Break a into a sign and representation of the absolute value | 262 | // Break a into a sign and representation of the absolute value |
| 96 | const a_abs = a & src_abs_mask; | 263 | const a_abs = a & src_abs_mask; |
| 97 | const sign: u16 = if (a & src_sign_mask != 0) 0x8000 else 0; | 264 | const sign: u16 = if (a & src_sign_mask != 0) 0x8000 else 0; |
lib/compiler_rt/extendf_test.zig+94-95| ... | @@ -1,31 +1,37 @@ | ... | @@ -1,31 +1,37 @@ |
| 1 | const builtin = @import("builtin"); | 1 | const builtin = @import("builtin"); |
| 2 | |||
| 3 | const std = @import("std"); | 2 | const std = @import("std"); |
| 4 | const math = std.math; | 3 | const testing = std.testing; |
| 4 | |||
| 5 | const impl = @import("extendf.zig"); | ||
| 6 | |||
| 7 | const f32_floatCast_f16 = impl.f32_floatCast_f16; | ||
| 8 | const f64_floatCast_f16 = impl.f64_floatCast_f16; | ||
| 9 | const f80_floatCast_f16 = impl.f80_floatCast_f16; | ||
| 10 | const f128_floatCast_f16 = impl.f128_floatCast_f16; | ||
| 11 | |||
| 12 | const f64_floatCast_f32 = impl.f64_floatCast_f32; | ||
| 13 | const f80_floatCast_f32 = impl.f80_floatCast_f32; | ||
| 14 | const f128_floatCast_f32 = impl.f128_floatCast_f32; | ||
| 5 | 15 | ||
| 6 | const __extendhfsf2 = @import("extendhfsf2.zig").__extendhfsf2; | 16 | const f80_floatCast_f64 = impl.f80_floatCast_f64; |
| 7 | const __extendhftf2 = @import("extendhftf2.zig").__extendhftf2; | 17 | const f128_floatCast_f64 = impl.f128_floatCast_f64; |
| 8 | const __extendsftf2 = @import("extendsftf2.zig").__extendsftf2; | ||
| 9 | const __extenddftf2 = @import("extenddftf2.zig").__extenddftf2; | ||
| 10 | const __extenddfxf2 = @import("extenddfxf2.zig").__extenddfxf2; | ||
| 11 | const F16T = @import("../compiler_rt.zig").F16T; | ||
| 12 | 18 | ||
| 13 | fn test__extenddfxf2(a: f64, expected: u80) !void { | 19 | const f128_floatCast_f80 = impl.f128_floatCast_f80; |
| 14 | const x = __extenddfxf2(a); | 20 | |
| 21 | fn test_f80_floatCast_f64(a: f64, expected: u80) !void { | ||
| 22 | const x = f80_floatCast_f64(a); | ||
| 15 | 23 | ||
| 16 | const rep: u80 = @bitCast(x); | 24 | const rep: u80 = @bitCast(x); |
| 17 | if (rep == expected) | 25 | if (rep == expected) |
| 18 | return; | 26 | return; |
| 19 | |||
| 20 | // test other possible NaN representation(signal NaN) | 27 | // test other possible NaN representation(signal NaN) |
| 21 | if (math.isNan(@as(f80, @bitCast(expected))) and math.isNan(x)) | 28 | if (std.math.isNan(@as(f80, @bitCast(expected))) and std.math.isNan(x)) |
| 22 | return; | 29 | return; |
| 23 | 30 | return error.TestFailure; | |
| 24 | @panic("__extenddfxf2 test failure"); | ||
| 25 | } | 31 | } |
| 26 | 32 | ||
| 27 | fn test__extenddftf2(a: f64, expected_hi: u64, expected_lo: u64) !void { | 33 | fn test_f128_floatCast_f64(a: f64, expected_hi: u64, expected_lo: u64) !void { |
| 28 | const x = __extenddftf2(a); | 34 | const x = f128_floatCast_f64(a); |
| 29 | 35 | ||
| 30 | const rep: u128 = @bitCast(x); | 36 | const rep: u128 = @bitCast(x); |
| 31 | const hi: u64 = @intCast(rep >> 64); | 37 | const hi: u64 = @intCast(rep >> 64); |
| ... | @@ -33,7 +39,6 @@ fn test__extenddftf2(a: f64, expected_hi: u64, expected_lo: u64) !void { | ... | @@ -33,7 +39,6 @@ fn test__extenddftf2(a: f64, expected_hi: u64, expected_lo: u64) !void { |
| 33 | 39 | ||
| 34 | if (hi == expected_hi and lo == expected_lo) | 40 | if (hi == expected_hi and lo == expected_lo) |
| 35 | return; | 41 | return; |
| 36 | |||
| 37 | // test other possible NaN representation(signal NaN) | 42 | // test other possible NaN representation(signal NaN) |
| 38 | if (expected_hi == 0x7fff800000000000 and expected_lo == 0x0) { | 43 | if (expected_hi == 0x7fff800000000000 and expected_lo == 0x0) { |
| 39 | if ((hi & 0x7fff000000000000) == 0x7fff000000000000 and | 44 | if ((hi & 0x7fff000000000000) == 0x7fff000000000000 and |
| ... | @@ -42,12 +47,11 @@ fn test__extenddftf2(a: f64, expected_hi: u64, expected_lo: u64) !void { | ... | @@ -42,12 +47,11 @@ fn test__extenddftf2(a: f64, expected_hi: u64, expected_lo: u64) !void { |
| 42 | return; | 47 | return; |
| 43 | } | 48 | } |
| 44 | } | 49 | } |
| 45 | 50 | return error.TestFailure; | |
| 46 | @panic("__extenddftf2 test failure"); | ||
| 47 | } | 51 | } |
| 48 | 52 | ||
| 49 | fn test__extendhfsf2(a: u16, expected: u32) !void { | 53 | fn test_f32_floatCast_f16(a: u16, expected: u32) !void { |
| 50 | const x = __extendhfsf2(@as(F16T(f32), @bitCast(a))); | 54 | const x = f32_floatCast_f16(@bitCast(a)); |
| 51 | const rep: u32 = @bitCast(x); | 55 | const rep: u32 = @bitCast(x); |
| 52 | 56 | ||
| 53 | if (rep == expected) { | 57 | if (rep == expected) { |
| ... | @@ -58,12 +62,11 @@ fn test__extendhfsf2(a: u16, expected: u32) !void { | ... | @@ -58,12 +62,11 @@ fn test__extendhfsf2(a: u16, expected: u32) !void { |
| 58 | return; | 62 | return; |
| 59 | } | 63 | } |
| 60 | } | 64 | } |
| 61 | |||
| 62 | return error.TestFailure; | 65 | return error.TestFailure; |
| 63 | } | 66 | } |
| 64 | 67 | ||
| 65 | fn test__extendsftf2(a: f32, expected_hi: u64, expected_lo: u64) !void { | 68 | fn test_f128_floatCast_f32(a: f32, expected_hi: u64, expected_lo: u64) !void { |
| 66 | const x = __extendsftf2(a); | 69 | const x = f128_floatCast_f32(a); |
| 67 | 70 | ||
| 68 | const rep: u128 = @bitCast(x); | 71 | const rep: u128 = @bitCast(x); |
| 69 | const hi: u64 = @intCast(rep >> 64); | 72 | const hi: u64 = @intCast(rep >> 64); |
| ... | @@ -71,7 +74,6 @@ fn test__extendsftf2(a: f32, expected_hi: u64, expected_lo: u64) !void { | ... | @@ -71,7 +74,6 @@ fn test__extendsftf2(a: f32, expected_hi: u64, expected_lo: u64) !void { |
| 71 | 74 | ||
| 72 | if (hi == expected_hi and lo == expected_lo) | 75 | if (hi == expected_hi and lo == expected_lo) |
| 73 | return; | 76 | return; |
| 74 | |||
| 75 | // test other possible NaN representation(signal NaN) | 77 | // test other possible NaN representation(signal NaN) |
| 76 | if (expected_hi == 0x7fff800000000000 and expected_lo == 0x0) { | 78 | if (expected_hi == 0x7fff800000000000 and expected_lo == 0x0) { |
| 77 | if ((hi & 0x7fff000000000000) == 0x7fff000000000000 and | 79 | if ((hi & 0x7fff000000000000) == 0x7fff000000000000 and |
| ... | @@ -80,111 +82,108 @@ fn test__extendsftf2(a: f32, expected_hi: u64, expected_lo: u64) !void { | ... | @@ -80,111 +82,108 @@ fn test__extendsftf2(a: f32, expected_hi: u64, expected_lo: u64) !void { |
| 80 | return; | 82 | return; |
| 81 | } | 83 | } |
| 82 | } | 84 | } |
| 83 | |||
| 84 | return error.TestFailure; | 85 | return error.TestFailure; |
| 85 | } | 86 | } |
| 86 | 87 | ||
| 87 | test "extenddfxf2" { | 88 | test f80_floatCast_f64 { |
| 88 | // qNaN | 89 | // qNaN |
| 89 | try test__extenddfxf2(makeQNaN64(), 0x7fffc000000000000000); | 90 | try test_f80_floatCast_f64(makeQNaN64(), 0x7fffc000000000000000); |
| 90 | 91 | ||
| 91 | // NaN | 92 | // NaN |
| 92 | try test__extenddfxf2(makeNaN64(0x7100000000000), 0x7fffe080000000000000); | 93 | try test_f80_floatCast_f64(makeNaN64(0x7100000000000), 0x7fffe080000000000000); |
| 93 | // This is bad? | 94 | // This is bad? |
| 94 | 95 | ||
| 95 | // inf | 96 | // inf |
| 96 | try test__extenddfxf2(makeInf64(), 0x7fff8000000000000000); | 97 | try test_f80_floatCast_f64(makeInf64(), 0x7fff8000000000000000); |
| 97 | 98 | ||
| 98 | // zero | 99 | // zero |
| 99 | try test__extenddfxf2(0.0, 0x0); | 100 | try test_f80_floatCast_f64(0.0, 0x0); |
| 100 | 101 | ||
| 101 | try test__extenddfxf2(0x0.a3456789abcdefp+6, 0x4004a3456789abcdf000); | 102 | try test_f80_floatCast_f64(0x0.a3456789abcdefp+6, 0x4004a3456789abcdf000); |
| 102 | 103 | ||
| 103 | try test__extenddfxf2(0x0.edcba987654321fp-8, 0x3ff6edcba98765432000); | 104 | try test_f80_floatCast_f64(0x0.edcba987654321fp-8, 0x3ff6edcba98765432000); |
| 104 | 105 | ||
| 105 | try test__extenddfxf2(0x0.a3456789abcdefp+46, 0x402ca3456789abcdf000); | 106 | try test_f80_floatCast_f64(0x0.a3456789abcdefp+46, 0x402ca3456789abcdf000); |
| 106 | 107 | ||
| 107 | try test__extenddfxf2(0x0.edcba987654321fp-44, 0x3fd2edcba98765432000); | 108 | try test_f80_floatCast_f64(0x0.edcba987654321fp-44, 0x3fd2edcba98765432000); |
| 108 | 109 | ||
| 109 | // subnormal | 110 | // subnormal |
| 110 | try test__extenddfxf2(0x1.8000000000001p-1022, 0x3c01c000000000000800); | 111 | try test_f80_floatCast_f64(0x1.8000000000001p-1022, 0x3c01c000000000000800); |
| 111 | try test__extenddfxf2(0x1.8000000000002p-1023, 0x3c00c000000000001000); | 112 | try test_f80_floatCast_f64(0x1.8000000000002p-1023, 0x3c00c000000000001000); |
| 112 | } | 113 | } |
| 113 | 114 | ||
| 114 | test "extenddftf2" { | 115 | test f128_floatCast_f64 { |
| 115 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | ||
| 116 | |||
| 117 | // qNaN | 116 | // qNaN |
| 118 | try test__extenddftf2(makeQNaN64(), 0x7fff800000000000, 0x0); | 117 | try test_f128_floatCast_f64(makeQNaN64(), 0x7fff800000000000, 0x0); |
| 119 | 118 | ||
| 120 | // NaN | 119 | // NaN |
| 121 | try test__extenddftf2(makeNaN64(0x7100000000000), 0x7fff710000000000, 0x0); | 120 | try test_f128_floatCast_f64(makeNaN64(0x7100000000000), 0x7fff710000000000, 0x0); |
| 122 | 121 | ||
| 123 | // inf | 122 | // inf |
| 124 | try test__extenddftf2(makeInf64(), 0x7fff000000000000, 0x0); | 123 | try test_f128_floatCast_f64(makeInf64(), 0x7fff000000000000, 0x0); |
| 125 | 124 | ||
| 126 | // zero | 125 | // zero |
| 127 | try test__extenddftf2(0.0, 0x0, 0x0); | 126 | try test_f128_floatCast_f64(0.0, 0x0, 0x0); |
| 128 | 127 | ||
| 129 | try test__extenddftf2(0x1.23456789abcdefp+5, 0x400423456789abcd, 0xf000000000000000); | 128 | try test_f128_floatCast_f64(0x1.23456789abcdefp+5, 0x400423456789abcd, 0xf000000000000000); |
| 130 | 129 | ||
| 131 | try test__extenddftf2(0x1.edcba987654321fp-9, 0x3ff6edcba9876543, 0x2000000000000000); | 130 | try test_f128_floatCast_f64(0x1.edcba987654321fp-9, 0x3ff6edcba9876543, 0x2000000000000000); |
| 132 | 131 | ||
| 133 | try test__extenddftf2(0x1.23456789abcdefp+45, 0x402c23456789abcd, 0xf000000000000000); | 132 | try test_f128_floatCast_f64(0x1.23456789abcdefp+45, 0x402c23456789abcd, 0xf000000000000000); |
| 134 | 133 | ||
| 135 | try test__extenddftf2(0x1.edcba987654321fp-45, 0x3fd2edcba9876543, 0x2000000000000000); | 134 | try test_f128_floatCast_f64(0x1.edcba987654321fp-45, 0x3fd2edcba9876543, 0x2000000000000000); |
| 136 | 135 | ||
| 137 | // subnormal | 136 | // subnormal |
| 138 | try test__extenddftf2(0x1.8p-1022, 0x3c01800000000000, 0x0); | 137 | try test_f128_floatCast_f64(0x1.8p-1022, 0x3c01800000000000, 0x0); |
| 139 | try test__extenddftf2(0x1.8p-1023, 0x3c00800000000000, 0x0); | 138 | try test_f128_floatCast_f64(0x1.8p-1023, 0x3c00800000000000, 0x0); |
| 140 | } | 139 | } |
| 141 | 140 | ||
| 142 | test "extendhfsf2" { | 141 | test f32_floatCast_f16 { |
| 143 | try test__extendhfsf2(0x7e00, 0x7fc00000); // qNaN | 142 | try test_f32_floatCast_f16(0x7e00, 0x7fc00000); // qNaN |
| 144 | try test__extendhfsf2(0x7f00, 0x7fe00000); // sNaN | 143 | try test_f32_floatCast_f16(0x7f00, 0x7fe00000); // sNaN |
| 145 | // On x86 the NaN becomes quiet because the return is pushed on the x87 | 144 | // On x86 the NaN becomes quiet because the return is pushed on the x87 |
| 146 | // stack due to ABI requirements | 145 | // stack due to ABI requirements |
| 147 | if (builtin.target.cpu.arch != .x86 and builtin.target.os.tag == .windows) | 146 | if (builtin.target.cpu.arch != .x86 and builtin.target.os.tag == .windows) |
| 148 | try test__extendhfsf2(0x7c01, 0x7f802000); // sNaN | 147 | try test_f32_floatCast_f16(0x7c01, 0x7f802000); // sNaN |
| 149 | 148 | ||
| 150 | try test__extendhfsf2(0, 0); // 0 | 149 | try test_f32_floatCast_f16(0, 0); // 0 |
| 151 | try test__extendhfsf2(0x8000, 0x80000000); // -0 | 150 | try test_f32_floatCast_f16(0x8000, 0x80000000); // -0 |
| 152 | 151 | ||
| 153 | try test__extendhfsf2(0x7c00, 0x7f800000); // inf | 152 | try test_f32_floatCast_f16(0x7c00, 0x7f800000); // inf |
| 154 | try test__extendhfsf2(0xfc00, 0xff800000); // -inf | 153 | try test_f32_floatCast_f16(0xfc00, 0xff800000); // -inf |
| 155 | 154 | ||
| 156 | try test__extendhfsf2(0x0001, 0x33800000); // denormal (min), 2**-24 | 155 | try test_f32_floatCast_f16(0x0001, 0x33800000); // denormal (min), 2**-24 |
| 157 | try test__extendhfsf2(0x8001, 0xb3800000); // denormal (min), -2**-24 | 156 | try test_f32_floatCast_f16(0x8001, 0xb3800000); // denormal (min), -2**-24 |
| 158 | 157 | ||
| 159 | try test__extendhfsf2(0x03ff, 0x387fc000); // denormal (max), 2**-14 - 2**-24 | 158 | try test_f32_floatCast_f16(0x03ff, 0x387fc000); // denormal (max), 2**-14 - 2**-24 |
| 160 | try test__extendhfsf2(0x83ff, 0xb87fc000); // denormal (max), -2**-14 + 2**-24 | 159 | try test_f32_floatCast_f16(0x83ff, 0xb87fc000); // denormal (max), -2**-14 + 2**-24 |
| 161 | 160 | ||
| 162 | try test__extendhfsf2(0x0400, 0x38800000); // normal (min), 2**-14 | 161 | try test_f32_floatCast_f16(0x0400, 0x38800000); // normal (min), 2**-14 |
| 163 | try test__extendhfsf2(0x8400, 0xb8800000); // normal (min), -2**-14 | 162 | try test_f32_floatCast_f16(0x8400, 0xb8800000); // normal (min), -2**-14 |
| 164 | 163 | ||
| 165 | try test__extendhfsf2(0x7bff, 0x477fe000); // normal (max), 65504 | 164 | try test_f32_floatCast_f16(0x7bff, 0x477fe000); // normal (max), 65504 |
| 166 | try test__extendhfsf2(0xfbff, 0xc77fe000); // normal (max), -65504 | 165 | try test_f32_floatCast_f16(0xfbff, 0xc77fe000); // normal (max), -65504 |
| 167 | 166 | ||
| 168 | try test__extendhfsf2(0x3c01, 0x3f802000); // normal, 1 + 2**-10 | 167 | try test_f32_floatCast_f16(0x3c01, 0x3f802000); // normal, 1 + 2**-10 |
| 169 | try test__extendhfsf2(0xbc01, 0xbf802000); // normal, -1 - 2**-10 | 168 | try test_f32_floatCast_f16(0xbc01, 0xbf802000); // normal, -1 - 2**-10 |
| 170 | 169 | ||
| 171 | try test__extendhfsf2(0x3555, 0x3eaaa000); // normal, approx. 1/3 | 170 | try test_f32_floatCast_f16(0x3555, 0x3eaaa000); // normal, approx. 1/3 |
| 172 | try test__extendhfsf2(0xb555, 0xbeaaa000); // normal, approx. -1/3 | 171 | try test_f32_floatCast_f16(0xb555, 0xbeaaa000); // normal, approx. -1/3 |
| 173 | } | 172 | } |
| 174 | 173 | ||
| 175 | test "extendsftf2" { | 174 | test f128_floatCast_f32 { |
| 176 | // qNaN | 175 | // qNaN |
| 177 | try test__extendsftf2(makeQNaN32(), 0x7fff800000000000, 0x0); | 176 | try test_f128_floatCast_f32(makeQNaN32(), 0x7fff800000000000, 0x0); |
| 178 | // NaN | 177 | // NaN |
| 179 | try test__extendsftf2(makeNaN32(0x410000), 0x7fff820000000000, 0x0); | 178 | try test_f128_floatCast_f32(makeNaN32(0x410000), 0x7fff820000000000, 0x0); |
| 180 | // inf | 179 | // inf |
| 181 | try test__extendsftf2(makeInf32(), 0x7fff000000000000, 0x0); | 180 | try test_f128_floatCast_f32(makeInf32(), 0x7fff000000000000, 0x0); |
| 182 | // zero | 181 | // zero |
| 183 | try test__extendsftf2(0.0, 0x0, 0x0); | 182 | try test_f128_floatCast_f32(0.0, 0x0, 0x0); |
| 184 | try test__extendsftf2(0x1.23456p+5, 0x4004234560000000, 0x0); | 183 | try test_f128_floatCast_f32(0x1.23456p+5, 0x4004234560000000, 0x0); |
| 185 | try test__extendsftf2(0x1.edcbap-9, 0x3ff6edcba0000000, 0x0); | 184 | try test_f128_floatCast_f32(0x1.edcbap-9, 0x3ff6edcba0000000, 0x0); |
| 186 | try test__extendsftf2(0x1.23456p+45, 0x402c234560000000, 0x0); | 185 | try test_f128_floatCast_f32(0x1.23456p+45, 0x402c234560000000, 0x0); |
| 187 | try test__extendsftf2(0x1.edcbap-45, 0x3fd2edcba0000000, 0x0); | 186 | try test_f128_floatCast_f32(0x1.edcbap-45, 0x3fd2edcba0000000, 0x0); |
| 188 | } | 187 | } |
| 189 | 188 | ||
| 190 | fn makeQNaN64() f64 { | 189 | fn makeQNaN64() f64 { |
| ... | @@ -211,8 +210,8 @@ fn makeInf32() f32 { | ... | @@ -211,8 +210,8 @@ fn makeInf32() f32 { |
| 211 | return @bitCast(@as(u32, 0x7f800000)); | 210 | return @bitCast(@as(u32, 0x7f800000)); |
| 212 | } | 211 | } |
| 213 | 212 | ||
| 214 | fn test__extendhftf2(a: u16, expected_hi: u64, expected_lo: u64) !void { | 213 | fn test_f128_floatCast_f16(a: u16, expected_hi: u64, expected_lo: u64) !void { |
| 215 | const x = __extendhftf2(@as(F16T(f128), @bitCast(a))); | 214 | const x = f128_floatCast_f16(@bitCast(a)); |
| 216 | 215 | ||
| 217 | const rep: u128 = @bitCast(x); | 216 | const rep: u128 = @bitCast(x); |
| 218 | const hi: u64 = @intCast(rep >> 64); | 217 | const hi: u64 = @intCast(rep >> 64); |
| ... | @@ -233,26 +232,26 @@ fn test__extendhftf2(a: u16, expected_hi: u64, expected_lo: u64) !void { | ... | @@ -233,26 +232,26 @@ fn test__extendhftf2(a: u16, expected_hi: u64, expected_lo: u64) !void { |
| 233 | return error.TestFailure; | 232 | return error.TestFailure; |
| 234 | } | 233 | } |
| 235 | 234 | ||
| 236 | test "extendhftf2" { | 235 | test f128_floatCast_f16 { |
| 237 | // qNaN | 236 | // qNaN |
| 238 | try test__extendhftf2(0x7e00, 0x7fff800000000000, 0x0); | 237 | try test_f128_floatCast_f16(0x7e00, 0x7fff800000000000, 0x0); |
| 239 | // NaN | 238 | // NaN |
| 240 | try test__extendhftf2(0x7d00, 0x7fff400000000000, 0x0); | 239 | try test_f128_floatCast_f16(0x7d00, 0x7fff400000000000, 0x0); |
| 241 | // inf | 240 | // inf |
| 242 | try test__extendhftf2(0x7c00, 0x7fff000000000000, 0x0); | 241 | try test_f128_floatCast_f16(0x7c00, 0x7fff000000000000, 0x0); |
| 243 | try test__extendhftf2(0xfc00, 0xffff000000000000, 0x0); | 242 | try test_f128_floatCast_f16(0xfc00, 0xffff000000000000, 0x0); |
| 244 | // zero | 243 | // zero |
| 245 | try test__extendhftf2(0x0000, 0x0000000000000000, 0x0); | 244 | try test_f128_floatCast_f16(0x0000, 0x0000000000000000, 0x0); |
| 246 | try test__extendhftf2(0x8000, 0x8000000000000000, 0x0); | 245 | try test_f128_floatCast_f16(0x8000, 0x8000000000000000, 0x0); |
| 247 | // denormal | 246 | // denormal |
| 248 | try test__extendhftf2(0x0010, 0x3feb000000000000, 0x0); | 247 | try test_f128_floatCast_f16(0x0010, 0x3feb000000000000, 0x0); |
| 249 | try test__extendhftf2(0x0001, 0x3fe7000000000000, 0x0); | 248 | try test_f128_floatCast_f16(0x0001, 0x3fe7000000000000, 0x0); |
| 250 | try test__extendhftf2(0x8001, 0xbfe7000000000000, 0x0); | 249 | try test_f128_floatCast_f16(0x8001, 0xbfe7000000000000, 0x0); |
| 251 | 250 | ||
| 252 | // pi | 251 | // pi |
| 253 | try test__extendhftf2(0x4248, 0x4000920000000000, 0x0); | 252 | try test_f128_floatCast_f16(0x4248, 0x4000920000000000, 0x0); |
| 254 | try test__extendhftf2(0xc248, 0xc000920000000000, 0x0); | 253 | try test_f128_floatCast_f16(0xc248, 0xc000920000000000, 0x0); |
| 255 | 254 | ||
| 256 | try test__extendhftf2(0x508c, 0x4004230000000000, 0x0); | 255 | try test_f128_floatCast_f16(0x508c, 0x4004230000000000, 0x0); |
| 257 | try test__extendhftf2(0x1bb7, 0x3ff6edc000000000, 0x0); | 256 | try test_f128_floatCast_f16(0x1bb7, 0x3ff6edc000000000, 0x0); |
| 258 | } | 257 | } |
lib/compiler_rt/extendhfdf2.zig deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 3 | const extendf = @import("./extendf.zig").extendf; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__extendhfdf2, "__extendhfdf2"); | ||
| 7 | } | ||
| 8 | |||
| 9 | pub fn __extendhfdf2(a: compiler_rt.F16T(f64)) callconv(.c) f64 { | ||
| 10 | return extendf(f64, f16, @as(u16, @bitCast(a))); | ||
| 11 | } | ||
lib/compiler_rt/extendhfsf2.zig deleted-24| ... | @@ -1,24 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const extendf = @import("./extendf.zig").extendf; | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.gnu_f16_abi) { | ||
| 7 | symbol(&__gnu_h2f_ieee, "__gnu_h2f_ieee"); | ||
| 8 | } else if (compiler_rt.want_aeabi) { | ||
| 9 | symbol(&__aeabi_h2f, "__aeabi_h2f"); | ||
| 10 | } | ||
| 11 | symbol(&__extendhfsf2, "__extendhfsf2"); | ||
| 12 | } | ||
| 13 | |||
| 14 | pub fn __extendhfsf2(a: compiler_rt.F16T(f32)) callconv(.c) f32 { | ||
| 15 | return extendf(f32, f16, @as(u16, @bitCast(a))); | ||
| 16 | } | ||
| 17 | |||
| 18 | fn __gnu_h2f_ieee(a: compiler_rt.F16T(f32)) callconv(.c) f32 { | ||
| 19 | return extendf(f32, f16, @as(u16, @bitCast(a))); | ||
| 20 | } | ||
| 21 | |||
| 22 | fn __aeabi_h2f(a: u16) callconv(.{ .arm_aapcs = .{} }) f32 { | ||
| 23 | return extendf(f32, f16, @as(u16, @bitCast(a))); | ||
| 24 | } | ||
lib/compiler_rt/extendhftf2.zig deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const extendf = @import("./extendf.zig").extendf; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__extendhftf2, "__extendhftf2"); | ||
| 7 | } | ||
| 8 | |||
| 9 | pub fn __extendhftf2(a: compiler_rt.F16T(f128)) callconv(.c) f128 { | ||
| 10 | return extendf(f128, f16, @as(u16, @bitCast(a))); | ||
| 11 | } | ||
lib/compiler_rt/extendhfxf2.zig deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const extend_f80 = @import("./extendf.zig").extend_f80; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__extendhfxf2, "__extendhfxf2"); | ||
| 7 | } | ||
| 8 | |||
| 9 | fn __extendhfxf2(a: compiler_rt.F16T(f80)) callconv(.c) f80 { | ||
| 10 | return extend_f80(f16, @as(u16, @bitCast(a))); | ||
| 11 | } | ||
lib/compiler_rt/extendsfdf2.zig deleted-19| ... | @@ -1,19 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const extendf = @import("./extendf.zig").extendf; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_aeabi) { | ||
| 7 | symbol(&__aeabi_f2d, "__aeabi_f2d"); | ||
| 8 | } else { | ||
| 9 | symbol(&__extendsfdf2, "__extendsfdf2"); | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | fn __extendsfdf2(a: f32) callconv(.c) f64 { | ||
| 14 | return extendf(f64, f32, @as(u32, @bitCast(a))); | ||
| 15 | } | ||
| 16 | |||
| 17 | fn __aeabi_f2d(a: f32) callconv(.{ .arm_aapcs = .{} }) f64 { | ||
| 18 | return extendf(f64, f32, @as(u32, @bitCast(a))); | ||
| 19 | } | ||
lib/compiler_rt/extendsftf2.zig deleted-22| ... | @@ -1,22 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const extendf = @import("./extendf.zig").extendf; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_ppc_abi) { | ||
| 7 | symbol(&__extendsftf2, "__extendsfkf2"); | ||
| 8 | } else if (compiler_rt.want_sparc64_abi) { | ||
| 9 | symbol(&_Qp_stoq, "_Qp_stoq"); | ||
| 10 | } else if (compiler_rt.want_sparc32_abi) { | ||
| 11 | symbol(&__extendsftf2, "_Q_stoq"); | ||
| 12 | } | ||
| 13 | symbol(&__extendsftf2, "__extendsftf2"); | ||
| 14 | } | ||
| 15 | |||
| 16 | pub fn __extendsftf2(a: f32) callconv(.c) f128 { | ||
| 17 | return extendf(f128, f32, @as(u32, @bitCast(a))); | ||
| 18 | } | ||
| 19 | |||
| 20 | fn _Qp_stoq(c: *f128, a: f32) callconv(.c) void { | ||
| 21 | c.* = extendf(f128, f32, @as(u32, @bitCast(a))); | ||
| 22 | } | ||
lib/compiler_rt/extendsfxf2.zig deleted-10| ... | @@ -1,10 +0,0 @@ | ||
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 2 | const extend_f80 = @import("./extendf.zig").extend_f80; | ||
| 3 | |||
| 4 | comptime { | ||
| 5 | symbol(&__extendsfxf2, "__extendsfxf2"); | ||
| 6 | } | ||
| 7 | |||
| 8 | fn __extendsfxf2(a: f32) callconv(.c) f80 { | ||
| 9 | return extend_f80(f32, @as(u32, @bitCast(a))); | ||
| 10 | } | ||
lib/compiler_rt/extendxftf2.zig deleted-42| ... | @@ -1,42 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | |||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__extendxftf2, "__extendxftf2"); | ||
| 7 | } | ||
| 8 | |||
| 9 | fn __extendxftf2(a: f80) callconv(.c) f128 { | ||
| 10 | const src_int_bit: u64 = 0x8000000000000000; | ||
| 11 | const src_sig_mask = ~src_int_bit; | ||
| 12 | const src_sig_bits = std.math.floatMantissaBits(f80) - 1; // -1 for the integer bit | ||
| 13 | const dst_sig_bits = std.math.floatMantissaBits(f128); | ||
| 14 | |||
| 15 | const dst_bits = @bitSizeOf(f128); | ||
| 16 | |||
| 17 | // Break a into a sign and representation of the absolute value | ||
| 18 | var a_rep = std.math.F80.fromFloat(a); | ||
| 19 | const sign = a_rep.exp & 0x8000; | ||
| 20 | a_rep.exp &= 0x7FFF; | ||
| 21 | var abs_result: u128 = undefined; | ||
| 22 | |||
| 23 | if (a_rep.exp == 0 and a_rep.fraction == 0) { | ||
| 24 | // zero | ||
| 25 | abs_result = 0; | ||
| 26 | } else if (a_rep.exp == 0x7FFF) { | ||
| 27 | // a is nan or infinite | ||
| 28 | abs_result = @as(u128, a_rep.fraction) << (dst_sig_bits - src_sig_bits); | ||
| 29 | abs_result |= @as(u128, a_rep.exp) << dst_sig_bits; | ||
| 30 | } else if (a_rep.fraction & src_int_bit != 0) { | ||
| 31 | // a is a normal value | ||
| 32 | abs_result = @as(u128, a_rep.fraction & src_sig_mask) << (dst_sig_bits - src_sig_bits); | ||
| 33 | abs_result |= @as(u128, a_rep.exp) << dst_sig_bits; | ||
| 34 | } else { | ||
| 35 | // a is denormal | ||
| 36 | abs_result = @as(u128, a_rep.fraction) << (dst_sig_bits - src_sig_bits); | ||
| 37 | } | ||
| 38 | |||
| 39 | // Apply the signbit to (dst_t)abs(a). | ||
| 40 | const result: u128 align(@alignOf(f128)) = abs_result | @as(u128, sign) << (dst_bits - 16); | ||
| 41 | return @bitCast(result); | ||
| 42 | } | ||
lib/compiler_rt/fabs.zig+25-13| ... | @@ -9,39 +9,51 @@ comptime { | ... | @@ -9,39 +9,51 @@ comptime { |
| 9 | symbol(&fabsf, "fabsf"); | 9 | symbol(&fabsf, "fabsf"); |
| 10 | symbol(&fabs, "fabs"); | 10 | symbol(&fabs, "fabs"); |
| 11 | symbol(&__fabsx, "__fabsx"); | 11 | symbol(&__fabsx, "__fabsx"); |
| 12 | if (compiler_rt.want_ppc_abi) { | 12 | symbol(&fabsq, "fabsf128"); |
| 13 | symbol(&fabsq, "fabsf128"); | ||
| 14 | } | ||
| 15 | symbol(&fabsq, "fabsq"); | ||
| 16 | symbol(&fabsl, "fabsl"); | 13 | symbol(&fabsl, "fabsl"); |
| 17 | } | 14 | } |
| 18 | 15 | ||
| 19 | pub fn __fabsh(a: f16) callconv(.c) f16 { | 16 | fn __fabsh(a: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { |
| 17 | return compiler_rt.f16.toAbi(fabs_f16(compiler_rt.f16.fromAbi(a))); | ||
| 18 | } | ||
| 19 | pub fn fabs_f16(a: f16) f16 { | ||
| 20 | return generic_fabs(a); | 20 | return generic_fabs(a); |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | pub fn fabsf(a: f32) callconv(.c) f32 { | 23 | fn fabsf(a: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { |
| 24 | return compiler_rt.f32.toAbi(fabs_f32(compiler_rt.f32.fromAbi(a))); | ||
| 25 | } | ||
| 26 | pub fn fabs_f32(a: f32) f32 { | ||
| 24 | return generic_fabs(a); | 27 | return generic_fabs(a); |
| 25 | } | 28 | } |
| 26 | 29 | ||
| 27 | pub fn fabs(a: f64) callconv(.c) f64 { | 30 | fn fabs(a: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { |
| 31 | return compiler_rt.f64.toAbi(fabs_f64(compiler_rt.f64.fromAbi(a))); | ||
| 32 | } | ||
| 33 | pub fn fabs_f64(a: f64) f64 { | ||
| 28 | return generic_fabs(a); | 34 | return generic_fabs(a); |
| 29 | } | 35 | } |
| 30 | 36 | ||
| 31 | pub fn __fabsx(a: f80) callconv(.c) f80 { | 37 | fn __fabsx(a: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { |
| 38 | return compiler_rt.f80.toAbi(fabs_f80(compiler_rt.f80.fromAbi(a))); | ||
| 39 | } | ||
| 40 | pub fn fabs_f80(a: f80) f80 { | ||
| 32 | return generic_fabs(a); | 41 | return generic_fabs(a); |
| 33 | } | 42 | } |
| 34 | 43 | ||
| 35 | pub fn fabsq(a: f128) callconv(.c) f128 { | 44 | fn fabsq(a: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { |
| 45 | return compiler_rt.f128.toAbi(fabs_f128(compiler_rt.f128.fromAbi(a))); | ||
| 46 | } | ||
| 47 | pub fn fabs_f128(a: f128) f128 { | ||
| 36 | return generic_fabs(a); | 48 | return generic_fabs(a); |
| 37 | } | 49 | } |
| 38 | 50 | ||
| 39 | pub fn fabsl(x: c_longdouble) callconv(.c) c_longdouble { | 51 | pub fn fabsl(x: c_longdouble) callconv(.c) c_longdouble { |
| 40 | switch (@typeInfo(c_longdouble).float.bits) { | 52 | switch (@typeInfo(c_longdouble).float.bits) { |
| 41 | 64 => return fabs(x), | 53 | 64 => return fabs_f64(x), |
| 42 | 80 => return __fabsx(x), | 54 | 80 => return fabs_f80(x), |
| 43 | 128 => return fabsq(x), | 55 | 128 => return fabs_f128(x), |
| 44 | else => @compileError("unreachable"), | 56 | else => comptime unreachable, |
| 45 | } | 57 | } |
| 46 | } | 58 | } |
| 47 | 59 |
lib/compiler_rt/fixdfdi.zig deleted-23| ... | @@ -1,23 +0,0 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 3 | const symbol = compiler_rt.symbol; | ||
| 4 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 5 | |||
| 6 | comptime { | ||
| 7 | if (compiler_rt.want_aeabi) { | ||
| 8 | symbol(&__aeabi_d2lz, "__aeabi_d2lz"); | ||
| 9 | } else { | ||
| 10 | if (compiler_rt.want_windows_arm_abi) { | ||
| 11 | symbol(&__fixdfdi, "__dtoi64"); | ||
| 12 | } | ||
| 13 | symbol(&__fixdfdi, "__fixdfdi"); | ||
| 14 | } | ||
| 15 | } | ||
| 16 | |||
| 17 | pub fn __fixdfdi(a: f64) callconv(.c) i64 { | ||
| 18 | return intFromFloat(i64, a); | ||
| 19 | } | ||
| 20 | |||
| 21 | fn __aeabi_d2lz(a: f64) callconv(.{ .arm_aapcs = .{} }) i64 { | ||
| 22 | return intFromFloat(i64, a); | ||
| 23 | } | ||
lib/compiler_rt/fixdfei.zig deleted-14| ... | @@ -1,14 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const builtin = @import("builtin"); | ||
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 4 | const symbol = compiler_rt.symbol; | ||
| 5 | const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; | ||
| 6 | |||
| 7 | comptime { | ||
| 8 | symbol(&__fixdfei, "__fixdfei"); | ||
| 9 | } | ||
| 10 | |||
| 11 | pub fn __fixdfei(r: [*]u8, bits: usize, a: f64) callconv(.c) void { | ||
| 12 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | ||
| 13 | return bigIntFromFloat(.signed, @ptrCast(@alignCast(r[0..byte_size])), a); | ||
| 14 | } | ||
lib/compiler_rt/fixdfsi.zig deleted-19| ... | @@ -1,19 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_aeabi) { | ||
| 7 | symbol(&__aeabi_d2iz, "__aeabi_d2iz"); | ||
| 8 | } else { | ||
| 9 | symbol(&__fixdfsi, "__fixdfsi"); | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | pub fn __fixdfsi(a: f64) callconv(.c) i32 { | ||
| 14 | return intFromFloat(i32, a); | ||
| 15 | } | ||
| 16 | |||
| 17 | fn __aeabi_d2iz(a: f64) callconv(.{ .arm_aapcs = .{} }) i32 { | ||
| 18 | return intFromFloat(i32, a); | ||
| 19 | } | ||
lib/compiler_rt/fixdfti.zig deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__fixdfti, "__fixdfti"); | ||
| 7 | } | ||
| 8 | |||
| 9 | pub fn __fixdfti(a: f64) callconv(.c) i128 { | ||
| 10 | return intFromFloat(i128, a); | ||
| 11 | } | ||
lib/compiler_rt/fixhfei.zig deleted-14| ... | @@ -1,14 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const builtin = @import("builtin"); | ||
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 4 | const symbol = compiler_rt.symbol; | ||
| 5 | const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; | ||
| 6 | |||
| 7 | comptime { | ||
| 8 | symbol(&__fixhfei, "__fixhfei"); | ||
| 9 | } | ||
| 10 | |||
| 11 | pub fn __fixhfei(r: [*]u8, bits: usize, a: f16) callconv(.c) void { | ||
| 12 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | ||
| 13 | return bigIntFromFloat(.signed, @ptrCast(@alignCast(r[0..byte_size])), a); | ||
| 14 | } | ||
lib/compiler_rt/fixint_test.zig deleted-149| ... | @@ -1,149 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const math = std.math; | ||
| 3 | const testing = std.testing; | ||
| 4 | |||
| 5 | const fixint = @import("fixint.zig").fixint; | ||
| 6 | |||
| 7 | fn test__fixint(comptime fp_t: type, comptime fixint_t: type, a: fp_t, expected: fixint_t) !void { | ||
| 8 | const x = fixint(fp_t, fixint_t, a); | ||
| 9 | try testing.expect(x == expected); | ||
| 10 | } | ||
| 11 | |||
| 12 | test "fixint.i1" { | ||
| 13 | try test__fixint(f32, i1, -math.inf(f32), -1); | ||
| 14 | try test__fixint(f32, i1, -math.floatMax(f32), -1); | ||
| 15 | try test__fixint(f32, i1, -2.0, -1); | ||
| 16 | try test__fixint(f32, i1, -1.1, -1); | ||
| 17 | try test__fixint(f32, i1, -1.0, -1); | ||
| 18 | try test__fixint(f32, i1, -0.9, 0); | ||
| 19 | try test__fixint(f32, i1, -0.1, 0); | ||
| 20 | try test__fixint(f32, i1, -math.floatMin(f32), 0); | ||
| 21 | try test__fixint(f32, i1, -0.0, 0); | ||
| 22 | try test__fixint(f32, i1, 0.0, 0); | ||
| 23 | try test__fixint(f32, i1, math.floatMin(f32), 0); | ||
| 24 | try test__fixint(f32, i1, 0.1, 0); | ||
| 25 | try test__fixint(f32, i1, 0.9, 0); | ||
| 26 | try test__fixint(f32, i1, 1.0, 0); | ||
| 27 | try test__fixint(f32, i1, 2.0, 0); | ||
| 28 | try test__fixint(f32, i1, math.floatMax(f32), 0); | ||
| 29 | try test__fixint(f32, i1, math.inf(f32), 0); | ||
| 30 | } | ||
| 31 | |||
| 32 | test "fixint.i2" { | ||
| 33 | try test__fixint(f32, i2, -math.inf(f32), -2); | ||
| 34 | try test__fixint(f32, i2, -math.floatMax(f32), -2); | ||
| 35 | try test__fixint(f32, i2, -2.0, -2); | ||
| 36 | try test__fixint(f32, i2, -1.9, -1); | ||
| 37 | try test__fixint(f32, i2, -1.1, -1); | ||
| 38 | try test__fixint(f32, i2, -1.0, -1); | ||
| 39 | try test__fixint(f32, i2, -0.9, 0); | ||
| 40 | try test__fixint(f32, i2, -0.1, 0); | ||
| 41 | try test__fixint(f32, i2, -math.floatMin(f32), 0); | ||
| 42 | try test__fixint(f32, i2, -0.0, 0); | ||
| 43 | try test__fixint(f32, i2, 0.0, 0); | ||
| 44 | try test__fixint(f32, i2, math.floatMin(f32), 0); | ||
| 45 | try test__fixint(f32, i2, 0.1, 0); | ||
| 46 | try test__fixint(f32, i2, 0.9, 0); | ||
| 47 | try test__fixint(f32, i2, 1.0, 1); | ||
| 48 | try test__fixint(f32, i2, 2.0, 1); | ||
| 49 | try test__fixint(f32, i2, math.floatMax(f32), 1); | ||
| 50 | try test__fixint(f32, i2, math.inf(f32), 1); | ||
| 51 | } | ||
| 52 | |||
| 53 | test "fixint.i3" { | ||
| 54 | try test__fixint(f32, i3, -math.inf(f32), -4); | ||
| 55 | try test__fixint(f32, i3, -math.floatMax(f32), -4); | ||
| 56 | try test__fixint(f32, i3, -4.0, -4); | ||
| 57 | try test__fixint(f32, i3, -3.0, -3); | ||
| 58 | try test__fixint(f32, i3, -2.0, -2); | ||
| 59 | try test__fixint(f32, i3, -1.9, -1); | ||
| 60 | try test__fixint(f32, i3, -1.1, -1); | ||
| 61 | try test__fixint(f32, i3, -1.0, -1); | ||
| 62 | try test__fixint(f32, i3, -0.9, 0); | ||
| 63 | try test__fixint(f32, i3, -0.1, 0); | ||
| 64 | try test__fixint(f32, i3, -math.floatMin(f32), 0); | ||
| 65 | try test__fixint(f32, i3, -0.0, 0); | ||
| 66 | try test__fixint(f32, i3, 0.0, 0); | ||
| 67 | try test__fixint(f32, i3, math.floatMin(f32), 0); | ||
| 68 | try test__fixint(f32, i3, 0.1, 0); | ||
| 69 | try test__fixint(f32, i3, 0.9, 0); | ||
| 70 | try test__fixint(f32, i3, 1.0, 1); | ||
| 71 | try test__fixint(f32, i3, 2.0, 2); | ||
| 72 | try test__fixint(f32, i3, 3.0, 3); | ||
| 73 | try test__fixint(f32, i3, 4.0, 3); | ||
| 74 | try test__fixint(f32, i3, math.floatMax(f32), 3); | ||
| 75 | try test__fixint(f32, i3, math.inf(f32), 3); | ||
| 76 | } | ||
| 77 | |||
| 78 | test "fixint.i32" { | ||
| 79 | try test__fixint(f64, i32, -math.inf(f64), math.minInt(i32)); | ||
| 80 | try test__fixint(f64, i32, -math.floatMax(f64), math.minInt(i32)); | ||
| 81 | try test__fixint(f64, i32, @as(f64, math.minInt(i32)), math.minInt(i32)); | ||
| 82 | try test__fixint(f64, i32, @as(f64, math.minInt(i32)) + 1, math.minInt(i32) + 1); | ||
| 83 | try test__fixint(f64, i32, -2.0, -2); | ||
| 84 | try test__fixint(f64, i32, -1.9, -1); | ||
| 85 | try test__fixint(f64, i32, -1.1, -1); | ||
| 86 | try test__fixint(f64, i32, -1.0, -1); | ||
| 87 | try test__fixint(f64, i32, -0.9, 0); | ||
| 88 | try test__fixint(f64, i32, -0.1, 0); | ||
| 89 | try test__fixint(f64, i32, -@as(f64, math.floatMin(f32)), 0); | ||
| 90 | try test__fixint(f64, i32, -0.0, 0); | ||
| 91 | try test__fixint(f64, i32, 0.0, 0); | ||
| 92 | try test__fixint(f64, i32, @as(f64, math.floatMin(f32)), 0); | ||
| 93 | try test__fixint(f64, i32, 0.1, 0); | ||
| 94 | try test__fixint(f64, i32, 0.9, 0); | ||
| 95 | try test__fixint(f64, i32, 1.0, 1); | ||
| 96 | try test__fixint(f64, i32, @as(f64, math.maxInt(i32)) - 1, math.maxInt(i32) - 1); | ||
| 97 | try test__fixint(f64, i32, @as(f64, math.maxInt(i32)), math.maxInt(i32)); | ||
| 98 | try test__fixint(f64, i32, math.floatMax(f64), math.maxInt(i32)); | ||
| 99 | try test__fixint(f64, i32, math.inf(f64), math.maxInt(i32)); | ||
| 100 | } | ||
| 101 | |||
| 102 | test "fixint.i64" { | ||
| 103 | try test__fixint(f64, i64, -math.inf(f64), math.minInt(i64)); | ||
| 104 | try test__fixint(f64, i64, -math.floatMax(f64), math.minInt(i64)); | ||
| 105 | try test__fixint(f64, i64, @as(f64, math.minInt(i64)), math.minInt(i64)); | ||
| 106 | try test__fixint(f64, i64, @as(f64, math.minInt(i64)) + 1, math.minInt(i64)); | ||
| 107 | try test__fixint(f64, i64, @as(f64, math.minInt(i64) / 2), math.minInt(i64) / 2); | ||
| 108 | try test__fixint(f64, i64, -2.0, -2); | ||
| 109 | try test__fixint(f64, i64, -1.9, -1); | ||
| 110 | try test__fixint(f64, i64, -1.1, -1); | ||
| 111 | try test__fixint(f64, i64, -1.0, -1); | ||
| 112 | try test__fixint(f64, i64, -0.9, 0); | ||
| 113 | try test__fixint(f64, i64, -0.1, 0); | ||
| 114 | try test__fixint(f64, i64, -@as(f64, math.floatMin(f32)), 0); | ||
| 115 | try test__fixint(f64, i64, -0.0, 0); | ||
| 116 | try test__fixint(f64, i64, 0.0, 0); | ||
| 117 | try test__fixint(f64, i64, @as(f64, math.floatMin(f32)), 0); | ||
| 118 | try test__fixint(f64, i64, 0.1, 0); | ||
| 119 | try test__fixint(f64, i64, 0.9, 0); | ||
| 120 | try test__fixint(f64, i64, 1.0, 1); | ||
| 121 | try test__fixint(f64, i64, @as(f64, math.maxInt(i64)) - 1, math.maxInt(i64)); | ||
| 122 | try test__fixint(f64, i64, @as(f64, math.maxInt(i64)), math.maxInt(i64)); | ||
| 123 | try test__fixint(f64, i64, math.floatMax(f64), math.maxInt(i64)); | ||
| 124 | try test__fixint(f64, i64, math.inf(f64), math.maxInt(i64)); | ||
| 125 | } | ||
| 126 | |||
| 127 | test "fixint.i128" { | ||
| 128 | try test__fixint(f64, i128, -math.inf(f64), math.minInt(i128)); | ||
| 129 | try test__fixint(f64, i128, -math.floatMax(f64), math.minInt(i128)); | ||
| 130 | try test__fixint(f64, i128, @as(f64, math.minInt(i128)), math.minInt(i128)); | ||
| 131 | try test__fixint(f64, i128, @as(f64, math.minInt(i128)) + 1, math.minInt(i128)); | ||
| 132 | try test__fixint(f64, i128, -2.0, -2); | ||
| 133 | try test__fixint(f64, i128, -1.9, -1); | ||
| 134 | try test__fixint(f64, i128, -1.1, -1); | ||
| 135 | try test__fixint(f64, i128, -1.0, -1); | ||
| 136 | try test__fixint(f64, i128, -0.9, 0); | ||
| 137 | try test__fixint(f64, i128, -0.1, 0); | ||
| 138 | try test__fixint(f64, i128, -@as(f64, math.floatMin(f32)), 0); | ||
| 139 | try test__fixint(f64, i128, -0.0, 0); | ||
| 140 | try test__fixint(f64, i128, 0.0, 0); | ||
| 141 | try test__fixint(f64, i128, @as(f64, math.floatMin(f32)), 0); | ||
| 142 | try test__fixint(f64, i128, 0.1, 0); | ||
| 143 | try test__fixint(f64, i128, 0.9, 0); | ||
| 144 | try test__fixint(f64, i128, 1.0, 1); | ||
| 145 | try test__fixint(f64, i128, @as(f64, math.maxInt(i128)) - 1, math.maxInt(i128)); | ||
| 146 | try test__fixint(f64, i128, @as(f64, math.maxInt(i128)), math.maxInt(i128)); | ||
| 147 | try test__fixint(f64, i128, math.floatMax(f64), math.maxInt(i128)); | ||
| 148 | try test__fixint(f64, i128, math.inf(f64), math.maxInt(i128)); | ||
| 149 | } | ||
lib/compiler_rt/fixsfdi.zig deleted-23| ... | @@ -1,23 +0,0 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 3 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 4 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 5 | |||
| 6 | comptime { | ||
| 7 | if (compiler_rt.want_aeabi) { | ||
| 8 | symbol(&__aeabi_f2lz, "__aeabi_f2lz"); | ||
| 9 | } else { | ||
| 10 | if (compiler_rt.want_windows_arm_abi) { | ||
| 11 | symbol(&__fixsfdi, "__stoi64"); | ||
| 12 | } | ||
| 13 | symbol(&__fixsfdi, "__fixsfdi"); | ||
| 14 | } | ||
| 15 | } | ||
| 16 | |||
| 17 | pub fn __fixsfdi(a: f32) callconv(.c) i64 { | ||
| 18 | return intFromFloat(i64, a); | ||
| 19 | } | ||
| 20 | |||
| 21 | fn __aeabi_f2lz(a: f32) callconv(.{ .arm_aapcs = .{} }) i64 { | ||
| 22 | return intFromFloat(i64, a); | ||
| 23 | } | ||
lib/compiler_rt/fixsfei.zig deleted-14| ... | @@ -1,14 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const builtin = @import("builtin"); | ||
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 4 | const symbol = compiler_rt.symbol; | ||
| 5 | const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; | ||
| 6 | |||
| 7 | comptime { | ||
| 8 | symbol(&__fixsfei, "__fixsfei"); | ||
| 9 | } | ||
| 10 | |||
| 11 | pub fn __fixsfei(r: [*]u8, bits: usize, a: f32) callconv(.c) void { | ||
| 12 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | ||
| 13 | return bigIntFromFloat(.signed, @ptrCast(@alignCast(r[0..byte_size])), a); | ||
| 14 | } | ||
lib/compiler_rt/fixsfsi.zig deleted-19| ... | @@ -1,19 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_aeabi) { | ||
| 7 | symbol(&__aeabi_f2iz, "__aeabi_f2iz"); | ||
| 8 | } else { | ||
| 9 | symbol(&__fixsfsi, "__fixsfsi"); | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | pub fn __fixsfsi(a: f32) callconv(.c) i32 { | ||
| 14 | return intFromFloat(i32, a); | ||
| 15 | } | ||
| 16 | |||
| 17 | fn __aeabi_f2iz(a: f32) callconv(.{ .arm_aapcs = .{} }) i32 { | ||
| 18 | return intFromFloat(i32, a); | ||
| 19 | } | ||
lib/compiler_rt/fixsfti.zig deleted-12| ... | @@ -1,12 +0,0 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 3 | const symbol = compiler_rt.symbol; | ||
| 4 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 5 | |||
| 6 | comptime { | ||
| 7 | symbol(&__fixsfti, "__fixsfti"); | ||
| 8 | } | ||
| 9 | |||
| 10 | pub fn __fixsfti(a: f32) callconv(.c) i128 { | ||
| 11 | return intFromFloat(i128, a); | ||
| 12 | } | ||
lib/compiler_rt/fixtfdi.zig deleted-22| ... | @@ -1,22 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_ppc_abi) { | ||
| 7 | symbol(&__fixtfdi, "__fixkfdi"); | ||
| 8 | } else if (compiler_rt.want_sparc64_abi) { | ||
| 9 | symbol(&_Qp_qtox, "_Qp_qtox"); | ||
| 10 | } else if (compiler_rt.want_sparc32_abi) { | ||
| 11 | symbol(&__fixtfdi, "_Q_qtoll"); | ||
| 12 | } | ||
| 13 | symbol(&__fixtfdi, "__fixtfdi"); | ||
| 14 | } | ||
| 15 | |||
| 16 | pub fn __fixtfdi(a: f128) callconv(.c) i64 { | ||
| 17 | return intFromFloat(i64, a); | ||
| 18 | } | ||
| 19 | |||
| 20 | fn _Qp_qtox(a: *const f128) callconv(.c) i64 { | ||
| 21 | return intFromFloat(i64, a.*); | ||
| 22 | } | ||
lib/compiler_rt/fixtfei.zig deleted-14| ... | @@ -1,14 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const builtin = @import("builtin"); | ||
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 4 | const symbol = compiler_rt.symbol; | ||
| 5 | const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; | ||
| 6 | |||
| 7 | comptime { | ||
| 8 | symbol(&__fixtfei, "__fixtfei"); | ||
| 9 | } | ||
| 10 | |||
| 11 | pub fn __fixtfei(r: [*]u8, bits: usize, a: f128) callconv(.c) void { | ||
| 12 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | ||
| 13 | return bigIntFromFloat(.signed, @ptrCast(@alignCast(r[0..byte_size])), a); | ||
| 14 | } | ||
lib/compiler_rt/fixtfsi.zig deleted-22| ... | @@ -1,22 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 3 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_ppc_abi) { | ||
| 7 | symbol(&__fixtfsi, "__fixkfsi"); | ||
| 8 | } else if (compiler_rt.want_sparc64_abi) { | ||
| 9 | symbol(&_Qp_qtoi, "_Qp_qtoi"); | ||
| 10 | } else if (compiler_rt.want_sparc32_abi) { | ||
| 11 | symbol(&__fixtfsi, "_Q_qtoi"); | ||
| 12 | } | ||
| 13 | symbol(&__fixtfsi, "__fixtfsi"); | ||
| 14 | } | ||
| 15 | |||
| 16 | pub fn __fixtfsi(a: f128) callconv(.c) i32 { | ||
| 17 | return intFromFloat(i32, a); | ||
| 18 | } | ||
| 19 | |||
| 20 | fn _Qp_qtoi(a: *const f128) callconv(.c) i32 { | ||
| 21 | return intFromFloat(i32, a.*); | ||
| 22 | } | ||
lib/compiler_rt/fixtfti.zig deleted-13| ... | @@ -1,13 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_ppc_abi) | ||
| 7 | symbol(&__fixtfti, "__fixkfti"); | ||
| 8 | symbol(&__fixtfti, "__fixtfti"); | ||
| 9 | } | ||
| 10 | |||
| 11 | pub fn __fixtfti(a: f128) callconv(.c) i128 { | ||
| 12 | return intFromFloat(i128, a); | ||
| 13 | } | ||
lib/compiler_rt/fixunsdfdi.zig deleted-23| ... | @@ -1,23 +0,0 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 3 | const symbol = compiler_rt.symbol; | ||
| 4 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 5 | |||
| 6 | comptime { | ||
| 7 | if (compiler_rt.want_aeabi) { | ||
| 8 | symbol(&__aeabi_d2ulz, "__aeabi_d2ulz"); | ||
| 9 | } else { | ||
| 10 | if (compiler_rt.want_windows_arm_abi) { | ||
| 11 | symbol(&__fixunsdfdi, "__dtou64"); | ||
| 12 | } | ||
| 13 | symbol(&__fixunsdfdi, "__fixunsdfdi"); | ||
| 14 | } | ||
| 15 | } | ||
| 16 | |||
| 17 | pub fn __fixunsdfdi(a: f64) callconv(.c) u64 { | ||
| 18 | return intFromFloat(u64, a); | ||
| 19 | } | ||
| 20 | |||
| 21 | fn __aeabi_d2ulz(a: f64) callconv(.{ .arm_aapcs = .{} }) u64 { | ||
| 22 | return intFromFloat(u64, a); | ||
| 23 | } | ||
lib/compiler_rt/fixunsdfei.zig deleted-15| ... | @@ -1,15 +0,0 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | |||
| 3 | const std = @import("std"); | ||
| 4 | |||
| 5 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 6 | const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; | ||
| 7 | |||
| 8 | comptime { | ||
| 9 | symbol(&__fixunsdfei, "__fixunsdfei"); | ||
| 10 | } | ||
| 11 | |||
| 12 | pub fn __fixunsdfei(r: [*]u8, bits: usize, a: f64) callconv(.c) void { | ||
| 13 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | ||
| 14 | return bigIntFromFloat(.unsigned, @ptrCast(@alignCast(r[0..byte_size])), a); | ||
| 15 | } | ||
lib/compiler_rt/fixunsdfsi.zig deleted-19| ... | @@ -1,19 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_aeabi) { | ||
| 7 | symbol(&__aeabi_d2uiz, "__aeabi_d2uiz"); | ||
| 8 | } else { | ||
| 9 | symbol(&__fixunsdfsi, "__fixunsdfsi"); | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | pub fn __fixunsdfsi(a: f64) callconv(.c) u32 { | ||
| 14 | return intFromFloat(u32, a); | ||
| 15 | } | ||
| 16 | |||
| 17 | fn __aeabi_d2uiz(a: f64) callconv(.{ .arm_aapcs = .{} }) u32 { | ||
| 18 | return intFromFloat(u32, a); | ||
| 19 | } | ||
lib/compiler_rt/fixunsdfti.zig deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 3 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__fixunsdfti, "__fixunsdfti"); | ||
| 7 | } | ||
| 8 | |||
| 9 | pub fn __fixunsdfti(a: f64) callconv(.c) u128 { | ||
| 10 | return intFromFloat(u128, a); | ||
| 11 | } | ||
lib/compiler_rt/fixunshfdi.zig deleted-10| ... | @@ -1,10 +0,0 @@ | ||
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 2 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 3 | |||
| 4 | comptime { | ||
| 5 | symbol(&__fixunshfdi, "__fixunshfdi"); | ||
| 6 | } | ||
| 7 | |||
| 8 | fn __fixunshfdi(a: f16) callconv(.c) u64 { | ||
| 9 | return intFromFloat(u64, a); | ||
| 10 | } | ||
lib/compiler_rt/fixunshfei.zig deleted-15| ... | @@ -1,15 +0,0 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | |||
| 3 | const std = @import("std"); | ||
| 4 | |||
| 5 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 6 | const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; | ||
| 7 | |||
| 8 | comptime { | ||
| 9 | symbol(&__fixunshfei, "__fixunshfei"); | ||
| 10 | } | ||
| 11 | |||
| 12 | pub fn __fixunshfei(r: [*]u8, bits: usize, a: f16) callconv(.c) void { | ||
| 13 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | ||
| 14 | return bigIntFromFloat(.unsigned, @ptrCast(@alignCast(r[0..byte_size])), a); | ||
| 15 | } | ||
lib/compiler_rt/fixunshfsi.zig deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__fixunshfsi, "__fixunshfsi"); | ||
| 7 | } | ||
| 8 | |||
| 9 | fn __fixunshfsi(a: f16) callconv(.c) u32 { | ||
| 10 | return intFromFloat(u32, a); | ||
| 11 | } | ||
lib/compiler_rt/fixunshfti.zig deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__fixunshfti, "__fixunshfti"); | ||
| 7 | } | ||
| 8 | |||
| 9 | pub fn __fixunshfti(a: f16) callconv(.c) u128 { | ||
| 10 | return intFromFloat(u128, a); | ||
| 11 | } | ||
lib/compiler_rt/fixunssfdi.zig deleted-23| ... | @@ -1,23 +0,0 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 3 | const symbol = compiler_rt.symbol; | ||
| 4 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 5 | |||
| 6 | comptime { | ||
| 7 | if (compiler_rt.want_aeabi) { | ||
| 8 | symbol(&__aeabi_f2ulz, "__aeabi_f2ulz"); | ||
| 9 | } else { | ||
| 10 | if (compiler_rt.want_windows_arm_abi) { | ||
| 11 | symbol(&__fixunssfdi, "__stou64"); | ||
| 12 | } | ||
| 13 | symbol(&__fixunssfdi, "__fixunssfdi"); | ||
| 14 | } | ||
| 15 | } | ||
| 16 | |||
| 17 | pub fn __fixunssfdi(a: f32) callconv(.c) u64 { | ||
| 18 | return intFromFloat(u64, a); | ||
| 19 | } | ||
| 20 | |||
| 21 | fn __aeabi_f2ulz(a: f32) callconv(.{ .arm_aapcs = .{} }) u64 { | ||
| 22 | return intFromFloat(u64, a); | ||
| 23 | } | ||
lib/compiler_rt/fixunssfei.zig deleted-15| ... | @@ -1,15 +0,0 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | |||
| 3 | const std = @import("std"); | ||
| 4 | |||
| 5 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 6 | const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; | ||
| 7 | |||
| 8 | comptime { | ||
| 9 | symbol(&__fixunssfei, "__fixunssfei"); | ||
| 10 | } | ||
| 11 | |||
| 12 | pub fn __fixunssfei(r: [*]u8, bits: usize, a: f32) callconv(.c) void { | ||
| 13 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | ||
| 14 | return bigIntFromFloat(.unsigned, @ptrCast(@alignCast(r[0..byte_size])), a); | ||
| 15 | } | ||
lib/compiler_rt/fixunssfsi.zig deleted-19| ... | @@ -1,19 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_aeabi) { | ||
| 7 | symbol(&__aeabi_f2uiz, "__aeabi_f2uiz"); | ||
| 8 | } else { | ||
| 9 | symbol(&__fixunssfsi, "__fixunssfsi"); | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | pub fn __fixunssfsi(a: f32) callconv(.c) u32 { | ||
| 14 | return intFromFloat(u32, a); | ||
| 15 | } | ||
| 16 | |||
| 17 | fn __aeabi_f2uiz(a: f32) callconv(.{ .arm_aapcs = .{} }) u32 { | ||
| 18 | return intFromFloat(u32, a); | ||
| 19 | } | ||
lib/compiler_rt/fixunssfti.zig deleted-12| ... | @@ -1,12 +0,0 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 3 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 4 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 5 | |||
| 6 | comptime { | ||
| 7 | symbol(&__fixunssfti, "__fixunssfti"); | ||
| 8 | } | ||
| 9 | |||
| 10 | pub fn __fixunssfti(a: f32) callconv(.c) u128 { | ||
| 11 | return intFromFloat(u128, a); | ||
| 12 | } | ||
lib/compiler_rt/fixunstfdi.zig deleted-22| ... | @@ -1,22 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_ppc_abi) { | ||
| 7 | symbol(&__fixunstfdi, "__fixunskfdi"); | ||
| 8 | } else if (compiler_rt.want_sparc64_abi) { | ||
| 9 | symbol(&_Qp_qtoux, "_Qp_qtoux"); | ||
| 10 | } else if (compiler_rt.want_sparc32_abi) { | ||
| 11 | symbol(&__fixunstfdi, "_Q_qtoull"); | ||
| 12 | } | ||
| 13 | symbol(&__fixunstfdi, "__fixunstfdi"); | ||
| 14 | } | ||
| 15 | |||
| 16 | pub fn __fixunstfdi(a: f128) callconv(.c) u64 { | ||
| 17 | return intFromFloat(u64, a); | ||
| 18 | } | ||
| 19 | |||
| 20 | fn _Qp_qtoux(a: *const f128) callconv(.c) u64 { | ||
| 21 | return intFromFloat(u64, a.*); | ||
| 22 | } | ||
lib/compiler_rt/fixunstfei.zig deleted-15| ... | @@ -1,15 +0,0 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | |||
| 3 | const std = @import("std"); | ||
| 4 | |||
| 5 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 6 | const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; | ||
| 7 | |||
| 8 | comptime { | ||
| 9 | symbol(&__fixunstfei, "__fixunstfei"); | ||
| 10 | } | ||
| 11 | |||
| 12 | pub fn __fixunstfei(r: [*]u8, bits: usize, a: f128) callconv(.c) void { | ||
| 13 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | ||
| 14 | return bigIntFromFloat(.unsigned, @ptrCast(@alignCast(r[0..byte_size])), a); | ||
| 15 | } | ||
lib/compiler_rt/fixunstfsi.zig deleted-22| ... | @@ -1,22 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_ppc_abi) { | ||
| 7 | symbol(&__fixunstfsi, "__fixunskfsi"); | ||
| 8 | } else if (compiler_rt.want_sparc64_abi) { | ||
| 9 | symbol(&_Qp_qtoui, "_Qp_qtoui"); | ||
| 10 | } else if (compiler_rt.want_sparc32_abi) { | ||
| 11 | symbol(&__fixunstfsi, "_Q_qtou"); | ||
| 12 | } | ||
| 13 | symbol(&__fixunstfsi, "__fixunstfsi"); | ||
| 14 | } | ||
| 15 | |||
| 16 | pub fn __fixunstfsi(a: f128) callconv(.c) u32 { | ||
| 17 | return intFromFloat(u32, a); | ||
| 18 | } | ||
| 19 | |||
| 20 | fn _Qp_qtoui(a: *const f128) callconv(.c) u32 { | ||
| 21 | return intFromFloat(u32, a.*); | ||
| 22 | } | ||
lib/compiler_rt/fixunstfti.zig deleted-14| ... | @@ -1,14 +0,0 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 3 | const symbol = compiler_rt.symbol; | ||
| 4 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 5 | |||
| 6 | comptime { | ||
| 7 | if (compiler_rt.want_ppc_abi) | ||
| 8 | symbol(&__fixunstfti, "__fixunskfti"); | ||
| 9 | symbol(&__fixunstfti, "__fixunstfti"); | ||
| 10 | } | ||
| 11 | |||
| 12 | pub fn __fixunstfti(a: f128) callconv(.c) u128 { | ||
| 13 | return intFromFloat(u128, a); | ||
| 14 | } | ||
lib/compiler_rt/fixunsxfdi.zig deleted-10| ... | @@ -1,10 +0,0 @@ | ||
| 1 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 3 | |||
| 4 | comptime { | ||
| 5 | symbol(&__fixunsxfdi, "__fixunsxfdi"); | ||
| 6 | } | ||
| 7 | |||
| 8 | fn __fixunsxfdi(a: f80) callconv(.c) u64 { | ||
| 9 | return intFromFloat(u64, a); | ||
| 10 | } | ||
lib/compiler_rt/fixunsxfei.zig deleted-13| ... | @@ -1,13 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const builtin = @import("builtin"); | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; | ||
| 5 | |||
| 6 | comptime { | ||
| 7 | symbol(&__fixunsxfei, "__fixunsxfei"); | ||
| 8 | } | ||
| 9 | |||
| 10 | pub fn __fixunsxfei(r: [*]u8, bits: usize, a: f80) callconv(.c) void { | ||
| 11 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | ||
| 12 | return bigIntFromFloat(.unsigned, @ptrCast(@alignCast(r[0..byte_size])), a); | ||
| 13 | } | ||
lib/compiler_rt/fixunsxfsi.zig deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__fixunsxfsi, "__fixunsxfsi"); | ||
| 7 | } | ||
| 8 | |||
| 9 | fn __fixunsxfsi(a: f80) callconv(.c) u32 { | ||
| 10 | return intFromFloat(u32, a); | ||
| 11 | } | ||
lib/compiler_rt/fixunsxfti.zig deleted-12| ... | @@ -1,12 +0,0 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 3 | const symbol = compiler_rt.symbol; | ||
| 4 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 5 | |||
| 6 | comptime { | ||
| 7 | symbol(&__fixunsxfti, "__fixunsxfti"); | ||
| 8 | } | ||
| 9 | |||
| 10 | pub fn __fixunsxfti(a: f80) callconv(.c) u128 { | ||
| 11 | return intFromFloat(u128, a); | ||
| 12 | } | ||
lib/compiler_rt/fixxfdi.zig deleted-10| ... | @@ -1,10 +0,0 @@ | ||
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 2 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 3 | |||
| 4 | comptime { | ||
| 5 | symbol(&__fixxfdi, "__fixxfdi"); | ||
| 6 | } | ||
| 7 | |||
| 8 | fn __fixxfdi(a: f80) callconv(.c) i64 { | ||
| 9 | return intFromFloat(i64, a); | ||
| 10 | } | ||
lib/compiler_rt/fixxfei.zig deleted-14| ... | @@ -1,14 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const builtin = @import("builtin"); | ||
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 4 | const symbol = compiler_rt.symbol; | ||
| 5 | const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; | ||
| 6 | |||
| 7 | comptime { | ||
| 8 | symbol(&__fixxfei, "__fixxfei"); | ||
| 9 | } | ||
| 10 | |||
| 11 | pub fn __fixxfei(r: [*]u8, bits: usize, a: f80) callconv(.c) void { | ||
| 12 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | ||
| 13 | return bigIntFromFloat(.signed, @ptrCast(@alignCast(r[0..byte_size])), a); | ||
| 14 | } | ||
lib/compiler_rt/fixxfsi.zig deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__fixxfsi, "__fixxfsi"); | ||
| 7 | } | ||
| 8 | |||
| 9 | fn __fixxfsi(a: f80) callconv(.c) i32 { | ||
| 10 | return intFromFloat(i32, a); | ||
| 11 | } | ||
lib/compiler_rt/float_from_int.zig+472-4| ... | @@ -1,7 +1,475 @@ | ... | @@ -1,7 +1,475 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 1 | const std = @import("std"); | 2 | const std = @import("std"); |
| 2 | const math = std.math; | 3 | const math = std.math; |
| 3 | 4 | ||
| 4 | pub fn floatFromInt(comptime T: type, x: anytype) T { | 5 | const compiler_rt = @import("../compiler_rt.zig"); |
| 6 | const symbol = compiler_rt.symbol; | ||
| 7 | |||
| 8 | comptime { | ||
| 9 | symbol(&__floatsihf, "__floatsihf"); | ||
| 10 | symbol(&__floatdihf, "__floatdihf"); | ||
| 11 | symbol(&__floattihf, "__floattihf"); | ||
| 12 | symbol(&__floateihf, "__floateihf"); | ||
| 13 | |||
| 14 | if (compiler_rt.want_aeabi) { | ||
| 15 | symbol(&__aeabi_i2f, "__aeabi_i2f"); | ||
| 16 | symbol(&__aeabi_l2f, "__aeabi_l2f"); | ||
| 17 | } else { | ||
| 18 | symbol(&__floatsisf, "__floatsisf"); | ||
| 19 | symbol(&__floatdisf, "__floatdisf"); | ||
| 20 | if (compiler_rt.want_windows_arm_abi) symbol(&__floatdisf, "__i64tos"); | ||
| 21 | } | ||
| 22 | symbol(&__floattisf, "__floattisf"); | ||
| 23 | symbol(&__floateisf, "__floateisf"); | ||
| 24 | |||
| 25 | if (compiler_rt.want_aeabi) { | ||
| 26 | symbol(&__aeabi_i2d, "__aeabi_i2d"); | ||
| 27 | symbol(&__aeabi_l2d, "__aeabi_l2d"); | ||
| 28 | } else { | ||
| 29 | symbol(&__floatsidf, "__floatsidf"); | ||
| 30 | symbol(&__floatdidf, "__floatdidf"); | ||
| 31 | if (compiler_rt.want_windows_arm_abi) symbol(&__floatdidf, "__i64tod"); | ||
| 32 | } | ||
| 33 | symbol(&__floattidf, "__floattidf"); | ||
| 34 | symbol(&__floateidf, "__floateidf"); | ||
| 35 | |||
| 36 | symbol(&__floatsixf, "__floatsixf"); | ||
| 37 | symbol(&__floatdixf, "__floatdixf"); | ||
| 38 | symbol(&__floattixf, "__floattixf"); | ||
| 39 | symbol(&__floateixf, "__floateixf"); | ||
| 40 | |||
| 41 | if (compiler_rt.want_ppc_abi) { | ||
| 42 | symbol(&__floatsitf, "__floatsikf"); | ||
| 43 | symbol(&__floatditf, "__floatdikf"); | ||
| 44 | } else if (compiler_rt.want_sparc64_abi) { | ||
| 45 | symbol(&_Qp_itoq, "_Qp_itoq"); | ||
| 46 | symbol(&_Qp_xtoq, "_Qp_xtoq"); | ||
| 47 | } else if (compiler_rt.want_sparc32_abi) { | ||
| 48 | symbol(&__floatsitf, "_Q_itoq"); | ||
| 49 | symbol(&__floatditf, "_Q_lltoq"); | ||
| 50 | } else { | ||
| 51 | symbol(&__floatsitf, "__floatsitf"); | ||
| 52 | symbol(&__floatditf, "__floatditf"); | ||
| 53 | } | ||
| 54 | if (compiler_rt.want_ppc_abi) { | ||
| 55 | symbol(&__floattitf, "__floattikf"); | ||
| 56 | symbol(&__floateitf, "__floateikf"); | ||
| 57 | } else { | ||
| 58 | if (builtin.cpu.arch == .x86) { | ||
| 59 | symbol(&__floattitf_x86, "__floattitf"); | ||
| 60 | } else { | ||
| 61 | symbol(&__floattitf, "__floattitf"); | ||
| 62 | } | ||
| 63 | symbol(&__floateitf, "__floateitf"); | ||
| 64 | } | ||
| 65 | } | ||
| 66 | |||
| 67 | fn __floatsihf(a: i32) callconv(.c) compiler_rt.f16.Abi { | ||
| 68 | return compiler_rt.f16.toAbi(f16_floatFromInt_i32(a)); | ||
| 69 | } | ||
| 70 | pub fn f16_floatFromInt_i32(a: i32) f16 { | ||
| 71 | return floatFromInt(f16, a); | ||
| 72 | } | ||
| 73 | |||
| 74 | fn __floatdihf(a: i64) callconv(.c) compiler_rt.f16.Abi { | ||
| 75 | return compiler_rt.f16.toAbi(f16_floatFromInt_i64(a)); | ||
| 76 | } | ||
| 77 | pub fn f16_floatFromInt_i64(a: i64) f16 { | ||
| 78 | return floatFromInt(f16, a); | ||
| 79 | } | ||
| 80 | |||
| 81 | fn __floattihf(a: i128) callconv(.c) compiler_rt.f16.Abi { | ||
| 82 | return compiler_rt.f16.toAbi(f16_floatFromInt_i128(a)); | ||
| 83 | } | ||
| 84 | pub fn f16_floatFromInt_i128(a: i128) f16 { | ||
| 85 | return floatFromInt(f16, a); | ||
| 86 | } | ||
| 87 | |||
| 88 | fn __floateihf(a: [*]const u8, bits: usize) callconv(.c) compiler_rt.f16.Abi { | ||
| 89 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | ||
| 90 | return compiler_rt.f16.toAbi(f16_floatFromInt_signed(a[0..byte_size])); | ||
| 91 | } | ||
| 92 | pub fn f16_floatFromInt_signed(a: []const u8) f16 { | ||
| 93 | return floatFromBigInt(f16, .signed, @ptrCast(@alignCast(a))); | ||
| 94 | } | ||
| 95 | |||
| 96 | fn __floatsisf(a: i32) callconv(.c) compiler_rt.f32.Abi { | ||
| 97 | return compiler_rt.f32.toAbi(f32_floatFromInt_i32(a)); | ||
| 98 | } | ||
| 99 | fn __aeabi_i2f(a: i32) callconv(.{ .arm_aapcs = .{} }) f32 { | ||
| 100 | return f32_floatFromInt_i32(a); | ||
| 101 | } | ||
| 102 | pub fn f32_floatFromInt_i32(a: i32) f32 { | ||
| 103 | return floatFromInt(f32, a); | ||
| 104 | } | ||
| 105 | |||
| 106 | fn __floatdisf(a: i64) callconv(.c) compiler_rt.f32.Abi { | ||
| 107 | return compiler_rt.f32.toAbi(f32_floatFromInt_i64(a)); | ||
| 108 | } | ||
| 109 | fn __aeabi_l2f(a: i64) callconv(.{ .arm_aapcs = .{} }) f32 { | ||
| 110 | return f32_floatFromInt_i64(a); | ||
| 111 | } | ||
| 112 | pub fn f32_floatFromInt_i64(a: i64) f32 { | ||
| 113 | return floatFromInt(f32, a); | ||
| 114 | } | ||
| 115 | |||
| 116 | fn __floattisf(a: i128) callconv(.c) compiler_rt.f32.Abi { | ||
| 117 | return compiler_rt.f32.toAbi(f32_floatFromInt_i128(a)); | ||
| 118 | } | ||
| 119 | pub fn f32_floatFromInt_i128(a: i128) f32 { | ||
| 120 | return floatFromInt(f32, a); | ||
| 121 | } | ||
| 122 | |||
| 123 | fn __floateisf(a: [*]const u8, bits: usize) callconv(.c) compiler_rt.f32.Abi { | ||
| 124 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | ||
| 125 | return compiler_rt.f32.toAbi(f32_floatFromInt_signed(a[0..byte_size])); | ||
| 126 | } | ||
| 127 | pub fn f32_floatFromInt_signed(a: []const u8) f32 { | ||
| 128 | return floatFromBigInt(f32, .signed, @ptrCast(@alignCast(a))); | ||
| 129 | } | ||
| 130 | |||
| 131 | fn __floatsidf(a: i32) callconv(.c) compiler_rt.f64.Abi { | ||
| 132 | return compiler_rt.f64.toAbi(f64_floatFromInt_i32(a)); | ||
| 133 | } | ||
| 134 | fn __aeabi_i2d(a: i32) callconv(.{ .arm_aapcs = .{} }) f64 { | ||
| 135 | return f64_floatFromInt_i32(a); | ||
| 136 | } | ||
| 137 | pub fn f64_floatFromInt_i32(a: i32) f64 { | ||
| 138 | return floatFromInt(f64, a); | ||
| 139 | } | ||
| 140 | |||
| 141 | fn __floatdidf(a: i64) callconv(.c) compiler_rt.f64.Abi { | ||
| 142 | return compiler_rt.f64.toAbi(f64_floatFromInt_i64(a)); | ||
| 143 | } | ||
| 144 | fn __aeabi_l2d(a: i64) callconv(.{ .arm_aapcs = .{} }) f64 { | ||
| 145 | return f64_floatFromInt_i64(a); | ||
| 146 | } | ||
| 147 | pub fn f64_floatFromInt_i64(a: i64) f64 { | ||
| 148 | return floatFromInt(f64, a); | ||
| 149 | } | ||
| 150 | |||
| 151 | fn __floattidf(a: i128) callconv(.c) compiler_rt.f64.Abi { | ||
| 152 | return compiler_rt.f64.toAbi(f64_floatFromInt_i128(a)); | ||
| 153 | } | ||
| 154 | pub fn f64_floatFromInt_i128(a: i128) f64 { | ||
| 155 | return floatFromInt(f64, a); | ||
| 156 | } | ||
| 157 | |||
| 158 | fn __floateidf(a: [*]const u8, bits: usize) callconv(.c) compiler_rt.f64.Abi { | ||
| 159 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | ||
| 160 | return compiler_rt.f64.toAbi(f64_floatFromInt_signed(a[0..byte_size])); | ||
| 161 | } | ||
| 162 | pub fn f64_floatFromInt_signed(a: []const u8) f64 { | ||
| 163 | return floatFromBigInt(f64, .signed, @ptrCast(@alignCast(a))); | ||
| 164 | } | ||
| 165 | |||
| 166 | fn __floatsixf(a: i32) callconv(.c) compiler_rt.f80.Abi { | ||
| 167 | return compiler_rt.f80.toAbi(f80_floatFromInt_i32(a)); | ||
| 168 | } | ||
| 169 | pub fn f80_floatFromInt_i32(a: i32) f80 { | ||
| 170 | return floatFromInt(f80, a); | ||
| 171 | } | ||
| 172 | |||
| 173 | fn __floatdixf(a: i64) callconv(.c) compiler_rt.f80.Abi { | ||
| 174 | return compiler_rt.f80.toAbi(f80_floatFromInt_i64(a)); | ||
| 175 | } | ||
| 176 | pub fn f80_floatFromInt_i64(a: i64) f80 { | ||
| 177 | return floatFromInt(f80, a); | ||
| 178 | } | ||
| 179 | |||
| 180 | fn __floattixf(a: i128) callconv(.c) compiler_rt.f80.Abi { | ||
| 181 | return compiler_rt.f80.toAbi(f80_floatFromInt_i128(a)); | ||
| 182 | } | ||
| 183 | pub fn f80_floatFromInt_i128(a: i128) f80 { | ||
| 184 | return floatFromInt(f80, a); | ||
| 185 | } | ||
| 186 | |||
| 187 | fn __floateixf(a: [*]const u8, bits: usize) callconv(.c) compiler_rt.f80.Abi { | ||
| 188 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | ||
| 189 | return compiler_rt.f80.toAbi(f80_floatFromInt_signed(a[0..byte_size])); | ||
| 190 | } | ||
| 191 | pub fn f80_floatFromInt_signed(a: []const u8) f80 { | ||
| 192 | return floatFromBigInt(f80, .signed, @ptrCast(@alignCast(a))); | ||
| 193 | } | ||
| 194 | |||
| 195 | fn __floatsitf(a: i32) callconv(.c) compiler_rt.f128.Abi { | ||
| 196 | return compiler_rt.f128.toAbi(f128_floatFromInt_i32(a)); | ||
| 197 | } | ||
| 198 | fn _Qp_itoq(c: *f128, a: i32) callconv(.c) void { | ||
| 199 | c.* = f128_floatFromInt_i32(a); | ||
| 200 | } | ||
| 201 | pub fn f128_floatFromInt_i32(a: i32) f128 { | ||
| 202 | return floatFromInt(f128, a); | ||
| 203 | } | ||
| 204 | |||
| 205 | fn __floatditf(a: i64) callconv(.c) compiler_rt.f128.Abi { | ||
| 206 | return compiler_rt.f128.toAbi(f128_floatFromInt_i64(a)); | ||
| 207 | } | ||
| 208 | fn _Qp_xtoq(c: *f128, a: i64) callconv(.c) void { | ||
| 209 | c.* = f128_floatFromInt_i64(a); | ||
| 210 | } | ||
| 211 | pub fn f128_floatFromInt_i64(a: i64) f128 { | ||
| 212 | return floatFromInt(f128, a); | ||
| 213 | } | ||
| 214 | |||
| 215 | fn __floattitf(a: i128) callconv(.c) compiler_rt.f128.Abi { | ||
| 216 | return compiler_rt.f128.toAbi(f128_floatFromInt_i128(a)); | ||
| 217 | } | ||
| 218 | fn __floattitf_x86(a: f128) callconv(.c) compiler_rt.f128.Abi { | ||
| 219 | return compiler_rt.f128.toAbi(f128_floatFromInt_i128(@bitCast(a))); | ||
| 220 | } | ||
| 221 | pub fn f128_floatFromInt_i128(a: i128) f128 { | ||
| 222 | return floatFromInt(f128, a); | ||
| 223 | } | ||
| 224 | |||
| 225 | fn __floateitf(a: [*]const u8, bits: usize) callconv(.c) compiler_rt.f128.Abi { | ||
| 226 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | ||
| 227 | return compiler_rt.f128.toAbi(f128_floatFromInt_signed(a[0..byte_size])); | ||
| 228 | } | ||
| 229 | pub fn f128_floatFromInt_signed(a: []const u8) f128 { | ||
| 230 | return floatFromBigInt(f128, .signed, @ptrCast(@alignCast(a))); | ||
| 231 | } | ||
| 232 | |||
| 233 | comptime { | ||
| 234 | symbol(&__floatunsihf, "__floatunsihf"); | ||
| 235 | symbol(&__floatundihf, "__floatundihf"); | ||
| 236 | symbol(&__floatuntihf, "__floatuntihf"); | ||
| 237 | symbol(&__floatuneihf, "__floatuneihf"); | ||
| 238 | |||
| 239 | if (compiler_rt.want_aeabi) { | ||
| 240 | symbol(&__aeabi_ui2f, "__aeabi_ui2f"); | ||
| 241 | symbol(&__aeabi_ul2f, "__aeabi_ul2f"); | ||
| 242 | } else { | ||
| 243 | symbol(&__floatunsisf, "__floatunsisf"); | ||
| 244 | symbol(&__floatundisf, "__floatundisf"); | ||
| 245 | if (compiler_rt.want_windows_arm_abi) symbol(&__floatundisf, "__u64tos"); | ||
| 246 | } | ||
| 247 | symbol(&__floatuntisf, "__floatuntisf"); | ||
| 248 | symbol(&__floatuneisf, "__floatuneisf"); | ||
| 249 | |||
| 250 | if (compiler_rt.want_aeabi) { | ||
| 251 | symbol(&__aeabi_ui2d, "__aeabi_ui2d"); | ||
| 252 | } else { | ||
| 253 | symbol(&__floatunsidf, "__floatunsidf"); | ||
| 254 | } | ||
| 255 | if (compiler_rt.want_aeabi) { | ||
| 256 | symbol(&__aeabi_ul2d, "__aeabi_ul2d"); | ||
| 257 | } else { | ||
| 258 | if (compiler_rt.want_windows_arm_abi) { | ||
| 259 | symbol(&__floatundidf, "__u64tod"); | ||
| 260 | } | ||
| 261 | symbol(&__floatundidf, "__floatundidf"); | ||
| 262 | } | ||
| 263 | symbol(&__floatuntidf, "__floatuntidf"); | ||
| 264 | symbol(&__floatuneidf, "__floatuneidf"); | ||
| 265 | |||
| 266 | symbol(&__floatunsixf, "__floatunsixf"); | ||
| 267 | symbol(&__floatundixf, "__floatundixf"); | ||
| 268 | symbol(&__floatuntixf, "__floatuntixf"); | ||
| 269 | symbol(&__floatuneixf, "__floatuneixf"); | ||
| 270 | |||
| 271 | if (compiler_rt.want_ppc_abi) { | ||
| 272 | symbol(&__floatunsitf, "__floatunsikf"); | ||
| 273 | symbol(&__floatunditf, "__floatundikf"); | ||
| 274 | } else if (compiler_rt.want_sparc64_abi) { | ||
| 275 | symbol(&_Qp_uitoq, "_Qp_uitoq"); | ||
| 276 | symbol(&_Qp_uxtoq, "_Qp_uxtoq"); | ||
| 277 | } else if (compiler_rt.want_sparc32_abi) { | ||
| 278 | symbol(&__floatunsitf, "_Q_utoq"); | ||
| 279 | symbol(&__floatunditf, "_Q_ulltoq"); | ||
| 280 | } else { | ||
| 281 | symbol(&__floatunsitf, "__floatunsitf"); | ||
| 282 | symbol(&__floatunditf, "__floatunditf"); | ||
| 283 | } | ||
| 284 | if (compiler_rt.want_ppc_abi) { | ||
| 285 | symbol(&__floatuntitf, "__floatuntikf"); | ||
| 286 | symbol(&__floatuneitf, "__floatuneikf"); | ||
| 287 | } else { | ||
| 288 | if (builtin.cpu.arch == .x86) { | ||
| 289 | symbol(&__floatuntitf_x86, "__floatuntitf"); | ||
| 290 | } else if (builtin.cpu.arch == .x86_64 and | ||
| 291 | (builtin.os.tag == .windows or builtin.os.tag == .uefi)) | ||
| 292 | { | ||
| 293 | symbol(&__floatuntitf_x86_64_windows, "__floatuntitf"); | ||
| 294 | } else { | ||
| 295 | symbol(&__floatuntitf, "__floatuntitf"); | ||
| 296 | } | ||
| 297 | symbol(&__floatuneitf, "__floatuneitf"); | ||
| 298 | } | ||
| 299 | } | ||
| 300 | |||
| 301 | fn __floatunsihf(a: u32) callconv(.c) compiler_rt.f16.Abi { | ||
| 302 | return compiler_rt.f16.toAbi(f16_floatFromInt_u32(a)); | ||
| 303 | } | ||
| 304 | pub fn f16_floatFromInt_u32(a: u32) f16 { | ||
| 305 | return floatFromInt(f16, a); | ||
| 306 | } | ||
| 307 | |||
| 308 | fn __floatundihf(a: u64) callconv(.c) compiler_rt.f16.Abi { | ||
| 309 | return compiler_rt.f16.toAbi(f16_floatFromInt_u64(a)); | ||
| 310 | } | ||
| 311 | pub fn f16_floatFromInt_u64(a: u64) f16 { | ||
| 312 | return floatFromInt(f16, a); | ||
| 313 | } | ||
| 314 | |||
| 315 | fn __floatuntihf(a: u128) callconv(.c) compiler_rt.f16.Abi { | ||
| 316 | return compiler_rt.f16.toAbi(f16_floatFromInt_u128(a)); | ||
| 317 | } | ||
| 318 | pub fn f16_floatFromInt_u128(a: u128) f16 { | ||
| 319 | return floatFromInt(f16, a); | ||
| 320 | } | ||
| 321 | |||
| 322 | fn __floatuneihf(a: [*]const u8, bits: usize) callconv(.c) compiler_rt.f16.Abi { | ||
| 323 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | ||
| 324 | return compiler_rt.f16.toAbi(f16_floatFromInt_unsigned(a[0..byte_size])); | ||
| 325 | } | ||
| 326 | pub fn f16_floatFromInt_unsigned(a: []const u8) f16 { | ||
| 327 | return floatFromBigInt(f16, .unsigned, @ptrCast(@alignCast(a))); | ||
| 328 | } | ||
| 329 | |||
| 330 | fn __floatunsisf(a: u32) callconv(.c) compiler_rt.f32.Abi { | ||
| 331 | return compiler_rt.f32.toAbi(f32_floatFromInt_u32(a)); | ||
| 332 | } | ||
| 333 | fn __aeabi_ui2f(a: u32) callconv(.{ .arm_aapcs = .{} }) f32 { | ||
| 334 | return f32_floatFromInt_u32(a); | ||
| 335 | } | ||
| 336 | pub fn f32_floatFromInt_u32(a: u32) f32 { | ||
| 337 | return floatFromInt(f32, a); | ||
| 338 | } | ||
| 339 | |||
| 340 | fn __floatundisf(a: u64) callconv(.c) compiler_rt.f32.Abi { | ||
| 341 | return compiler_rt.f32.toAbi(f32_floatFromInt_u64(a)); | ||
| 342 | } | ||
| 343 | fn __aeabi_ul2f(a: u64) callconv(.{ .arm_aapcs = .{} }) f32 { | ||
| 344 | return f32_floatFromInt_u64(a); | ||
| 345 | } | ||
| 346 | pub fn f32_floatFromInt_u64(a: u64) f32 { | ||
| 347 | return floatFromInt(f32, a); | ||
| 348 | } | ||
| 349 | |||
| 350 | fn __floatuntisf(a: u128) callconv(.c) compiler_rt.f32.Abi { | ||
| 351 | return compiler_rt.f32.toAbi(f32_floatFromInt_u128(a)); | ||
| 352 | } | ||
| 353 | pub fn f32_floatFromInt_u128(a: u128) f32 { | ||
| 354 | return floatFromInt(f32, a); | ||
| 355 | } | ||
| 356 | |||
| 357 | fn __floatuneisf(a: [*]const u8, bits: usize) callconv(.c) compiler_rt.f32.Abi { | ||
| 358 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | ||
| 359 | return compiler_rt.f32.toAbi(f32_floatFromInt_unsigned(a[0..byte_size])); | ||
| 360 | } | ||
| 361 | pub fn f32_floatFromInt_unsigned(a: []const u8) f32 { | ||
| 362 | return floatFromBigInt(f32, .unsigned, @ptrCast(@alignCast(a))); | ||
| 363 | } | ||
| 364 | |||
| 365 | fn __floatunsidf(a: u32) callconv(.c) compiler_rt.f64.Abi { | ||
| 366 | return compiler_rt.f64.toAbi(f64_floatFromInt_u32(a)); | ||
| 367 | } | ||
| 368 | fn __aeabi_ui2d(a: u32) callconv(.{ .arm_aapcs = .{} }) f64 { | ||
| 369 | return f64_floatFromInt_u32(a); | ||
| 370 | } | ||
| 371 | pub fn f64_floatFromInt_u32(a: u32) f64 { | ||
| 372 | return floatFromInt(f64, a); | ||
| 373 | } | ||
| 374 | |||
| 375 | fn __floatundidf(a: u64) callconv(.c) compiler_rt.f64.Abi { | ||
| 376 | return compiler_rt.f64.toAbi(f64_floatFromInt_u64(a)); | ||
| 377 | } | ||
| 378 | fn __aeabi_ul2d(a: u64) callconv(.{ .arm_aapcs = .{} }) f64 { | ||
| 379 | return f64_floatFromInt_u64(a); | ||
| 380 | } | ||
| 381 | pub fn f64_floatFromInt_u64(a: u64) f64 { | ||
| 382 | return floatFromInt(f64, a); | ||
| 383 | } | ||
| 384 | |||
| 385 | fn __floatuntidf(a: u128) callconv(.c) compiler_rt.f64.Abi { | ||
| 386 | return compiler_rt.f64.toAbi(f64_floatFromInt_u128(a)); | ||
| 387 | } | ||
| 388 | pub fn f64_floatFromInt_u128(a: u128) f64 { | ||
| 389 | return floatFromInt(f64, a); | ||
| 390 | } | ||
| 391 | |||
| 392 | fn __floatuneidf(a: [*]const u8, bits: usize) callconv(.c) compiler_rt.f64.Abi { | ||
| 393 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | ||
| 394 | return compiler_rt.f64.toAbi(f64_floatFromInt_unsigned(a[0..byte_size])); | ||
| 395 | } | ||
| 396 | pub fn f64_floatFromInt_unsigned(a: []const u8) f64 { | ||
| 397 | return floatFromBigInt(f64, .unsigned, @ptrCast(@alignCast(a))); | ||
| 398 | } | ||
| 399 | |||
| 400 | fn __floatunsixf(a: u32) callconv(.c) compiler_rt.f80.Abi { | ||
| 401 | return compiler_rt.f80.toAbi(f80_floatFromInt_u32(a)); | ||
| 402 | } | ||
| 403 | pub fn f80_floatFromInt_u32(a: u32) f80 { | ||
| 404 | return floatFromInt(f80, a); | ||
| 405 | } | ||
| 406 | |||
| 407 | fn __floatundixf(a: u64) callconv(.c) compiler_rt.f80.Abi { | ||
| 408 | return compiler_rt.f80.toAbi(f80_floatFromInt_u64(a)); | ||
| 409 | } | ||
| 410 | pub fn f80_floatFromInt_u64(a: u64) f80 { | ||
| 411 | return floatFromInt(f80, a); | ||
| 412 | } | ||
| 413 | |||
| 414 | fn __floatuntixf(a: u128) callconv(.c) compiler_rt.f80.Abi { | ||
| 415 | return compiler_rt.f80.toAbi(f80_floatFromInt_u128(a)); | ||
| 416 | } | ||
| 417 | pub fn f80_floatFromInt_u128(a: u128) f80 { | ||
| 418 | return floatFromInt(f80, a); | ||
| 419 | } | ||
| 420 | |||
| 421 | fn __floatuneixf(a: [*]const u8, bits: usize) callconv(.c) compiler_rt.f80.Abi { | ||
| 422 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | ||
| 423 | return compiler_rt.f80.toAbi(f80_floatFromInt_unsigned(a[0..byte_size])); | ||
| 424 | } | ||
| 425 | pub fn f80_floatFromInt_unsigned(a: []const u8) f80 { | ||
| 426 | return floatFromBigInt(f80, .unsigned, @ptrCast(@alignCast(a))); | ||
| 427 | } | ||
| 428 | |||
| 429 | fn __floatunsitf(a: u32) callconv(.c) compiler_rt.f128.Abi { | ||
| 430 | return compiler_rt.f128.toAbi(f128_floatFromInt_u32(a)); | ||
| 431 | } | ||
| 432 | fn _Qp_uitoq(c: *f128, a: u32) callconv(.c) void { | ||
| 433 | c.* = f128_floatFromInt_u32(a); | ||
| 434 | } | ||
| 435 | pub fn f128_floatFromInt_u32(a: u32) f128 { | ||
| 436 | return floatFromInt(f128, a); | ||
| 437 | } | ||
| 438 | |||
| 439 | fn __floatunditf(a: u64) callconv(.c) compiler_rt.f128.Abi { | ||
| 440 | return compiler_rt.f128.toAbi(f128_floatFromInt_u64(a)); | ||
| 441 | } | ||
| 442 | fn _Qp_uxtoq(c: *f128, a: u64) callconv(.c) void { | ||
| 443 | c.* = f128_floatFromInt_u64(a); | ||
| 444 | } | ||
| 445 | pub fn f128_floatFromInt_u64(a: u64) f128 { | ||
| 446 | return floatFromInt(f128, a); | ||
| 447 | } | ||
| 448 | |||
| 449 | fn __floatuntitf(a: u128) callconv(.c) compiler_rt.f128.Abi { | ||
| 450 | return compiler_rt.f128.toAbi(f128_floatFromInt_u128(a)); | ||
| 451 | } | ||
| 452 | fn __floatuntitf_x86(a: f128) callconv(.c) compiler_rt.f128.Abi { | ||
| 453 | return compiler_rt.f128.toAbi(f128_floatFromInt_u128(@bitCast(a))); | ||
| 454 | } | ||
| 455 | fn __floatuntitf_x86_64_windows(a_lo: u64, a_hi: u64) callconv(.c) compiler_rt.f128.Abi { | ||
| 456 | return compiler_rt.f128.toAbi(f128_floatFromInt_u128(@bitCast( | ||
| 457 | packed struct { lo: u64, hi: u64 }{ .lo = a_lo, .hi = a_hi }, | ||
| 458 | ))); | ||
| 459 | } | ||
| 460 | pub fn f128_floatFromInt_u128(a: u128) f128 { | ||
| 461 | return floatFromInt(f128, a); | ||
| 462 | } | ||
| 463 | |||
| 464 | fn __floatuneitf(a: [*]const u8, bits: usize) callconv(.c) compiler_rt.f128.Abi { | ||
| 465 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | ||
| 466 | return compiler_rt.f128.toAbi(f128_floatFromInt_unsigned(a[0..byte_size])); | ||
| 467 | } | ||
| 468 | pub fn f128_floatFromInt_unsigned(a: []const u8) f128 { | ||
| 469 | return floatFromBigInt(f128, .unsigned, @ptrCast(@alignCast(a))); | ||
| 470 | } | ||
| 471 | |||
| 472 | inline fn floatFromInt(comptime T: type, x: anytype) T { | ||
| 5 | if (x == 0) return 0; | 473 | if (x == 0) return 0; |
| 6 | 474 | ||
| 7 | // Various constants whose values follow from the type parameters. | 475 | // Various constants whose values follow from the type parameters. |
| ... | @@ -53,7 +521,7 @@ pub fn floatFromInt(comptime T: type, x: anytype) T { | ... | @@ -53,7 +521,7 @@ pub fn floatFromInt(comptime T: type, x: anytype) T { |
| 53 | return @bitCast(sign_bit | result); | 521 | return @bitCast(sign_bit | result); |
| 54 | } | 522 | } |
| 55 | 523 | ||
| 56 | const endian = @import("builtin").cpu.arch.endian(); | 524 | const endian = builtin.cpu.arch.endian(); |
| 57 | inline fn limb(limbs: []const u32, index: usize) u32 { | 525 | inline fn limb(limbs: []const u32, index: usize) u32 { |
| 58 | return switch (endian) { | 526 | return switch (endian) { |
| 59 | .little => limbs[index], | 527 | .little => limbs[index], |
| ... | @@ -61,11 +529,11 @@ inline fn limb(limbs: []const u32, index: usize) u32 { | ... | @@ -61,11 +529,11 @@ inline fn limb(limbs: []const u32, index: usize) u32 { |
| 61 | }; | 529 | }; |
| 62 | } | 530 | } |
| 63 | 531 | ||
| 64 | pub inline fn floatFromBigInt(comptime T: type, comptime signedness: std.builtin.Signedness, x: []const u32) T { | 532 | inline fn floatFromBigInt(comptime T: type, comptime signedness: std.lang.Signedness, x: []const u32) T { |
| 65 | switch (x.len) { | 533 | switch (x.len) { |
| 66 | 0 => return 0, | 534 | 0 => return 0, |
| 67 | inline 1...4 => |limbs_len| { | 535 | inline 1...4 => |limbs_len| { |
| 68 | const low_to_high: [limbs_len]u32 = switch (@import("builtin").cpu.arch.endian()) { | 536 | const low_to_high: [limbs_len]u32 = switch (endian) { |
| 69 | .little => x[0..limbs_len].*, | 537 | .little => x[0..limbs_len].*, |
| 70 | .big => switch (limbs_len) { | 538 | .big => switch (limbs_len) { |
| 71 | 1 => .{x[0]}, | 539 | 1 => .{x[0]}, |
lib/compiler_rt/float_from_int_test.zig+757-733| ... | @@ -2,571 +2,593 @@ const std = @import("std"); | ... | @@ -2,571 +2,593 @@ const std = @import("std"); |
| 2 | const testing = std.testing; | 2 | const testing = std.testing; |
| 3 | const math = std.math; | 3 | const math = std.math; |
| 4 | 4 | ||
| 5 | const __floatunsihf = @import("floatunsihf.zig").__floatunsihf; | 5 | const impl = @import("float_from_int.zig"); |
| 6 | 6 | ||
| 7 | // Conversion to f32 | 7 | const f16_floatFromInt_i32 = impl.f16_floatFromInt_i32; |
| 8 | const __floatsisf = @import("floatsisf.zig").__floatsisf; | 8 | const f16_floatFromInt_u32 = impl.f16_floatFromInt_u32; |
| 9 | const __floatunsisf = @import("floatunsisf.zig").__floatunsisf; | 9 | const f16_floatFromInt_i64 = impl.f16_floatFromInt_i64; |
| 10 | const __floatdisf = @import("floatdisf.zig").__floatdisf; | 10 | const f16_floatFromInt_u64 = impl.f16_floatFromInt_u64; |
| 11 | const __floatundisf = @import("floatundisf.zig").__floatundisf; | 11 | const f16_floatFromInt_i128 = impl.f16_floatFromInt_i128; |
| 12 | const __floattisf = @import("floattisf.zig").__floattisf; | 12 | const f16_floatFromInt_u128 = impl.f16_floatFromInt_u128; |
| 13 | const __floatuntisf = @import("floatuntisf.zig").__floatuntisf; | 13 | const f16_floatFromInt_signed = impl.f16_floatFromInt_signed; |
| 14 | const __floateisf = @import("floateisf.zig").__floateisf; | 14 | const f16_floatFromInt_unsigned = impl.f16_floatFromInt_unsigned; |
| 15 | const __floatuneisf = @import("floatuneisf.zig").__floatuneisf; | 15 | |
| 16 | 16 | const f32_floatFromInt_i32 = impl.f32_floatFromInt_i32; | |
| 17 | // Conversion to f64 | 17 | const f32_floatFromInt_u32 = impl.f32_floatFromInt_u32; |
| 18 | const __floatsidf = @import("floatsidf.zig").__floatsidf; | 18 | const f32_floatFromInt_i64 = impl.f32_floatFromInt_i64; |
| 19 | const __floatunsidf = @import("floatunsidf.zig").__floatunsidf; | 19 | const f32_floatFromInt_u64 = impl.f32_floatFromInt_u64; |
| 20 | const __floatdidf = @import("floatdidf.zig").__floatdidf; | 20 | const f32_floatFromInt_i128 = impl.f32_floatFromInt_i128; |
| 21 | const __floatundidf = @import("floatundidf.zig").__floatundidf; | 21 | const f32_floatFromInt_u128 = impl.f32_floatFromInt_u128; |
| 22 | const __floattidf = @import("floattidf.zig").__floattidf; | 22 | const f32_floatFromInt_signed = impl.f32_floatFromInt_signed; |
| 23 | const __floatuntidf = @import("floatuntidf.zig").__floatuntidf; | 23 | const f32_floatFromInt_unsigned = impl.f32_floatFromInt_unsigned; |
| 24 | 24 | ||
| 25 | // Conversion to f128 | 25 | const f64_floatFromInt_i32 = impl.f64_floatFromInt_i32; |
| 26 | const __floatsitf = @import("floatsitf.zig").__floatsitf; | 26 | const f64_floatFromInt_u32 = impl.f64_floatFromInt_u32; |
| 27 | const __floatunsitf = @import("floatunsitf.zig").__floatunsitf; | 27 | const f64_floatFromInt_i64 = impl.f64_floatFromInt_i64; |
| 28 | const __floatditf = @import("floatditf.zig").__floatditf; | 28 | const f64_floatFromInt_u64 = impl.f64_floatFromInt_u64; |
| 29 | const __floatunditf = @import("floatunditf.zig").__floatunditf; | 29 | const f64_floatFromInt_i128 = impl.f64_floatFromInt_i128; |
| 30 | const __floattitf = @import("floattitf.zig").__floattitf; | 30 | const f64_floatFromInt_u128 = impl.f64_floatFromInt_u128; |
| 31 | const __floatuntitf = @import("floatuntitf.zig").__floatuntitf; | 31 | const f64_floatFromInt_signed = impl.f64_floatFromInt_signed; |
| 32 | 32 | const f64_floatFromInt_unsigned = impl.f64_floatFromInt_unsigned; | |
| 33 | fn test__floatsisf(a: i32, expected: u32) !void { | 33 | |
| 34 | const r = __floatsisf(a); | 34 | const f80_floatFromInt_i32 = impl.f80_floatFromInt_i32; |
| 35 | const f80_floatFromInt_u32 = impl.f80_floatFromInt_u32; | ||
| 36 | const f80_floatFromInt_i64 = impl.f80_floatFromInt_i64; | ||
| 37 | const f80_floatFromInt_u64 = impl.f80_floatFromInt_u64; | ||
| 38 | const f80_floatFromInt_i128 = impl.f80_floatFromInt_i128; | ||
| 39 | const f80_floatFromInt_u128 = impl.f80_floatFromInt_u128; | ||
| 40 | const f80_floatFromInt_signed = impl.f80_floatFromInt_signed; | ||
| 41 | const f80_floatFromInt_unsigned = impl.f80_floatFromInt_unsigned; | ||
| 42 | |||
| 43 | const f128_floatFromInt_i32 = impl.f128_floatFromInt_i32; | ||
| 44 | const f128_floatFromInt_u32 = impl.f128_floatFromInt_u32; | ||
| 45 | const f128_floatFromInt_i64 = impl.f128_floatFromInt_i64; | ||
| 46 | const f128_floatFromInt_u64 = impl.f128_floatFromInt_u64; | ||
| 47 | const f128_floatFromInt_i128 = impl.f128_floatFromInt_i128; | ||
| 48 | const f128_floatFromInt_u128 = impl.f128_floatFromInt_u128; | ||
| 49 | const f128_floatFromInt_signed = impl.f128_floatFromInt_signed; | ||
| 50 | const f128_floatFromInt_unsigned = impl.f128_floatFromInt_unsigned; | ||
| 51 | |||
| 52 | fn test_f32_floatFromInt_i32(a: i32, expected: u32) !void { | ||
| 53 | const r = f32_floatFromInt_i32(a); | ||
| 35 | try std.testing.expect(@as(u32, @bitCast(r)) == expected); | 54 | try std.testing.expect(@as(u32, @bitCast(r)) == expected); |
| 36 | } | 55 | } |
| 37 | 56 | ||
| 38 | fn test_one_floatunsisf(a: u32, expected: u32) !void { | 57 | fn test_f32_floatFromInt_u32(a: u32, expected: u32) !void { |
| 39 | const r = __floatunsisf(a); | 58 | const r = f32_floatFromInt_u32(a); |
| 40 | try std.testing.expect(@as(u32, @bitCast(r)) == expected); | 59 | try std.testing.expect(@as(u32, @bitCast(r)) == expected); |
| 41 | } | 60 | } |
| 42 | 61 | ||
| 43 | test "floatsisf" { | 62 | test f32_floatFromInt_i32 { |
| 44 | try test__floatsisf(0, 0x00000000); | 63 | try test_f32_floatFromInt_i32(0, 0x00000000); |
| 45 | try test__floatsisf(1, 0x3f800000); | 64 | try test_f32_floatFromInt_i32(1, 0x3f800000); |
| 46 | try test__floatsisf(-1, 0xbf800000); | 65 | try test_f32_floatFromInt_i32(-1, 0xbf800000); |
| 47 | try test__floatsisf(0x7FFFFFFF, 0x4f000000); | 66 | try test_f32_floatFromInt_i32(0x7FFFFFFF, 0x4f000000); |
| 48 | try test__floatsisf(@bitCast(@as(u32, @intCast(0x80000000))), 0xcf000000); | 67 | try test_f32_floatFromInt_i32(@bitCast(@as(u32, @intCast(0x80000000))), 0xcf000000); |
| 68 | |||
| 69 | try testing.expect(f32_floatFromInt_i32(math.minInt(i32)) == math.minInt(i32)); | ||
| 49 | } | 70 | } |
| 50 | 71 | ||
| 51 | test "floatunsisf" { | 72 | test f32_floatFromInt_u32 { |
| 52 | // Test the produced bit pattern | 73 | // Test the produced bit pattern |
| 53 | try test_one_floatunsisf(0, 0); | 74 | try test_f32_floatFromInt_u32(0, 0); |
| 54 | try test_one_floatunsisf(1, 0x3f800000); | 75 | try test_f32_floatFromInt_u32(1, 0x3f800000); |
| 55 | try test_one_floatunsisf(0x7FFFFFFF, 0x4f000000); | 76 | try test_f32_floatFromInt_u32(0x7FFFFFFF, 0x4f000000); |
| 56 | try test_one_floatunsisf(0x80000000, 0x4f000000); | 77 | try test_f32_floatFromInt_u32(0x80000000, 0x4f000000); |
| 57 | try test_one_floatunsisf(0xFFFFFFFF, 0x4f800000); | 78 | try test_f32_floatFromInt_u32(0xFFFFFFFF, 0x4f800000); |
| 79 | |||
| 80 | try testing.expect(f32_floatFromInt_u32(0) == 0.0); | ||
| 81 | try testing.expect(f32_floatFromInt_u32(math.maxInt(u24)) == math.maxInt(u24)); | ||
| 82 | try testing.expect(f32_floatFromInt_u32(math.maxInt(u24) + 1) == math.maxInt(u24) + 1); // 0x100_0000 - Exact | ||
| 83 | try testing.expect(f32_floatFromInt_u32(math.maxInt(u24) + 2) == math.maxInt(u24) + 1); // 0x100_0001 - Tie: Rounds down to even | ||
| 84 | try testing.expect(f32_floatFromInt_u32(math.maxInt(u24) + 3) == math.maxInt(u24) + 3); // 0x100_0002 - Exact | ||
| 85 | try testing.expect(f32_floatFromInt_u32(math.maxInt(u24) + 4) == math.maxInt(u24) + 5); // 0x100_0003 - Tie: Rounds up to even | ||
| 86 | try testing.expect(f32_floatFromInt_u32(math.maxInt(u24) + 5) == math.maxInt(u24) + 5); // 0x100_0004 - Exact | ||
| 87 | try testing.expect(f32_floatFromInt_u32(math.maxInt(u32)) == math.maxInt(u32) + 1); | ||
| 88 | } | ||
| 89 | |||
| 90 | fn test_f32_floatFromInt_i64(a: i64, expected: f32) !void { | ||
| 91 | const x = f32_floatFromInt_i64(a); | ||
| 92 | try testing.expect(x == expected); | ||
| 58 | } | 93 | } |
| 59 | 94 | ||
| 60 | fn test__floatdisf(a: i64, expected: f32) !void { | 95 | fn test_f32_floatFromInt_u64(a: u64, expected: f32) !void { |
| 61 | const x = __floatdisf(a); | 96 | const x = f32_floatFromInt_u64(a); |
| 62 | try testing.expect(x == expected); | 97 | try testing.expect(x == expected); |
| 63 | } | 98 | } |
| 64 | 99 | ||
| 65 | fn test__floatundisf(a: u64, expected: f32) !void { | 100 | test f32_floatFromInt_i64 { |
| 66 | try std.testing.expectEqual(expected, __floatundisf(a)); | 101 | try test_f32_floatFromInt_i64(0, 0.0); |
| 67 | } | 102 | try test_f32_floatFromInt_i64(1, 1.0); |
| 68 | 103 | try test_f32_floatFromInt_i64(2, 2.0); | |
| 69 | test "floatdisf" { | 104 | try test_f32_floatFromInt_i64(-1, -1.0); |
| 70 | try test__floatdisf(0, 0.0); | 105 | try test_f32_floatFromInt_i64(-2, -2.0); |
| 71 | try test__floatdisf(1, 1.0); | 106 | try test_f32_floatFromInt_i64(0x7FFFFF8000000000, 0x1.FFFFFEp+62); |
| 72 | try test__floatdisf(2, 2.0); | 107 | try test_f32_floatFromInt_i64(0x7FFFFF0000000000, 0x1.FFFFFCp+62); |
| 73 | try test__floatdisf(-1, -1.0); | 108 | try test_f32_floatFromInt_i64(@bitCast(@as(u64, 0x8000008000000000)), -0x1.FFFFFEp+62); |
| 74 | try test__floatdisf(-2, -2.0); | 109 | try test_f32_floatFromInt_i64(@bitCast(@as(u64, 0x8000010000000000)), -0x1.FFFFFCp+62); |
| 75 | try test__floatdisf(0x7FFFFF8000000000, 0x1.FFFFFEp+62); | 110 | try test_f32_floatFromInt_i64(@bitCast(@as(u64, 0x8000000000000000)), -0x1.000000p+63); |
| 76 | try test__floatdisf(0x7FFFFF0000000000, 0x1.FFFFFCp+62); | 111 | try test_f32_floatFromInt_i64(@bitCast(@as(u64, 0x8000000000000001)), -0x1.000000p+63); |
| 77 | try test__floatdisf(@bitCast(@as(u64, 0x8000008000000000)), -0x1.FFFFFEp+62); | 112 | try test_f32_floatFromInt_i64(0x0007FB72E8000000, 0x1.FEDCBAp+50); |
| 78 | try test__floatdisf(@bitCast(@as(u64, 0x8000010000000000)), -0x1.FFFFFCp+62); | 113 | try test_f32_floatFromInt_i64(0x0007FB72EA000000, 0x1.FEDCBAp+50); |
| 79 | try test__floatdisf(@bitCast(@as(u64, 0x8000000000000000)), -0x1.000000p+63); | 114 | try test_f32_floatFromInt_i64(0x0007FB72EB000000, 0x1.FEDCBAp+50); |
| 80 | try test__floatdisf(@bitCast(@as(u64, 0x8000000000000001)), -0x1.000000p+63); | 115 | try test_f32_floatFromInt_i64(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50); |
| 81 | try test__floatdisf(0x0007FB72E8000000, 0x1.FEDCBAp+50); | 116 | try test_f32_floatFromInt_i64(0x0007FB72EC000000, 0x1.FEDCBCp+50); |
| 82 | try test__floatdisf(0x0007FB72EA000000, 0x1.FEDCBAp+50); | 117 | try test_f32_floatFromInt_i64(0x0007FB72E8000001, 0x1.FEDCBAp+50); |
| 83 | try test__floatdisf(0x0007FB72EB000000, 0x1.FEDCBAp+50); | 118 | try test_f32_floatFromInt_i64(0x0007FB72E6000000, 0x1.FEDCBAp+50); |
| 84 | try test__floatdisf(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50); | 119 | try test_f32_floatFromInt_i64(0x0007FB72E7000000, 0x1.FEDCBAp+50); |
| 85 | try test__floatdisf(0x0007FB72EC000000, 0x1.FEDCBCp+50); | 120 | try test_f32_floatFromInt_i64(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50); |
| 86 | try test__floatdisf(0x0007FB72E8000001, 0x1.FEDCBAp+50); | 121 | try test_f32_floatFromInt_i64(0x0007FB72E4000001, 0x1.FEDCBAp+50); |
| 87 | try test__floatdisf(0x0007FB72E6000000, 0x1.FEDCBAp+50); | 122 | try test_f32_floatFromInt_i64(0x0007FB72E4000000, 0x1.FEDCB8p+50); |
| 88 | try test__floatdisf(0x0007FB72E7000000, 0x1.FEDCBAp+50); | 123 | } |
| 89 | try test__floatdisf(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50); | 124 | |
| 90 | try test__floatdisf(0x0007FB72E4000001, 0x1.FEDCBAp+50); | 125 | test f32_floatFromInt_u64 { |
| 91 | try test__floatdisf(0x0007FB72E4000000, 0x1.FEDCB8p+50); | 126 | try test_f32_floatFromInt_u64(0, 0.0); |
| 92 | } | 127 | try test_f32_floatFromInt_u64(1, 1.0); |
| 93 | 128 | try test_f32_floatFromInt_u64(2, 2.0); | |
| 94 | test "floatundisf" { | 129 | try test_f32_floatFromInt_u64(0x7FFFFF8000000000, 0x1.FFFFFEp+62); |
| 95 | try test__floatundisf(0, 0.0); | 130 | try test_f32_floatFromInt_u64(0x7FFFFF0000000000, 0x1.FFFFFCp+62); |
| 96 | try test__floatundisf(1, 1.0); | 131 | try test_f32_floatFromInt_u64(0x8000008000000000, 0x1p+63); |
| 97 | try test__floatundisf(2, 2.0); | 132 | try test_f32_floatFromInt_u64(0x8000010000000000, 0x1.000002p+63); |
| 98 | try test__floatundisf(0x7FFFFF8000000000, 0x1.FFFFFEp+62); | 133 | try test_f32_floatFromInt_u64(0x8000000000000000, 0x1p+63); |
| 99 | try test__floatundisf(0x7FFFFF0000000000, 0x1.FFFFFCp+62); | 134 | try test_f32_floatFromInt_u64(0x8000000000000001, 0x1p+63); |
| 100 | try test__floatundisf(0x8000008000000000, 0x1p+63); | 135 | try test_f32_floatFromInt_u64(0xFFFFFFFFFFFFFFFE, 0x1p+64); |
| 101 | try test__floatundisf(0x8000010000000000, 0x1.000002p+63); | 136 | try test_f32_floatFromInt_u64(0xFFFFFFFFFFFFFFFF, 0x1p+64); |
| 102 | try test__floatundisf(0x8000000000000000, 0x1p+63); | 137 | try test_f32_floatFromInt_u64(0x0007FB72E8000000, 0x1.FEDCBAp+50); |
| 103 | try test__floatundisf(0x8000000000000001, 0x1p+63); | 138 | try test_f32_floatFromInt_u64(0x0007FB72EA000000, 0x1.FEDCBAp+50); |
| 104 | try test__floatundisf(0xFFFFFFFFFFFFFFFE, 0x1p+64); | 139 | try test_f32_floatFromInt_u64(0x0007FB72EB000000, 0x1.FEDCBAp+50); |
| 105 | try test__floatundisf(0xFFFFFFFFFFFFFFFF, 0x1p+64); | 140 | try test_f32_floatFromInt_u64(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50); |
| 106 | try test__floatundisf(0x0007FB72E8000000, 0x1.FEDCBAp+50); | 141 | try test_f32_floatFromInt_u64(0x0007FB72EC000000, 0x1.FEDCBCp+50); |
| 107 | try test__floatundisf(0x0007FB72EA000000, 0x1.FEDCBAp+50); | 142 | try test_f32_floatFromInt_u64(0x0007FB72E8000001, 0x1.FEDCBAp+50); |
| 108 | try test__floatundisf(0x0007FB72EB000000, 0x1.FEDCBAp+50); | 143 | try test_f32_floatFromInt_u64(0x0007FB72E6000000, 0x1.FEDCBAp+50); |
| 109 | try test__floatundisf(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50); | 144 | try test_f32_floatFromInt_u64(0x0007FB72E7000000, 0x1.FEDCBAp+50); |
| 110 | try test__floatundisf(0x0007FB72EC000000, 0x1.FEDCBCp+50); | 145 | try test_f32_floatFromInt_u64(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50); |
| 111 | try test__floatundisf(0x0007FB72E8000001, 0x1.FEDCBAp+50); | 146 | try test_f32_floatFromInt_u64(0x0007FB72E4000001, 0x1.FEDCBAp+50); |
| 112 | try test__floatundisf(0x0007FB72E6000000, 0x1.FEDCBAp+50); | 147 | try test_f32_floatFromInt_u64(0x0007FB72E4000000, 0x1.FEDCB8p+50); |
| 113 | try test__floatundisf(0x0007FB72E7000000, 0x1.FEDCBAp+50); | 148 | } |
| 114 | try test__floatundisf(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50); | 149 | |
| 115 | try test__floatundisf(0x0007FB72E4000001, 0x1.FEDCBAp+50); | 150 | fn test_f32_floatFromInt_i128(a: i128, expected: f32) !void { |
| 116 | try test__floatundisf(0x0007FB72E4000000, 0x1.FEDCB8p+50); | 151 | const x = f32_floatFromInt_i128(a); |
| 117 | } | ||
| 118 | |||
| 119 | fn test__floattisf(a: i128, expected: f32) !void { | ||
| 120 | const x = __floattisf(a); | ||
| 121 | try testing.expect(x == expected); | 152 | try testing.expect(x == expected); |
| 122 | } | 153 | } |
| 123 | 154 | ||
| 124 | fn test__floatuntisf(a: u128, expected: f32) !void { | 155 | fn test_f32_floatFromInt_u128(a: u128, expected: f32) !void { |
| 125 | const x = __floatuntisf(a); | 156 | const x = f32_floatFromInt_u128(a); |
| 126 | try testing.expect(x == expected); | 157 | try testing.expect(x == expected); |
| 127 | } | 158 | } |
| 128 | 159 | ||
| 129 | test "floattisf" { | 160 | test f32_floatFromInt_i128 { |
| 130 | try test__floattisf(0, 0.0); | 161 | try test_f32_floatFromInt_i128(0, 0.0); |
| 131 | 162 | ||
| 132 | try test__floattisf(1, 1.0); | 163 | try test_f32_floatFromInt_i128(1, 1.0); |
| 133 | try test__floattisf(2, 2.0); | 164 | try test_f32_floatFromInt_i128(2, 2.0); |
| 134 | try test__floattisf(-1, -1.0); | 165 | try test_f32_floatFromInt_i128(-1, -1.0); |
| 135 | try test__floattisf(-2, -2.0); | 166 | try test_f32_floatFromInt_i128(-2, -2.0); |
| 136 | 167 | ||
| 137 | try test__floattisf(0x7FFFFF8000000000, 0x1.FFFFFEp+62); | 168 | try test_f32_floatFromInt_i128(0x7FFFFF8000000000, 0x1.FFFFFEp+62); |
| 138 | try test__floattisf(0x7FFFFF0000000000, 0x1.FFFFFCp+62); | 169 | try test_f32_floatFromInt_i128(0x7FFFFF0000000000, 0x1.FFFFFCp+62); |
| 139 | 170 | ||
| 140 | try test__floattisf(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000008000000000), -0x1.FFFFFEp+62); | 171 | try test_f32_floatFromInt_i128(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000008000000000), -0x1.FFFFFEp+62); |
| 141 | try test__floattisf(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000010000000000), -0x1.FFFFFCp+62); | 172 | try test_f32_floatFromInt_i128(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000010000000000), -0x1.FFFFFCp+62); |
| 142 | 173 | ||
| 143 | try test__floattisf(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000000000000000), -0x1.000000p+63); | 174 | try test_f32_floatFromInt_i128(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000000000000000), -0x1.000000p+63); |
| 144 | try test__floattisf(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000000000000001), -0x1.000000p+63); | 175 | try test_f32_floatFromInt_i128(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000000000000001), -0x1.000000p+63); |
| 145 | 176 | ||
| 146 | try test__floattisf(0x0007FB72E8000000, 0x1.FEDCBAp+50); | 177 | try test_f32_floatFromInt_i128(0x0007FB72E8000000, 0x1.FEDCBAp+50); |
| 147 | 178 | ||
| 148 | try test__floattisf(0x0007FB72EA000000, 0x1.FEDCBAp+50); | 179 | try test_f32_floatFromInt_i128(0x0007FB72EA000000, 0x1.FEDCBAp+50); |
| 149 | try test__floattisf(0x0007FB72EB000000, 0x1.FEDCBAp+50); | 180 | try test_f32_floatFromInt_i128(0x0007FB72EB000000, 0x1.FEDCBAp+50); |
| 150 | try test__floattisf(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50); | 181 | try test_f32_floatFromInt_i128(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50); |
| 151 | try test__floattisf(0x0007FB72EC000000, 0x1.FEDCBCp+50); | 182 | try test_f32_floatFromInt_i128(0x0007FB72EC000000, 0x1.FEDCBCp+50); |
| 152 | try test__floattisf(0x0007FB72E8000001, 0x1.FEDCBAp+50); | 183 | try test_f32_floatFromInt_i128(0x0007FB72E8000001, 0x1.FEDCBAp+50); |
| 153 | 184 | ||
| 154 | try test__floattisf(0x0007FB72E6000000, 0x1.FEDCBAp+50); | 185 | try test_f32_floatFromInt_i128(0x0007FB72E6000000, 0x1.FEDCBAp+50); |
| 155 | try test__floattisf(0x0007FB72E7000000, 0x1.FEDCBAp+50); | 186 | try test_f32_floatFromInt_i128(0x0007FB72E7000000, 0x1.FEDCBAp+50); |
| 156 | try test__floattisf(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50); | 187 | try test_f32_floatFromInt_i128(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50); |
| 157 | try test__floattisf(0x0007FB72E4000001, 0x1.FEDCBAp+50); | 188 | try test_f32_floatFromInt_i128(0x0007FB72E4000001, 0x1.FEDCBAp+50); |
| 158 | try test__floattisf(0x0007FB72E4000000, 0x1.FEDCB8p+50); | 189 | try test_f32_floatFromInt_i128(0x0007FB72E4000000, 0x1.FEDCB8p+50); |
| 159 | 190 | ||
| 160 | try test__floattisf(make_ti(0x0007FB72E8000000, 0), 0x1.FEDCBAp+114); | 191 | try test_f32_floatFromInt_i128(make_ti(0x0007FB72E8000000, 0), 0x1.FEDCBAp+114); |
| 161 | 192 | ||
| 162 | try test__floattisf(make_ti(0x0007FB72EA000000, 0), 0x1.FEDCBAp+114); | 193 | try test_f32_floatFromInt_i128(make_ti(0x0007FB72EA000000, 0), 0x1.FEDCBAp+114); |
| 163 | try test__floattisf(make_ti(0x0007FB72EB000000, 0), 0x1.FEDCBAp+114); | 194 | try test_f32_floatFromInt_i128(make_ti(0x0007FB72EB000000, 0), 0x1.FEDCBAp+114); |
| 164 | try test__floattisf(make_ti(0x0007FB72EBFFFFFF, 0), 0x1.FEDCBAp+114); | 195 | try test_f32_floatFromInt_i128(make_ti(0x0007FB72EBFFFFFF, 0), 0x1.FEDCBAp+114); |
| 165 | try test__floattisf(make_ti(0x0007FB72EC000000, 0), 0x1.FEDCBCp+114); | 196 | try test_f32_floatFromInt_i128(make_ti(0x0007FB72EC000000, 0), 0x1.FEDCBCp+114); |
| 166 | try test__floattisf(make_ti(0x0007FB72E8000001, 0), 0x1.FEDCBAp+114); | 197 | try test_f32_floatFromInt_i128(make_ti(0x0007FB72E8000001, 0), 0x1.FEDCBAp+114); |
| 167 | 198 | ||
| 168 | try test__floattisf(make_ti(0x0007FB72E6000000, 0), 0x1.FEDCBAp+114); | 199 | try test_f32_floatFromInt_i128(make_ti(0x0007FB72E6000000, 0), 0x1.FEDCBAp+114); |
| 169 | try test__floattisf(make_ti(0x0007FB72E7000000, 0), 0x1.FEDCBAp+114); | 200 | try test_f32_floatFromInt_i128(make_ti(0x0007FB72E7000000, 0), 0x1.FEDCBAp+114); |
| 170 | try test__floattisf(make_ti(0x0007FB72E7FFFFFF, 0), 0x1.FEDCBAp+114); | 201 | try test_f32_floatFromInt_i128(make_ti(0x0007FB72E7FFFFFF, 0), 0x1.FEDCBAp+114); |
| 171 | try test__floattisf(make_ti(0x0007FB72E4000001, 0), 0x1.FEDCBAp+114); | 202 | try test_f32_floatFromInt_i128(make_ti(0x0007FB72E4000001, 0), 0x1.FEDCBAp+114); |
| 172 | try test__floattisf(make_ti(0x0007FB72E4000000, 0), 0x1.FEDCB8p+114); | 203 | try test_f32_floatFromInt_i128(make_ti(0x0007FB72E4000000, 0), 0x1.FEDCB8p+114); |
| 173 | } | 204 | } |
| 174 | 205 | ||
| 175 | test "floatuntisf" { | 206 | test f32_floatFromInt_u128 { |
| 176 | try test__floatuntisf(0, 0.0); | 207 | try test_f32_floatFromInt_u128(0, 0.0); |
| 177 | 208 | ||
| 178 | try test__floatuntisf(1, 1.0); | 209 | try test_f32_floatFromInt_u128(1, 1.0); |
| 179 | try test__floatuntisf(2, 2.0); | 210 | try test_f32_floatFromInt_u128(2, 2.0); |
| 180 | try test__floatuntisf(20, 20.0); | 211 | try test_f32_floatFromInt_u128(20, 20.0); |
| 181 | 212 | ||
| 182 | try test__floatuntisf(0x7FFFFF8000000000, 0x1.FFFFFEp+62); | 213 | try test_f32_floatFromInt_u128(0x7FFFFF8000000000, 0x1.FFFFFEp+62); |
| 183 | try test__floatuntisf(0x7FFFFF0000000000, 0x1.FFFFFCp+62); | 214 | try test_f32_floatFromInt_u128(0x7FFFFF0000000000, 0x1.FFFFFCp+62); |
| 184 | 215 | ||
| 185 | try test__floatuntisf(make_uti(0x8000008000000000, 0), 0x1.000001p+127); | 216 | try test_f32_floatFromInt_u128(make_uti(0x8000008000000000, 0), 0x1.000001p+127); |
| 186 | try test__floatuntisf(make_uti(0x8000000000000800, 0), 0x1.0p+127); | 217 | try test_f32_floatFromInt_u128(make_uti(0x8000000000000800, 0), 0x1.0p+127); |
| 187 | try test__floatuntisf(make_uti(0x8000010000000000, 0), 0x1.000002p+127); | 218 | try test_f32_floatFromInt_u128(make_uti(0x8000010000000000, 0), 0x1.000002p+127); |
| 188 | 219 | ||
| 189 | try test__floatuntisf(make_uti(0x8000000000000000, 0), 0x1.000000p+127); | 220 | try test_f32_floatFromInt_u128(make_uti(0x8000000000000000, 0), 0x1.000000p+127); |
| 190 | 221 | ||
| 191 | try test__floatuntisf(0x0007FB72E8000000, 0x1.FEDCBAp+50); | 222 | try test_f32_floatFromInt_u128(0x0007FB72E8000000, 0x1.FEDCBAp+50); |
| 192 | 223 | ||
| 193 | try test__floatuntisf(0x0007FB72EA000000, 0x1.FEDCBA8p+50); | 224 | try test_f32_floatFromInt_u128(0x0007FB72EA000000, 0x1.FEDCBA8p+50); |
| 194 | try test__floatuntisf(0x0007FB72EB000000, 0x1.FEDCBACp+50); | 225 | try test_f32_floatFromInt_u128(0x0007FB72EB000000, 0x1.FEDCBACp+50); |
| 195 | 226 | ||
| 196 | try test__floatuntisf(0x0007FB72EC000000, 0x1.FEDCBBp+50); | 227 | try test_f32_floatFromInt_u128(0x0007FB72EC000000, 0x1.FEDCBBp+50); |
| 197 | 228 | ||
| 198 | try test__floatuntisf(0x0007FB72E6000000, 0x1.FEDCB98p+50); | 229 | try test_f32_floatFromInt_u128(0x0007FB72E6000000, 0x1.FEDCB98p+50); |
| 199 | try test__floatuntisf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50); | 230 | try test_f32_floatFromInt_u128(0x0007FB72E7000000, 0x1.FEDCB9Cp+50); |
| 200 | try test__floatuntisf(0x0007FB72E4000000, 0x1.FEDCB9p+50); | 231 | try test_f32_floatFromInt_u128(0x0007FB72E4000000, 0x1.FEDCB9p+50); |
| 201 | 232 | ||
| 202 | try test__floatuntisf(0xFFFFFFFFFFFFFFFE, 0x1p+64); | 233 | try test_f32_floatFromInt_u128(0xFFFFFFFFFFFFFFFE, 0x1p+64); |
| 203 | try test__floatuntisf(0xFFFFFFFFFFFFFFFF, 0x1p+64); | 234 | try test_f32_floatFromInt_u128(0xFFFFFFFFFFFFFFFF, 0x1p+64); |
| 204 | 235 | ||
| 205 | try test__floatuntisf(0x0007FB72E8000000, 0x1.FEDCBAp+50); | 236 | try test_f32_floatFromInt_u128(0x0007FB72E8000000, 0x1.FEDCBAp+50); |
| 206 | 237 | ||
| 207 | try test__floatuntisf(0x0007FB72EA000000, 0x1.FEDCBAp+50); | 238 | try test_f32_floatFromInt_u128(0x0007FB72EA000000, 0x1.FEDCBAp+50); |
| 208 | try test__floatuntisf(0x0007FB72EB000000, 0x1.FEDCBAp+50); | 239 | try test_f32_floatFromInt_u128(0x0007FB72EB000000, 0x1.FEDCBAp+50); |
| 209 | try test__floatuntisf(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50); | 240 | try test_f32_floatFromInt_u128(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50); |
| 210 | try test__floatuntisf(0x0007FB72EC000000, 0x1.FEDCBCp+50); | 241 | try test_f32_floatFromInt_u128(0x0007FB72EC000000, 0x1.FEDCBCp+50); |
| 211 | try test__floatuntisf(0x0007FB72E8000001, 0x1.FEDCBAp+50); | 242 | try test_f32_floatFromInt_u128(0x0007FB72E8000001, 0x1.FEDCBAp+50); |
| 212 | 243 | ||
| 213 | try test__floatuntisf(0x0007FB72E6000000, 0x1.FEDCBAp+50); | 244 | try test_f32_floatFromInt_u128(0x0007FB72E6000000, 0x1.FEDCBAp+50); |
| 214 | try test__floatuntisf(0x0007FB72E7000000, 0x1.FEDCBAp+50); | 245 | try test_f32_floatFromInt_u128(0x0007FB72E7000000, 0x1.FEDCBAp+50); |
| 215 | try test__floatuntisf(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50); | 246 | try test_f32_floatFromInt_u128(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50); |
| 216 | try test__floatuntisf(0x0007FB72E4000001, 0x1.FEDCBAp+50); | 247 | try test_f32_floatFromInt_u128(0x0007FB72E4000001, 0x1.FEDCBAp+50); |
| 217 | try test__floatuntisf(0x0007FB72E4000000, 0x1.FEDCB8p+50); | 248 | try test_f32_floatFromInt_u128(0x0007FB72E4000000, 0x1.FEDCB8p+50); |
| 218 | 249 | ||
| 219 | try test__floatuntisf(make_uti(0x0000000000001FED, 0xCB90000000000001), 0x1.FEDCBAp+76); | 250 | try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCB90000000000001), 0x1.FEDCBAp+76); |
| 220 | try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBA0000000000000), 0x1.FEDCBAp+76); | 251 | try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBA0000000000000), 0x1.FEDCBAp+76); |
| 221 | try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBAFFFFFFFFFFFFF), 0x1.FEDCBAp+76); | 252 | try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBAFFFFFFFFFFFFF), 0x1.FEDCBAp+76); |
| 222 | try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBB0000000000000), 0x1.FEDCBCp+76); | 253 | try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBB0000000000000), 0x1.FEDCBCp+76); |
| 223 | try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBB0000000000001), 0x1.FEDCBCp+76); | 254 | try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBB0000000000001), 0x1.FEDCBCp+76); |
| 224 | try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBBFFFFFFFFFFFFF), 0x1.FEDCBCp+76); | 255 | try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBBFFFFFFFFFFFFF), 0x1.FEDCBCp+76); |
| 225 | try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBC0000000000000), 0x1.FEDCBCp+76); | 256 | try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBC0000000000000), 0x1.FEDCBCp+76); |
| 226 | try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBC0000000000001), 0x1.FEDCBCp+76); | 257 | try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBC0000000000001), 0x1.FEDCBCp+76); |
| 227 | try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBD0000000000000), 0x1.FEDCBCp+76); | 258 | try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBD0000000000000), 0x1.FEDCBCp+76); |
| 228 | try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBD0000000000001), 0x1.FEDCBEp+76); | 259 | try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBD0000000000001), 0x1.FEDCBEp+76); |
| 229 | try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBDFFFFFFFFFFFFF), 0x1.FEDCBEp+76); | 260 | try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBDFFFFFFFFFFFFF), 0x1.FEDCBEp+76); |
| 230 | try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBE0000000000000), 0x1.FEDCBEp+76); | 261 | try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBE0000000000000), 0x1.FEDCBEp+76); |
| 231 | 262 | ||
| 232 | // Test overflow to infinity | 263 | // Test overflow to infinity |
| 233 | try test__floatuntisf(math.maxInt(u128), @bitCast(math.inf(f32))); | 264 | try test_f32_floatFromInt_u128(math.maxInt(u128), @bitCast(math.inf(f32))); |
| 234 | } | 265 | } |
| 235 | 266 | ||
| 236 | fn test_floateisf(expected: u32, comptime T: type, a: T) !void { | 267 | fn test_f32_floatFromInt(expected: u32, comptime T: type, a: T) !void { |
| 237 | const int = @typeInfo(T).int; | 268 | const int = @typeInfo(T).int; |
| 238 | const r = switch (int.signedness) { | 269 | const r = switch (int.signedness) { |
| 239 | .signed => __floateisf, | 270 | .signed => f32_floatFromInt_signed, |
| 240 | .unsigned => __floatuneisf, | 271 | .unsigned => f32_floatFromInt_unsigned, |
| 241 | }(@ptrCast(&a), int.bits); | 272 | }(@ptrCast(&a)); |
| 242 | try testing.expect(expected == @as(u32, @bitCast(r))); | 273 | try testing.expect(expected == @as(u32, @bitCast(r))); |
| 243 | } | 274 | } |
| 244 | 275 | ||
| 245 | test "floateisf" { | 276 | test f32_floatFromInt_signed { |
| 246 | try test_floateisf(0xFF000000, i256, -1 << 127); | 277 | try test_f32_floatFromInt(0xFF000000, i256, -1 << 127); |
| 247 | try test_floateisf(0xFF000000, i256, -math.maxInt(u127)); | 278 | try test_f32_floatFromInt(0xFF000000, i256, -math.maxInt(u127)); |
| 248 | try test_floateisf(0xDF012347, i256, -0x8123468100000000); | 279 | try test_f32_floatFromInt(0xDF012347, i256, -0x8123468100000000); |
| 249 | try test_floateisf(0xDF012347, i256, -0x8123468000000001); | 280 | try test_f32_floatFromInt(0xDF012347, i256, -0x8123468000000001); |
| 250 | try test_floateisf(0xDF012346, i256, -0x8123468000000000); | 281 | try test_f32_floatFromInt(0xDF012346, i256, -0x8123468000000000); |
| 251 | try test_floateisf(0xDF012346, i256, -0x8123458100000000); | 282 | try test_f32_floatFromInt(0xDF012346, i256, -0x8123458100000000); |
| 252 | try test_floateisf(0xDF012346, i256, -0x8123458000000001); | 283 | try test_f32_floatFromInt(0xDF012346, i256, -0x8123458000000001); |
| 253 | try test_floateisf(0xDF012346, i256, -0x8123458000000000); | 284 | try test_f32_floatFromInt(0xDF012346, i256, -0x8123458000000000); |
| 254 | try test_floateisf(0xDF012345, i256, -0x8123456789ABCDEF); | 285 | try test_f32_floatFromInt(0xDF012345, i256, -0x8123456789ABCDEF); |
| 255 | try test_floateisf(0xBF800000, i256, -1); | 286 | try test_f32_floatFromInt(0xBF800000, i256, -1); |
| 256 | try test_floateisf(0x00000000, i256, 0); | 287 | try test_f32_floatFromInt(0x00000000, i256, 0); |
| 257 | try test_floateisf(0x5F012345, i256, 0x8123456789ABCDEF); | 288 | try test_f32_floatFromInt(0x5F012345, i256, 0x8123456789ABCDEF); |
| 258 | try test_floateisf(0x5F012346, i256, 0x8123458000000000); | 289 | try test_f32_floatFromInt(0x5F012346, i256, 0x8123458000000000); |
| 259 | try test_floateisf(0x5F012346, i256, 0x8123458000000001); | 290 | try test_f32_floatFromInt(0x5F012346, i256, 0x8123458000000001); |
| 260 | try test_floateisf(0x5F012346, i256, 0x8123458100000000); | 291 | try test_f32_floatFromInt(0x5F012346, i256, 0x8123458100000000); |
| 261 | try test_floateisf(0x5F012346, i256, 0x8123468000000000); | 292 | try test_f32_floatFromInt(0x5F012346, i256, 0x8123468000000000); |
| 262 | try test_floateisf(0x5F012347, i256, 0x8123468000000001); | 293 | try test_f32_floatFromInt(0x5F012347, i256, 0x8123468000000001); |
| 263 | try test_floateisf(0x5F012347, i256, 0x8123468100000000); | 294 | try test_f32_floatFromInt(0x5F012347, i256, 0x8123468100000000); |
| 264 | try test_floateisf(0x7F000000, i256, math.maxInt(u127)); | 295 | try test_f32_floatFromInt(0x7F000000, i256, math.maxInt(u127)); |
| 265 | try test_floateisf(0x7F000000, i256, 1 << 127); | 296 | try test_f32_floatFromInt(0x7F000000, i256, 1 << 127); |
| 266 | } | 297 | } |
| 267 | 298 | ||
| 268 | test "floatuneisf" { | 299 | test f32_floatFromInt_unsigned { |
| 269 | try test_floateisf(0x00000000, u256, 0); | 300 | try test_f32_floatFromInt(0x00000000, u256, 0); |
| 270 | try test_floateisf(0x5F012345, u256, 0x8123456789ABCDEF); | 301 | try test_f32_floatFromInt(0x5F012345, u256, 0x8123456789ABCDEF); |
| 271 | try test_floateisf(0x5F012346, u256, 0x8123458000000000); | 302 | try test_f32_floatFromInt(0x5F012346, u256, 0x8123458000000000); |
| 272 | try test_floateisf(0x5F012346, u256, 0x8123458000000001); | 303 | try test_f32_floatFromInt(0x5F012346, u256, 0x8123458000000001); |
| 273 | try test_floateisf(0x5F012346, u256, 0x8123458080000000); | 304 | try test_f32_floatFromInt(0x5F012346, u256, 0x8123458080000000); |
| 274 | try test_floateisf(0x5F012346, u256, 0x8123468000000000); | 305 | try test_f32_floatFromInt(0x5F012346, u256, 0x8123468000000000); |
| 275 | try test_floateisf(0x5F012347, u256, 0x8123468000000001); | 306 | try test_f32_floatFromInt(0x5F012347, u256, 0x8123468000000001); |
| 276 | try test_floateisf(0x5F012347, u256, 0x8123468080000000); | 307 | try test_f32_floatFromInt(0x5F012347, u256, 0x8123468080000000); |
| 277 | try test_floateisf(0x7F000000, u256, math.maxInt(u127)); | 308 | try test_f32_floatFromInt(0x7F000000, u256, math.maxInt(u127)); |
| 278 | try test_floateisf(0x7F000000, u256, 1 << 127); | 309 | try test_f32_floatFromInt(0x7F000000, u256, 1 << 127); |
| 279 | try test_floateisf(0x7F800000, u256, math.maxInt(u256)); | 310 | try test_f32_floatFromInt(0x7F800000, u256, math.maxInt(u256)); |
| 280 | } | 311 | } |
| 281 | 312 | ||
| 282 | fn test_one_floatsidf(a: i32, expected: u64) !void { | 313 | fn test_f64_floatFromInt_i32(a: i32, expected: u64) !void { |
| 283 | const r = __floatsidf(a); | 314 | const r = f64_floatFromInt_i32(a); |
| 284 | try std.testing.expect(@as(u64, @bitCast(r)) == expected); | 315 | try std.testing.expect(@as(u64, @bitCast(r)) == expected); |
| 285 | } | 316 | } |
| 286 | 317 | ||
| 287 | fn test_one_floatunsidf(a: u32, expected: u64) !void { | 318 | fn test_f64_floatFromInt_u32(a: u32, expected: u64) !void { |
| 288 | const r = __floatunsidf(a); | 319 | const r = f64_floatFromInt_u32(a); |
| 289 | try std.testing.expect(@as(u64, @bitCast(r)) == expected); | 320 | try std.testing.expect(@as(u64, @bitCast(r)) == expected); |
| 290 | } | 321 | } |
| 291 | 322 | ||
| 292 | test "floatsidf" { | 323 | test f64_floatFromInt_i32 { |
| 293 | try test_one_floatsidf(0, 0x0000000000000000); | 324 | try test_f64_floatFromInt_i32(0, 0x0000000000000000); |
| 294 | try test_one_floatsidf(1, 0x3ff0000000000000); | 325 | try test_f64_floatFromInt_i32(1, 0x3ff0000000000000); |
| 295 | try test_one_floatsidf(-1, 0xbff0000000000000); | 326 | try test_f64_floatFromInt_i32(-1, 0xbff0000000000000); |
| 296 | try test_one_floatsidf(0x7FFFFFFF, 0x41dfffffffc00000); | 327 | try test_f64_floatFromInt_i32(0x7FFFFFFF, 0x41dfffffffc00000); |
| 297 | try test_one_floatsidf(@bitCast(@as(u32, @intCast(0x80000000))), 0xc1e0000000000000); | 328 | try test_f64_floatFromInt_i32(@bitCast(@as(u32, @intCast(0x80000000))), 0xc1e0000000000000); |
| 298 | } | 329 | } |
| 299 | 330 | ||
| 300 | test "floatunsidf" { | 331 | test f64_floatFromInt_u32 { |
| 301 | try test_one_floatunsidf(0, 0x0000000000000000); | 332 | try test_f64_floatFromInt_u32(0, 0x0000000000000000); |
| 302 | try test_one_floatunsidf(1, 0x3ff0000000000000); | 333 | try test_f64_floatFromInt_u32(1, 0x3ff0000000000000); |
| 303 | try test_one_floatunsidf(0x7FFFFFFF, 0x41dfffffffc00000); | 334 | try test_f64_floatFromInt_u32(0x7FFFFFFF, 0x41dfffffffc00000); |
| 304 | try test_one_floatunsidf(@intCast(0x80000000), 0x41e0000000000000); | 335 | try test_f64_floatFromInt_u32(@intCast(0x80000000), 0x41e0000000000000); |
| 305 | try test_one_floatunsidf(@intCast(0xFFFFFFFF), 0x41efffffffe00000); | 336 | try test_f64_floatFromInt_u32(@intCast(0xFFFFFFFF), 0x41efffffffe00000); |
| 306 | } | 337 | } |
| 307 | 338 | ||
| 308 | fn test__floatdidf(a: i64, expected: f64) !void { | 339 | fn test_f64_floatFromInt_i64(a: i64, expected: f64) !void { |
| 309 | const r = __floatdidf(a); | 340 | const r = f64_floatFromInt_i64(a); |
| 310 | try testing.expect(r == expected); | 341 | try testing.expect(r == expected); |
| 311 | } | 342 | } |
| 312 | 343 | ||
| 313 | fn test__floatundidf(a: u64, expected: f64) !void { | 344 | fn test_f64_floatFromInt_u64(a: u64, expected: f64) !void { |
| 314 | const r = __floatundidf(a); | 345 | const r = f64_floatFromInt_u64(a); |
| 315 | try testing.expect(r == expected); | 346 | try testing.expect(r == expected); |
| 316 | } | 347 | } |
| 317 | 348 | ||
| 318 | test "floatdidf" { | 349 | test f64_floatFromInt_i64 { |
| 319 | try test__floatdidf(0, 0.0); | 350 | try test_f64_floatFromInt_i64(0, 0.0); |
| 320 | try test__floatdidf(1, 1.0); | 351 | try test_f64_floatFromInt_i64(1, 1.0); |
| 321 | try test__floatdidf(2, 2.0); | 352 | try test_f64_floatFromInt_i64(2, 2.0); |
| 322 | try test__floatdidf(20, 20.0); | 353 | try test_f64_floatFromInt_i64(20, 20.0); |
| 323 | try test__floatdidf(-1, -1.0); | 354 | try test_f64_floatFromInt_i64(-1, -1.0); |
| 324 | try test__floatdidf(-2, -2.0); | 355 | try test_f64_floatFromInt_i64(-2, -2.0); |
| 325 | try test__floatdidf(-20, -20.0); | 356 | try test_f64_floatFromInt_i64(-20, -20.0); |
| 326 | try test__floatdidf(0x7FFFFF8000000000, 0x1.FFFFFEp+62); | 357 | try test_f64_floatFromInt_i64(0x7FFFFF8000000000, 0x1.FFFFFEp+62); |
| 327 | try test__floatdidf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62); | 358 | try test_f64_floatFromInt_i64(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62); |
| 328 | try test__floatdidf(0x7FFFFF0000000000, 0x1.FFFFFCp+62); | 359 | try test_f64_floatFromInt_i64(0x7FFFFF0000000000, 0x1.FFFFFCp+62); |
| 329 | try test__floatdidf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62); | 360 | try test_f64_floatFromInt_i64(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62); |
| 330 | try test__floatdidf(@bitCast(@as(u64, @intCast(0x8000008000000000))), -0x1.FFFFFEp+62); | 361 | try test_f64_floatFromInt_i64(@bitCast(@as(u64, @intCast(0x8000008000000000))), -0x1.FFFFFEp+62); |
| 331 | try test__floatdidf(@bitCast(@as(u64, @intCast(0x8000000000000800))), -0x1.FFFFFFFFFFFFEp+62); | 362 | try test_f64_floatFromInt_i64(@bitCast(@as(u64, @intCast(0x8000000000000800))), -0x1.FFFFFFFFFFFFEp+62); |
| 332 | try test__floatdidf(@bitCast(@as(u64, @intCast(0x8000010000000000))), -0x1.FFFFFCp+62); | 363 | try test_f64_floatFromInt_i64(@bitCast(@as(u64, @intCast(0x8000010000000000))), -0x1.FFFFFCp+62); |
| 333 | try test__floatdidf(@bitCast(@as(u64, @intCast(0x8000000000001000))), -0x1.FFFFFFFFFFFFCp+62); | 364 | try test_f64_floatFromInt_i64(@bitCast(@as(u64, @intCast(0x8000000000001000))), -0x1.FFFFFFFFFFFFCp+62); |
| 334 | try test__floatdidf(@bitCast(@as(u64, @intCast(0x8000000000000000))), -0x1.000000p+63); | 365 | try test_f64_floatFromInt_i64(@bitCast(@as(u64, @intCast(0x8000000000000000))), -0x1.000000p+63); |
| 335 | try test__floatdidf(@bitCast(@as(u64, @intCast(0x8000000000000001))), -0x1.000000p+63); // 0x8000000000000001 | 366 | try test_f64_floatFromInt_i64(@bitCast(@as(u64, @intCast(0x8000000000000001))), -0x1.000000p+63); // 0x8000000000000001 |
| 336 | try test__floatdidf(0x0007FB72E8000000, 0x1.FEDCBAp+50); | 367 | try test_f64_floatFromInt_i64(0x0007FB72E8000000, 0x1.FEDCBAp+50); |
| 337 | try test__floatdidf(0x0007FB72EA000000, 0x1.FEDCBA8p+50); | 368 | try test_f64_floatFromInt_i64(0x0007FB72EA000000, 0x1.FEDCBA8p+50); |
| 338 | try test__floatdidf(0x0007FB72EB000000, 0x1.FEDCBACp+50); | 369 | try test_f64_floatFromInt_i64(0x0007FB72EB000000, 0x1.FEDCBACp+50); |
| 339 | try test__floatdidf(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50); | 370 | try test_f64_floatFromInt_i64(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50); |
| 340 | try test__floatdidf(0x0007FB72EC000000, 0x1.FEDCBBp+50); | 371 | try test_f64_floatFromInt_i64(0x0007FB72EC000000, 0x1.FEDCBBp+50); |
| 341 | try test__floatdidf(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50); | 372 | try test_f64_floatFromInt_i64(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50); |
| 342 | try test__floatdidf(0x0007FB72E6000000, 0x1.FEDCB98p+50); | 373 | try test_f64_floatFromInt_i64(0x0007FB72E6000000, 0x1.FEDCB98p+50); |
| 343 | try test__floatdidf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50); | 374 | try test_f64_floatFromInt_i64(0x0007FB72E7000000, 0x1.FEDCB9Cp+50); |
| 344 | try test__floatdidf(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50); | 375 | try test_f64_floatFromInt_i64(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50); |
| 345 | try test__floatdidf(0x0007FB72E4000001, 0x1.FEDCB90000004p+50); | 376 | try test_f64_floatFromInt_i64(0x0007FB72E4000001, 0x1.FEDCB90000004p+50); |
| 346 | try test__floatdidf(0x0007FB72E4000000, 0x1.FEDCB9p+50); | 377 | try test_f64_floatFromInt_i64(0x0007FB72E4000000, 0x1.FEDCB9p+50); |
| 347 | try test__floatdidf(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57); | 378 | try test_f64_floatFromInt_i64(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57); |
| 348 | try test__floatdidf(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57); | 379 | try test_f64_floatFromInt_i64(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57); |
| 349 | try test__floatdidf(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57); | 380 | try test_f64_floatFromInt_i64(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57); |
| 350 | try test__floatdidf(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57); | 381 | try test_f64_floatFromInt_i64(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57); |
| 351 | try test__floatdidf(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57); | 382 | try test_f64_floatFromInt_i64(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57); |
| 352 | try test__floatdidf(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57); | 383 | try test_f64_floatFromInt_i64(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57); |
| 353 | try test__floatdidf(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57); | 384 | try test_f64_floatFromInt_i64(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57); |
| 354 | try test__floatdidf(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57); | 385 | try test_f64_floatFromInt_i64(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57); |
| 355 | try test__floatdidf(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57); | 386 | try test_f64_floatFromInt_i64(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57); |
| 356 | try test__floatdidf(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57); | 387 | try test_f64_floatFromInt_i64(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57); |
| 357 | try test__floatdidf(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57); | 388 | try test_f64_floatFromInt_i64(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57); |
| 358 | try test__floatdidf(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57); | 389 | try test_f64_floatFromInt_i64(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57); |
| 359 | try test__floatdidf(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57); | 390 | try test_f64_floatFromInt_i64(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57); |
| 360 | try test__floatdidf(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57); | 391 | try test_f64_floatFromInt_i64(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57); |
| 361 | try test__floatdidf(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57); | 392 | try test_f64_floatFromInt_i64(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57); |
| 362 | } | 393 | } |
| 363 | 394 | ||
| 364 | test "floatundidf" { | 395 | test f64_floatFromInt_u64 { |
| 365 | try test__floatundidf(0, 0.0); | 396 | try test_f64_floatFromInt_u64(0, 0.0); |
| 366 | try test__floatundidf(1, 1.0); | 397 | try test_f64_floatFromInt_u64(1, 1.0); |
| 367 | try test__floatundidf(2, 2.0); | 398 | try test_f64_floatFromInt_u64(2, 2.0); |
| 368 | try test__floatundidf(20, 20.0); | 399 | try test_f64_floatFromInt_u64(20, 20.0); |
| 369 | try test__floatundidf(0x7FFFFF8000000000, 0x1.FFFFFEp+62); | 400 | try test_f64_floatFromInt_u64(0x7FFFFF8000000000, 0x1.FFFFFEp+62); |
| 370 | try test__floatundidf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62); | 401 | try test_f64_floatFromInt_u64(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62); |
| 371 | try test__floatundidf(0x7FFFFF0000000000, 0x1.FFFFFCp+62); | 402 | try test_f64_floatFromInt_u64(0x7FFFFF0000000000, 0x1.FFFFFCp+62); |
| 372 | try test__floatundidf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62); | 403 | try test_f64_floatFromInt_u64(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62); |
| 373 | try test__floatundidf(0x8000008000000000, 0x1.000001p+63); | 404 | try test_f64_floatFromInt_u64(0x8000008000000000, 0x1.000001p+63); |
| 374 | try test__floatundidf(0x8000000000000800, 0x1.0000000000001p+63); | 405 | try test_f64_floatFromInt_u64(0x8000000000000800, 0x1.0000000000001p+63); |
| 375 | try test__floatundidf(0x8000010000000000, 0x1.000002p+63); | 406 | try test_f64_floatFromInt_u64(0x8000010000000000, 0x1.000002p+63); |
| 376 | try test__floatundidf(0x8000000000001000, 0x1.0000000000002p+63); | 407 | try test_f64_floatFromInt_u64(0x8000000000001000, 0x1.0000000000002p+63); |
| 377 | try test__floatundidf(0x8000000000000000, 0x1p+63); | 408 | try test_f64_floatFromInt_u64(0x8000000000000000, 0x1p+63); |
| 378 | try test__floatundidf(0x8000000000000001, 0x1p+63); | 409 | try test_f64_floatFromInt_u64(0x8000000000000001, 0x1p+63); |
| 379 | try test__floatundidf(0x0007FB72E8000000, 0x1.FEDCBAp+50); | 410 | try test_f64_floatFromInt_u64(0x0007FB72E8000000, 0x1.FEDCBAp+50); |
| 380 | try test__floatundidf(0x0007FB72EA000000, 0x1.FEDCBA8p+50); | 411 | try test_f64_floatFromInt_u64(0x0007FB72EA000000, 0x1.FEDCBA8p+50); |
| 381 | try test__floatundidf(0x0007FB72EB000000, 0x1.FEDCBACp+50); | 412 | try test_f64_floatFromInt_u64(0x0007FB72EB000000, 0x1.FEDCBACp+50); |
| 382 | try test__floatundidf(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50); | 413 | try test_f64_floatFromInt_u64(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50); |
| 383 | try test__floatundidf(0x0007FB72EC000000, 0x1.FEDCBBp+50); | 414 | try test_f64_floatFromInt_u64(0x0007FB72EC000000, 0x1.FEDCBBp+50); |
| 384 | try test__floatundidf(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50); | 415 | try test_f64_floatFromInt_u64(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50); |
| 385 | try test__floatundidf(0x0007FB72E6000000, 0x1.FEDCB98p+50); | 416 | try test_f64_floatFromInt_u64(0x0007FB72E6000000, 0x1.FEDCB98p+50); |
| 386 | try test__floatundidf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50); | 417 | try test_f64_floatFromInt_u64(0x0007FB72E7000000, 0x1.FEDCB9Cp+50); |
| 387 | try test__floatundidf(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50); | 418 | try test_f64_floatFromInt_u64(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50); |
| 388 | try test__floatundidf(0x0007FB72E4000001, 0x1.FEDCB90000004p+50); | 419 | try test_f64_floatFromInt_u64(0x0007FB72E4000001, 0x1.FEDCB90000004p+50); |
| 389 | try test__floatundidf(0x0007FB72E4000000, 0x1.FEDCB9p+50); | 420 | try test_f64_floatFromInt_u64(0x0007FB72E4000000, 0x1.FEDCB9p+50); |
| 390 | try test__floatundidf(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57); | 421 | try test_f64_floatFromInt_u64(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57); |
| 391 | try test__floatundidf(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57); | 422 | try test_f64_floatFromInt_u64(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57); |
| 392 | try test__floatundidf(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57); | 423 | try test_f64_floatFromInt_u64(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57); |
| 393 | try test__floatundidf(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57); | 424 | try test_f64_floatFromInt_u64(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57); |
| 394 | try test__floatundidf(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57); | 425 | try test_f64_floatFromInt_u64(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57); |
| 395 | try test__floatundidf(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57); | 426 | try test_f64_floatFromInt_u64(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57); |
| 396 | try test__floatundidf(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57); | 427 | try test_f64_floatFromInt_u64(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57); |
| 397 | try test__floatundidf(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57); | 428 | try test_f64_floatFromInt_u64(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57); |
| 398 | try test__floatundidf(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57); | 429 | try test_f64_floatFromInt_u64(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57); |
| 399 | try test__floatundidf(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57); | 430 | try test_f64_floatFromInt_u64(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57); |
| 400 | try test__floatundidf(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57); | 431 | try test_f64_floatFromInt_u64(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57); |
| 401 | try test__floatundidf(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57); | 432 | try test_f64_floatFromInt_u64(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57); |
| 402 | try test__floatundidf(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57); | 433 | try test_f64_floatFromInt_u64(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57); |
| 403 | try test__floatundidf(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57); | 434 | try test_f64_floatFromInt_u64(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57); |
| 404 | try test__floatundidf(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57); | 435 | try test_f64_floatFromInt_u64(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57); |
| 405 | } | 436 | } |
| 406 | 437 | ||
| 407 | fn test__floattidf(a: i128, expected: f64) !void { | 438 | fn test_f64_floatFromInt_i128(a: i128, expected: f64) !void { |
| 408 | const x = __floattidf(a); | 439 | const x = f64_floatFromInt_i128(a); |
| 409 | try testing.expect(x == expected); | 440 | try testing.expect(x == expected); |
| 410 | } | 441 | } |
| 411 | 442 | ||
| 412 | fn test__floatuntidf(a: u128, expected: f64) !void { | 443 | fn test_f64_floatFromInt_u128(a: u128, expected: f64) !void { |
| 413 | const x = __floatuntidf(a); | 444 | const x = f64_floatFromInt_u128(a); |
| 414 | try testing.expect(x == expected); | 445 | try testing.expect(x == expected); |
| 415 | } | 446 | } |
| 416 | 447 | ||
| 417 | test "floattidf" { | 448 | test f64_floatFromInt_i128 { |
| 418 | try test__floattidf(0, 0.0); | 449 | try test_f64_floatFromInt_i128(0, 0.0); |
| 419 | 450 | ||
| 420 | try test__floattidf(1, 1.0); | 451 | try test_f64_floatFromInt_i128(1, 1.0); |
| 421 | try test__floattidf(2, 2.0); | 452 | try test_f64_floatFromInt_i128(2, 2.0); |
| 422 | try test__floattidf(20, 20.0); | 453 | try test_f64_floatFromInt_i128(20, 20.0); |
| 423 | try test__floattidf(-1, -1.0); | 454 | try test_f64_floatFromInt_i128(-1, -1.0); |
| 424 | try test__floattidf(-2, -2.0); | 455 | try test_f64_floatFromInt_i128(-2, -2.0); |
| 425 | try test__floattidf(-20, -20.0); | 456 | try test_f64_floatFromInt_i128(-20, -20.0); |
| 426 | 457 | ||
| 427 | try test__floattidf(0x7FFFFF8000000000, 0x1.FFFFFEp+62); | 458 | try test_f64_floatFromInt_i128(0x7FFFFF8000000000, 0x1.FFFFFEp+62); |
| 428 | try test__floattidf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62); | 459 | try test_f64_floatFromInt_i128(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62); |
| 429 | try test__floattidf(0x7FFFFF0000000000, 0x1.FFFFFCp+62); | 460 | try test_f64_floatFromInt_i128(0x7FFFFF0000000000, 0x1.FFFFFCp+62); |
| 430 | try test__floattidf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62); | 461 | try test_f64_floatFromInt_i128(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62); |
| 431 | 462 | ||
| 432 | try test__floattidf(make_ti(0x8000008000000000, 0), -0x1.FFFFFEp+126); | 463 | try test_f64_floatFromInt_i128(make_ti(0x8000008000000000, 0), -0x1.FFFFFEp+126); |
| 433 | try test__floattidf(make_ti(0x8000000000000800, 0), -0x1.FFFFFFFFFFFFEp+126); | 464 | try test_f64_floatFromInt_i128(make_ti(0x8000000000000800, 0), -0x1.FFFFFFFFFFFFEp+126); |
| 434 | try test__floattidf(make_ti(0x8000010000000000, 0), -0x1.FFFFFCp+126); | 465 | try test_f64_floatFromInt_i128(make_ti(0x8000010000000000, 0), -0x1.FFFFFCp+126); |
| 435 | try test__floattidf(make_ti(0x8000000000001000, 0), -0x1.FFFFFFFFFFFFCp+126); | 466 | try test_f64_floatFromInt_i128(make_ti(0x8000000000001000, 0), -0x1.FFFFFFFFFFFFCp+126); |
| 436 | 467 | ||
| 437 | try test__floattidf(make_ti(0x8000000000000000, 0), -0x1.000000p+127); | 468 | try test_f64_floatFromInt_i128(make_ti(0x8000000000000000, 0), -0x1.000000p+127); |
| 438 | try test__floattidf(make_ti(0x8000000000000001, 0), -0x1.000000p+127); | 469 | try test_f64_floatFromInt_i128(make_ti(0x8000000000000001, 0), -0x1.000000p+127); |
| 439 | 470 | ||
| 440 | try test__floattidf(0x0007FB72E8000000, 0x1.FEDCBAp+50); | 471 | try test_f64_floatFromInt_i128(0x0007FB72E8000000, 0x1.FEDCBAp+50); |
| 441 | 472 | ||
| 442 | try test__floattidf(0x0007FB72EA000000, 0x1.FEDCBA8p+50); | 473 | try test_f64_floatFromInt_i128(0x0007FB72EA000000, 0x1.FEDCBA8p+50); |
| 443 | try test__floattidf(0x0007FB72EB000000, 0x1.FEDCBACp+50); | 474 | try test_f64_floatFromInt_i128(0x0007FB72EB000000, 0x1.FEDCBACp+50); |
| 444 | try test__floattidf(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50); | 475 | try test_f64_floatFromInt_i128(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50); |
| 445 | try test__floattidf(0x0007FB72EC000000, 0x1.FEDCBBp+50); | 476 | try test_f64_floatFromInt_i128(0x0007FB72EC000000, 0x1.FEDCBBp+50); |
| 446 | try test__floattidf(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50); | 477 | try test_f64_floatFromInt_i128(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50); |
| 447 | 478 | ||
| 448 | try test__floattidf(0x0007FB72E6000000, 0x1.FEDCB98p+50); | 479 | try test_f64_floatFromInt_i128(0x0007FB72E6000000, 0x1.FEDCB98p+50); |
| 449 | try test__floattidf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50); | 480 | try test_f64_floatFromInt_i128(0x0007FB72E7000000, 0x1.FEDCB9Cp+50); |
| 450 | try test__floattidf(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50); | 481 | try test_f64_floatFromInt_i128(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50); |
| 451 | try test__floattidf(0x0007FB72E4000001, 0x1.FEDCB90000004p+50); | 482 | try test_f64_floatFromInt_i128(0x0007FB72E4000001, 0x1.FEDCB90000004p+50); |
| 452 | try test__floattidf(0x0007FB72E4000000, 0x1.FEDCB9p+50); | 483 | try test_f64_floatFromInt_i128(0x0007FB72E4000000, 0x1.FEDCB9p+50); |
| 453 | 484 | ||
| 454 | try test__floattidf(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57); | 485 | try test_f64_floatFromInt_i128(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57); |
| 455 | try test__floattidf(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57); | 486 | try test_f64_floatFromInt_i128(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57); |
| 456 | try test__floattidf(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57); | 487 | try test_f64_floatFromInt_i128(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57); |
| 457 | try test__floattidf(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57); | 488 | try test_f64_floatFromInt_i128(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57); |
| 458 | try test__floattidf(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57); | 489 | try test_f64_floatFromInt_i128(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57); |
| 459 | try test__floattidf(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57); | 490 | try test_f64_floatFromInt_i128(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57); |
| 460 | try test__floattidf(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57); | 491 | try test_f64_floatFromInt_i128(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57); |
| 461 | try test__floattidf(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57); | 492 | try test_f64_floatFromInt_i128(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57); |
| 462 | try test__floattidf(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57); | 493 | try test_f64_floatFromInt_i128(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57); |
| 463 | try test__floattidf(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57); | 494 | try test_f64_floatFromInt_i128(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57); |
| 464 | try test__floattidf(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57); | 495 | try test_f64_floatFromInt_i128(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57); |
| 465 | try test__floattidf(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57); | 496 | try test_f64_floatFromInt_i128(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57); |
| 466 | try test__floattidf(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57); | 497 | try test_f64_floatFromInt_i128(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57); |
| 467 | try test__floattidf(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57); | 498 | try test_f64_floatFromInt_i128(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57); |
| 468 | try test__floattidf(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57); | 499 | try test_f64_floatFromInt_i128(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57); |
| 469 | 500 | ||
| 470 | try test__floattidf(make_ti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121); | 501 | try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121); |
| 471 | try test__floattidf(make_ti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496Dp+121); | 502 | try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496Dp+121); |
| 472 | try test__floattidf(make_ti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496Ep+121); | 503 | try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496Ep+121); |
| 473 | try test__floattidf(make_ti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496Ep+121); | 504 | try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496Ep+121); |
| 474 | try test__floattidf(make_ti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496Ep+121); | 505 | try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496Ep+121); |
| 475 | try test__floattidf(make_ti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496Ep+121); | 506 | try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496Ep+121); |
| 476 | try test__floattidf(make_ti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496Ep+121); | 507 | try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496Ep+121); |
| 477 | try test__floattidf(make_ti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496Ep+121); | 508 | try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496Ep+121); |
| 478 | try test__floattidf(make_ti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496Ep+121); | 509 | try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496Ep+121); |
| 479 | try test__floattidf(make_ti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496Ep+121); | 510 | try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496Ep+121); |
| 480 | try test__floattidf(make_ti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496Ep+121); | 511 | try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496Ep+121); |
| 481 | try test__floattidf(make_ti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496Fp+121); | 512 | try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496Fp+121); |
| 482 | try test__floattidf(make_ti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496Fp+121); | 513 | try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496Fp+121); |
| 483 | try test__floattidf(make_ti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496Fp+121); | 514 | try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496Fp+121); |
| 484 | try test__floattidf(make_ti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121); | 515 | try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121); |
| 485 | } | 516 | } |
| 486 | 517 | ||
| 487 | test "floatuntidf" { | 518 | test f64_floatFromInt_u128 { |
| 488 | try test__floatuntidf(0, 0.0); | 519 | try test_f64_floatFromInt_u128(0, 0.0); |
| 489 | 520 | ||
| 490 | try test__floatuntidf(1, 1.0); | 521 | try test_f64_floatFromInt_u128(1, 1.0); |
| 491 | try test__floatuntidf(2, 2.0); | 522 | try test_f64_floatFromInt_u128(2, 2.0); |
| 492 | try test__floatuntidf(20, 20.0); | 523 | try test_f64_floatFromInt_u128(20, 20.0); |
| 493 | 524 | ||
| 494 | try test__floatuntidf(0x7FFFFF8000000000, 0x1.FFFFFEp+62); | 525 | try test_f64_floatFromInt_u128(0x7FFFFF8000000000, 0x1.FFFFFEp+62); |
| 495 | try test__floatuntidf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62); | 526 | try test_f64_floatFromInt_u128(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62); |
| 496 | try test__floatuntidf(0x7FFFFF0000000000, 0x1.FFFFFCp+62); | 527 | try test_f64_floatFromInt_u128(0x7FFFFF0000000000, 0x1.FFFFFCp+62); |
| 497 | try test__floatuntidf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62); | 528 | try test_f64_floatFromInt_u128(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62); |
| 498 | 529 | ||
| 499 | try test__floatuntidf(make_uti(0x8000008000000000, 0), 0x1.000001p+127); | 530 | try test_f64_floatFromInt_u128(make_uti(0x8000008000000000, 0), 0x1.000001p+127); |
| 500 | try test__floatuntidf(make_uti(0x8000000000000800, 0), 0x1.0000000000001p+127); | 531 | try test_f64_floatFromInt_u128(make_uti(0x8000000000000800, 0), 0x1.0000000000001p+127); |
| 501 | try test__floatuntidf(make_uti(0x8000010000000000, 0), 0x1.000002p+127); | 532 | try test_f64_floatFromInt_u128(make_uti(0x8000010000000000, 0), 0x1.000002p+127); |
| 502 | try test__floatuntidf(make_uti(0x8000000000001000, 0), 0x1.0000000000002p+127); | 533 | try test_f64_floatFromInt_u128(make_uti(0x8000000000001000, 0), 0x1.0000000000002p+127); |
| 503 | 534 | ||
| 504 | try test__floatuntidf(make_uti(0x8000000000000000, 0), 0x1.000000p+127); | 535 | try test_f64_floatFromInt_u128(make_uti(0x8000000000000000, 0), 0x1.000000p+127); |
| 505 | try test__floatuntidf(make_uti(0x8000000000000001, 0), 0x1.0000000000000002p+127); | 536 | try test_f64_floatFromInt_u128(make_uti(0x8000000000000001, 0), 0x1.0000000000000002p+127); |
| 506 | 537 | ||
| 507 | try test__floatuntidf(0x0007FB72E8000000, 0x1.FEDCBAp+50); | 538 | try test_f64_floatFromInt_u128(0x0007FB72E8000000, 0x1.FEDCBAp+50); |
| 508 | 539 | ||
| 509 | try test__floatuntidf(0x0007FB72EA000000, 0x1.FEDCBA8p+50); | 540 | try test_f64_floatFromInt_u128(0x0007FB72EA000000, 0x1.FEDCBA8p+50); |
| 510 | try test__floatuntidf(0x0007FB72EB000000, 0x1.FEDCBACp+50); | 541 | try test_f64_floatFromInt_u128(0x0007FB72EB000000, 0x1.FEDCBACp+50); |
| 511 | try test__floatuntidf(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50); | 542 | try test_f64_floatFromInt_u128(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50); |
| 512 | try test__floatuntidf(0x0007FB72EC000000, 0x1.FEDCBBp+50); | 543 | try test_f64_floatFromInt_u128(0x0007FB72EC000000, 0x1.FEDCBBp+50); |
| 513 | try test__floatuntidf(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50); | 544 | try test_f64_floatFromInt_u128(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50); |
| 514 | 545 | ||
| 515 | try test__floatuntidf(0x0007FB72E6000000, 0x1.FEDCB98p+50); | 546 | try test_f64_floatFromInt_u128(0x0007FB72E6000000, 0x1.FEDCB98p+50); |
| 516 | try test__floatuntidf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50); | 547 | try test_f64_floatFromInt_u128(0x0007FB72E7000000, 0x1.FEDCB9Cp+50); |
| 517 | try test__floatuntidf(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50); | 548 | try test_f64_floatFromInt_u128(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50); |
| 518 | try test__floatuntidf(0x0007FB72E4000001, 0x1.FEDCB90000004p+50); | 549 | try test_f64_floatFromInt_u128(0x0007FB72E4000001, 0x1.FEDCB90000004p+50); |
| 519 | try test__floatuntidf(0x0007FB72E4000000, 0x1.FEDCB9p+50); | 550 | try test_f64_floatFromInt_u128(0x0007FB72E4000000, 0x1.FEDCB9p+50); |
| 520 | 551 | ||
| 521 | try test__floatuntidf(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57); | 552 | try test_f64_floatFromInt_u128(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57); |
| 522 | try test__floatuntidf(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57); | 553 | try test_f64_floatFromInt_u128(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57); |
| 523 | try test__floatuntidf(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57); | 554 | try test_f64_floatFromInt_u128(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57); |
| 524 | try test__floatuntidf(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57); | 555 | try test_f64_floatFromInt_u128(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57); |
| 525 | try test__floatuntidf(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57); | 556 | try test_f64_floatFromInt_u128(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57); |
| 526 | try test__floatuntidf(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57); | 557 | try test_f64_floatFromInt_u128(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57); |
| 527 | try test__floatuntidf(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57); | 558 | try test_f64_floatFromInt_u128(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57); |
| 528 | try test__floatuntidf(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57); | 559 | try test_f64_floatFromInt_u128(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57); |
| 529 | try test__floatuntidf(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57); | 560 | try test_f64_floatFromInt_u128(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57); |
| 530 | try test__floatuntidf(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57); | 561 | try test_f64_floatFromInt_u128(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57); |
| 531 | try test__floatuntidf(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57); | 562 | try test_f64_floatFromInt_u128(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57); |
| 532 | try test__floatuntidf(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57); | 563 | try test_f64_floatFromInt_u128(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57); |
| 533 | try test__floatuntidf(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57); | 564 | try test_f64_floatFromInt_u128(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57); |
| 534 | try test__floatuntidf(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57); | 565 | try test_f64_floatFromInt_u128(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57); |
| 535 | try test__floatuntidf(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57); | 566 | try test_f64_floatFromInt_u128(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57); |
| 536 | 567 | ||
| 537 | try test__floatuntidf(make_uti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121); | 568 | try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121); |
| 538 | try test__floatuntidf(make_uti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496Dp+121); | 569 | try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496Dp+121); |
| 539 | try test__floatuntidf(make_uti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496Ep+121); | 570 | try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496Ep+121); |
| 540 | try test__floatuntidf(make_uti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496Ep+121); | 571 | try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496Ep+121); |
| 541 | try test__floatuntidf(make_uti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496Ep+121); | 572 | try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496Ep+121); |
| 542 | try test__floatuntidf(make_uti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496Ep+121); | 573 | try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496Ep+121); |
| 543 | try test__floatuntidf(make_uti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496Ep+121); | 574 | try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496Ep+121); |
| 544 | try test__floatuntidf(make_uti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496Ep+121); | 575 | try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496Ep+121); |
| 545 | try test__floatuntidf(make_uti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496Ep+121); | 576 | try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496Ep+121); |
| 546 | try test__floatuntidf(make_uti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496Ep+121); | 577 | try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496Ep+121); |
| 547 | try test__floatuntidf(make_uti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496Ep+121); | 578 | try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496Ep+121); |
| 548 | try test__floatuntidf(make_uti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496Fp+121); | 579 | try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496Fp+121); |
| 549 | try test__floatuntidf(make_uti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496Fp+121); | 580 | try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496Fp+121); |
| 550 | try test__floatuntidf(make_uti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496Fp+121); | 581 | try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496Fp+121); |
| 551 | try test__floatuntidf(make_uti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121); | 582 | try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121); |
| 552 | } | 583 | } |
| 553 | 584 | ||
| 554 | fn test__floatsitf(a: i32, expected: u128) !void { | 585 | fn test_f128_floatFromInt_i32(a: i32, expected: u128) !void { |
| 555 | const r = __floatsitf(a); | 586 | const r = f128_floatFromInt_i32(a); |
| 556 | try std.testing.expect(@as(u128, @bitCast(r)) == expected); | 587 | try std.testing.expect(@as(u128, @bitCast(r)) == expected); |
| 557 | } | 588 | } |
| 558 | 589 | ||
| 559 | test "floatsitf" { | 590 | fn test_f128_floatFromInt_u32(a: u32, expected_hi: u64, expected_lo: u64) !void { |
| 560 | try test__floatsitf(0, 0); | 591 | const x = f128_floatFromInt_u32(a); |
| 561 | try test__floatsitf(0x7FFFFFFF, 0x401dfffffffc00000000000000000000); | ||
| 562 | try test__floatsitf(0x12345678, 0x401b2345678000000000000000000000); | ||
| 563 | try test__floatsitf(-0x12345678, 0xc01b2345678000000000000000000000); | ||
| 564 | try test__floatsitf(@bitCast(@as(u32, @intCast(0xffffffff))), 0xbfff0000000000000000000000000000); | ||
| 565 | try test__floatsitf(@bitCast(@as(u32, @intCast(0x80000000))), 0xc01e0000000000000000000000000000); | ||
| 566 | } | ||
| 567 | |||
| 568 | fn test__floatunsitf(a: u32, expected_hi: u64, expected_lo: u64) !void { | ||
| 569 | const x = __floatunsitf(a); | ||
| 570 | 592 | ||
| 571 | const x_repr: u128 = @bitCast(x); | 593 | const x_repr: u128 = @bitCast(x); |
| 572 | const x_hi: u64 = @intCast(x_repr >> 64); | 594 | const x_hi: u64 = @intCast(x_repr >> 64); |
| ... | @@ -581,24 +603,32 @@ fn test__floatunsitf(a: u32, expected_hi: u64, expected_lo: u64) !void { | ... | @@ -581,24 +603,32 @@ fn test__floatunsitf(a: u32, expected_hi: u64, expected_lo: u64) !void { |
| 581 | return; | 603 | return; |
| 582 | } | 604 | } |
| 583 | } | 605 | } |
| 606 | return error.TestFailure; | ||
| 607 | } | ||
| 584 | 608 | ||
| 585 | @panic("__floatunsitf test failure"); | 609 | test f128_floatFromInt_i32 { |
| 610 | try test_f128_floatFromInt_i32(0, 0); | ||
| 611 | try test_f128_floatFromInt_i32(0x7FFFFFFF, 0x401dfffffffc00000000000000000000); | ||
| 612 | try test_f128_floatFromInt_i32(0x12345678, 0x401b2345678000000000000000000000); | ||
| 613 | try test_f128_floatFromInt_i32(-0x12345678, 0xc01b2345678000000000000000000000); | ||
| 614 | try test_f128_floatFromInt_i32(@bitCast(@as(u32, @intCast(0xffffffff))), 0xbfff0000000000000000000000000000); | ||
| 615 | try test_f128_floatFromInt_i32(@bitCast(@as(u32, @intCast(0x80000000))), 0xc01e0000000000000000000000000000); | ||
| 586 | } | 616 | } |
| 587 | 617 | ||
| 588 | test "floatunsitf" { | 618 | test f128_floatFromInt_u32 { |
| 589 | try test__floatunsitf(0x7fffffff, 0x401dfffffffc0000, 0x0); | 619 | try test_f128_floatFromInt_u32(0x7fffffff, 0x401dfffffffc0000, 0x0); |
| 590 | try test__floatunsitf(0, 0x0, 0x0); | 620 | try test_f128_floatFromInt_u32(0, 0x0, 0x0); |
| 591 | try test__floatunsitf(0xffffffff, 0x401efffffffe0000, 0x0); | 621 | try test_f128_floatFromInt_u32(0xffffffff, 0x401efffffffe0000, 0x0); |
| 592 | try test__floatunsitf(0x12345678, 0x401b234567800000, 0x0); | 622 | try test_f128_floatFromInt_u32(0x12345678, 0x401b234567800000, 0x0); |
| 593 | } | 623 | } |
| 594 | 624 | ||
| 595 | fn test__floatditf(a: i64, expected: f128) !void { | 625 | fn test_f128_floatFromInt_i64(a: i64, expected: f128) !void { |
| 596 | const x = __floatditf(a); | 626 | const x = f128_floatFromInt_i64(a); |
| 597 | try testing.expect(x == expected); | 627 | try testing.expect(x == expected); |
| 598 | } | 628 | } |
| 599 | 629 | ||
| 600 | fn test__floatunditf(a: u64, expected_hi: u64, expected_lo: u64) !void { | 630 | fn test_f128_floatFromInt_u64(a: u64, expected_hi: u64, expected_lo: u64) !void { |
| 601 | const x = __floatunditf(a); | 631 | const x = f128_floatFromInt_u64(a); |
| 602 | 632 | ||
| 603 | const x_repr: u128 = @bitCast(x); | 633 | const x_repr: u128 = @bitCast(x); |
| 604 | const x_hi: u64 = @intCast(x_repr >> 64); | 634 | const x_hi: u64 = @intCast(x_repr >> 64); |
| ... | @@ -613,208 +643,207 @@ fn test__floatunditf(a: u64, expected_hi: u64, expected_lo: u64) !void { | ... | @@ -613,208 +643,207 @@ fn test__floatunditf(a: u64, expected_hi: u64, expected_lo: u64) !void { |
| 613 | return; | 643 | return; |
| 614 | } | 644 | } |
| 615 | } | 645 | } |
| 616 | 646 | return error.TestFailure; | |
| 617 | @panic("__floatunditf test failure"); | 647 | } |
| 618 | } | 648 | |
| 619 | 649 | test f128_floatFromInt_i64 { | |
| 620 | test "floatditf" { | 650 | try test_f128_floatFromInt_i64(0x7fffffffffffffff, make_tf(0x403dffffffffffff, 0xfffc000000000000)); |
| 621 | try test__floatditf(0x7fffffffffffffff, make_tf(0x403dffffffffffff, 0xfffc000000000000)); | 651 | try test_f128_floatFromInt_i64(0x123456789abcdef1, make_tf(0x403b23456789abcd, 0xef10000000000000)); |
| 622 | try test__floatditf(0x123456789abcdef1, make_tf(0x403b23456789abcd, 0xef10000000000000)); | 652 | try test_f128_floatFromInt_i64(0x2, make_tf(0x4000000000000000, 0x0)); |
| 623 | try test__floatditf(0x2, make_tf(0x4000000000000000, 0x0)); | 653 | try test_f128_floatFromInt_i64(0x1, make_tf(0x3fff000000000000, 0x0)); |
| 624 | try test__floatditf(0x1, make_tf(0x3fff000000000000, 0x0)); | 654 | try test_f128_floatFromInt_i64(0x0, make_tf(0x0, 0x0)); |
| 625 | try test__floatditf(0x0, make_tf(0x0, 0x0)); | 655 | try test_f128_floatFromInt_i64(@bitCast(@as(u64, 0xffffffffffffffff)), make_tf(0xbfff000000000000, 0x0)); |
| 626 | try test__floatditf(@bitCast(@as(u64, 0xffffffffffffffff)), make_tf(0xbfff000000000000, 0x0)); | 656 | try test_f128_floatFromInt_i64(@bitCast(@as(u64, 0xfffffffffffffffe)), make_tf(0xc000000000000000, 0x0)); |
| 627 | try test__floatditf(@bitCast(@as(u64, 0xfffffffffffffffe)), make_tf(0xc000000000000000, 0x0)); | 657 | try test_f128_floatFromInt_i64(-0x123456789abcdef1, make_tf(0xc03b23456789abcd, 0xef10000000000000)); |
| 628 | try test__floatditf(-0x123456789abcdef1, make_tf(0xc03b23456789abcd, 0xef10000000000000)); | 658 | try test_f128_floatFromInt_i64(@bitCast(@as(u64, 0x8000000000000000)), make_tf(0xc03e000000000000, 0x0)); |
| 629 | try test__floatditf(@bitCast(@as(u64, 0x8000000000000000)), make_tf(0xc03e000000000000, 0x0)); | 659 | } |
| 630 | } | 660 | |
| 631 | 661 | test f128_floatFromInt_u64 { | |
| 632 | test "floatunditf" { | 662 | try test_f128_floatFromInt_u64(0xffffffffffffffff, 0x403effffffffffff, 0xfffe000000000000); |
| 633 | try test__floatunditf(0xffffffffffffffff, 0x403effffffffffff, 0xfffe000000000000); | 663 | try test_f128_floatFromInt_u64(0xfffffffffffffffe, 0x403effffffffffff, 0xfffc000000000000); |
| 634 | try test__floatunditf(0xfffffffffffffffe, 0x403effffffffffff, 0xfffc000000000000); | 664 | try test_f128_floatFromInt_u64(0x8000000000000000, 0x403e000000000000, 0x0); |
| 635 | try test__floatunditf(0x8000000000000000, 0x403e000000000000, 0x0); | 665 | try test_f128_floatFromInt_u64(0x7fffffffffffffff, 0x403dffffffffffff, 0xfffc000000000000); |
| 636 | try test__floatunditf(0x7fffffffffffffff, 0x403dffffffffffff, 0xfffc000000000000); | 666 | try test_f128_floatFromInt_u64(0x123456789abcdef1, 0x403b23456789abcd, 0xef10000000000000); |
| 637 | try test__floatunditf(0x123456789abcdef1, 0x403b23456789abcd, 0xef10000000000000); | 667 | try test_f128_floatFromInt_u64(0x2, 0x4000000000000000, 0x0); |
| 638 | try test__floatunditf(0x2, 0x4000000000000000, 0x0); | 668 | try test_f128_floatFromInt_u64(0x1, 0x3fff000000000000, 0x0); |
| 639 | try test__floatunditf(0x1, 0x3fff000000000000, 0x0); | 669 | try test_f128_floatFromInt_u64(0x0, 0x0, 0x0); |
| 640 | try test__floatunditf(0x0, 0x0, 0x0); | 670 | } |
| 641 | } | 671 | |
| 642 | 672 | fn test_f128_floatFromInt_i128(a: i128, expected: f128) !void { | |
| 643 | fn test__floattitf(a: i128, expected: f128) !void { | 673 | const x = f128_floatFromInt_i128(a); |
| 644 | const x = __floattitf(a); | ||
| 645 | try testing.expect(x == expected); | 674 | try testing.expect(x == expected); |
| 646 | } | 675 | } |
| 647 | 676 | ||
| 648 | fn test__floatuntitf(a: u128, expected: f128) !void { | 677 | fn test_f128_floatFromInt_u128(a: u128, expected: f128) !void { |
| 649 | const x = __floatuntitf(a); | 678 | const x = f128_floatFromInt_u128(a); |
| 650 | try testing.expect(x == expected); | 679 | try testing.expect(x == expected); |
| 651 | } | 680 | } |
| 652 | 681 | ||
| 653 | test "floattitf" { | 682 | test f128_floatFromInt_i128 { |
| 654 | try test__floattitf(0, 0.0); | 683 | try test_f128_floatFromInt_i128(0, 0.0); |
| 655 | 684 | ||
| 656 | try test__floattitf(1, 1.0); | 685 | try test_f128_floatFromInt_i128(1, 1.0); |
| 657 | try test__floattitf(2, 2.0); | 686 | try test_f128_floatFromInt_i128(2, 2.0); |
| 658 | try test__floattitf(20, 20.0); | 687 | try test_f128_floatFromInt_i128(20, 20.0); |
| 659 | try test__floattitf(-1, -1.0); | 688 | try test_f128_floatFromInt_i128(-1, -1.0); |
| 660 | try test__floattitf(-2, -2.0); | 689 | try test_f128_floatFromInt_i128(-2, -2.0); |
| 661 | try test__floattitf(-20, -20.0); | 690 | try test_f128_floatFromInt_i128(-20, -20.0); |
| 662 | 691 | ||
| 663 | try test__floattitf(0x7FFFFF8000000000, 0x1.FFFFFEp+62); | 692 | try test_f128_floatFromInt_i128(0x7FFFFF8000000000, 0x1.FFFFFEp+62); |
| 664 | try test__floattitf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62); | 693 | try test_f128_floatFromInt_i128(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62); |
| 665 | try test__floattitf(0x7FFFFF0000000000, 0x1.FFFFFCp+62); | 694 | try test_f128_floatFromInt_i128(0x7FFFFF0000000000, 0x1.FFFFFCp+62); |
| 666 | try test__floattitf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62); | 695 | try test_f128_floatFromInt_i128(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62); |
| 667 | 696 | ||
| 668 | try test__floattitf(make_ti(0x8000008000000000, 0), -0x1.FFFFFEp+126); | 697 | try test_f128_floatFromInt_i128(make_ti(0x8000008000000000, 0), -0x1.FFFFFEp+126); |
| 669 | try test__floattitf(make_ti(0x8000000000000800, 0), -0x1.FFFFFFFFFFFFEp+126); | 698 | try test_f128_floatFromInt_i128(make_ti(0x8000000000000800, 0), -0x1.FFFFFFFFFFFFEp+126); |
| 670 | try test__floattitf(make_ti(0x8000010000000000, 0), -0x1.FFFFFCp+126); | 699 | try test_f128_floatFromInt_i128(make_ti(0x8000010000000000, 0), -0x1.FFFFFCp+126); |
| 671 | try test__floattitf(make_ti(0x8000000000001000, 0), -0x1.FFFFFFFFFFFFCp+126); | 700 | try test_f128_floatFromInt_i128(make_ti(0x8000000000001000, 0), -0x1.FFFFFFFFFFFFCp+126); |
| 672 | 701 | ||
| 673 | try test__floattitf(make_ti(0x8000000000000000, 0), -0x1.000000p+127); | 702 | try test_f128_floatFromInt_i128(make_ti(0x8000000000000000, 0), -0x1.000000p+127); |
| 674 | try test__floattitf(make_ti(0x8000000000000001, 0), -0x1.FFFFFFFFFFFFFFFCp+126); | 703 | try test_f128_floatFromInt_i128(make_ti(0x8000000000000001, 0), -0x1.FFFFFFFFFFFFFFFCp+126); |
| 675 | 704 | ||
| 676 | try test__floattitf(0x0007FB72E8000000, 0x1.FEDCBAp+50); | 705 | try test_f128_floatFromInt_i128(0x0007FB72E8000000, 0x1.FEDCBAp+50); |
| 677 | 706 | ||
| 678 | try test__floattitf(0x0007FB72EA000000, 0x1.FEDCBA8p+50); | 707 | try test_f128_floatFromInt_i128(0x0007FB72EA000000, 0x1.FEDCBA8p+50); |
| 679 | try test__floattitf(0x0007FB72EB000000, 0x1.FEDCBACp+50); | 708 | try test_f128_floatFromInt_i128(0x0007FB72EB000000, 0x1.FEDCBACp+50); |
| 680 | try test__floattitf(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50); | 709 | try test_f128_floatFromInt_i128(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50); |
| 681 | try test__floattitf(0x0007FB72EC000000, 0x1.FEDCBBp+50); | 710 | try test_f128_floatFromInt_i128(0x0007FB72EC000000, 0x1.FEDCBBp+50); |
| 682 | try test__floattitf(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50); | 711 | try test_f128_floatFromInt_i128(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50); |
| 683 | 712 | ||
| 684 | try test__floattitf(0x0007FB72E6000000, 0x1.FEDCB98p+50); | 713 | try test_f128_floatFromInt_i128(0x0007FB72E6000000, 0x1.FEDCB98p+50); |
| 685 | try test__floattitf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50); | 714 | try test_f128_floatFromInt_i128(0x0007FB72E7000000, 0x1.FEDCB9Cp+50); |
| 686 | try test__floattitf(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50); | 715 | try test_f128_floatFromInt_i128(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50); |
| 687 | try test__floattitf(0x0007FB72E4000001, 0x1.FEDCB90000004p+50); | 716 | try test_f128_floatFromInt_i128(0x0007FB72E4000001, 0x1.FEDCB90000004p+50); |
| 688 | try test__floattitf(0x0007FB72E4000000, 0x1.FEDCB9p+50); | 717 | try test_f128_floatFromInt_i128(0x0007FB72E4000000, 0x1.FEDCB9p+50); |
| 689 | 718 | ||
| 690 | try test__floattitf(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57); | 719 | try test_f128_floatFromInt_i128(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57); |
| 691 | try test__floattitf(0x023479FD0E092DA1, 0x1.1A3CFE870496D08p+57); | 720 | try test_f128_floatFromInt_i128(0x023479FD0E092DA1, 0x1.1A3CFE870496D08p+57); |
| 692 | try test__floattitf(0x023479FD0E092DB0, 0x1.1A3CFE870496D8p+57); | 721 | try test_f128_floatFromInt_i128(0x023479FD0E092DB0, 0x1.1A3CFE870496D8p+57); |
| 693 | try test__floattitf(0x023479FD0E092DB8, 0x1.1A3CFE870496DCp+57); | 722 | try test_f128_floatFromInt_i128(0x023479FD0E092DB8, 0x1.1A3CFE870496DCp+57); |
| 694 | try test__floattitf(0x023479FD0E092DB6, 0x1.1A3CFE870496DBp+57); | 723 | try test_f128_floatFromInt_i128(0x023479FD0E092DB6, 0x1.1A3CFE870496DBp+57); |
| 695 | try test__floattitf(0x023479FD0E092DBF, 0x1.1A3CFE870496DF8p+57); | 724 | try test_f128_floatFromInt_i128(0x023479FD0E092DBF, 0x1.1A3CFE870496DF8p+57); |
| 696 | try test__floattitf(0x023479FD0E092DC1, 0x1.1A3CFE870496E08p+57); | 725 | try test_f128_floatFromInt_i128(0x023479FD0E092DC1, 0x1.1A3CFE870496E08p+57); |
| 697 | try test__floattitf(0x023479FD0E092DC7, 0x1.1A3CFE870496E38p+57); | 726 | try test_f128_floatFromInt_i128(0x023479FD0E092DC7, 0x1.1A3CFE870496E38p+57); |
| 698 | try test__floattitf(0x023479FD0E092DC8, 0x1.1A3CFE870496E4p+57); | 727 | try test_f128_floatFromInt_i128(0x023479FD0E092DC8, 0x1.1A3CFE870496E4p+57); |
| 699 | try test__floattitf(0x023479FD0E092DCF, 0x1.1A3CFE870496E78p+57); | 728 | try test_f128_floatFromInt_i128(0x023479FD0E092DCF, 0x1.1A3CFE870496E78p+57); |
| 700 | try test__floattitf(0x023479FD0E092DD0, 0x1.1A3CFE870496E8p+57); | 729 | try test_f128_floatFromInt_i128(0x023479FD0E092DD0, 0x1.1A3CFE870496E8p+57); |
| 701 | try test__floattitf(0x023479FD0E092DD1, 0x1.1A3CFE870496E88p+57); | 730 | try test_f128_floatFromInt_i128(0x023479FD0E092DD1, 0x1.1A3CFE870496E88p+57); |
| 702 | try test__floattitf(0x023479FD0E092DD8, 0x1.1A3CFE870496ECp+57); | 731 | try test_f128_floatFromInt_i128(0x023479FD0E092DD8, 0x1.1A3CFE870496ECp+57); |
| 703 | try test__floattitf(0x023479FD0E092DDF, 0x1.1A3CFE870496EF8p+57); | 732 | try test_f128_floatFromInt_i128(0x023479FD0E092DDF, 0x1.1A3CFE870496EF8p+57); |
| 704 | try test__floattitf(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57); | 733 | try test_f128_floatFromInt_i128(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57); |
| 705 | 734 | ||
| 706 | try test__floattitf(make_ti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121); | 735 | try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121); |
| 707 | try test__floattitf(make_ti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496D08p+121); | 736 | try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496D08p+121); |
| 708 | try test__floattitf(make_ti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496D8p+121); | 737 | try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496D8p+121); |
| 709 | try test__floattitf(make_ti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496DCp+121); | 738 | try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496DCp+121); |
| 710 | try test__floattitf(make_ti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496DBp+121); | 739 | try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496DBp+121); |
| 711 | try test__floattitf(make_ti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496DF8p+121); | 740 | try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496DF8p+121); |
| 712 | try test__floattitf(make_ti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496E08p+121); | 741 | try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496E08p+121); |
| 713 | try test__floattitf(make_ti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496E38p+121); | 742 | try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496E38p+121); |
| 714 | try test__floattitf(make_ti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496E4p+121); | 743 | try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496E4p+121); |
| 715 | try test__floattitf(make_ti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496E78p+121); | 744 | try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496E78p+121); |
| 716 | try test__floattitf(make_ti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496E8p+121); | 745 | try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496E8p+121); |
| 717 | try test__floattitf(make_ti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496E88p+121); | 746 | try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496E88p+121); |
| 718 | try test__floattitf(make_ti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496ECp+121); | 747 | try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496ECp+121); |
| 719 | try test__floattitf(make_ti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496EF8p+121); | 748 | try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496EF8p+121); |
| 720 | try test__floattitf(make_ti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121); | 749 | try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121); |
| 721 | 750 | ||
| 722 | try test__floattitf(make_ti(0, 0xFFFFFFFFFFFFFFFF), 0x1.FFFFFFFFFFFFFFFEp+63); | 751 | try test_f128_floatFromInt_i128(make_ti(0, 0xFFFFFFFFFFFFFFFF), 0x1.FFFFFFFFFFFFFFFEp+63); |
| 723 | 752 | ||
| 724 | try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC2801), 0x1.23456789ABCDEF0123456789ABC3p+124); | 753 | try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC2801), 0x1.23456789ABCDEF0123456789ABC3p+124); |
| 725 | try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC3000), 0x1.23456789ABCDEF0123456789ABC3p+124); | 754 | try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC3000), 0x1.23456789ABCDEF0123456789ABC3p+124); |
| 726 | try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC37FF), 0x1.23456789ABCDEF0123456789ABC3p+124); | 755 | try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC37FF), 0x1.23456789ABCDEF0123456789ABC3p+124); |
| 727 | try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC3800), 0x1.23456789ABCDEF0123456789ABC4p+124); | 756 | try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC3800), 0x1.23456789ABCDEF0123456789ABC4p+124); |
| 728 | try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC4000), 0x1.23456789ABCDEF0123456789ABC4p+124); | 757 | try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC4000), 0x1.23456789ABCDEF0123456789ABC4p+124); |
| 729 | try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC47FF), 0x1.23456789ABCDEF0123456789ABC4p+124); | 758 | try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC47FF), 0x1.23456789ABCDEF0123456789ABC4p+124); |
| 730 | try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC4800), 0x1.23456789ABCDEF0123456789ABC4p+124); | 759 | try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC4800), 0x1.23456789ABCDEF0123456789ABC4p+124); |
| 731 | try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC4801), 0x1.23456789ABCDEF0123456789ABC5p+124); | 760 | try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC4801), 0x1.23456789ABCDEF0123456789ABC5p+124); |
| 732 | try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC57FF), 0x1.23456789ABCDEF0123456789ABC5p+124); | 761 | try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC57FF), 0x1.23456789ABCDEF0123456789ABC5p+124); |
| 733 | } | 762 | } |
| 734 | 763 | ||
| 735 | test "floatuntitf" { | 764 | test f128_floatFromInt_u128 { |
| 736 | try test__floatuntitf(0, 0.0); | 765 | try test_f128_floatFromInt_u128(0, 0.0); |
| 737 | 766 | ||
| 738 | try test__floatuntitf(1, 1.0); | 767 | try test_f128_floatFromInt_u128(1, 1.0); |
| 739 | try test__floatuntitf(2, 2.0); | 768 | try test_f128_floatFromInt_u128(2, 2.0); |
| 740 | try test__floatuntitf(20, 20.0); | 769 | try test_f128_floatFromInt_u128(20, 20.0); |
| 741 | 770 | ||
| 742 | try test__floatuntitf(0x7FFFFF8000000000, 0x1.FFFFFEp+62); | 771 | try test_f128_floatFromInt_u128(0x7FFFFF8000000000, 0x1.FFFFFEp+62); |
| 743 | try test__floatuntitf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62); | 772 | try test_f128_floatFromInt_u128(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62); |
| 744 | try test__floatuntitf(0x7FFFFF0000000000, 0x1.FFFFFCp+62); | 773 | try test_f128_floatFromInt_u128(0x7FFFFF0000000000, 0x1.FFFFFCp+62); |
| 745 | try test__floatuntitf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62); | 774 | try test_f128_floatFromInt_u128(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62); |
| 746 | try test__floatuntitf(0x7FFFFFFFFFFFFFFF, 0xF.FFFFFFFFFFFFFFEp+59); | 775 | try test_f128_floatFromInt_u128(0x7FFFFFFFFFFFFFFF, 0xF.FFFFFFFFFFFFFFEp+59); |
| 747 | try test__floatuntitf(0xFFFFFFFFFFFFFFFE, 0xF.FFFFFFFFFFFFFFEp+60); | 776 | try test_f128_floatFromInt_u128(0xFFFFFFFFFFFFFFFE, 0xF.FFFFFFFFFFFFFFEp+60); |
| 748 | try test__floatuntitf(0xFFFFFFFFFFFFFFFF, 0xF.FFFFFFFFFFFFFFFp+60); | 777 | try test_f128_floatFromInt_u128(0xFFFFFFFFFFFFFFFF, 0xF.FFFFFFFFFFFFFFFp+60); |
| 749 | 778 | ||
| 750 | try test__floatuntitf(0x8000008000000000, 0x8.000008p+60); | 779 | try test_f128_floatFromInt_u128(0x8000008000000000, 0x8.000008p+60); |
| 751 | try test__floatuntitf(0x8000000000000800, 0x8.0000000000008p+60); | 780 | try test_f128_floatFromInt_u128(0x8000000000000800, 0x8.0000000000008p+60); |
| 752 | try test__floatuntitf(0x8000010000000000, 0x8.00001p+60); | 781 | try test_f128_floatFromInt_u128(0x8000010000000000, 0x8.00001p+60); |
| 753 | try test__floatuntitf(0x8000000000001000, 0x8.000000000001p+60); | 782 | try test_f128_floatFromInt_u128(0x8000000000001000, 0x8.000000000001p+60); |
| 754 | 783 | ||
| 755 | try test__floatuntitf(0x8000000000000000, 0x8p+60); | 784 | try test_f128_floatFromInt_u128(0x8000000000000000, 0x8p+60); |
| 756 | try test__floatuntitf(0x8000000000000001, 0x8.000000000000001p+60); | 785 | try test_f128_floatFromInt_u128(0x8000000000000001, 0x8.000000000000001p+60); |
| 757 | 786 | ||
| 758 | try test__floatuntitf(0x0007FB72E8000000, 0x1.FEDCBAp+50); | 787 | try test_f128_floatFromInt_u128(0x0007FB72E8000000, 0x1.FEDCBAp+50); |
| 759 | 788 | ||
| 760 | try test__floatuntitf(0x0007FB72EA000000, 0x1.FEDCBA8p+50); | 789 | try test_f128_floatFromInt_u128(0x0007FB72EA000000, 0x1.FEDCBA8p+50); |
| 761 | try test__floatuntitf(0x0007FB72EB000000, 0x1.FEDCBACp+50); | 790 | try test_f128_floatFromInt_u128(0x0007FB72EB000000, 0x1.FEDCBACp+50); |
| 762 | try test__floatuntitf(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50); | 791 | try test_f128_floatFromInt_u128(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50); |
| 763 | try test__floatuntitf(0x0007FB72EC000000, 0x1.FEDCBBp+50); | 792 | try test_f128_floatFromInt_u128(0x0007FB72EC000000, 0x1.FEDCBBp+50); |
| 764 | try test__floatuntitf(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50); | 793 | try test_f128_floatFromInt_u128(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50); |
| 765 | 794 | ||
| 766 | try test__floatuntitf(0x0007FB72E6000000, 0x1.FEDCB98p+50); | 795 | try test_f128_floatFromInt_u128(0x0007FB72E6000000, 0x1.FEDCB98p+50); |
| 767 | try test__floatuntitf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50); | 796 | try test_f128_floatFromInt_u128(0x0007FB72E7000000, 0x1.FEDCB9Cp+50); |
| 768 | try test__floatuntitf(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50); | 797 | try test_f128_floatFromInt_u128(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50); |
| 769 | try test__floatuntitf(0x0007FB72E4000001, 0x1.FEDCB90000004p+50); | 798 | try test_f128_floatFromInt_u128(0x0007FB72E4000001, 0x1.FEDCB90000004p+50); |
| 770 | try test__floatuntitf(0x0007FB72E4000000, 0x1.FEDCB9p+50); | 799 | try test_f128_floatFromInt_u128(0x0007FB72E4000000, 0x1.FEDCB9p+50); |
| 771 | 800 | ||
| 772 | try test__floatuntitf(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57); | 801 | try test_f128_floatFromInt_u128(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57); |
| 773 | try test__floatuntitf(0x023479FD0E092DA1, 0x1.1A3CFE870496D08p+57); | 802 | try test_f128_floatFromInt_u128(0x023479FD0E092DA1, 0x1.1A3CFE870496D08p+57); |
| 774 | try test__floatuntitf(0x023479FD0E092DB0, 0x1.1A3CFE870496D8p+57); | 803 | try test_f128_floatFromInt_u128(0x023479FD0E092DB0, 0x1.1A3CFE870496D8p+57); |
| 775 | try test__floatuntitf(0x023479FD0E092DB8, 0x1.1A3CFE870496DCp+57); | 804 | try test_f128_floatFromInt_u128(0x023479FD0E092DB8, 0x1.1A3CFE870496DCp+57); |
| 776 | try test__floatuntitf(0x023479FD0E092DB6, 0x1.1A3CFE870496DBp+57); | 805 | try test_f128_floatFromInt_u128(0x023479FD0E092DB6, 0x1.1A3CFE870496DBp+57); |
| 777 | try test__floatuntitf(0x023479FD0E092DBF, 0x1.1A3CFE870496DF8p+57); | 806 | try test_f128_floatFromInt_u128(0x023479FD0E092DBF, 0x1.1A3CFE870496DF8p+57); |
| 778 | try test__floatuntitf(0x023479FD0E092DC1, 0x1.1A3CFE870496E08p+57); | 807 | try test_f128_floatFromInt_u128(0x023479FD0E092DC1, 0x1.1A3CFE870496E08p+57); |
| 779 | try test__floatuntitf(0x023479FD0E092DC7, 0x1.1A3CFE870496E38p+57); | 808 | try test_f128_floatFromInt_u128(0x023479FD0E092DC7, 0x1.1A3CFE870496E38p+57); |
| 780 | try test__floatuntitf(0x023479FD0E092DC8, 0x1.1A3CFE870496E4p+57); | 809 | try test_f128_floatFromInt_u128(0x023479FD0E092DC8, 0x1.1A3CFE870496E4p+57); |
| 781 | try test__floatuntitf(0x023479FD0E092DCF, 0x1.1A3CFE870496E78p+57); | 810 | try test_f128_floatFromInt_u128(0x023479FD0E092DCF, 0x1.1A3CFE870496E78p+57); |
| 782 | try test__floatuntitf(0x023479FD0E092DD0, 0x1.1A3CFE870496E8p+57); | 811 | try test_f128_floatFromInt_u128(0x023479FD0E092DD0, 0x1.1A3CFE870496E8p+57); |
| 783 | try test__floatuntitf(0x023479FD0E092DD1, 0x1.1A3CFE870496E88p+57); | 812 | try test_f128_floatFromInt_u128(0x023479FD0E092DD1, 0x1.1A3CFE870496E88p+57); |
| 784 | try test__floatuntitf(0x023479FD0E092DD8, 0x1.1A3CFE870496ECp+57); | 813 | try test_f128_floatFromInt_u128(0x023479FD0E092DD8, 0x1.1A3CFE870496ECp+57); |
| 785 | try test__floatuntitf(0x023479FD0E092DDF, 0x1.1A3CFE870496EF8p+57); | 814 | try test_f128_floatFromInt_u128(0x023479FD0E092DDF, 0x1.1A3CFE870496EF8p+57); |
| 786 | try test__floatuntitf(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57); | 815 | try test_f128_floatFromInt_u128(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57); |
| 787 | 816 | ||
| 788 | try test__floatuntitf(make_uti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121); | 817 | try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121); |
| 789 | try test__floatuntitf(make_uti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496D08p+121); | 818 | try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496D08p+121); |
| 790 | try test__floatuntitf(make_uti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496D8p+121); | 819 | try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496D8p+121); |
| 791 | try test__floatuntitf(make_uti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496DCp+121); | 820 | try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496DCp+121); |
| 792 | try test__floatuntitf(make_uti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496DBp+121); | 821 | try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496DBp+121); |
| 793 | try test__floatuntitf(make_uti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496DF8p+121); | 822 | try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496DF8p+121); |
| 794 | try test__floatuntitf(make_uti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496E08p+121); | 823 | try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496E08p+121); |
| 795 | try test__floatuntitf(make_uti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496E38p+121); | 824 | try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496E38p+121); |
| 796 | try test__floatuntitf(make_uti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496E4p+121); | 825 | try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496E4p+121); |
| 797 | try test__floatuntitf(make_uti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496E78p+121); | 826 | try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496E78p+121); |
| 798 | try test__floatuntitf(make_uti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496E8p+121); | 827 | try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496E8p+121); |
| 799 | try test__floatuntitf(make_uti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496E88p+121); | 828 | try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496E88p+121); |
| 800 | try test__floatuntitf(make_uti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496ECp+121); | 829 | try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496ECp+121); |
| 801 | try test__floatuntitf(make_uti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496EF8p+121); | 830 | try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496EF8p+121); |
| 802 | try test__floatuntitf(make_uti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121); | 831 | try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121); |
| 803 | 832 | ||
| 804 | try test__floatuntitf(make_uti(0, 0xFFFFFFFFFFFFFFFF), 0x1.FFFFFFFFFFFFFFFEp+63); | 833 | try test_f128_floatFromInt_u128(make_uti(0, 0xFFFFFFFFFFFFFFFF), 0x1.FFFFFFFFFFFFFFFEp+63); |
| 805 | 834 | ||
| 806 | try test__floatuntitf(make_uti(0xFFFFFFFFFFFFFFFF, 0x0000000000000000), 0x1.FFFFFFFFFFFFFFFEp+127); | 835 | try test_f128_floatFromInt_u128(make_uti(0xFFFFFFFFFFFFFFFF, 0x0000000000000000), 0x1.FFFFFFFFFFFFFFFEp+127); |
| 807 | try test__floatuntitf(make_uti(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 0x1.0000000000000000p+128); | 836 | try test_f128_floatFromInt_u128(make_uti(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 0x1.0000000000000000p+128); |
| 808 | 837 | ||
| 809 | try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC2801), 0x1.23456789ABCDEF0123456789ABC3p+124); | 838 | try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC2801), 0x1.23456789ABCDEF0123456789ABC3p+124); |
| 810 | try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC3000), 0x1.23456789ABCDEF0123456789ABC3p+124); | 839 | try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC3000), 0x1.23456789ABCDEF0123456789ABC3p+124); |
| 811 | try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC37FF), 0x1.23456789ABCDEF0123456789ABC3p+124); | 840 | try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC37FF), 0x1.23456789ABCDEF0123456789ABC3p+124); |
| 812 | try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC3800), 0x1.23456789ABCDEF0123456789ABC4p+124); | 841 | try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC3800), 0x1.23456789ABCDEF0123456789ABC4p+124); |
| 813 | try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC4000), 0x1.23456789ABCDEF0123456789ABC4p+124); | 842 | try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC4000), 0x1.23456789ABCDEF0123456789ABC4p+124); |
| 814 | try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC47FF), 0x1.23456789ABCDEF0123456789ABC4p+124); | 843 | try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC47FF), 0x1.23456789ABCDEF0123456789ABC4p+124); |
| 815 | try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC4800), 0x1.23456789ABCDEF0123456789ABC4p+124); | 844 | try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC4800), 0x1.23456789ABCDEF0123456789ABC4p+124); |
| 816 | try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC4801), 0x1.23456789ABCDEF0123456789ABC5p+124); | 845 | try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC4801), 0x1.23456789ABCDEF0123456789ABC5p+124); |
| 817 | try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC57FF), 0x1.23456789ABCDEF0123456789ABC5p+124); | 846 | try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC57FF), 0x1.23456789ABCDEF0123456789ABC5p+124); |
| 818 | } | 847 | } |
| 819 | 848 | ||
| 820 | fn make_ti(high: u64, low: u64) i128 { | 849 | fn make_ti(high: u64, low: u64) i128 { |
| ... | @@ -838,45 +867,40 @@ fn make_tf(high: u64, low: u64) f128 { | ... | @@ -838,45 +867,40 @@ fn make_tf(high: u64, low: u64) f128 { |
| 838 | return @bitCast(result); | 867 | return @bitCast(result); |
| 839 | } | 868 | } |
| 840 | 869 | ||
| 841 | test "conversion to f16" { | 870 | test f16_floatFromInt_u32 { |
| 842 | try testing.expect(__floatunsihf(@as(u32, 0)) == 0.0); | 871 | try testing.expect(f16_floatFromInt_u32(0) == 0.0); |
| 843 | try testing.expect(__floatunsihf(@as(u32, 1)) == 1.0); | 872 | try testing.expect(f16_floatFromInt_u32(1) == 1.0); |
| 844 | try testing.expect(__floatunsihf(@as(u32, 65504)) == 65504); | 873 | try testing.expect(f16_floatFromInt_u32(65504) == 65504); |
| 845 | try testing.expect(__floatunsihf(@as(u32, 65504 + (1 << 4))) == math.inf(f16)); | 874 | try testing.expect(f16_floatFromInt_u32(65504 + (1 << 4)) == math.inf(f16)); |
| 846 | } | 875 | } |
| 847 | 876 | ||
| 848 | test "conversion to f32" { | 877 | test f80_floatFromInt_u32 { |
| 849 | try testing.expect(__floatunsisf(@as(u32, 0)) == 0.0); | 878 | try testing.expect(f80_floatFromInt_u32(0) == 0.0); |
| 850 | try testing.expect(__floatunsisf(@as(u32, math.maxInt(u32))) != 1.0); | 879 | try testing.expect(f80_floatFromInt_u32(1) == 1.0); |
| 851 | try testing.expect(__floatsisf(@as(i32, math.minInt(i32))) != 1.0); | 880 | try testing.expect(f80_floatFromInt_u32(math.maxInt(u24) + 0) == math.maxInt(u24)); |
| 852 | try testing.expect(__floatunsisf(@as(u32, math.maxInt(u24))) == math.maxInt(u24)); | 881 | } |
| 853 | try testing.expect(__floatunsisf(@as(u32, math.maxInt(u24)) + 1) == math.maxInt(u24) + 1); // 0x100_0000 - Exact | 882 | |
| 854 | try testing.expect(__floatunsisf(@as(u32, math.maxInt(u24)) + 2) == math.maxInt(u24) + 1); // 0x100_0001 - Tie: Rounds down to even | 883 | test f80_floatFromInt_u64 { |
| 855 | try testing.expect(__floatunsisf(@as(u32, math.maxInt(u24)) + 3) == math.maxInt(u24) + 3); // 0x100_0002 - Exact | 884 | try testing.expect(f80_floatFromInt_u64(math.maxInt(u64) + 0) == math.maxInt(u64) + 0); |
| 856 | try testing.expect(__floatunsisf(@as(u32, math.maxInt(u24)) + 4) == math.maxInt(u24) + 5); // 0x100_0003 - Tie: Rounds up to even | 885 | } |
| 857 | try testing.expect(__floatunsisf(@as(u32, math.maxInt(u24)) + 5) == math.maxInt(u24) + 5); // 0x100_0004 - Exact | 886 | |
| 858 | } | 887 | test f80_floatFromInt_i128 { |
| 859 | 888 | try testing.expect(f80_floatFromInt_i128(-12) == -12); | |
| 860 | test "conversion to f80" { | 889 | } |
| 861 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | 890 | |
| 862 | 891 | test f80_floatFromInt_u128 { | |
| 863 | try testing.expect(floatFromInt(f80, @as(i80, -12)) == -12); | 892 | try testing.expect(f80_floatFromInt_u128(math.maxInt(u64) + 1) == math.maxInt(u64) + 1); |
| 864 | try testing.expect(@as(u80, @intFromFloat(floatFromInt(f80, @as(u64, math.maxInt(u64)) + 0))) == math.maxInt(u64) + 0); | 893 | |
| 865 | try testing.expect(@as(u80, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 1))) == math.maxInt(u64) + 1); | 894 | try testing.expect(f80_floatFromInt_u128(math.maxInt(u64) + 0) == math.maxInt(u64)); |
| 866 | 895 | try testing.expect(f80_floatFromInt_u128(math.maxInt(u64) + 1) == math.maxInt(u64) + 1); // Exact | |
| 867 | try testing.expect(floatFromInt(f80, @as(u32, 0)) == 0.0); | 896 | try testing.expect(f80_floatFromInt_u128(math.maxInt(u64) + 2) == math.maxInt(u64) + 1); // Rounds down |
| 868 | try testing.expect(floatFromInt(f80, @as(u32, 1)) == 1.0); | 897 | try testing.expect(f80_floatFromInt_u128(math.maxInt(u64) + 3) == math.maxInt(u64) + 3); // Tie - Exact |
| 869 | try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u32, math.maxInt(u24)) + 0))) == math.maxInt(u24)); | 898 | try testing.expect(f80_floatFromInt_u128(math.maxInt(u64) + 4) == math.maxInt(u64) + 5); // Rounds up |
| 870 | try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 0))) == math.maxInt(u64)); | 899 | |
| 871 | try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 1))) == math.maxInt(u64) + 1); // Exact | 900 | try testing.expect(f80_floatFromInt_u128(math.maxInt(u65) + 0) == math.maxInt(u65) + 1); // Rounds up |
| 872 | try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 2))) == math.maxInt(u64) + 1); // Rounds down | 901 | try testing.expect(f80_floatFromInt_u128(math.maxInt(u65) + 1) == math.maxInt(u65) + 1); // Exact |
| 873 | try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 3))) == math.maxInt(u64) + 3); // Tie - Exact | 902 | try testing.expect(f80_floatFromInt_u128(math.maxInt(u65) + 2) == math.maxInt(u65) + 1); // Rounds down |
| 874 | try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 4))) == math.maxInt(u64) + 5); // Rounds up | 903 | try testing.expect(f80_floatFromInt_u128(math.maxInt(u65) + 3) == math.maxInt(u65) + 1); // Tie - Rounds down |
| 875 | 904 | try testing.expect(f80_floatFromInt_u128(math.maxInt(u65) + 4) == math.maxInt(u65) + 5); // Rounds up | |
| 876 | try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u65)) + 0))) == math.maxInt(u65) + 1); // Rounds up | 905 | try testing.expect(f80_floatFromInt_u128(math.maxInt(u65) + 5) == math.maxInt(u65) + 5); // Exact |
| 877 | try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u65)) + 1))) == math.maxInt(u65) + 1); // Exact | ||
| 878 | try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u65)) + 2))) == math.maxInt(u65) + 1); // Rounds down | ||
| 879 | try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u65)) + 3))) == math.maxInt(u65) + 1); // Tie - Rounds down | ||
| 880 | try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u65)) + 4))) == math.maxInt(u65) + 5); // Rounds up | ||
| 881 | try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u65)) + 5))) == math.maxInt(u65) + 5); // Exact | ||
| 882 | } | 906 | } |
lib/compiler_rt/floatdidf.zig deleted-23| ... | @@ -1,23 +0,0 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 3 | const symbol = compiler_rt.symbol; | ||
| 4 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 5 | |||
| 6 | comptime { | ||
| 7 | if (compiler_rt.want_aeabi) { | ||
| 8 | symbol(&__aeabi_l2d, "__aeabi_l2d"); | ||
| 9 | } else { | ||
| 10 | if (compiler_rt.want_windows_arm_abi) { | ||
| 11 | symbol(&__floatdidf, "__i64tod"); | ||
| 12 | } | ||
| 13 | symbol(&__floatdidf, "__floatdidf"); | ||
| 14 | } | ||
| 15 | } | ||
| 16 | |||
| 17 | pub fn __floatdidf(a: i64) callconv(.c) f64 { | ||
| 18 | return floatFromInt(f64, a); | ||
| 19 | } | ||
| 20 | |||
| 21 | fn __aeabi_l2d(a: i64) callconv(.{ .arm_aapcs = .{} }) f64 { | ||
| 22 | return floatFromInt(f64, a); | ||
| 23 | } | ||
lib/compiler_rt/floatdihf.zig deleted-10| ... | @@ -1,10 +0,0 @@ | ||
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 2 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 3 | |||
| 4 | comptime { | ||
| 5 | symbol(&__floatdihf, "__floatdihf"); | ||
| 6 | } | ||
| 7 | |||
| 8 | fn __floatdihf(a: i64) callconv(.c) f16 { | ||
| 9 | return floatFromInt(f16, a); | ||
| 10 | } | ||
lib/compiler_rt/floatdisf.zig deleted-22| ... | @@ -1,22 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 3 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_aeabi) { | ||
| 7 | symbol(&__aeabi_l2f, "__aeabi_l2f"); | ||
| 8 | } else { | ||
| 9 | if (compiler_rt.want_windows_arm_abi) { | ||
| 10 | symbol(&__floatdisf, "__i64tos"); | ||
| 11 | } | ||
| 12 | symbol(&__floatdisf, "__floatdisf"); | ||
| 13 | } | ||
| 14 | } | ||
| 15 | |||
| 16 | pub fn __floatdisf(a: i64) callconv(.c) f32 { | ||
| 17 | return floatFromInt(f32, a); | ||
| 18 | } | ||
| 19 | |||
| 20 | fn __aeabi_l2f(a: i64) callconv(.{ .arm_aapcs = .{} }) f32 { | ||
| 21 | return floatFromInt(f32, a); | ||
| 22 | } | ||
lib/compiler_rt/floatditf.zig deleted-22| ... | @@ -1,22 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_ppc_abi) { | ||
| 7 | symbol(&__floatditf, "__floatdikf"); | ||
| 8 | } else if (compiler_rt.want_sparc64_abi) { | ||
| 9 | symbol(&_Qp_xtoq, "_Qp_xtoq"); | ||
| 10 | } else if (compiler_rt.want_sparc32_abi) { | ||
| 11 | symbol(&__floatditf, "_Q_lltoq"); | ||
| 12 | } | ||
| 13 | symbol(&__floatditf, "__floatditf"); | ||
| 14 | } | ||
| 15 | |||
| 16 | pub fn __floatditf(a: i64) callconv(.c) f128 { | ||
| 17 | return floatFromInt(f128, a); | ||
| 18 | } | ||
| 19 | |||
| 20 | fn _Qp_xtoq(c: *f128, a: i64) callconv(.c) void { | ||
| 21 | c.* = floatFromInt(f128, a); | ||
| 22 | } | ||
lib/compiler_rt/floatdixf.zig deleted-10| ... | @@ -1,10 +0,0 @@ | ||
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 2 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 3 | |||
| 4 | comptime { | ||
| 5 | symbol(&__floatdixf, "__floatdixf"); | ||
| 6 | } | ||
| 7 | |||
| 8 | fn __floatdixf(a: i64) callconv(.c) f80 { | ||
| 9 | return floatFromInt(f80, a); | ||
| 10 | } | ||
lib/compiler_rt/floateidf.zig deleted-15| ... | @@ -1,15 +0,0 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | |||
| 3 | const std = @import("std"); | ||
| 4 | |||
| 5 | const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; | ||
| 6 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 7 | |||
| 8 | comptime { | ||
| 9 | symbol(&__floateidf, "__floateidf"); | ||
| 10 | } | ||
| 11 | |||
| 12 | pub fn __floateidf(a: [*]const u8, bits: usize) callconv(.c) f64 { | ||
| 13 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | ||
| 14 | return floatFromBigInt(f64, .signed, @ptrCast(@alignCast(a[0..byte_size]))); | ||
| 15 | } | ||
lib/compiler_rt/floateihf.zig deleted-14| ... | @@ -1,14 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const builtin = @import("builtin"); | ||
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 4 | const symbol = compiler_rt.symbol; | ||
| 5 | const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; | ||
| 6 | |||
| 7 | comptime { | ||
| 8 | symbol(&__floateihf, "__floateihf"); | ||
| 9 | } | ||
| 10 | |||
| 11 | pub fn __floateihf(a: [*]const u8, bits: usize) callconv(.c) f16 { | ||
| 12 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | ||
| 13 | return floatFromBigInt(f16, .signed, @ptrCast(@alignCast(a[0..byte_size]))); | ||
| 14 | } | ||
lib/compiler_rt/floateisf.zig deleted-14| ... | @@ -1,14 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const builtin = @import("builtin"); | ||
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 4 | const symbol = compiler_rt.symbol; | ||
| 5 | const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; | ||
| 6 | |||
| 7 | comptime { | ||
| 8 | symbol(&__floateisf, "__floateisf"); | ||
| 9 | } | ||
| 10 | |||
| 11 | pub fn __floateisf(a: [*]const u8, bits: usize) callconv(.c) f32 { | ||
| 12 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | ||
| 13 | return floatFromBigInt(f32, .signed, @ptrCast(@alignCast(a[0..byte_size]))); | ||
| 14 | } | ||
lib/compiler_rt/floateitf.zig deleted-14| ... | @@ -1,14 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const builtin = @import("builtin"); | ||
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 4 | const symbol = compiler_rt.symbol; | ||
| 5 | const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; | ||
| 6 | |||
| 7 | comptime { | ||
| 8 | symbol(&__floateitf, "__floateitf"); | ||
| 9 | } | ||
| 10 | |||
| 11 | pub fn __floateitf(a: [*]const u8, bits: usize) callconv(.c) f128 { | ||
| 12 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | ||
| 13 | return floatFromBigInt(f128, .signed, @ptrCast(@alignCast(a[0..byte_size]))); | ||
| 14 | } | ||
lib/compiler_rt/floateixf.zig deleted-15| ... | @@ -1,15 +0,0 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | |||
| 3 | const std = @import("std"); | ||
| 4 | |||
| 5 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 6 | const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; | ||
| 7 | |||
| 8 | comptime { | ||
| 9 | symbol(&__floateixf, "__floateixf"); | ||
| 10 | } | ||
| 11 | |||
| 12 | pub fn __floateixf(a: [*]const u8, bits: usize) callconv(.c) f80 { | ||
| 13 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | ||
| 14 | return floatFromBigInt(f80, .signed, @ptrCast(@alignCast(a[0..byte_size]))); | ||
| 15 | } | ||
lib/compiler_rt/floatsidf.zig deleted-19| ... | @@ -1,19 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_aeabi) { | ||
| 7 | symbol(&__aeabi_i2d, "__aeabi_i2d"); | ||
| 8 | } else { | ||
| 9 | symbol(&__floatsidf, "__floatsidf"); | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | pub fn __floatsidf(a: i32) callconv(.c) f64 { | ||
| 14 | return floatFromInt(f64, a); | ||
| 15 | } | ||
| 16 | |||
| 17 | fn __aeabi_i2d(a: i32) callconv(.{ .arm_aapcs = .{} }) f64 { | ||
| 18 | return floatFromInt(f64, a); | ||
| 19 | } | ||
lib/compiler_rt/floatsihf.zig deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__floatsihf, "__floatsihf"); | ||
| 7 | } | ||
| 8 | |||
| 9 | fn __floatsihf(a: i32) callconv(.c) f16 { | ||
| 10 | return floatFromInt(f16, a); | ||
| 11 | } | ||
lib/compiler_rt/floatsisf.zig deleted-19| ... | @@ -1,19 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_aeabi) { | ||
| 7 | symbol(&__aeabi_i2f, "__aeabi_i2f"); | ||
| 8 | } else { | ||
| 9 | symbol(&__floatsisf, "__floatsisf"); | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | pub fn __floatsisf(a: i32) callconv(.c) f32 { | ||
| 14 | return floatFromInt(f32, a); | ||
| 15 | } | ||
| 16 | |||
| 17 | fn __aeabi_i2f(a: i32) callconv(.{ .arm_aapcs = .{} }) f32 { | ||
| 18 | return floatFromInt(f32, a); | ||
| 19 | } | ||
lib/compiler_rt/floatsitf.zig deleted-22| ... | @@ -1,22 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_ppc_abi) { | ||
| 7 | symbol(&__floatsitf, "__floatsikf"); | ||
| 8 | } else if (compiler_rt.want_sparc64_abi) { | ||
| 9 | symbol(&_Qp_itoq, "_Qp_itoq"); | ||
| 10 | } else if (compiler_rt.want_sparc32_abi) { | ||
| 11 | symbol(&__floatsitf, "_Q_itoq"); | ||
| 12 | } | ||
| 13 | symbol(&__floatsitf, "__floatsitf"); | ||
| 14 | } | ||
| 15 | |||
| 16 | pub fn __floatsitf(a: i32) callconv(.c) f128 { | ||
| 17 | return floatFromInt(f128, a); | ||
| 18 | } | ||
| 19 | |||
| 20 | fn _Qp_itoq(c: *f128, a: i32) callconv(.c) void { | ||
| 21 | c.* = floatFromInt(f128, a); | ||
| 22 | } | ||
lib/compiler_rt/floatsixf.zig deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__floatsixf, "__floatsixf"); | ||
| 7 | } | ||
| 8 | |||
| 9 | fn __floatsixf(a: i32) callconv(.c) f80 { | ||
| 10 | return floatFromInt(f80, a); | ||
| 11 | } | ||
lib/compiler_rt/floattidf.zig deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 3 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__floattidf, "__floattidf"); | ||
| 7 | } | ||
| 8 | |||
| 9 | pub fn __floattidf(a: i128) callconv(.c) f64 { | ||
| 10 | return floatFromInt(f64, a); | ||
| 11 | } | ||
lib/compiler_rt/floattihf.zig deleted-12| ... | @@ -1,12 +0,0 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 3 | const symbol = compiler_rt.symbol; | ||
| 4 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 5 | |||
| 6 | comptime { | ||
| 7 | symbol(&__floattihf, "__floattihf"); | ||
| 8 | } | ||
| 9 | |||
| 10 | pub fn __floattihf(a: i128) callconv(.c) f16 { | ||
| 11 | return floatFromInt(f16, a); | ||
| 12 | } | ||
lib/compiler_rt/floattisf.zig deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__floattisf, "__floattisf"); | ||
| 7 | } | ||
| 8 | |||
| 9 | pub fn __floattisf(a: i128) callconv(.c) f32 { | ||
| 10 | return floatFromInt(f32, a); | ||
| 11 | } | ||
lib/compiler_rt/floattitf.zig deleted-13| ... | @@ -1,13 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 3 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_ppc_abi) | ||
| 7 | symbol(&__floattitf, "__floattikf"); | ||
| 8 | symbol(&__floattitf, "__floattitf"); | ||
| 9 | } | ||
| 10 | |||
| 11 | pub fn __floattitf(a: i128) callconv(.c) f128 { | ||
| 12 | return floatFromInt(f128, a); | ||
| 13 | } | ||
lib/compiler_rt/floattixf.zig deleted-12| ... | @@ -1,12 +0,0 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 3 | const symbol = compiler_rt.symbol; | ||
| 4 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 5 | |||
| 6 | comptime { | ||
| 7 | symbol(&__floattixf, "__floattixf"); | ||
| 8 | } | ||
| 9 | |||
| 10 | pub fn __floattixf(a: i128) callconv(.c) f80 { | ||
| 11 | return floatFromInt(f80, a); | ||
| 12 | } | ||
lib/compiler_rt/floatundidf.zig deleted-22| ... | @@ -1,22 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_aeabi) { | ||
| 7 | symbol(&__aeabi_ul2d, "__aeabi_ul2d"); | ||
| 8 | } else { | ||
| 9 | if (compiler_rt.want_windows_arm_abi) { | ||
| 10 | symbol(&__floatundidf, "__u64tod"); | ||
| 11 | } | ||
| 12 | symbol(&__floatundidf, "__floatundidf"); | ||
| 13 | } | ||
| 14 | } | ||
| 15 | |||
| 16 | pub fn __floatundidf(a: u64) callconv(.c) f64 { | ||
| 17 | return floatFromInt(f64, a); | ||
| 18 | } | ||
| 19 | |||
| 20 | fn __aeabi_ul2d(a: u64) callconv(.{ .arm_aapcs = .{} }) f64 { | ||
| 21 | return floatFromInt(f64, a); | ||
| 22 | } | ||
lib/compiler_rt/floatundihf.zig deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__floatundihf, "__floatundihf"); | ||
| 7 | } | ||
| 8 | |||
| 9 | fn __floatundihf(a: u64) callconv(.c) f16 { | ||
| 10 | return floatFromInt(f16, a); | ||
| 11 | } | ||
lib/compiler_rt/floatundisf.zig deleted-23| ... | @@ -1,23 +0,0 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 3 | const symbol = compiler_rt.symbol; | ||
| 4 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 5 | |||
| 6 | comptime { | ||
| 7 | if (compiler_rt.want_aeabi) { | ||
| 8 | symbol(&__aeabi_ul2f, "__aeabi_ul2f"); | ||
| 9 | } else { | ||
| 10 | if (compiler_rt.want_windows_arm_abi) { | ||
| 11 | symbol(&__floatundisf, "__u64tos"); | ||
| 12 | } | ||
| 13 | symbol(&__floatundisf, "__floatundisf"); | ||
| 14 | } | ||
| 15 | } | ||
| 16 | |||
| 17 | pub fn __floatundisf(a: u64) callconv(.c) f32 { | ||
| 18 | return floatFromInt(f32, a); | ||
| 19 | } | ||
| 20 | |||
| 21 | fn __aeabi_ul2f(a: u64) callconv(.{ .arm_aapcs = .{} }) f32 { | ||
| 22 | return floatFromInt(f32, a); | ||
| 23 | } | ||
lib/compiler_rt/floatunditf.zig deleted-22| ... | @@ -1,22 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_ppc_abi) { | ||
| 7 | symbol(&__floatunditf, "__floatundikf"); | ||
| 8 | } else if (compiler_rt.want_sparc64_abi) { | ||
| 9 | symbol(&_Qp_uxtoq, "_Qp_uxtoq"); | ||
| 10 | } else if (compiler_rt.want_sparc32_abi) { | ||
| 11 | @export(&__floatunditf, "_Q_ulltoq"); | ||
| 12 | } | ||
| 13 | symbol(&__floatunditf, "__floatunditf"); | ||
| 14 | } | ||
| 15 | |||
| 16 | pub fn __floatunditf(a: u64) callconv(.c) f128 { | ||
| 17 | return floatFromInt(f128, a); | ||
| 18 | } | ||
| 19 | |||
| 20 | fn _Qp_uxtoq(c: *f128, a: u64) callconv(.c) void { | ||
| 21 | c.* = floatFromInt(f128, a); | ||
| 22 | } | ||
lib/compiler_rt/floatundixf.zig deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__floatundixf, "__floatundixf"); | ||
| 7 | } | ||
| 8 | |||
| 9 | fn __floatundixf(a: u64) callconv(.c) f80 { | ||
| 10 | return floatFromInt(f80, a); | ||
| 11 | } | ||
lib/compiler_rt/floatuneidf.zig deleted-14| ... | @@ -1,14 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const builtin = @import("builtin"); | ||
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 4 | const symbol = compiler_rt.symbol; | ||
| 5 | const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; | ||
| 6 | |||
| 7 | comptime { | ||
| 8 | symbol(&__floatuneidf, "__floatuneidf"); | ||
| 9 | } | ||
| 10 | |||
| 11 | pub fn __floatuneidf(a: [*]const u8, bits: usize) callconv(.c) f64 { | ||
| 12 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | ||
| 13 | return floatFromBigInt(f64, .unsigned, @ptrCast(@alignCast(a[0..byte_size]))); | ||
| 14 | } | ||
lib/compiler_rt/floatuneihf.zig deleted-14| ... | @@ -1,14 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const builtin = @import("builtin"); | ||
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 4 | const symbol = compiler_rt.symbol; | ||
| 5 | const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; | ||
| 6 | |||
| 7 | comptime { | ||
| 8 | symbol(&__floatuneihf, "__floatuneihf"); | ||
| 9 | } | ||
| 10 | |||
| 11 | pub fn __floatuneihf(a: [*]const u8, bits: usize) callconv(.c) f16 { | ||
| 12 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | ||
| 13 | return floatFromBigInt(f16, .unsigned, @ptrCast(@alignCast(a[0..byte_size]))); | ||
| 14 | } | ||
lib/compiler_rt/floatuneisf.zig deleted-14| ... | @@ -1,14 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const builtin = @import("builtin"); | ||
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 4 | const symbol = compiler_rt.symbol; | ||
| 5 | const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; | ||
| 6 | |||
| 7 | comptime { | ||
| 8 | symbol(&__floatuneisf, "__floatuneisf"); | ||
| 9 | } | ||
| 10 | |||
| 11 | pub fn __floatuneisf(a: [*]const u8, bits: usize) callconv(.c) f32 { | ||
| 12 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | ||
| 13 | return floatFromBigInt(f32, .unsigned, @ptrCast(@alignCast(a[0..byte_size]))); | ||
| 14 | } | ||
lib/compiler_rt/floatuneitf.zig deleted-15| ... | @@ -1,15 +0,0 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | |||
| 3 | const std = @import("std"); | ||
| 4 | |||
| 5 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 6 | const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; | ||
| 7 | |||
| 8 | comptime { | ||
| 9 | symbol(&__floatuneitf, "__floatuneitf"); | ||
| 10 | } | ||
| 11 | |||
| 12 | pub fn __floatuneitf(a: [*]const u8, bits: usize) callconv(.c) f128 { | ||
| 13 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | ||
| 14 | return floatFromBigInt(f128, .unsigned, @ptrCast(@alignCast(a[0..byte_size]))); | ||
| 15 | } | ||
lib/compiler_rt/floatuneixf.zig deleted-14| ... | @@ -1,14 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const builtin = @import("builtin"); | ||
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 4 | const symbol = compiler_rt.symbol; | ||
| 5 | const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; | ||
| 6 | |||
| 7 | comptime { | ||
| 8 | symbol(&__floatuneixf, "__floatuneixf"); | ||
| 9 | } | ||
| 10 | |||
| 11 | pub fn __floatuneixf(a: [*]const u8, bits: usize) callconv(.c) f80 { | ||
| 12 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | ||
| 13 | return floatFromBigInt(f80, .unsigned, @ptrCast(@alignCast(a[0..byte_size]))); | ||
| 14 | } | ||
lib/compiler_rt/floatunsidf.zig deleted-19| ... | @@ -1,19 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_aeabi) { | ||
| 7 | symbol(&__aeabi_ui2d, "__aeabi_ui2d"); | ||
| 8 | } else { | ||
| 9 | symbol(&__floatunsidf, "__floatunsidf"); | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | pub fn __floatunsidf(a: u32) callconv(.c) f64 { | ||
| 14 | return floatFromInt(f64, a); | ||
| 15 | } | ||
| 16 | |||
| 17 | fn __aeabi_ui2d(a: u32) callconv(.{ .arm_aapcs = .{} }) f64 { | ||
| 18 | return floatFromInt(f64, a); | ||
| 19 | } | ||
lib/compiler_rt/floatunsihf.zig deleted-10| ... | @@ -1,10 +0,0 @@ | ||
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 2 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 3 | |||
| 4 | comptime { | ||
| 5 | symbol(&__floatunsihf, "__floatunsihf"); | ||
| 6 | } | ||
| 7 | |||
| 8 | pub fn __floatunsihf(a: u32) callconv(.c) f16 { | ||
| 9 | return floatFromInt(f16, a); | ||
| 10 | } | ||
lib/compiler_rt/floatunsisf.zig deleted-19| ... | @@ -1,19 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_aeabi) { | ||
| 7 | symbol(&__aeabi_ui2f, "__aeabi_ui2f"); | ||
| 8 | } else { | ||
| 9 | symbol(&__floatunsisf, "__floatunsisf"); | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | pub fn __floatunsisf(a: u32) callconv(.c) f32 { | ||
| 14 | return floatFromInt(f32, a); | ||
| 15 | } | ||
| 16 | |||
| 17 | fn __aeabi_ui2f(a: u32) callconv(.{ .arm_aapcs = .{} }) f32 { | ||
| 18 | return floatFromInt(f32, a); | ||
| 19 | } | ||
lib/compiler_rt/floatunsitf.zig deleted-22| ... | @@ -1,22 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_ppc_abi) { | ||
| 7 | symbol(&__floatunsitf, "__floatunsikf"); | ||
| 8 | } else if (compiler_rt.want_sparc64_abi) { | ||
| 9 | symbol(&_Qp_uitoq, "_Qp_uitoq"); | ||
| 10 | } else if (compiler_rt.want_sparc32_abi) { | ||
| 11 | symbol(&__floatunsitf, "_Q_utoq"); | ||
| 12 | } | ||
| 13 | symbol(&__floatunsitf, "__floatunsitf"); | ||
| 14 | } | ||
| 15 | |||
| 16 | pub fn __floatunsitf(a: u32) callconv(.c) f128 { | ||
| 17 | return floatFromInt(f128, a); | ||
| 18 | } | ||
| 19 | |||
| 20 | fn _Qp_uitoq(c: *f128, a: u32) callconv(.c) void { | ||
| 21 | c.* = floatFromInt(f128, a); | ||
| 22 | } | ||
lib/compiler_rt/floatunsixf.zig deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__floatunsixf, "__floatunsixf"); | ||
| 7 | } | ||
| 8 | |||
| 9 | fn __floatunsixf(a: u32) callconv(.c) f80 { | ||
| 10 | return floatFromInt(f80, a); | ||
| 11 | } | ||
lib/compiler_rt/floatuntidf.zig deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__floatuntidf, "__floatuntidf"); | ||
| 7 | } | ||
| 8 | |||
| 9 | pub fn __floatuntidf(a: u128) callconv(.c) f64 { | ||
| 10 | return floatFromInt(f64, a); | ||
| 11 | } | ||
lib/compiler_rt/floatuntihf.zig deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 3 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__floatuntihf, "__floatuntihf"); | ||
| 7 | } | ||
| 8 | |||
| 9 | pub fn __floatuntihf(a: u128) callconv(.c) f16 { | ||
| 10 | return floatFromInt(f16, a); | ||
| 11 | } | ||
lib/compiler_rt/floatuntisf.zig deleted-12| ... | @@ -1,12 +0,0 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 3 | const symbol = compiler_rt.symbol; | ||
| 4 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 5 | |||
| 6 | comptime { | ||
| 7 | symbol(&__floatuntisf, "__floatuntisf"); | ||
| 8 | } | ||
| 9 | |||
| 10 | pub fn __floatuntisf(a: u128) callconv(.c) f32 { | ||
| 11 | return floatFromInt(f32, a); | ||
| 12 | } | ||
lib/compiler_rt/floatuntitf.zig deleted-13| ... | @@ -1,13 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_ppc_abi) | ||
| 7 | symbol(&__floatuntitf, "__floatuntikf"); | ||
| 8 | symbol(&__floatuntitf, "__floatuntitf"); | ||
| 9 | } | ||
| 10 | |||
| 11 | pub fn __floatuntitf(a: u128) callconv(.c) f128 { | ||
| 12 | return floatFromInt(f128, a); | ||
| 13 | } | ||
lib/compiler_rt/floatuntixf.zig deleted-12| ... | @@ -1,12 +0,0 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 3 | const symbol = compiler_rt.symbol; | ||
| 4 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | ||
| 5 | |||
| 6 | comptime { | ||
| 7 | symbol(&__floatuntixf, "__floatuntixf"); | ||
| 8 | } | ||
| 9 | |||
| 10 | pub fn __floatuntixf(a: u128) callconv(.c) f80 { | ||
| 11 | return floatFromInt(f80, a); | ||
| 12 | } | ||
lib/compiler_rt/floor_ceil.zig+173-159| ... | @@ -15,7 +15,7 @@ const mem = std.mem; | ... | @@ -15,7 +15,7 @@ const mem = std.mem; |
| 15 | const expect = std.testing.expect; | 15 | const expect = std.testing.expect; |
| 16 | 16 | ||
| 17 | const compiler_rt = @import("../compiler_rt.zig"); | 17 | const compiler_rt = @import("../compiler_rt.zig"); |
| 18 | const symbol = @import("../compiler_rt.zig").symbol; | 18 | const symbol = compiler_rt.symbol; |
| 19 | 19 | ||
| 20 | comptime { | 20 | comptime { |
| 21 | // floor | 21 | // floor |
| ... | @@ -23,10 +23,7 @@ comptime { | ... | @@ -23,10 +23,7 @@ comptime { |
| 23 | symbol(&floorf, "floorf"); | 23 | symbol(&floorf, "floorf"); |
| 24 | symbol(&floor, "floor"); | 24 | symbol(&floor, "floor"); |
| 25 | symbol(&__floorx, "__floorx"); | 25 | symbol(&__floorx, "__floorx"); |
| 26 | if (compiler_rt.want_ppc_abi) { | 26 | symbol(&floorq, "floorf128"); |
| 27 | symbol(&floorq, "floorf128"); | ||
| 28 | } | ||
| 29 | symbol(&floorq, "floorq"); | ||
| 30 | symbol(&floorl, "floorl"); | 27 | symbol(&floorl, "floorl"); |
| 31 | 28 | ||
| 32 | // ceil | 29 | // ceil |
| ... | @@ -34,59 +31,96 @@ comptime { | ... | @@ -34,59 +31,96 @@ comptime { |
| 34 | symbol(&ceilf, "ceilf"); | 31 | symbol(&ceilf, "ceilf"); |
| 35 | symbol(&ceil, "ceil"); | 32 | symbol(&ceil, "ceil"); |
| 36 | symbol(&__ceilx, "__ceilx"); | 33 | symbol(&__ceilx, "__ceilx"); |
| 37 | if (compiler_rt.want_ppc_abi) { | 34 | symbol(&ceilq, "ceilf128"); |
| 38 | symbol(&ceilq, "ceilf128"); | ||
| 39 | } | ||
| 40 | symbol(&ceilq, "ceilq"); | ||
| 41 | symbol(&ceill, "ceill"); | 35 | symbol(&ceill, "ceill"); |
| 42 | } | 36 | } |
| 43 | 37 | ||
| 44 | pub fn __floorh(x: f16) callconv(.c) f16 { | 38 | fn __floorh(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { |
| 39 | return compiler_rt.f16.toAbi(floor_f16(compiler_rt.f16.fromAbi(x))); | ||
| 40 | } | ||
| 41 | pub fn floor_f16(x: f16) f16 { | ||
| 45 | return impl(f16, .floor, x); | 42 | return impl(f16, .floor, x); |
| 46 | } | 43 | } |
| 47 | 44 | ||
| 48 | pub fn floorf(x: f32) callconv(.c) f32 { | 45 | fn floorf(x: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { |
| 46 | return compiler_rt.f32.toAbi(floor_f32(compiler_rt.f32.fromAbi(x))); | ||
| 47 | } | ||
| 48 | pub fn floor_f32(x: f32) f32 { | ||
| 49 | return impl(f32, .floor, x); | 49 | return impl(f32, .floor, x); |
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | pub fn floor(x: f64) callconv(.c) f64 { | 52 | fn floor(x: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { |
| 53 | return compiler_rt.f64.toAbi(floor_f64(compiler_rt.f64.fromAbi(x))); | ||
| 54 | } | ||
| 55 | pub fn floor_f64(x: f64) f64 { | ||
| 53 | return impl(f64, .floor, x); | 56 | return impl(f64, .floor, x); |
| 54 | } | 57 | } |
| 55 | 58 | ||
| 56 | pub fn __floorx(x: f80) callconv(.c) f80 { | 59 | fn __floorx(x: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { |
| 60 | return compiler_rt.f80.toAbi(floor_f80(compiler_rt.f80.fromAbi(x))); | ||
| 61 | } | ||
| 62 | pub fn floor_f80(x: f80) f80 { | ||
| 57 | return impl(f80, .floor, x); | 63 | return impl(f80, .floor, x); |
| 58 | } | 64 | } |
| 59 | 65 | ||
| 60 | pub fn floorq(x: f128) callconv(.c) f128 { | 66 | fn floorq(x: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { |
| 67 | return compiler_rt.f128.toAbi(floor_f128(compiler_rt.f128.fromAbi(x))); | ||
| 68 | } | ||
| 69 | pub fn floor_f128(x: f128) f128 { | ||
| 61 | return impl(f128, .floor, x); | 70 | return impl(f128, .floor, x); |
| 62 | } | 71 | } |
| 63 | 72 | ||
| 64 | pub fn floorl(x: c_longdouble) callconv(.c) c_longdouble { | 73 | pub fn floorl(x: c_longdouble) callconv(.c) c_longdouble { |
| 65 | return impl(std.meta.Float(@bitSizeOf(c_longdouble)), .floor, x); | 74 | switch (@typeInfo(c_longdouble).float.bits) { |
| 75 | 64 => return floor_f64(x), | ||
| 76 | 80 => return floor_f80(x), | ||
| 77 | 128 => return floor_f128(x), | ||
| 78 | else => comptime unreachable, | ||
| 79 | } | ||
| 66 | } | 80 | } |
| 67 | 81 | ||
| 68 | pub fn __ceilh(x: f16) callconv(.c) f16 { | 82 | fn __ceilh(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { |
| 83 | return compiler_rt.f16.toAbi(ceil_f16(compiler_rt.f16.fromAbi(x))); | ||
| 84 | } | ||
| 85 | pub fn ceil_f16(x: f16) f16 { | ||
| 69 | return impl(f16, .ceil, x); | 86 | return impl(f16, .ceil, x); |
| 70 | } | 87 | } |
| 71 | 88 | ||
| 72 | pub fn ceilf(x: f32) callconv(.c) f32 { | 89 | fn ceilf(x: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { |
| 90 | return compiler_rt.f32.toAbi(ceil_f32(compiler_rt.f32.fromAbi(x))); | ||
| 91 | } | ||
| 92 | pub fn ceil_f32(x: f32) f32 { | ||
| 73 | return impl(f32, .ceil, x); | 93 | return impl(f32, .ceil, x); |
| 74 | } | 94 | } |
| 75 | 95 | ||
| 76 | pub fn ceil(x: f64) callconv(.c) f64 { | 96 | fn ceil(x: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { |
| 97 | return compiler_rt.f64.toAbi(ceil_f64(compiler_rt.f64.fromAbi(x))); | ||
| 98 | } | ||
| 99 | pub fn ceil_f64(x: f64) f64 { | ||
| 77 | return impl(f64, .ceil, x); | 100 | return impl(f64, .ceil, x); |
| 78 | } | 101 | } |
| 79 | 102 | ||
| 80 | pub fn __ceilx(x: f80) callconv(.c) f80 { | 103 | fn __ceilx(x: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { |
| 104 | return compiler_rt.f80.toAbi(ceil_f80(compiler_rt.f80.fromAbi(x))); | ||
| 105 | } | ||
| 106 | pub fn ceil_f80(x: f80) f80 { | ||
| 81 | return impl(f80, .ceil, x); | 107 | return impl(f80, .ceil, x); |
| 82 | } | 108 | } |
| 83 | 109 | ||
| 84 | pub fn ceilq(x: f128) callconv(.c) f128 { | 110 | fn ceilq(x: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { |
| 111 | return compiler_rt.f128.toAbi(ceil_f128(compiler_rt.f128.fromAbi(x))); | ||
| 112 | } | ||
| 113 | pub fn ceil_f128(x: f128) f128 { | ||
| 85 | return impl(f128, .ceil, x); | 114 | return impl(f128, .ceil, x); |
| 86 | } | 115 | } |
| 87 | 116 | ||
| 88 | pub fn ceill(x: c_longdouble) callconv(.c) c_longdouble { | 117 | pub fn ceill(x: c_longdouble) callconv(.c) c_longdouble { |
| 89 | return impl(std.meta.Float(@bitSizeOf(c_longdouble)), .ceil, x); | 118 | switch (@typeInfo(c_longdouble).float.bits) { |
| 119 | 64 => return ceil_f64(x), | ||
| 120 | 80 => return ceil_f80(x), | ||
| 121 | 128 => return ceil_f128(x), | ||
| 122 | else => comptime unreachable, | ||
| 123 | } | ||
| 90 | } | 124 | } |
| 91 | 125 | ||
| 92 | inline fn impl(comptime T: type, comptime op: enum { floor, ceil }, x: T) T { | 126 | inline fn impl(comptime T: type, comptime op: enum { floor, ceil }, x: T) T { |
| ... | @@ -144,142 +178,122 @@ inline fn impl(comptime T: type, comptime op: enum { floor, ceil }, x: T) T { | ... | @@ -144,142 +178,122 @@ inline fn impl(comptime T: type, comptime op: enum { floor, ceil }, x: T) T { |
| 144 | } | 178 | } |
| 145 | } | 179 | } |
| 146 | 180 | ||
| 147 | test "floor16" { | 181 | test floor_f16 { |
| 148 | try expect(__floorh(1.3) == 1.0); | 182 | try expect(floor_f16(1.3) == 1.0); |
| 149 | try expect(__floorh(-1.3) == -2.0); | 183 | try expect(floor_f16(-1.3) == -2.0); |
| 150 | try expect(__floorh(0.2) == 0.0); | 184 | try expect(floor_f16(-0.2) == -1.0); |
| 151 | } | 185 | try expect(math.isPositiveZero(floor_f16(0.2))); |
| 152 | 186 | try expect(math.isPositiveZero(floor_f16(0.0))); | |
| 153 | test "floor32" { | 187 | try expect(math.isNegativeZero(floor_f16(-0.0))); |
| 154 | try expect(floorf(1.3) == 1.0); | 188 | try expect(math.isPositiveInf(floor_f16(math.inf(f16)))); |
| 155 | try expect(floorf(-1.3) == -2.0); | 189 | try expect(math.isNegativeInf(floor_f16(-math.inf(f16)))); |
| 156 | try expect(floorf(0.2) == 0.0); | 190 | try expect(math.isNan(floor_f16(math.nan(f16)))); |
| 157 | } | 191 | } |
| 158 | 192 | ||
| 159 | test "floor64" { | 193 | test floor_f32 { |
| 160 | try expect(floor(1.3) == 1.0); | 194 | try expect(floor_f32(1.3) == 1.0); |
| 161 | try expect(floor(-1.3) == -2.0); | 195 | try expect(floor_f32(-1.3) == -2.0); |
| 162 | try expect(floor(0.2) == 0.0); | 196 | try expect(floor_f32(-0.2) == -1.0); |
| 163 | } | 197 | try expect(math.isPositiveZero(floor_f32(0.2))); |
| 164 | 198 | try expect(math.isPositiveZero(floor_f32(0.0))); | |
| 165 | test "floor80" { | 199 | try expect(math.isNegativeZero(floor_f32(-0.0))); |
| 166 | try expect(__floorx(1.3) == 1.0); | 200 | try expect(math.isPositiveInf(floor_f32(math.inf(f32)))); |
| 167 | try expect(__floorx(-1.3) == -2.0); | 201 | try expect(math.isNegativeInf(floor_f32(-math.inf(f32)))); |
| 168 | try expect(__floorx(0.2) == 0.0); | 202 | try expect(math.isNan(floor_f32(math.nan(f32)))); |
| 169 | } | 203 | } |
| 170 | 204 | ||
| 171 | test "floor128" { | 205 | test floor_f64 { |
| 172 | try expect(floorq(1.3) == 1.0); | 206 | try expect(floor_f64(1.3) == 1.0); |
| 173 | try expect(floorq(-1.3) == -2.0); | 207 | try expect(floor_f64(-1.3) == -2.0); |
| 174 | try expect(floorq(0.2) == 0.0); | 208 | try expect(floor_f64(-0.2) == -1.0); |
| 175 | } | 209 | try expect(math.isPositiveZero(floor_f64(0.2))); |
| 176 | 210 | try expect(math.isPositiveZero(floor_f64(0.0))); | |
| 177 | test "floor16.special" { | 211 | try expect(math.isNegativeZero(floor_f64(-0.0))); |
| 178 | try expect(__floorh(0.0) == 0.0); | 212 | try expect(math.isPositiveInf(floor_f64(math.inf(f64)))); |
| 179 | try expect(__floorh(-0.0) == -0.0); | 213 | try expect(math.isNegativeInf(floor_f64(-math.inf(f64)))); |
| 180 | try expect(math.isPositiveInf(__floorh(math.inf(f16)))); | 214 | try expect(math.isNan(floor_f64(math.nan(f64)))); |
| 181 | try expect(math.isNegativeInf(__floorh(-math.inf(f16)))); | 215 | } |
| 182 | try expect(math.isNan(__floorh(math.nan(f16)))); | 216 | |
| 183 | } | 217 | test floor_f80 { |
| 184 | 218 | try expect(floor_f80(1.3) == 1.0); | |
| 185 | test "floor32.special" { | 219 | try expect(floor_f80(-1.3) == -2.0); |
| 186 | try expect(floorf(0.0) == 0.0); | 220 | try expect(floor_f80(-0.2) == -1.0); |
| 187 | try expect(floorf(-0.0) == -0.0); | 221 | try expect(math.isPositiveZero(floor_f80(0.2))); |
| 188 | try expect(math.isPositiveInf(floorf(math.inf(f32)))); | 222 | try expect(math.isPositiveZero(floor_f80(0.0))); |
| 189 | try expect(math.isNegativeInf(floorf(-math.inf(f32)))); | 223 | try expect(math.isNegativeZero(floor_f80(-0.0))); |
| 190 | try expect(math.isNan(floorf(math.nan(f32)))); | 224 | try expect(math.isPositiveInf(floor_f80(math.inf(f80)))); |
| 191 | } | 225 | try expect(math.isNegativeInf(floor_f80(-math.inf(f80)))); |
| 192 | 226 | try expect(math.isNan(floor_f80(math.nan(f80)))); | |
| 193 | test "floor64.special" { | 227 | } |
| 194 | try expect(floor(0.0) == 0.0); | 228 | |
| 195 | try expect(floor(-0.0) == -0.0); | 229 | test floor_f128 { |
| 196 | try expect(math.isPositiveInf(floor(math.inf(f64)))); | 230 | try expect(floor_f128(1.3) == 1.0); |
| 197 | try expect(math.isNegativeInf(floor(-math.inf(f64)))); | 231 | try expect(floor_f128(-1.3) == -2.0); |
| 198 | try expect(math.isNan(floor(math.nan(f64)))); | 232 | try expect(floor_f128(-0.2) == -1.0); |
| 199 | } | 233 | try expect(math.isPositiveZero(floor_f128(0.2))); |
| 200 | 234 | try expect(math.isPositiveZero(floor_f128(0.0))); | |
| 201 | test "floor80.special" { | 235 | try expect(math.isNegativeZero(floor_f128(-0.0))); |
| 202 | try expect(__floorx(0.0) == 0.0); | 236 | try expect(math.isPositiveInf(floor_f128(math.inf(f128)))); |
| 203 | try expect(__floorx(-0.0) == -0.0); | 237 | try expect(math.isNegativeInf(floor_f128(-math.inf(f128)))); |
| 204 | try expect(math.isPositiveInf(__floorx(math.inf(f80)))); | 238 | try expect(math.isNan(floor_f128(math.nan(f128)))); |
| 205 | try expect(math.isNegativeInf(__floorx(-math.inf(f80)))); | 239 | } |
| 206 | try expect(math.isNan(__floorx(math.nan(f80)))); | 240 | |
| 207 | } | 241 | test ceil_f16 { |
| 208 | 242 | try expect(ceil_f16(1.3) == 2.0); | |
| 209 | test "floor128.special" { | 243 | try expect(ceil_f16(-1.3) == -1.0); |
| 210 | try expect(floorq(0.0) == 0.0); | 244 | try expect(ceil_f16(0.2) == 1.0); |
| 211 | try expect(floorq(-0.0) == -0.0); | 245 | try expect(math.isNegativeZero(ceil_f16(-0.2))); |
| 212 | try expect(math.isPositiveInf(floorq(math.inf(f128)))); | 246 | try expect(math.isPositiveZero(ceil_f16(0.0))); |
| 213 | try expect(math.isNegativeInf(floorq(-math.inf(f128)))); | 247 | try expect(math.isNegativeZero(ceil_f16(-0.0))); |
| 214 | try expect(math.isNan(floorq(math.nan(f128)))); | 248 | try expect(math.isPositiveInf(ceil_f16(math.inf(f16)))); |
| 215 | } | 249 | try expect(math.isNegativeInf(ceil_f16(-math.inf(f16)))); |
| 216 | 250 | try expect(math.isNan(ceil_f16(math.nan(f16)))); | |
| 217 | test "ceil16" { | 251 | } |
| 218 | try expect(__ceilh(1.3) == 2.0); | 252 | |
| 219 | try expect(__ceilh(-1.3) == -1.0); | 253 | test ceil_f32 { |
| 220 | try expect(__ceilh(0.2) == 1.0); | 254 | try expect(ceil_f32(1.3) == 2.0); |
| 221 | } | 255 | try expect(ceil_f32(-1.3) == -1.0); |
| 222 | 256 | try expect(ceil_f32(0.2) == 1.0); | |
| 223 | test "ceil32" { | 257 | try expect(math.isNegativeZero(ceil_f32(-0.2))); |
| 224 | try expect(ceilf(1.3) == 2.0); | 258 | try expect(math.isPositiveZero(ceil_f32(0.0))); |
| 225 | try expect(ceilf(-1.3) == -1.0); | 259 | try expect(math.isNegativeZero(ceil_f32(-0.0))); |
| 226 | try expect(ceilf(0.2) == 1.0); | 260 | try expect(math.isPositiveInf(ceil_f32(math.inf(f32)))); |
| 227 | } | 261 | try expect(math.isNegativeInf(ceil_f32(-math.inf(f32)))); |
| 228 | 262 | try expect(math.isNan(ceil_f32(math.nan(f32)))); | |
| 229 | test "ceil64" { | 263 | } |
| 230 | try expect(ceil(1.3) == 2.0); | 264 | |
| 231 | try expect(ceil(-1.3) == -1.0); | 265 | test ceil_f64 { |
| 232 | try expect(ceil(0.2) == 1.0); | 266 | try expect(ceil_f64(1.3) == 2.0); |
| 233 | } | 267 | try expect(ceil_f64(-1.3) == -1.0); |
| 234 | 268 | try expect(ceil_f64(0.2) == 1.0); | |
| 235 | test "ceil80" { | 269 | try expect(math.isNegativeZero(ceil_f64(-0.2))); |
| 236 | try expect(__ceilx(1.3) == 2.0); | 270 | try expect(math.isPositiveZero(ceil_f64(0.0))); |
| 237 | try expect(__ceilx(-1.3) == -1.0); | 271 | try expect(math.isNegativeZero(ceil_f64(-0.0))); |
| 238 | try expect(__ceilx(0.2) == 1.0); | 272 | try expect(math.isPositiveInf(ceil_f64(math.inf(f64)))); |
| 239 | } | 273 | try expect(math.isNegativeInf(ceil_f64(-math.inf(f64)))); |
| 240 | 274 | try expect(math.isNan(ceil_f64(math.nan(f64)))); | |
| 241 | test "ceil128" { | 275 | } |
| 242 | try expect(ceilq(1.3) == 2.0); | 276 | |
| 243 | try expect(ceilq(-1.3) == -1.0); | 277 | test ceil_f80 { |
| 244 | try expect(ceilq(0.2) == 1.0); | 278 | try expect(ceil_f80(1.3) == 2.0); |
| 245 | } | 279 | try expect(ceil_f80(-1.3) == -1.0); |
| 246 | 280 | try expect(ceil_f80(0.2) == 1.0); | |
| 247 | test "ceil16.special" { | 281 | try expect(math.isNegativeZero(ceil_f80(-0.2))); |
| 248 | try expect(__ceilh(0.0) == 0.0); | 282 | try expect(math.isPositiveZero(ceil_f80(0.0))); |
| 249 | try expect(__ceilh(-0.0) == -0.0); | 283 | try expect(math.isNegativeZero(ceil_f80(-0.0))); |
| 250 | try expect(math.isPositiveInf(__ceilh(math.inf(f16)))); | 284 | try expect(math.isPositiveInf(ceil_f80(math.inf(f80)))); |
| 251 | try expect(math.isNegativeInf(__ceilh(-math.inf(f16)))); | 285 | try expect(math.isNegativeInf(ceil_f80(-math.inf(f80)))); |
| 252 | try expect(math.isNan(__ceilh(math.nan(f16)))); | 286 | try expect(math.isNan(ceil_f80(math.nan(f80)))); |
| 253 | } | 287 | } |
| 254 | 288 | ||
| 255 | test "ceil32.special" { | 289 | test ceil_f128 { |
| 256 | try expect(ceilf(0.0) == 0.0); | 290 | try expect(ceil_f128(1.3) == 2.0); |
| 257 | try expect(ceilf(-0.0) == -0.0); | 291 | try expect(ceil_f128(-1.3) == -1.0); |
| 258 | try expect(math.isPositiveInf(ceilf(math.inf(f32)))); | 292 | try expect(ceil_f128(0.2) == 1.0); |
| 259 | try expect(math.isNegativeInf(ceilf(-math.inf(f32)))); | 293 | try expect(math.isNegativeZero(ceil_f128(-0.2))); |
| 260 | try expect(math.isNan(ceilf(math.nan(f32)))); | 294 | try expect(math.isPositiveZero(ceil_f128(0.0))); |
| 261 | } | 295 | try expect(math.isNegativeZero(ceil_f128(-0.0))); |
| 262 | 296 | try expect(math.isPositiveInf(ceil_f128(math.inf(f128)))); | |
| 263 | test "ceil64.special" { | 297 | try expect(math.isNegativeInf(ceil_f128(-math.inf(f128)))); |
| 264 | try expect(ceil(0.0) == 0.0); | 298 | try expect(math.isNan(ceil_f128(math.nan(f128)))); |
| 265 | try expect(ceil(-0.0) == -0.0); | ||
| 266 | try expect(math.isPositiveInf(ceil(math.inf(f64)))); | ||
| 267 | try expect(math.isNegativeInf(ceil(-math.inf(f64)))); | ||
| 268 | try expect(math.isNan(ceil(math.nan(f64)))); | ||
| 269 | } | ||
| 270 | |||
| 271 | test "ceil80.special" { | ||
| 272 | try expect(__ceilx(0.0) == 0.0); | ||
| 273 | try expect(__ceilx(-0.0) == -0.0); | ||
| 274 | try expect(math.isPositiveInf(__ceilx(math.inf(f80)))); | ||
| 275 | try expect(math.isNegativeInf(__ceilx(-math.inf(f80)))); | ||
| 276 | try expect(math.isNan(__ceilx(math.nan(f80)))); | ||
| 277 | } | ||
| 278 | |||
| 279 | test "ceil128.special" { | ||
| 280 | try expect(ceilq(0.0) == 0.0); | ||
| 281 | try expect(ceilq(-0.0) == -0.0); | ||
| 282 | try expect(math.isPositiveInf(ceilq(math.inf(f128)))); | ||
| 283 | try expect(math.isNegativeInf(ceilq(-math.inf(f128)))); | ||
| 284 | try expect(math.isNan(ceilq(math.nan(f128)))); | ||
| 285 | } | 299 | } |
lib/compiler_rt/fma.zig+48-36| ... | @@ -16,19 +16,22 @@ comptime { | ... | @@ -16,19 +16,22 @@ comptime { |
| 16 | symbol(&fmaf, "fmaf"); | 16 | symbol(&fmaf, "fmaf"); |
| 17 | symbol(&fma, "fma"); | 17 | symbol(&fma, "fma"); |
| 18 | symbol(&__fmax, "__fmax"); | 18 | symbol(&__fmax, "__fmax"); |
| 19 | if (compiler_rt.want_ppc_abi) { | 19 | symbol(&fmaq, "fmaf128"); |
| 20 | symbol(&fmaq, "fmaf128"); | ||
| 21 | } | ||
| 22 | symbol(&fmaq, "fmaq"); | ||
| 23 | symbol(&fmal, "fmal"); | 20 | symbol(&fmal, "fmal"); |
| 24 | } | 21 | } |
| 25 | 22 | ||
| 26 | pub fn __fmah(x: f16, y: f16, z: f16) callconv(.c) f16 { | 23 | fn __fmah(x: compiler_rt.f16.Abi, y: compiler_rt.f16.Abi, z: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { |
| 24 | return compiler_rt.f16.toAbi(fma_f16(compiler_rt.f16.fromAbi(x), compiler_rt.f16.fromAbi(y), compiler_rt.f16.fromAbi(z))); | ||
| 25 | } | ||
| 26 | pub fn fma_f16(x: f16, y: f16, z: f16) f16 { | ||
| 27 | // TODO: more efficient implementation | 27 | // TODO: more efficient implementation |
| 28 | return @floatCast(fmaf(x, y, z)); | 28 | return @floatCast(fma_f32(x, y, z)); |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | pub fn fmaf(x: f32, y: f32, z: f32) callconv(.c) f32 { | 31 | fn fmaf(x: compiler_rt.f32.Abi, y: compiler_rt.f32.Abi, z: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { |
| 32 | return compiler_rt.f32.toAbi(fma_f32(compiler_rt.f32.fromAbi(x), compiler_rt.f32.fromAbi(y), compiler_rt.f32.fromAbi(z))); | ||
| 33 | } | ||
| 34 | pub fn fma_f32(x: f32, y: f32, z: f32) f32 { | ||
| 32 | const xy = @as(f64, x) * y; | 35 | const xy = @as(f64, x) * y; |
| 33 | const xy_z = xy + z; | 36 | const xy_z = xy + z; |
| 34 | const u = @as(u64, @bitCast(xy_z)); | 37 | const u = @as(u64, @bitCast(xy_z)); |
| ... | @@ -42,8 +45,11 @@ pub fn fmaf(x: f32, y: f32, z: f32) callconv(.c) f32 { | ... | @@ -42,8 +45,11 @@ pub fn fmaf(x: f32, y: f32, z: f32) callconv(.c) f32 { |
| 42 | } | 45 | } |
| 43 | } | 46 | } |
| 44 | 47 | ||
| 48 | fn fma(x: compiler_rt.f64.Abi, y: compiler_rt.f64.Abi, z: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { | ||
| 49 | return compiler_rt.f64.toAbi(fma_f64(compiler_rt.f64.fromAbi(x), compiler_rt.f64.fromAbi(y), compiler_rt.f64.fromAbi(z))); | ||
| 50 | } | ||
| 45 | /// NOTE: Upstream fma.c has been rewritten completely to raise fp exceptions more accurately. | 51 | /// NOTE: Upstream fma.c has been rewritten completely to raise fp exceptions more accurately. |
| 46 | pub fn fma(x: f64, y: f64, z: f64) callconv(.c) f64 { | 52 | pub fn fma_f64(x: f64, y: f64, z: f64) f64 { |
| 47 | if (!math.isFinite(x) or !math.isFinite(y)) { | 53 | if (!math.isFinite(x) or !math.isFinite(y)) { |
| 48 | return x * y + z; | 54 | return x * y + z; |
| 49 | } | 55 | } |
| ... | @@ -90,11 +96,17 @@ pub fn fma(x: f64, y: f64, z: f64) callconv(.c) f64 { | ... | @@ -90,11 +96,17 @@ pub fn fma(x: f64, y: f64, z: f64) callconv(.c) f64 { |
| 90 | } | 96 | } |
| 91 | } | 97 | } |
| 92 | 98 | ||
| 93 | pub fn __fmax(a: f80, b: f80, c: f80) callconv(.c) f80 { | 99 | fn __fmax(a: compiler_rt.f80.Abi, b: compiler_rt.f80.Abi, c: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { |
| 100 | return compiler_rt.f80.toAbi(fma_f80(compiler_rt.f80.fromAbi(a), compiler_rt.f80.fromAbi(b), compiler_rt.f80.fromAbi(c))); | ||
| 101 | } | ||
| 102 | pub fn fma_f80(a: f80, b: f80, c: f80) f80 { | ||
| 94 | // TODO: more efficient implementation | 103 | // TODO: more efficient implementation |
| 95 | return @floatCast(fmaq(a, b, c)); | 104 | return @floatCast(fma_f128(a, b, c)); |
| 96 | } | 105 | } |
| 97 | 106 | ||
| 107 | fn fmaq(x: compiler_rt.f128.Abi, y: compiler_rt.f128.Abi, z: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { | ||
| 108 | return compiler_rt.f128.toAbi(fma_f128(compiler_rt.f128.fromAbi(x), compiler_rt.f128.fromAbi(y), compiler_rt.f128.fromAbi(z))); | ||
| 109 | } | ||
| 98 | /// Fused multiply-add: Compute x * y + z with a single rounding error. | 110 | /// Fused multiply-add: Compute x * y + z with a single rounding error. |
| 99 | /// | 111 | /// |
| 100 | /// We use scaling to avoid overflow/underflow, along with the | 112 | /// We use scaling to avoid overflow/underflow, along with the |
| ... | @@ -102,7 +114,7 @@ pub fn __fmax(a: f80, b: f80, c: f80) callconv(.c) f80 { | ... | @@ -102,7 +114,7 @@ pub fn __fmax(a: f80, b: f80, c: f80) callconv(.c) f80 { |
| 102 | /// | 114 | /// |
| 103 | /// Dekker, T. A Floating-Point Technique for Extending the | 115 | /// Dekker, T. A Floating-Point Technique for Extending the |
| 104 | /// Available Precision. Numer. Math. 18, 224-242 (1971). | 116 | /// Available Precision. Numer. Math. 18, 224-242 (1971). |
| 105 | pub fn fmaq(x: f128, y: f128, z: f128) callconv(.c) f128 { | 117 | pub fn fma_f128(x: f128, y: f128, z: f128) f128 { |
| 106 | if (!math.isFinite(x) or !math.isFinite(y)) { | 118 | if (!math.isFinite(x) or !math.isFinite(y)) { |
| 107 | return x * y + z; | 119 | return x * y + z; |
| 108 | } | 120 | } |
| ... | @@ -151,10 +163,10 @@ pub fn fmaq(x: f128, y: f128, z: f128) callconv(.c) f128 { | ... | @@ -151,10 +163,10 @@ pub fn fmaq(x: f128, y: f128, z: f128) callconv(.c) f128 { |
| 151 | 163 | ||
| 152 | pub fn fmal(x: c_longdouble, y: c_longdouble, z: c_longdouble) callconv(.c) c_longdouble { | 164 | pub fn fmal(x: c_longdouble, y: c_longdouble, z: c_longdouble) callconv(.c) c_longdouble { |
| 153 | switch (@typeInfo(c_longdouble).float.bits) { | 165 | switch (@typeInfo(c_longdouble).float.bits) { |
| 154 | 64 => return fma(x, y, z), | 166 | 64 => return fma_f64(x, y, z), |
| 155 | 80 => return __fmax(x, y, z), | 167 | 80 => return fma_f80(x, y, z), |
| 156 | 128 => return fmaq(x, y, z), | 168 | 128 => return fma_f128(x, y, z), |
| 157 | else => @compileError("unreachable"), | 169 | else => comptime unreachable, |
| 158 | } | 170 | } |
| 159 | } | 171 | } |
| 160 | 172 | ||
| ... | @@ -316,35 +328,35 @@ fn dd_mul128(a: f128, b: f128) dd128 { | ... | @@ -316,35 +328,35 @@ fn dd_mul128(a: f128, b: f128) dd128 { |
| 316 | test "32" { | 328 | test "32" { |
| 317 | const epsilon = 0.000001; | 329 | const epsilon = 0.000001; |
| 318 | 330 | ||
| 319 | try expect(math.approxEqAbs(f32, fmaf(0.0, 5.0, 9.124), 9.124, epsilon)); | 331 | try expect(math.approxEqAbs(f32, fma_f32(0.0, 5.0, 9.124), 9.124, epsilon)); |
| 320 | try expect(math.approxEqAbs(f32, fmaf(0.2, 5.0, 9.124), 10.124, epsilon)); | 332 | try expect(math.approxEqAbs(f32, fma_f32(0.2, 5.0, 9.124), 10.124, epsilon)); |
| 321 | try expect(math.approxEqAbs(f32, fmaf(0.8923, 5.0, 9.124), 13.5855, epsilon)); | 333 | try expect(math.approxEqAbs(f32, fma_f32(0.8923, 5.0, 9.124), 13.5855, epsilon)); |
| 322 | try expect(math.approxEqAbs(f32, fmaf(1.5, 5.0, 9.124), 16.624, epsilon)); | 334 | try expect(math.approxEqAbs(f32, fma_f32(1.5, 5.0, 9.124), 16.624, epsilon)); |
| 323 | try expect(math.approxEqAbs(f32, fmaf(37.45, 5.0, 9.124), 196.374004, epsilon)); | 335 | try expect(math.approxEqAbs(f32, fma_f32(37.45, 5.0, 9.124), 196.374004, epsilon)); |
| 324 | try expect(math.approxEqAbs(f32, fmaf(89.123, 5.0, 9.124), 454.739005, epsilon)); | 336 | try expect(math.approxEqAbs(f32, fma_f32(89.123, 5.0, 9.124), 454.739005, epsilon)); |
| 325 | try expect(math.approxEqAbs(f32, fmaf(123123.234375, 5.0, 9.124), 615625.295875, epsilon)); | 337 | try expect(math.approxEqAbs(f32, fma_f32(123123.234375, 5.0, 9.124), 615625.295875, epsilon)); |
| 326 | } | 338 | } |
| 327 | 339 | ||
| 328 | test "64" { | 340 | test "64" { |
| 329 | const epsilon = 0.000001; | 341 | const epsilon = 0.000001; |
| 330 | 342 | ||
| 331 | try expect(math.approxEqAbs(f64, fma(0.0, 5.0, 9.124), 9.124, epsilon)); | 343 | try expect(math.approxEqAbs(f64, fma_f64(0.0, 5.0, 9.124), 9.124, epsilon)); |
| 332 | try expect(math.approxEqAbs(f64, fma(0.2, 5.0, 9.124), 10.124, epsilon)); | 344 | try expect(math.approxEqAbs(f64, fma_f64(0.2, 5.0, 9.124), 10.124, epsilon)); |
| 333 | try expect(math.approxEqAbs(f64, fma(0.8923, 5.0, 9.124), 13.5855, epsilon)); | 345 | try expect(math.approxEqAbs(f64, fma_f64(0.8923, 5.0, 9.124), 13.5855, epsilon)); |
| 334 | try expect(math.approxEqAbs(f64, fma(1.5, 5.0, 9.124), 16.624, epsilon)); | 346 | try expect(math.approxEqAbs(f64, fma_f64(1.5, 5.0, 9.124), 16.624, epsilon)); |
| 335 | try expect(math.approxEqAbs(f64, fma(37.45, 5.0, 9.124), 196.374, epsilon)); | 347 | try expect(math.approxEqAbs(f64, fma_f64(37.45, 5.0, 9.124), 196.374, epsilon)); |
| 336 | try expect(math.approxEqAbs(f64, fma(89.123, 5.0, 9.124), 454.739, epsilon)); | 348 | try expect(math.approxEqAbs(f64, fma_f64(89.123, 5.0, 9.124), 454.739, epsilon)); |
| 337 | try expect(math.approxEqAbs(f64, fma(123123.234375, 5.0, 9.124), 615625.295875, epsilon)); | 349 | try expect(math.approxEqAbs(f64, fma_f64(123123.234375, 5.0, 9.124), 615625.295875, epsilon)); |
| 338 | } | 350 | } |
| 339 | 351 | ||
| 340 | test "128" { | 352 | test "128" { |
| 341 | const epsilon = 0.000001; | 353 | const epsilon = 0.000001; |
| 342 | 354 | ||
| 343 | try expect(math.approxEqAbs(f128, fmaq(0.0, 5.0, 9.124), 9.124, epsilon)); | 355 | try expect(math.approxEqAbs(f128, fma_f128(0.0, 5.0, 9.124), 9.124, epsilon)); |
| 344 | try expect(math.approxEqAbs(f128, fmaq(0.2, 5.0, 9.124), 10.124, epsilon)); | 356 | try expect(math.approxEqAbs(f128, fma_f128(0.2, 5.0, 9.124), 10.124, epsilon)); |
| 345 | try expect(math.approxEqAbs(f128, fmaq(0.8923, 5.0, 9.124), 13.5855, epsilon)); | 357 | try expect(math.approxEqAbs(f128, fma_f128(0.8923, 5.0, 9.124), 13.5855, epsilon)); |
| 346 | try expect(math.approxEqAbs(f128, fmaq(1.5, 5.0, 9.124), 16.624, epsilon)); | 358 | try expect(math.approxEqAbs(f128, fma_f128(1.5, 5.0, 9.124), 16.624, epsilon)); |
| 347 | try expect(math.approxEqAbs(f128, fmaq(37.45, 5.0, 9.124), 196.374, epsilon)); | 359 | try expect(math.approxEqAbs(f128, fma_f128(37.45, 5.0, 9.124), 196.374, epsilon)); |
| 348 | try expect(math.approxEqAbs(f128, fmaq(89.123, 5.0, 9.124), 454.739, epsilon)); | 360 | try expect(math.approxEqAbs(f128, fma_f128(89.123, 5.0, 9.124), 454.739, epsilon)); |
| 349 | try expect(math.approxEqAbs(f128, fmaq(123123.234375, 5.0, 9.124), 615625.295875, epsilon)); | 361 | try expect(math.approxEqAbs(f128, fma_f128(123123.234375, 5.0, 9.124), 615625.295875, epsilon)); |
| 350 | } | 362 | } |
lib/compiler_rt/fmax.zig+25-13| ... | @@ -10,39 +10,51 @@ comptime { | ... | @@ -10,39 +10,51 @@ comptime { |
| 10 | symbol(&fmaxf, "fmaxf"); | 10 | symbol(&fmaxf, "fmaxf"); |
| 11 | symbol(&fmax, "fmax"); | 11 | symbol(&fmax, "fmax"); |
| 12 | symbol(&__fmaxx, "__fmaxx"); | 12 | symbol(&__fmaxx, "__fmaxx"); |
| 13 | if (compiler_rt.want_ppc_abi) { | 13 | symbol(&fmaxq, "fmaxf128"); |
| 14 | symbol(&fmaxq, "fmaxf128"); | ||
| 15 | } | ||
| 16 | symbol(&fmaxq, "fmaxq"); | ||
| 17 | symbol(&fmaxl, "fmaxl"); | 14 | symbol(&fmaxl, "fmaxl"); |
| 18 | } | 15 | } |
| 19 | 16 | ||
| 20 | pub fn __fmaxh(x: f16, y: f16) callconv(.c) f16 { | 17 | fn __fmaxh(x: compiler_rt.f16.Abi, y: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { |
| 18 | return compiler_rt.f16.toAbi(fmax_f16(compiler_rt.f16.fromAbi(x), compiler_rt.f16.fromAbi(y))); | ||
| 19 | } | ||
| 20 | pub fn fmax_f16(x: f16, y: f16) f16 { | ||
| 21 | return generic_fmax(f16, x, y); | 21 | return generic_fmax(f16, x, y); |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | pub fn fmaxf(x: f32, y: f32) callconv(.c) f32 { | 24 | fn fmaxf(x: compiler_rt.f32.Abi, y: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { |
| 25 | return compiler_rt.f32.toAbi(fmax_f32(compiler_rt.f32.fromAbi(x), compiler_rt.f32.fromAbi(y))); | ||
| 26 | } | ||
| 27 | pub fn fmax_f32(x: f32, y: f32) f32 { | ||
| 25 | return generic_fmax(f32, x, y); | 28 | return generic_fmax(f32, x, y); |
| 26 | } | 29 | } |
| 27 | 30 | ||
| 28 | pub fn fmax(x: f64, y: f64) callconv(.c) f64 { | 31 | fn fmax(x: compiler_rt.f64.Abi, y: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { |
| 32 | return compiler_rt.f64.toAbi(fmax_f64(compiler_rt.f64.fromAbi(x), compiler_rt.f64.fromAbi(y))); | ||
| 33 | } | ||
| 34 | pub fn fmax_f64(x: f64, y: f64) f64 { | ||
| 29 | return generic_fmax(f64, x, y); | 35 | return generic_fmax(f64, x, y); |
| 30 | } | 36 | } |
| 31 | 37 | ||
| 32 | pub fn __fmaxx(x: f80, y: f80) callconv(.c) f80 { | 38 | fn __fmaxx(x: compiler_rt.f80.Abi, y: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { |
| 39 | return compiler_rt.f80.toAbi(fmax_f80(compiler_rt.f80.fromAbi(x), compiler_rt.f80.fromAbi(y))); | ||
| 40 | } | ||
| 41 | pub fn fmax_f80(x: f80, y: f80) f80 { | ||
| 33 | return generic_fmax(f80, x, y); | 42 | return generic_fmax(f80, x, y); |
| 34 | } | 43 | } |
| 35 | 44 | ||
| 36 | pub fn fmaxq(x: f128, y: f128) callconv(.c) f128 { | 45 | fn fmaxq(x: compiler_rt.f128.Abi, y: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { |
| 46 | return compiler_rt.f128.toAbi(fmax_f128(compiler_rt.f128.fromAbi(x), compiler_rt.f128.fromAbi(y))); | ||
| 47 | } | ||
| 48 | pub fn fmax_f128(x: f128, y: f128) f128 { | ||
| 37 | return generic_fmax(f128, x, y); | 49 | return generic_fmax(f128, x, y); |
| 38 | } | 50 | } |
| 39 | 51 | ||
| 40 | pub fn fmaxl(x: c_longdouble, y: c_longdouble) callconv(.c) c_longdouble { | 52 | pub fn fmaxl(x: c_longdouble, y: c_longdouble) callconv(.c) c_longdouble { |
| 41 | switch (@typeInfo(c_longdouble).float.bits) { | 53 | switch (@typeInfo(c_longdouble).float.bits) { |
| 42 | 64 => return fmax(x, y), | 54 | 64 => return fmax_f64(x, y), |
| 43 | 80 => return __fmaxx(x, y), | 55 | 80 => return fmax_f80(x, y), |
| 44 | 128 => return fmaxq(x, y), | 56 | 128 => return fmax_f128(x, y), |
| 45 | else => @compileError("unreachable"), | 57 | else => comptime unreachable, |
| 46 | } | 58 | } |
| 47 | } | 59 | } |
| 48 | 60 |
lib/compiler_rt/fmin.zig+25-13| ... | @@ -10,39 +10,51 @@ comptime { | ... | @@ -10,39 +10,51 @@ comptime { |
| 10 | symbol(&fminf, "fminf"); | 10 | symbol(&fminf, "fminf"); |
| 11 | symbol(&fmin, "fmin"); | 11 | symbol(&fmin, "fmin"); |
| 12 | symbol(&__fminx, "__fminx"); | 12 | symbol(&__fminx, "__fminx"); |
| 13 | if (compiler_rt.want_ppc_abi) { | 13 | symbol(&fminq, "fminf128"); |
| 14 | symbol(&fminq, "fminf128"); | ||
| 15 | } | ||
| 16 | symbol(&fminq, "fminq"); | ||
| 17 | symbol(&fminl, "fminl"); | 14 | symbol(&fminl, "fminl"); |
| 18 | } | 15 | } |
| 19 | 16 | ||
| 20 | pub fn __fminh(x: f16, y: f16) callconv(.c) f16 { | 17 | fn __fminh(x: compiler_rt.f16.Abi, y: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { |
| 18 | return compiler_rt.f16.toAbi(fmin_f16(compiler_rt.f16.fromAbi(x), compiler_rt.f16.fromAbi(y))); | ||
| 19 | } | ||
| 20 | pub fn fmin_f16(x: f16, y: f16) f16 { | ||
| 21 | return generic_fmin(f16, x, y); | 21 | return generic_fmin(f16, x, y); |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | pub fn fminf(x: f32, y: f32) callconv(.c) f32 { | 24 | fn fminf(x: compiler_rt.f32.Abi, y: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { |
| 25 | return compiler_rt.f32.toAbi(fmin_f32(compiler_rt.f32.fromAbi(x), compiler_rt.f32.fromAbi(y))); | ||
| 26 | } | ||
| 27 | pub fn fmin_f32(x: f32, y: f32) f32 { | ||
| 25 | return generic_fmin(f32, x, y); | 28 | return generic_fmin(f32, x, y); |
| 26 | } | 29 | } |
| 27 | 30 | ||
| 28 | pub fn fmin(x: f64, y: f64) callconv(.c) f64 { | 31 | fn fmin(x: compiler_rt.f64.Abi, y: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { |
| 32 | return compiler_rt.f64.toAbi(fmin_f64(compiler_rt.f64.fromAbi(x), compiler_rt.f64.fromAbi(y))); | ||
| 33 | } | ||
| 34 | pub fn fmin_f64(x: f64, y: f64) f64 { | ||
| 29 | return generic_fmin(f64, x, y); | 35 | return generic_fmin(f64, x, y); |
| 30 | } | 36 | } |
| 31 | 37 | ||
| 32 | pub fn __fminx(x: f80, y: f80) callconv(.c) f80 { | 38 | fn __fminx(x: compiler_rt.f80.Abi, y: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { |
| 39 | return compiler_rt.f80.toAbi(fmin_f80(compiler_rt.f80.fromAbi(x), compiler_rt.f80.fromAbi(y))); | ||
| 40 | } | ||
| 41 | pub fn fmin_f80(x: f80, y: f80) f80 { | ||
| 33 | return generic_fmin(f80, x, y); | 42 | return generic_fmin(f80, x, y); |
| 34 | } | 43 | } |
| 35 | 44 | ||
| 36 | pub fn fminq(x: f128, y: f128) callconv(.c) f128 { | 45 | fn fminq(x: compiler_rt.f128.Abi, y: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { |
| 46 | return compiler_rt.f128.toAbi(fmin_f128(compiler_rt.f128.fromAbi(x), compiler_rt.f128.fromAbi(y))); | ||
| 47 | } | ||
| 48 | pub fn fmin_f128(x: f128, y: f128) f128 { | ||
| 37 | return generic_fmin(f128, x, y); | 49 | return generic_fmin(f128, x, y); |
| 38 | } | 50 | } |
| 39 | 51 | ||
| 40 | pub fn fminl(x: c_longdouble, y: c_longdouble) callconv(.c) c_longdouble { | 52 | pub fn fminl(x: c_longdouble, y: c_longdouble) callconv(.c) c_longdouble { |
| 41 | switch (@typeInfo(c_longdouble).float.bits) { | 53 | switch (@typeInfo(c_longdouble).float.bits) { |
| 42 | 64 => return fmin(x, y), | 54 | 64 => return fmin_f64(x, y), |
| 43 | 80 => return __fminx(x, y), | 55 | 80 => return fmin_f80(x, y), |
| 44 | 128 => return fminq(x, y), | 56 | 128 => return fmin_f128(x, y), |
| 45 | else => @compileError("unreachable"), | 57 | else => comptime unreachable, |
| 46 | } | 58 | } |
| 47 | } | 59 | } |
| 48 | 60 |
lib/compiler_rt/fmod.zig+50-38| ... | @@ -12,29 +12,38 @@ comptime { | ... | @@ -12,29 +12,38 @@ comptime { |
| 12 | symbol(&fmodf, "fmodf"); | 12 | symbol(&fmodf, "fmodf"); |
| 13 | symbol(&fmod, "fmod"); | 13 | symbol(&fmod, "fmod"); |
| 14 | symbol(&__fmodx, "__fmodx"); | 14 | symbol(&__fmodx, "__fmodx"); |
| 15 | if (compiler_rt.want_ppc_abi) { | 15 | symbol(&fmodq, "fmodf128"); |
| 16 | symbol(&fmodq, "fmodf128"); | ||
| 17 | } | ||
| 18 | symbol(&fmodq, "fmodq"); | ||
| 19 | symbol(&fmodl, "fmodl"); | 16 | symbol(&fmodl, "fmodl"); |
| 20 | } | 17 | } |
| 21 | 18 | ||
| 22 | pub fn __fmodh(x: f16, y: f16) callconv(.c) f16 { | 19 | fn __fmodh(a: compiler_rt.f16.Abi, b: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { |
| 20 | return compiler_rt.f16.toAbi(fmod_f16(compiler_rt.f16.fromAbi(a), compiler_rt.f16.fromAbi(b))); | ||
| 21 | } | ||
| 22 | pub fn fmod_f16(x: f16, y: f16) f16 { | ||
| 23 | // TODO: more efficient implementation | 23 | // TODO: more efficient implementation |
| 24 | return @floatCast(fmodf(x, y)); | 24 | return @floatCast(fmod_f32(x, y)); |
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | pub fn fmodf(x: f32, y: f32) callconv(.c) f32 { | 27 | fn fmodf(a: compiler_rt.f32.Abi, b: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { |
| 28 | return compiler_rt.f32.toAbi(fmod_f32(compiler_rt.f32.fromAbi(a), compiler_rt.f32.fromAbi(b))); | ||
| 29 | } | ||
| 30 | pub fn fmod_f32(x: f32, y: f32) f32 { | ||
| 28 | return generic_fmod(f32, x, y); | 31 | return generic_fmod(f32, x, y); |
| 29 | } | 32 | } |
| 30 | 33 | ||
| 31 | pub fn fmod(x: f64, y: f64) callconv(.c) f64 { | 34 | fn fmod(a: compiler_rt.f64.Abi, b: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { |
| 35 | return compiler_rt.f64.toAbi(fmod_f64(compiler_rt.f64.fromAbi(a), compiler_rt.f64.fromAbi(b))); | ||
| 36 | } | ||
| 37 | pub fn fmod_f64(x: f64, y: f64) f64 { | ||
| 32 | return generic_fmod(f64, x, y); | 38 | return generic_fmod(f64, x, y); |
| 33 | } | 39 | } |
| 34 | 40 | ||
| 41 | fn __fmodx(a: compiler_rt.f80.Abi, b: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { | ||
| 42 | return compiler_rt.f80.toAbi(fmod_f80(compiler_rt.f80.fromAbi(a), compiler_rt.f80.fromAbi(b))); | ||
| 43 | } | ||
| 35 | /// fmodx - floating modulo large, returns the remainder of division for f80 types | 44 | /// fmodx - floating modulo large, returns the remainder of division for f80 types |
| 36 | /// Logic and flow heavily inspired by MUSL fmodl for 113 mantissa digits | 45 | /// Logic and flow heavily inspired by MUSL fmodl for 113 mantissa digits |
| 37 | pub fn __fmodx(a: f80, b: f80) callconv(.c) f80 { | 46 | pub fn fmod_f80(a: f80, b: f80) f80 { |
| 38 | const T = f80; | 47 | const T = f80; |
| 39 | const Z = @Int(.unsigned, @bitSizeOf(T)); | 48 | const Z = @Int(.unsigned, @bitSizeOf(T)); |
| 40 | 49 | ||
| ... | @@ -130,9 +139,12 @@ pub fn __fmodx(a: f80, b: f80) callconv(.c) f80 { | ... | @@ -130,9 +139,12 @@ pub fn __fmodx(a: f80, b: f80) callconv(.c) f80 { |
| 130 | } | 139 | } |
| 131 | } | 140 | } |
| 132 | 141 | ||
| 142 | fn fmodq(a: compiler_rt.f128.Abi, b: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { | ||
| 143 | return compiler_rt.f128.toAbi(fmod_f128(compiler_rt.f128.fromAbi(a), compiler_rt.f128.fromAbi(b))); | ||
| 144 | } | ||
| 133 | /// fmodq - floating modulo large, returns the remainder of division for f128 types | 145 | /// fmodq - floating modulo large, returns the remainder of division for f128 types |
| 134 | /// Logic and flow heavily inspired by MUSL fmodl for 113 mantissa digits | 146 | /// Logic and flow heavily inspired by MUSL fmodl for 113 mantissa digits |
| 135 | pub fn fmodq(a: f128, b: f128) callconv(.c) f128 { | 147 | pub fn fmod_f128(a: f128, b: f128) f128 { |
| 136 | var amod = a; | 148 | var amod = a; |
| 137 | var bmod = b; | 149 | var bmod = b; |
| 138 | const aPtr_u64: [*]u64 = @ptrCast(&amod); | 150 | const aPtr_u64: [*]u64 = @ptrCast(&amod); |
| ... | @@ -251,10 +263,10 @@ pub fn fmodq(a: f128, b: f128) callconv(.c) f128 { | ... | @@ -251,10 +263,10 @@ pub fn fmodq(a: f128, b: f128) callconv(.c) f128 { |
| 251 | 263 | ||
| 252 | pub fn fmodl(a: c_longdouble, b: c_longdouble) callconv(.c) c_longdouble { | 264 | pub fn fmodl(a: c_longdouble, b: c_longdouble) callconv(.c) c_longdouble { |
| 253 | switch (@typeInfo(c_longdouble).float.bits) { | 265 | switch (@typeInfo(c_longdouble).float.bits) { |
| 254 | 64 => return fmod(a, b), | 266 | 64 => return fmod_f64(a, b), |
| 255 | 80 => return __fmodx(a, b), | 267 | 80 => return fmod_f80(a, b), |
| 256 | 128 => return fmodq(a, b), | 268 | 128 => return fmod_f128(a, b), |
| 257 | else => @compileError("unreachable"), | 269 | else => comptime unreachable, |
| 258 | } | 270 | } |
| 259 | } | 271 | } |
| 260 | 272 | ||
| ... | @@ -342,42 +354,42 @@ inline fn generic_fmod(comptime T: type, x: T, y: T) T { | ... | @@ -342,42 +354,42 @@ inline fn generic_fmod(comptime T: type, x: T, y: T) T { |
| 342 | return @bitCast(ux); | 354 | return @bitCast(ux); |
| 343 | } | 355 | } |
| 344 | 356 | ||
| 345 | test "fmodf" { | 357 | test fmod_f32 { |
| 346 | const nan_val = math.nan(f32); | 358 | const nan_val = math.nan(f32); |
| 347 | const inf_val = math.inf(f32); | 359 | const inf_val = math.inf(f32); |
| 348 | 360 | ||
| 349 | try std.testing.expect(math.isNan(fmodf(nan_val, 1.0))); | 361 | try std.testing.expect(math.isNan(fmod_f32(nan_val, 1.0))); |
| 350 | try std.testing.expect(math.isNan(fmodf(1.0, nan_val))); | 362 | try std.testing.expect(math.isNan(fmod_f32(1.0, nan_val))); |
| 351 | try std.testing.expect(math.isNan(fmodf(inf_val, 1.0))); | 363 | try std.testing.expect(math.isNan(fmod_f32(inf_val, 1.0))); |
| 352 | try std.testing.expect(math.isNan(fmodf(0.0, 0.0))); | 364 | try std.testing.expect(math.isNan(fmod_f32(0.0, 0.0))); |
| 353 | try std.testing.expect(math.isNan(fmodf(1.0, 0.0))); | 365 | try std.testing.expect(math.isNan(fmod_f32(1.0, 0.0))); |
| 354 | 366 | ||
| 355 | try std.testing.expectEqual(@as(f32, 0.0), fmodf(0.0, 2.0)); | 367 | try std.testing.expectEqual(@as(f32, 0.0), fmod_f32(0.0, 2.0)); |
| 356 | try std.testing.expectEqual(@as(f32, -0.0), fmodf(-0.0, 2.0)); | 368 | try std.testing.expectEqual(@as(f32, -0.0), fmod_f32(-0.0, 2.0)); |
| 357 | 369 | ||
| 358 | try std.testing.expectEqual(@as(f32, -2.0), fmodf(-32.0, 10.0)); | 370 | try std.testing.expectEqual(@as(f32, -2.0), fmod_f32(-32.0, 10.0)); |
| 359 | try std.testing.expectEqual(@as(f32, -2.0), fmodf(-32.0, -10.0)); | 371 | try std.testing.expectEqual(@as(f32, -2.0), fmod_f32(-32.0, -10.0)); |
| 360 | try std.testing.expectEqual(@as(f32, 2.0), fmodf(32.0, 10.0)); | 372 | try std.testing.expectEqual(@as(f32, 2.0), fmod_f32(32.0, 10.0)); |
| 361 | try std.testing.expectEqual(@as(f32, 2.0), fmodf(32.0, -10.0)); | 373 | try std.testing.expectEqual(@as(f32, 2.0), fmod_f32(32.0, -10.0)); |
| 362 | } | 374 | } |
| 363 | 375 | ||
| 364 | test "fmod" { | 376 | test fmod_f64 { |
| 365 | const nan_val = math.nan(f64); | 377 | const nan_val = math.nan(f64); |
| 366 | const inf_val = math.inf(f64); | 378 | const inf_val = math.inf(f64); |
| 367 | 379 | ||
| 368 | try std.testing.expect(math.isNan(fmod(nan_val, 1.0))); | 380 | try std.testing.expect(math.isNan(fmod_f64(nan_val, 1.0))); |
| 369 | try std.testing.expect(math.isNan(fmod(1.0, nan_val))); | 381 | try std.testing.expect(math.isNan(fmod_f64(1.0, nan_val))); |
| 370 | try std.testing.expect(math.isNan(fmod(inf_val, 1.0))); | 382 | try std.testing.expect(math.isNan(fmod_f64(inf_val, 1.0))); |
| 371 | try std.testing.expect(math.isNan(fmod(0.0, 0.0))); | 383 | try std.testing.expect(math.isNan(fmod_f64(0.0, 0.0))); |
| 372 | try std.testing.expect(math.isNan(fmod(1.0, 0.0))); | 384 | try std.testing.expect(math.isNan(fmod_f64(1.0, 0.0))); |
| 373 | 385 | ||
| 374 | try std.testing.expectEqual(@as(f64, 0.0), fmod(0.0, 2.0)); | 386 | try std.testing.expectEqual(@as(f64, 0.0), fmod_f64(0.0, 2.0)); |
| 375 | try std.testing.expectEqual(@as(f64, -0.0), fmod(-0.0, 2.0)); | 387 | try std.testing.expectEqual(@as(f64, -0.0), fmod_f64(-0.0, 2.0)); |
| 376 | 388 | ||
| 377 | try std.testing.expectEqual(@as(f64, -2.0), fmod(-32.0, 10.0)); | 389 | try std.testing.expectEqual(@as(f64, -2.0), fmod_f64(-32.0, 10.0)); |
| 378 | try std.testing.expectEqual(@as(f64, -2.0), fmod(-32.0, -10.0)); | 390 | try std.testing.expectEqual(@as(f64, -2.0), fmod_f64(-32.0, -10.0)); |
| 379 | try std.testing.expectEqual(@as(f64, 2.0), fmod(32.0, 10.0)); | 391 | try std.testing.expectEqual(@as(f64, 2.0), fmod_f64(32.0, 10.0)); |
| 380 | try std.testing.expectEqual(@as(f64, 2.0), fmod(32.0, -10.0)); | 392 | try std.testing.expectEqual(@as(f64, 2.0), fmod_f64(32.0, -10.0)); |
| 381 | } | 393 | } |
| 382 | 394 | ||
| 383 | test { | 395 | test { |
lib/compiler_rt/fmodq_test.zig+32-32| ... | @@ -1,52 +1,52 @@ | ... | @@ -1,52 +1,52 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const fmod = @import("fmod.zig"); | 2 | const fmod_f128 = @import("fmod.zig").fmod_f128; |
| 3 | const testing = std.testing; | 3 | const testing = std.testing; |
| 4 | 4 | ||
| 5 | fn test_fmodq(a: f128, b: f128, exp: f128) !void { | 5 | fn test_fmod_f128(a: f128, b: f128, exp: f128) !void { |
| 6 | const res = fmod.fmodq(a, b); | 6 | const res = fmod_f128(a, b); |
| 7 | try testing.expect(exp == res); | 7 | try testing.expect(exp == res); |
| 8 | } | 8 | } |
| 9 | 9 | ||
| 10 | fn test_fmodq_nans() !void { | 10 | fn test_fmod_f128_nans() !void { |
| 11 | try testing.expect(std.math.isNan(fmod.fmodq(1.0, std.math.nan(f128)))); | 11 | try testing.expect(std.math.isNan(fmod_f128(1.0, std.math.nan(f128)))); |
| 12 | try testing.expect(std.math.isNan(fmod.fmodq(1.0, -std.math.nan(f128)))); | 12 | try testing.expect(std.math.isNan(fmod_f128(1.0, -std.math.nan(f128)))); |
| 13 | try testing.expect(std.math.isNan(fmod.fmodq(std.math.nan(f128), 1.0))); | 13 | try testing.expect(std.math.isNan(fmod_f128(std.math.nan(f128), 1.0))); |
| 14 | try testing.expect(std.math.isNan(fmod.fmodq(-std.math.nan(f128), 1.0))); | 14 | try testing.expect(std.math.isNan(fmod_f128(-std.math.nan(f128), 1.0))); |
| 15 | } | 15 | } |
| 16 | 16 | ||
| 17 | fn test_fmodq_infs() !void { | 17 | fn test_fmod_f128_infs() !void { |
| 18 | try testing.expect(fmod.fmodq(1.0, std.math.inf(f128)) == 1.0); | 18 | try testing.expect(fmod_f128(1.0, std.math.inf(f128)) == 1.0); |
| 19 | try testing.expect(fmod.fmodq(1.0, -std.math.inf(f128)) == 1.0); | 19 | try testing.expect(fmod_f128(1.0, -std.math.inf(f128)) == 1.0); |
| 20 | try testing.expect(std.math.isNan(fmod.fmodq(std.math.inf(f128), 1.0))); | 20 | try testing.expect(std.math.isNan(fmod_f128(std.math.inf(f128), 1.0))); |
| 21 | try testing.expect(std.math.isNan(fmod.fmodq(-std.math.inf(f128), 1.0))); | 21 | try testing.expect(std.math.isNan(fmod_f128(-std.math.inf(f128), 1.0))); |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | test "fmodq" { | 24 | test fmod_f128 { |
| 25 | try test_fmodq(6.8, 4.0, 2.8); | 25 | try test_fmod_f128(6.8, 4.0, 2.8); |
| 26 | try test_fmodq(6.8, -4.0, 2.8); | 26 | try test_fmod_f128(6.8, -4.0, 2.8); |
| 27 | try test_fmodq(-6.8, 4.0, -2.8); | 27 | try test_fmod_f128(-6.8, 4.0, -2.8); |
| 28 | try test_fmodq(-6.8, -4.0, -2.8); | 28 | try test_fmod_f128(-6.8, -4.0, -2.8); |
| 29 | try test_fmodq(3.0, 2.0, 1.0); | 29 | try test_fmod_f128(3.0, 2.0, 1.0); |
| 30 | try test_fmodq(-5.0, 3.0, -2.0); | 30 | try test_fmod_f128(-5.0, 3.0, -2.0); |
| 31 | try test_fmodq(3.0, 2.0, 1.0); | 31 | try test_fmod_f128(3.0, 2.0, 1.0); |
| 32 | try test_fmodq(1.0, 2.0, 1.0); | 32 | try test_fmod_f128(1.0, 2.0, 1.0); |
| 33 | try test_fmodq(0.0, 1.0, 0.0); | 33 | try test_fmod_f128(0.0, 1.0, 0.0); |
| 34 | try test_fmodq(-0.0, 1.0, -0.0); | 34 | try test_fmod_f128(-0.0, 1.0, -0.0); |
| 35 | try test_fmodq(7046119.0, 5558362.0, 1487757.0); | 35 | try test_fmod_f128(7046119.0, 5558362.0, 1487757.0); |
| 36 | try test_fmodq(9010357.0, 1957236.0, 1181413.0); | 36 | try test_fmod_f128(9010357.0, 1957236.0, 1181413.0); |
| 37 | try test_fmodq(5192296858534827628530496329220095, 10.0, 5.0); | 37 | try test_fmod_f128(5192296858534827628530496329220095, 10.0, 5.0); |
| 38 | try test_fmodq(5192296858534827628530496329220095, 922337203681230954775807, 220474884073715748246157); | 38 | try test_fmod_f128(5192296858534827628530496329220095, 922337203681230954775807, 220474884073715748246157); |
| 39 | 39 | ||
| 40 | // Denormals | 40 | // Denormals |
| 41 | const a1: f128 = 0xedcb34a235253948765432134674p-16494; | 41 | const a1: f128 = 0xedcb34a235253948765432134674p-16494; |
| 42 | const b1: f128 = 0x5d2e38791cfbc0737402da5a9518p-16494; | 42 | const b1: f128 = 0x5d2e38791cfbc0737402da5a9518p-16494; |
| 43 | const exp1: f128 = 0x336ec3affb2db8618e4e7d5e1c44p-16494; | 43 | const exp1: f128 = 0x336ec3affb2db8618e4e7d5e1c44p-16494; |
| 44 | try test_fmodq(a1, b1, exp1); | 44 | try test_fmod_f128(a1, b1, exp1); |
| 45 | const a2: f128 = 0x0.7654_3210_fdec_ba98_7654_3210_fdecp-16382; | 45 | const a2: f128 = 0x0.7654_3210_fdec_ba98_7654_3210_fdecp-16382; |
| 46 | const b2: f128 = 0x0.0012_fdac_bdef_1234_fdec_3222_1111p-16382; | 46 | const b2: f128 = 0x0.0012_fdac_bdef_1234_fdec_3222_1111p-16382; |
| 47 | const exp2: f128 = 0x0.0001_aecd_9d66_4a6e_67b7_d7d0_a901p-16382; | 47 | const exp2: f128 = 0x0.0001_aecd_9d66_4a6e_67b7_d7d0_a901p-16382; |
| 48 | try test_fmodq(a2, b2, exp2); | 48 | try test_fmod_f128(a2, b2, exp2); |
| 49 | 49 | ||
| 50 | try test_fmodq_nans(); | 50 | try test_fmod_f128_nans(); |
| 51 | try test_fmodq_infs(); | 51 | try test_fmod_f128_infs(); |
| 52 | } | 52 | } |
lib/compiler_rt/fmodx_test.zig+31-31| ... | @@ -1,52 +1,52 @@ | ... | @@ -1,52 +1,52 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const builtin = @import("builtin"); | 2 | const builtin = @import("builtin"); |
| 3 | const fmod = @import("fmod.zig"); | 3 | const fmod_f80 = @import("fmod.zig").fmod_f80; |
| 4 | const testing = std.testing; | 4 | const testing = std.testing; |
| 5 | 5 | ||
| 6 | fn test_fmodx(a: f80, b: f80, exp: f80) !void { | 6 | fn test_fmod_f80(a: f80, b: f80, exp: f80) !void { |
| 7 | const res = fmod.__fmodx(a, b); | 7 | const res = fmod_f80(a, b); |
| 8 | try testing.expect(exp == res); | 8 | try testing.expect(exp == res); |
| 9 | } | 9 | } |
| 10 | 10 | ||
| 11 | fn test_fmodx_nans() !void { | 11 | fn test_fmod_f80_nans() !void { |
| 12 | try testing.expect(std.math.isNan(fmod.__fmodx(1.0, std.math.nan(f80)))); | 12 | try testing.expect(std.math.isNan(fmod_f80(1.0, std.math.nan(f80)))); |
| 13 | try testing.expect(std.math.isNan(fmod.__fmodx(1.0, -std.math.nan(f80)))); | 13 | try testing.expect(std.math.isNan(fmod_f80(1.0, -std.math.nan(f80)))); |
| 14 | try testing.expect(std.math.isNan(fmod.__fmodx(std.math.nan(f80), 1.0))); | 14 | try testing.expect(std.math.isNan(fmod_f80(std.math.nan(f80), 1.0))); |
| 15 | try testing.expect(std.math.isNan(fmod.__fmodx(-std.math.nan(f80), 1.0))); | 15 | try testing.expect(std.math.isNan(fmod_f80(-std.math.nan(f80), 1.0))); |
| 16 | } | 16 | } |
| 17 | 17 | ||
| 18 | fn test_fmodx_infs() !void { | 18 | fn test_fmod_f80_infs() !void { |
| 19 | try testing.expect(fmod.__fmodx(1.0, std.math.inf(f80)) == 1.0); | 19 | try testing.expect(fmod_f80(1.0, std.math.inf(f80)) == 1.0); |
| 20 | try testing.expect(fmod.__fmodx(1.0, -std.math.inf(f80)) == 1.0); | 20 | try testing.expect(fmod_f80(1.0, -std.math.inf(f80)) == 1.0); |
| 21 | try testing.expect(std.math.isNan(fmod.__fmodx(std.math.inf(f80), 1.0))); | 21 | try testing.expect(std.math.isNan(fmod_f80(std.math.inf(f80), 1.0))); |
| 22 | try testing.expect(std.math.isNan(fmod.__fmodx(-std.math.inf(f80), 1.0))); | 22 | try testing.expect(std.math.isNan(fmod_f80(-std.math.inf(f80), 1.0))); |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | test "fmodx" { | 25 | test fmod_f80 { |
| 26 | try test_fmodx(6.4, 4.0, 2.4); | 26 | try test_fmod_f80(6.4, 4.0, 2.4); |
| 27 | try test_fmodx(6.4, -4.0, 2.4); | 27 | try test_fmod_f80(6.4, -4.0, 2.4); |
| 28 | try test_fmodx(-6.4, 4.0, -2.4); | 28 | try test_fmod_f80(-6.4, 4.0, -2.4); |
| 29 | try test_fmodx(-6.4, -4.0, -2.4); | 29 | try test_fmod_f80(-6.4, -4.0, -2.4); |
| 30 | try test_fmodx(3.0, 2.0, 1.0); | 30 | try test_fmod_f80(3.0, 2.0, 1.0); |
| 31 | try test_fmodx(-5.0, 3.0, -2.0); | 31 | try test_fmod_f80(-5.0, 3.0, -2.0); |
| 32 | try test_fmodx(3.0, 2.0, 1.0); | 32 | try test_fmod_f80(3.0, 2.0, 1.0); |
| 33 | try test_fmodx(1.0, 2.0, 1.0); | 33 | try test_fmod_f80(1.0, 2.0, 1.0); |
| 34 | try test_fmodx(0.0, 1.0, 0.0); | 34 | try test_fmod_f80(0.0, 1.0, 0.0); |
| 35 | try test_fmodx(-0.0, 1.0, -0.0); | 35 | try test_fmod_f80(-0.0, 1.0, -0.0); |
| 36 | try test_fmodx(7046119.0, 5558362.0, 1487757.0); | 36 | try test_fmod_f80(7046119.0, 5558362.0, 1487757.0); |
| 37 | try test_fmodx(9010357.0, 1957236.0, 1181413.0); | 37 | try test_fmod_f80(9010357.0, 1957236.0, 1181413.0); |
| 38 | try test_fmodx(9223372036854775807, 10.0, 7.0); | 38 | try test_fmod_f80(9223372036854775807, 10.0, 7.0); |
| 39 | 39 | ||
| 40 | // Denormals | 40 | // Denormals |
| 41 | const a1: f80 = 0x0.76e5_9a51_1a92_9ca4p-16381; | 41 | const a1: f80 = 0x0.76e5_9a51_1a92_9ca4p-16381; |
| 42 | const b1: f80 = 0x0.2e97_1c3c_8e7d_e03ap-16381; | 42 | const b1: f80 = 0x0.2e97_1c3c_8e7d_e03ap-16381; |
| 43 | const exp1: f80 = 0x0.19b7_61d7_fd96_dc30p-16381; | 43 | const exp1: f80 = 0x0.19b7_61d7_fd96_dc30p-16381; |
| 44 | try test_fmodx(a1, b1, exp1); | 44 | try test_fmod_f80(a1, b1, exp1); |
| 45 | const a2: f80 = 0x0.76e5_9a51_1a92_9ca4p-16381; | 45 | const a2: f80 = 0x0.76e5_9a51_1a92_9ca4p-16381; |
| 46 | const b2: f80 = 0x0.0e97_1c3c_8e7d_e03ap-16381; | 46 | const b2: f80 = 0x0.0e97_1c3c_8e7d_e03ap-16381; |
| 47 | const exp2: f80 = 0x0.022c_b86c_a6a3_9ad4p-16381; | 47 | const exp2: f80 = 0x0.022c_b86c_a6a3_9ad4p-16381; |
| 48 | try test_fmodx(a2, b2, exp2); | 48 | try test_fmod_f80(a2, b2, exp2); |
| 49 | 49 | ||
| 50 | try test_fmodx_nans(); | 50 | try test_fmod_f80_nans(); |
| 51 | try test_fmodx_infs(); | 51 | try test_fmod_f80_infs(); |
| 52 | } | 52 | } |
lib/compiler_rt/gedf2.zig deleted-35| ... | @@ -1,35 +0,0 @@ | ||
| 1 | ///! The quoted behavior definitions are from | ||
| 2 | ///! https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gccint/Soft-float-library-routines.html#Soft-float-library-routines | ||
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 4 | const comparef = @import("./comparef.zig"); | ||
| 5 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 6 | |||
| 7 | comptime { | ||
| 8 | if (compiler_rt.want_aeabi) { | ||
| 9 | symbol(&__aeabi_dcmpge, "__aeabi_dcmpge"); | ||
| 10 | symbol(&__aeabi_dcmpgt, "__aeabi_dcmpgt"); | ||
| 11 | } else { | ||
| 12 | symbol(&__gedf2, "__gedf2"); | ||
| 13 | symbol(&__gtdf2, "__gtdf2"); | ||
| 14 | } | ||
| 15 | } | ||
| 16 | |||
| 17 | /// "These functions return a value greater than or equal to zero if neither | ||
| 18 | /// argument is NaN, and a is greater than or equal to b." | ||
| 19 | pub fn __gedf2(a: f64, b: f64) callconv(.c) i32 { | ||
| 20 | return @backingInt(comparef.cmpf2(f64, comparef.GE, a, b)); | ||
| 21 | } | ||
| 22 | |||
| 23 | /// "These functions return a value greater than zero if neither argument is NaN, | ||
| 24 | /// and a is strictly greater than b." | ||
| 25 | pub fn __gtdf2(a: f64, b: f64) callconv(.c) i32 { | ||
| 26 | return __gedf2(a, b); | ||
| 27 | } | ||
| 28 | |||
| 29 | fn __aeabi_dcmpge(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { | ||
| 30 | return @intFromBool(comparef.cmpf2(f64, comparef.GE, a, b) != .Less); | ||
| 31 | } | ||
| 32 | |||
| 33 | fn __aeabi_dcmpgt(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { | ||
| 34 | return @intFromBool(comparef.cmpf2(f64, comparef.GE, a, b) == .Greater); | ||
| 35 | } | ||
lib/compiler_rt/gehf2.zig deleted-21| ... | @@ -1,21 +0,0 @@ | ||
| 1 | ///! The quoted behavior definitions are from | ||
| 2 | ///! https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gccint/Soft-float-library-routines.html#Soft-float-library-routines | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | const comparef = @import("./comparef.zig"); | ||
| 5 | |||
| 6 | comptime { | ||
| 7 | symbol(&__gehf2, "__gehf2"); | ||
| 8 | symbol(&__gthf2, "__gthf2"); | ||
| 9 | } | ||
| 10 | |||
| 11 | /// "These functions return a value greater than or equal to zero if neither | ||
| 12 | /// argument is NaN, and a is greater than or equal to b." | ||
| 13 | pub fn __gehf2(a: f16, b: f16) callconv(.c) i32 { | ||
| 14 | return @backingInt(comparef.cmpf2(f16, comparef.GE, a, b)); | ||
| 15 | } | ||
| 16 | |||
| 17 | /// "These functions return a value greater than zero if neither argument is NaN, | ||
| 18 | /// and a is strictly greater than b." | ||
| 19 | pub fn __gthf2(a: f16, b: f16) callconv(.c) i32 { | ||
| 20 | return __gehf2(a, b); | ||
| 21 | } | ||
lib/compiler_rt/gesf2.zig deleted-35| ... | @@ -1,35 +0,0 @@ | ||
| 1 | ///! The quoted behavior definitions are from | ||
| 2 | ///! https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gccint/Soft-float-library-routines.html#Soft-float-library-routines | ||
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 4 | const symbol = compiler_rt.symbol; | ||
| 5 | const comparef = @import("./comparef.zig"); | ||
| 6 | |||
| 7 | comptime { | ||
| 8 | if (compiler_rt.want_aeabi) { | ||
| 9 | symbol(&__aeabi_fcmpge, "__aeabi_fcmpge"); | ||
| 10 | symbol(&__aeabi_fcmpgt, "__aeabi_fcmpgt"); | ||
| 11 | } else { | ||
| 12 | symbol(&__gesf2, "__gesf2"); | ||
| 13 | symbol(&__gtsf2, "__gtsf2"); | ||
| 14 | } | ||
| 15 | } | ||
| 16 | |||
| 17 | /// "These functions return a value greater than or equal to zero if neither | ||
| 18 | /// argument is NaN, and a is greater than or equal to b." | ||
| 19 | pub fn __gesf2(a: f32, b: f32) callconv(.c) i32 { | ||
| 20 | return @backingInt(comparef.cmpf2(f32, comparef.GE, a, b)); | ||
| 21 | } | ||
| 22 | |||
| 23 | /// "These functions return a value greater than zero if neither argument is NaN, | ||
| 24 | /// and a is strictly greater than b." | ||
| 25 | pub fn __gtsf2(a: f32, b: f32) callconv(.c) i32 { | ||
| 26 | return __gesf2(a, b); | ||
| 27 | } | ||
| 28 | |||
| 29 | fn __aeabi_fcmpge(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 { | ||
| 30 | return @intFromBool(comparef.cmpf2(f32, comparef.GE, a, b) != .Less); | ||
| 31 | } | ||
| 32 | |||
| 33 | fn __aeabi_fcmpgt(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 { | ||
| 34 | return @intFromBool(comparef.cmpf2(f32, comparef.LE, a, b) == .Greater); | ||
| 35 | } | ||
lib/compiler_rt/getf2.zig deleted-26| ... | @@ -1,26 +0,0 @@ | ||
| 1 | ///! The quoted behavior definitions are from | ||
| 2 | ///! https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gccint/Soft-float-library-routines.html#Soft-float-library-routines | ||
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 4 | const symbol = compiler_rt.symbol; | ||
| 5 | const comparef = @import("./comparef.zig"); | ||
| 6 | |||
| 7 | comptime { | ||
| 8 | if (compiler_rt.want_ppc_abi) { | ||
| 9 | symbol(&__getf2, "__gekf2"); | ||
| 10 | symbol(&__gttf2, "__gtkf2"); | ||
| 11 | } | ||
| 12 | symbol(&__getf2, "__getf2"); | ||
| 13 | symbol(&__gttf2, "__gttf2"); | ||
| 14 | } | ||
| 15 | |||
| 16 | /// "These functions return a value greater than or equal to zero if neither | ||
| 17 | /// argument is NaN, and a is greater than or equal to b." | ||
| 18 | fn __getf2(a: f128, b: f128) callconv(.c) i32 { | ||
| 19 | return @backingInt(comparef.cmpf2(f128, comparef.GE, a, b)); | ||
| 20 | } | ||
| 21 | |||
| 22 | /// "These functions return a value greater than zero if neither argument is NaN, | ||
| 23 | /// and a is strictly greater than b." | ||
| 24 | fn __gttf2(a: f128, b: f128) callconv(.c) i32 { | ||
| 25 | return __getf2(a, b); | ||
| 26 | } | ||
lib/compiler_rt/gexf2.zig deleted-15| ... | @@ -1,15 +0,0 @@ | ||
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 2 | const comparef = @import("./comparef.zig"); | ||
| 3 | |||
| 4 | comptime { | ||
| 5 | symbol(&__gexf2, "__gexf2"); | ||
| 6 | symbol(&__gtxf2, "__gtxf2"); | ||
| 7 | } | ||
| 8 | |||
| 9 | fn __gexf2(a: f80, b: f80) callconv(.c) i32 { | ||
| 10 | return @backingInt(comparef.cmp_f80(comparef.GE, a, b)); | ||
| 11 | } | ||
| 12 | |||
| 13 | fn __gtxf2(a: f80, b: f80) callconv(.c) i32 { | ||
| 14 | return __gexf2(a, b); | ||
| 15 | } | ||
lib/compiler_rt/int.zig+39-40| ... | @@ -36,7 +36,7 @@ comptime { | ... | @@ -36,7 +36,7 @@ comptime { |
| 36 | 36 | ||
| 37 | pub fn __divmodti4(a: i128, b: i128, rem: *i128) callconv(.c) i128 { | 37 | pub fn __divmodti4(a: i128, b: i128, rem: *i128) callconv(.c) i128 { |
| 38 | const d = __divti3(a, b); | 38 | const d = __divti3(a, b); |
| 39 | rem.* = a -% (d * b); | 39 | rem.* = a - d *% b; |
| 40 | return d; | 40 | return d; |
| 41 | } | 41 | } |
| 42 | 42 | ||
| ... | @@ -69,7 +69,7 @@ fn test_one_divmodti4(a: i128, b: i128, expected_q: i128, expected_r: i128) !voi | ... | @@ -69,7 +69,7 @@ fn test_one_divmodti4(a: i128, b: i128, expected_q: i128, expected_r: i128) !voi |
| 69 | 69 | ||
| 70 | pub fn __divmoddi4(a: i64, b: i64, rem: *i64) callconv(.c) i64 { | 70 | pub fn __divmoddi4(a: i64, b: i64, rem: *i64) callconv(.c) i64 { |
| 71 | const d = __divdi3(a, b); | 71 | const d = __divdi3(a, b); |
| 72 | rem.* = a -% (d * b); | 72 | rem.* = a - d *% b; |
| 73 | return d; | 73 | return d; |
| 74 | } | 74 | } |
| 75 | 75 | ||
| ... | @@ -79,21 +79,20 @@ fn test_one_divmoddi4(a: i64, b: i64, expected_q: i64, expected_r: i64) !void { | ... | @@ -79,21 +79,20 @@ fn test_one_divmoddi4(a: i64, b: i64, expected_q: i64, expected_r: i64) !void { |
| 79 | try testing.expect(q == expected_q and r == expected_r); | 79 | try testing.expect(q == expected_q and r == expected_r); |
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | const cases__divmoddi4 = | 82 | const cases__divmoddi4 = [_][4]i64{ |
| 83 | [_][4]i64{ | 83 | [_]i64{ 0, 1, 0, 0 }, |
| 84 | [_]i64{ 0, 1, 0, 0 }, | 84 | [_]i64{ 0, -1, 0, 0 }, |
| 85 | [_]i64{ 0, -1, 0, 0 }, | 85 | [_]i64{ 2, 1, 2, 0 }, |
| 86 | [_]i64{ 2, 1, 2, 0 }, | 86 | [_]i64{ 2, -1, -2, 0 }, |
| 87 | [_]i64{ 2, -1, -2, 0 }, | 87 | [_]i64{ -2, 1, -2, 0 }, |
| 88 | [_]i64{ -2, 1, -2, 0 }, | 88 | [_]i64{ -2, -1, 2, 0 }, |
| 89 | [_]i64{ -2, -1, 2, 0 }, | 89 | [_]i64{ 7, 5, 1, 2 }, |
| 90 | [_]i64{ 7, 5, 1, 2 }, | 90 | [_]i64{ -7, 5, -1, -2 }, |
| 91 | [_]i64{ -7, 5, -1, -2 }, | 91 | [_]i64{ 19, 5, 3, 4 }, |
| 92 | [_]i64{ 19, 5, 3, 4 }, | 92 | [_]i64{ 19, -5, -3, 4 }, |
| 93 | [_]i64{ 19, -5, -3, 4 }, | 93 | [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 8, @as(i64, @bitCast(@as(u64, 0xf000000000000000))), 0 }, |
| 94 | [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 8, @as(i64, @bitCast(@as(u64, 0xf000000000000000))), 0 }, | 94 | [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000007))), 8, @as(i64, @bitCast(@as(u64, 0xf000000000000001))), -1 }, |
| 95 | [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000007))), 8, @as(i64, @bitCast(@as(u64, 0xf000000000000001))), -1 }, | 95 | }; |
| 96 | }; | ||
| 97 | 96 | ||
| 98 | test "test_divmoddi4" { | 97 | test "test_divmoddi4" { |
| 99 | for (cases__divmoddi4) |case| { | 98 | for (cases__divmoddi4) |case| { |
| ... | @@ -105,10 +104,6 @@ pub fn __udivmoddi4(a: u64, b: u64, maybe_rem: ?*u64) callconv(.c) u64 { | ... | @@ -105,10 +104,6 @@ pub fn __udivmoddi4(a: u64, b: u64, maybe_rem: ?*u64) callconv(.c) u64 { |
| 105 | return udivmod(u64, a, b, maybe_rem); | 104 | return udivmod(u64, a, b, maybe_rem); |
| 106 | } | 105 | } |
| 107 | 106 | ||
| 108 | test "test_udivmoddi4" { | ||
| 109 | _ = @import("udivmoddi4_test.zig"); | ||
| 110 | } | ||
| 111 | |||
| 112 | pub fn __divdi3(a: i64, b: i64) callconv(.c) i64 { | 107 | pub fn __divdi3(a: i64, b: i64) callconv(.c) i64 { |
| 113 | // Set aside the sign of the quotient. | 108 | // Set aside the sign of the quotient. |
| 114 | const sign: u64 = @bitCast((a ^ b) >> 63); | 109 | const sign: u64 = @bitCast((a ^ b) >> 63); |
| ... | @@ -209,25 +204,24 @@ fn test_one_umoddi3(a: u64, b: u64, expected_r: u64) !void { | ... | @@ -209,25 +204,24 @@ fn test_one_umoddi3(a: u64, b: u64, expected_r: u64) !void { |
| 209 | 204 | ||
| 210 | pub fn __divmodsi4(a: i32, b: i32, rem: *i32) callconv(.c) i32 { | 205 | pub fn __divmodsi4(a: i32, b: i32, rem: *i32) callconv(.c) i32 { |
| 211 | const d = __divsi3(a, b); | 206 | const d = __divsi3(a, b); |
| 212 | rem.* = a -% (d * b); | 207 | rem.* = a - d *% b; |
| 213 | return d; | 208 | return d; |
| 214 | } | 209 | } |
| 215 | 210 | ||
| 216 | const cases__divmodsi4 = | 211 | const cases__divmodsi4 = [_][4]i32{ |
| 217 | [_][4]i32{ | 212 | [_]i32{ 0, 1, 0, 0 }, |
| 218 | [_]i32{ 0, 1, 0, 0 }, | 213 | [_]i32{ 0, -1, 0, 0 }, |
| 219 | [_]i32{ 0, -1, 0, 0 }, | 214 | [_]i32{ 2, 1, 2, 0 }, |
| 220 | [_]i32{ 2, 1, 2, 0 }, | 215 | [_]i32{ 2, -1, -2, 0 }, |
| 221 | [_]i32{ 2, -1, -2, 0 }, | 216 | [_]i32{ -2, 1, -2, 0 }, |
| 222 | [_]i32{ -2, 1, -2, 0 }, | 217 | [_]i32{ -2, -1, 2, 0 }, |
| 223 | [_]i32{ -2, -1, 2, 0 }, | 218 | [_]i32{ 7, 5, 1, 2 }, |
| 224 | [_]i32{ 7, 5, 1, 2 }, | 219 | [_]i32{ -7, 5, -1, -2 }, |
| 225 | [_]i32{ -7, 5, -1, -2 }, | 220 | [_]i32{ 19, 5, 3, 4 }, |
| 226 | [_]i32{ 19, 5, 3, 4 }, | 221 | [_]i32{ 19, -5, -3, 4 }, |
| 227 | [_]i32{ 19, -5, -3, 4 }, | 222 | [_]i32{ @bitCast(@as(u32, 0x80000000)), 8, @bitCast(@as(u32, 0xf0000000)), 0 }, |
| 228 | [_]i32{ @bitCast(@as(u32, 0x80000000)), 8, @bitCast(@as(u32, 0xf0000000)), 0 }, | 223 | [_]i32{ @bitCast(@as(u32, 0x80000007)), 8, @bitCast(@as(u32, 0xf0000001)), -1 }, |
| 229 | [_]i32{ @bitCast(@as(u32, 0x80000007)), 8, @bitCast(@as(u32, 0xf0000001)), -1 }, | 224 | }; |
| 230 | }; | ||
| 231 | 225 | ||
| 232 | fn test_one_divmodsi4(a: i32, b: i32, expected_q: i32, expected_r: i32) !void { | 226 | fn test_one_divmodsi4(a: i32, b: i32, expected_q: i32, expected_r: i32) !void { |
| 233 | var r: i32 = undefined; | 227 | var r: i32 = undefined; |
| ... | @@ -243,7 +237,7 @@ test "test_divmodsi4" { | ... | @@ -243,7 +237,7 @@ test "test_divmodsi4" { |
| 243 | 237 | ||
| 244 | pub fn __udivmodsi4(a: u32, b: u32, rem: *u32) callconv(.c) u32 { | 238 | pub fn __udivmodsi4(a: u32, b: u32, rem: *u32) callconv(.c) u32 { |
| 245 | const d = __udivsi3(a, b); | 239 | const d = __udivsi3(a, b); |
| 246 | rem.* = @bitCast(@as(i32, @bitCast(a)) -% (@as(i32, @bitCast(d)) * @as(i32, @bitCast(b)))); | 240 | rem.* = a - d * b; |
| 247 | return d; | 241 | return d; |
| 248 | } | 242 | } |
| 249 | 243 | ||
| ... | @@ -486,7 +480,7 @@ fn test_one_udivsi3(a: u32, b: u32, expected_q: u32) !void { | ... | @@ -486,7 +480,7 @@ fn test_one_udivsi3(a: u32, b: u32, expected_q: u32) !void { |
| 486 | } | 480 | } |
| 487 | 481 | ||
| 488 | pub fn __modsi3(n: i32, d: i32) callconv(.c) i32 { | 482 | pub fn __modsi3(n: i32, d: i32) callconv(.c) i32 { |
| 489 | return n -% __divsi3(n, d) * d; | 483 | return n - __divsi3(n, d) *% d; |
| 490 | } | 484 | } |
| 491 | 485 | ||
| 492 | test "test_modsi3" { | 486 | test "test_modsi3" { |
| ... | @@ -515,7 +509,7 @@ fn test_one_modsi3(a: i32, b: i32, expected_r: i32) !void { | ... | @@ -515,7 +509,7 @@ fn test_one_modsi3(a: i32, b: i32, expected_r: i32) !void { |
| 515 | } | 509 | } |
| 516 | 510 | ||
| 517 | pub fn __umodsi3(n: u32, d: u32) callconv(.c) u32 { | 511 | pub fn __umodsi3(n: u32, d: u32) callconv(.c) u32 { |
| 518 | return n -% __udivsi3(n, d) * d; | 512 | return n - __udivsi3(n, d) * d; |
| 519 | } | 513 | } |
| 520 | 514 | ||
| 521 | test "test_umodsi3" { | 515 | test "test_umodsi3" { |
| ... | @@ -663,3 +657,8 @@ fn test_one_umodsi3(a: u32, b: u32, expected_r: u32) !void { | ... | @@ -663,3 +657,8 @@ fn test_one_umodsi3(a: u32, b: u32, expected_r: u32) !void { |
| 663 | const r: u32 = __umodsi3(a, b); | 657 | const r: u32 = __umodsi3(a, b); |
| 664 | try testing.expect(r == expected_r); | 658 | try testing.expect(r == expected_r); |
| 665 | } | 659 | } |
| 660 | |||
| 661 | test { | ||
| 662 | _ = @import("udivmodsi4_test.zig"); | ||
| 663 | _ = @import("udivmoddi4_test.zig"); | ||
| 664 | } |
lib/compiler_rt/int_from_float.zig+513-9| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 1 | const std = @import("std"); | 2 | const std = @import("std"); |
| 2 | const math = std.math; | 3 | const math = std.math; |
| 3 | const Log2Int = std.math.Log2Int; | 4 | const Log2Int = std.math.Log2Int; |
| ... | @@ -6,29 +7,532 @@ const compiler_rt = @import("../compiler_rt.zig"); | ... | @@ -6,29 +7,532 @@ const compiler_rt = @import("../compiler_rt.zig"); |
| 6 | const symbol = compiler_rt.symbol; | 7 | const symbol = compiler_rt.symbol; |
| 7 | 8 | ||
| 8 | comptime { | 9 | comptime { |
| 9 | symbol(&__fixxfti, "__fixxfti"); | ||
| 10 | symbol(&__fixhfsi, "__fixhfsi"); | 10 | symbol(&__fixhfsi, "__fixhfsi"); |
| 11 | symbol(&__fixhfdi, "__fixhfdi"); | 11 | symbol(&__fixhfdi, "__fixhfdi"); |
| 12 | symbol(&__fixhfti, "__fixhfti"); | 12 | symbol(&__fixhfti, "__fixhfti"); |
| 13 | symbol(&__fixhfei, "__fixhfei"); | ||
| 14 | |||
| 15 | if (compiler_rt.want_aeabi) { | ||
| 16 | symbol(&__aeabi_f2iz, "__aeabi_f2iz"); | ||
| 17 | symbol(&__aeabi_f2lz, "__aeabi_f2lz"); | ||
| 18 | symbol(&__aeabi_fixsfti, "__fixsfti"); | ||
| 19 | } else { | ||
| 20 | symbol(&__fixsfsi, "__fixsfsi"); | ||
| 21 | symbol(&__fixsfdi, "__fixsfdi"); | ||
| 22 | if (compiler_rt.want_windows_arm_abi) symbol(&__fixsfdi, "__stoi64"); | ||
| 23 | symbol(&__fixsfti, "__fixsfti"); | ||
| 24 | } | ||
| 25 | symbol(&__fixsfei, "__fixsfei"); | ||
| 26 | |||
| 27 | if (compiler_rt.want_aeabi) { | ||
| 28 | symbol(&__aeabi_d2iz, "__aeabi_d2iz"); | ||
| 29 | symbol(&__aeabi_d2lz, "__aeabi_d2lz"); | ||
| 30 | symbol(&__aeabi_fixdfti, "__fixdfti"); | ||
| 31 | } else { | ||
| 32 | symbol(&__fixdfsi, "__fixdfsi"); | ||
| 33 | symbol(&__fixdfdi, "__fixdfdi"); | ||
| 34 | if (compiler_rt.want_windows_arm_abi) symbol(&__fixdfdi, "__dtoi64"); | ||
| 35 | symbol(&__fixdfti, "__fixdfti"); | ||
| 36 | } | ||
| 37 | symbol(&__fixdfei, "__fixdfei"); | ||
| 38 | |||
| 39 | symbol(&__fixxfsi, "__fixxfsi"); | ||
| 40 | symbol(&__fixxfdi, "__fixxfdi"); | ||
| 41 | symbol(&__fixxfti, "__fixxfti"); | ||
| 42 | symbol(&__fixxfei, "__fixxfei"); | ||
| 43 | |||
| 44 | if (compiler_rt.want_ppc_abi) { | ||
| 45 | symbol(&__fixtfsi, "__fixkfsi"); | ||
| 46 | symbol(&__fixtfdi, "__fixkfdi"); | ||
| 47 | } else if (compiler_rt.want_sparc64_abi) { | ||
| 48 | symbol(&_Qp_qtoi, "_Qp_qtoi"); | ||
| 49 | symbol(&_Qp_qtox, "_Qp_qtox"); | ||
| 50 | } else if (compiler_rt.want_sparc32_abi) { | ||
| 51 | symbol(&__fixtfsi, "_Q_qtoi"); | ||
| 52 | symbol(&__fixtfdi, "_Q_qtoll"); | ||
| 53 | } else { | ||
| 54 | symbol(&__fixtfsi, "__fixtfsi"); | ||
| 55 | symbol(&__fixtfdi, "__fixtfdi"); | ||
| 56 | } | ||
| 57 | if (compiler_rt.want_ppc_abi) { | ||
| 58 | symbol(&__fixtfti, "__fixkfti"); | ||
| 59 | symbol(&__fixtfei, "__fixkfei"); | ||
| 60 | } else { | ||
| 61 | symbol(&__fixtfti, "__fixtfti"); | ||
| 62 | symbol(&__fixtfei, "__fixtfei"); | ||
| 63 | } | ||
| 64 | } | ||
| 65 | |||
| 66 | fn __fixhfsi(a: compiler_rt.f16.Abi) callconv(.c) i32 { | ||
| 67 | return i32_intFromFloat_f16(compiler_rt.f16.fromAbi(a)); | ||
| 68 | } | ||
| 69 | pub fn i32_intFromFloat_f16(a: f16) i32 { | ||
| 70 | return intFromFloat(i32, a); | ||
| 71 | } | ||
| 72 | |||
| 73 | fn __fixhfdi(a: compiler_rt.f16.Abi) callconv(.c) i64 { | ||
| 74 | return i64_intFromFloat_f16(compiler_rt.f16.fromAbi(a)); | ||
| 75 | } | ||
| 76 | pub fn i64_intFromFloat_f16(a: f16) i64 { | ||
| 77 | return intFromFloat(i64, a); | ||
| 78 | } | ||
| 79 | |||
| 80 | fn __fixhfti(a: compiler_rt.f16.Abi) callconv(.c) i128 { | ||
| 81 | return i128_intFromFloat_f16(compiler_rt.f16.fromAbi(a)); | ||
| 82 | } | ||
| 83 | pub fn i128_intFromFloat_f16(a: f16) i128 { | ||
| 84 | return intFromFloat(i128, a); | ||
| 85 | } | ||
| 86 | |||
| 87 | fn __fixhfei(r: [*]u8, bits: usize, a: compiler_rt.f16.Abi) callconv(.c) void { | ||
| 88 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | ||
| 89 | return signed_intFromFloat_f16(r[0..byte_size], compiler_rt.f16.fromAbi(a)); | ||
| 90 | } | ||
| 91 | pub fn signed_intFromFloat_f16(result: []u8, a: f16) void { | ||
| 92 | bigIntFromFloat(.signed, @ptrCast(@alignCast(result)), a); | ||
| 93 | } | ||
| 94 | |||
| 95 | fn __fixsfsi(a: compiler_rt.f32.Abi) callconv(.c) i32 { | ||
| 96 | return i32_intFromFloat_f32(compiler_rt.f32.fromAbi(a)); | ||
| 97 | } | ||
| 98 | fn __aeabi_f2iz(a: f32) callconv(.{ .arm_aapcs = .{} }) i32 { | ||
| 99 | return i32_intFromFloat_f32(a); | ||
| 100 | } | ||
| 101 | pub fn i32_intFromFloat_f32(a: f32) i32 { | ||
| 102 | return intFromFloat(i32, a); | ||
| 103 | } | ||
| 104 | |||
| 105 | fn __fixsfdi(a: compiler_rt.f32.Abi) callconv(.c) i64 { | ||
| 106 | return i64_intFromFloat_f32(compiler_rt.f32.fromAbi(a)); | ||
| 107 | } | ||
| 108 | fn __aeabi_f2lz(a: f32) callconv(.{ .arm_aapcs = .{} }) i64 { | ||
| 109 | return i64_intFromFloat_f32(a); | ||
| 110 | } | ||
| 111 | pub fn i64_intFromFloat_f32(a: f32) i64 { | ||
| 112 | return intFromFloat(i64, a); | ||
| 113 | } | ||
| 114 | |||
| 115 | fn __fixsfti(a: compiler_rt.f32.Abi) callconv(.c) i128 { | ||
| 116 | return i128_intFromFloat_f32(compiler_rt.f32.fromAbi(a)); | ||
| 117 | } | ||
| 118 | fn __aeabi_fixsfti(_: compiler_rt.f32.Abi) callconv(.naked) i128 { | ||
| 119 | switch (builtin.abi.float()) { | ||
| 120 | .soft => asm volatile ( | ||
| 121 | \\ push {r0-r4, lr} | ||
| 122 | \\ movs r1, r0 | ||
| 123 | \\ mov r0, sp | ||
| 124 | \\ bl %[__fixsfti] | ||
| 125 | \\ pop {r0-r4, pc} | ||
| 126 | : | ||
| 127 | : [__fixsfti] "X" (&__fixsfti), | ||
| 128 | ), | ||
| 129 | .hard => asm volatile ( | ||
| 130 | \\ push {r0-r4, lr} | ||
| 131 | \\ mov r0, sp | ||
| 132 | \\ bl %[__fixsfti] | ||
| 133 | \\ pop {r0-r4, pc} | ||
| 134 | : | ||
| 135 | : [__fixsfti] "X" (&__fixsfti), | ||
| 136 | ), | ||
| 137 | } | ||
| 138 | } | ||
| 139 | pub fn i128_intFromFloat_f32(a: f32) i128 { | ||
| 140 | return intFromFloat(i128, a); | ||
| 141 | } | ||
| 142 | |||
| 143 | fn __fixsfei(r: [*]u8, bits: usize, a: compiler_rt.f32.Abi) callconv(.c) void { | ||
| 144 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | ||
| 145 | return signed_intFromFloat_f32(r[0..byte_size], compiler_rt.f32.fromAbi(a)); | ||
| 146 | } | ||
| 147 | pub fn signed_intFromFloat_f32(result: []u8, a: f32) void { | ||
| 148 | bigIntFromFloat(.signed, @ptrCast(@alignCast(result)), a); | ||
| 149 | } | ||
| 150 | |||
| 151 | fn __fixdfsi(a: compiler_rt.f64.Abi) callconv(.c) i32 { | ||
| 152 | return i32_intFromFloat_f64(compiler_rt.f64.fromAbi(a)); | ||
| 153 | } | ||
| 154 | fn __aeabi_d2iz(a: f64) callconv(.{ .arm_aapcs = .{} }) i32 { | ||
| 155 | return i32_intFromFloat_f64(a); | ||
| 156 | } | ||
| 157 | pub fn i32_intFromFloat_f64(a: f64) i32 { | ||
| 158 | return intFromFloat(i32, a); | ||
| 159 | } | ||
| 160 | |||
| 161 | fn __fixdfdi(a: compiler_rt.f64.Abi) callconv(.c) i64 { | ||
| 162 | return i64_intFromFloat_f64(compiler_rt.f64.fromAbi(a)); | ||
| 163 | } | ||
| 164 | fn __aeabi_d2lz(a: f64) callconv(.{ .arm_aapcs = .{} }) i64 { | ||
| 165 | return i64_intFromFloat_f64(a); | ||
| 166 | } | ||
| 167 | pub fn i64_intFromFloat_f64(a: f64) i64 { | ||
| 168 | return intFromFloat(i64, a); | ||
| 13 | } | 169 | } |
| 14 | 170 | ||
| 15 | pub fn __fixhfti(a: f16) callconv(.c) i128 { | 171 | fn __fixdfti(a: compiler_rt.f64.Abi) callconv(.c) i128 { |
| 172 | return i128_intFromFloat_f64(compiler_rt.f64.fromAbi(a)); | ||
| 173 | } | ||
| 174 | fn __aeabi_fixdfti(_: compiler_rt.f64.Abi) callconv(.naked) i128 { | ||
| 175 | switch (builtin.abi.float()) { | ||
| 176 | .soft => asm volatile ( | ||
| 177 | \\ push {r0-r4, lr} | ||
| 178 | \\ movs r3, r1 | ||
| 179 | \\ movs r2, r0 | ||
| 180 | \\ mov r0, sp | ||
| 181 | \\ bl %[__fixdfti] | ||
| 182 | \\ pop {r0-r4, pc} | ||
| 183 | : | ||
| 184 | : [__fixdfti] "X" (&__fixdfti), | ||
| 185 | ), | ||
| 186 | .hard => asm volatile ( | ||
| 187 | \\ push {r0-r4, lr} | ||
| 188 | \\ mov r0, sp | ||
| 189 | \\ bl %[__fixdfti] | ||
| 190 | \\ pop {r0-r4, pc} | ||
| 191 | : | ||
| 192 | : [__fixdfti] "X" (&__fixdfti), | ||
| 193 | ), | ||
| 194 | } | ||
| 195 | } | ||
| 196 | pub fn i128_intFromFloat_f64(a: f64) i128 { | ||
| 16 | return intFromFloat(i128, a); | 197 | return intFromFloat(i128, a); |
| 17 | } | 198 | } |
| 18 | 199 | ||
| 19 | fn __fixhfdi(a: f16) callconv(.c) i64 { | 200 | fn __fixdfei(r: [*]u8, bits: usize, a: compiler_rt.f64.Abi) callconv(.c) void { |
| 201 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | ||
| 202 | return signed_intFromFloat_f64(r[0..byte_size], compiler_rt.f64.fromAbi(a)); | ||
| 203 | } | ||
| 204 | pub fn signed_intFromFloat_f64(result: []u8, a: f64) void { | ||
| 205 | bigIntFromFloat(.signed, @ptrCast(@alignCast(result)), a); | ||
| 206 | } | ||
| 207 | |||
| 208 | fn __fixxfsi(a: compiler_rt.f80.Abi) callconv(.c) i32 { | ||
| 209 | return i32_intFromFloat_f80(compiler_rt.f80.fromAbi(a)); | ||
| 210 | } | ||
| 211 | pub fn i32_intFromFloat_f80(a: f80) i32 { | ||
| 212 | return intFromFloat(i32, a); | ||
| 213 | } | ||
| 214 | |||
| 215 | fn __fixxfdi(a: compiler_rt.f80.Abi) callconv(.c) i64 { | ||
| 216 | return i64_intFromFloat_f80(compiler_rt.f80.fromAbi(a)); | ||
| 217 | } | ||
| 218 | pub fn i64_intFromFloat_f80(a: f80) i64 { | ||
| 20 | return intFromFloat(i64, a); | 219 | return intFromFloat(i64, a); |
| 21 | } | 220 | } |
| 22 | 221 | ||
| 23 | fn __fixhfsi(a: f16) callconv(.c) i32 { | 222 | fn __fixxfti(a: compiler_rt.f80.Abi) callconv(.c) i128 { |
| 223 | return i128_intFromFloat_f80(compiler_rt.f80.fromAbi(a)); | ||
| 224 | } | ||
| 225 | pub fn i128_intFromFloat_f80(a: f80) i128 { | ||
| 226 | return intFromFloat(i128, a); | ||
| 227 | } | ||
| 228 | |||
| 229 | fn __fixxfei(r: [*]u8, bits: usize, a: compiler_rt.f80.Abi) callconv(.c) void { | ||
| 230 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | ||
| 231 | return signed_intFromFloat_f80(r[0..byte_size], compiler_rt.f80.fromAbi(a)); | ||
| 232 | } | ||
| 233 | pub fn signed_intFromFloat_f80(result: []u8, a: f80) void { | ||
| 234 | bigIntFromFloat(.signed, @ptrCast(@alignCast(result)), a); | ||
| 235 | } | ||
| 236 | |||
| 237 | fn __fixtfsi(a: compiler_rt.f128.Abi) callconv(.c) i32 { | ||
| 238 | return i32_intFromFloat_f128(compiler_rt.f128.fromAbi(a)); | ||
| 239 | } | ||
| 240 | fn _Qp_qtoi(a: *const f128) callconv(.c) i32 { | ||
| 241 | return i32_intFromFloat_f128(a.*); | ||
| 242 | } | ||
| 243 | pub fn i32_intFromFloat_f128(a: f128) i32 { | ||
| 24 | return intFromFloat(i32, a); | 244 | return intFromFloat(i32, a); |
| 25 | } | 245 | } |
| 26 | 246 | ||
| 27 | pub fn __fixxfti(a: f80) callconv(.c) i128 { | 247 | fn __fixtfdi(a: compiler_rt.f128.Abi) callconv(.c) i64 { |
| 248 | return i64_intFromFloat_f128(compiler_rt.f128.fromAbi(a)); | ||
| 249 | } | ||
| 250 | fn _Qp_qtox(a: *const f128) callconv(.c) i64 { | ||
| 251 | return i64_intFromFloat_f128(a.*); | ||
| 252 | } | ||
| 253 | pub fn i64_intFromFloat_f128(a: f128) i64 { | ||
| 254 | return intFromFloat(i64, a); | ||
| 255 | } | ||
| 256 | |||
| 257 | fn __fixtfti(a: compiler_rt.f128.Abi) callconv(.c) i128 { | ||
| 258 | return i128_intFromFloat_f128(compiler_rt.f128.fromAbi(a)); | ||
| 259 | } | ||
| 260 | pub fn i128_intFromFloat_f128(a: f128) i128 { | ||
| 28 | return intFromFloat(i128, a); | 261 | return intFromFloat(i128, a); |
| 29 | } | 262 | } |
| 30 | 263 | ||
| 31 | pub inline fn intFromFloat(comptime I: type, a: anytype) I { | 264 | fn __fixtfei(r: [*]u8, bits: usize, a: compiler_rt.f128.Abi) callconv(.c) void { |
| 265 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | ||
| 266 | return signed_intFromFloat_f128(r[0..byte_size], compiler_rt.f128.fromAbi(a)); | ||
| 267 | } | ||
| 268 | pub fn signed_intFromFloat_f128(result: []u8, a: f128) void { | ||
| 269 | bigIntFromFloat(.signed, @ptrCast(@alignCast(result)), a); | ||
| 270 | } | ||
| 271 | |||
| 272 | comptime { | ||
| 273 | symbol(&__fixunshfsi, "__fixunshfsi"); | ||
| 274 | symbol(&__fixunshfdi, "__fixunshfdi"); | ||
| 275 | symbol(&__fixunshfti, "__fixunshfti"); | ||
| 276 | symbol(&__fixunshfei, "__fixunshfei"); | ||
| 277 | |||
| 278 | if (compiler_rt.want_aeabi) { | ||
| 279 | symbol(&__aeabi_f2uiz, "__aeabi_f2uiz"); | ||
| 280 | symbol(&__aeabi_f2ulz, "__aeabi_f2ulz"); | ||
| 281 | symbol(&__aeabi_fixunssfti, "__fixunssfti"); | ||
| 282 | } else { | ||
| 283 | symbol(&__fixunssfsi, "__fixunssfsi"); | ||
| 284 | symbol(&__fixunssfdi, "__fixunssfdi"); | ||
| 285 | if (compiler_rt.want_windows_arm_abi) symbol(&__fixunssfdi, "__stou64"); | ||
| 286 | symbol(&__fixunssfti, "__fixunssfti"); | ||
| 287 | } | ||
| 288 | symbol(&__fixunssfei, "__fixunssfei"); | ||
| 289 | |||
| 290 | if (compiler_rt.want_aeabi) { | ||
| 291 | symbol(&__aeabi_d2uiz, "__aeabi_d2uiz"); | ||
| 292 | symbol(&__aeabi_d2ulz, "__aeabi_d2ulz"); | ||
| 293 | symbol(&__aeabi_fixunsdfti, "__fixunsdfti"); | ||
| 294 | } else { | ||
| 295 | symbol(&__fixunsdfsi, "__fixunsdfsi"); | ||
| 296 | symbol(&__fixunsdfdi, "__fixunsdfdi"); | ||
| 297 | if (compiler_rt.want_windows_arm_abi) symbol(&__fixunsdfdi, "__dtou64"); | ||
| 298 | symbol(&__fixunsdfti, "__fixunsdfti"); | ||
| 299 | } | ||
| 300 | symbol(&__fixunsdfei, "__fixunsdfei"); | ||
| 301 | |||
| 302 | symbol(&__fixunsxfsi, "__fixunsxfsi"); | ||
| 303 | symbol(&__fixunsxfdi, "__fixunsxfdi"); | ||
| 304 | symbol(&__fixunsxfti, "__fixunsxfti"); | ||
| 305 | symbol(&__fixunsxfei, "__fixunsxfei"); | ||
| 306 | |||
| 307 | if (compiler_rt.want_ppc_abi) { | ||
| 308 | symbol(&__fixunstfsi, "__fixunskfsi"); | ||
| 309 | symbol(&__fixunstfdi, "__fixunskfdi"); | ||
| 310 | } else if (compiler_rt.want_sparc64_abi) { | ||
| 311 | symbol(&_Qp_qtoui, "_Qp_qtoui"); | ||
| 312 | symbol(&_Qp_qtoux, "_Qp_qtoux"); | ||
| 313 | } else if (compiler_rt.want_sparc32_abi) { | ||
| 314 | symbol(&__fixunstfsi, "_Q_qtou"); | ||
| 315 | symbol(&__fixunstfdi, "_Q_qtoull"); | ||
| 316 | } else { | ||
| 317 | symbol(&__fixunstfsi, "__fixunstfsi"); | ||
| 318 | symbol(&__fixunstfdi, "__fixunstfdi"); | ||
| 319 | } | ||
| 320 | if (compiler_rt.want_ppc_abi) { | ||
| 321 | symbol(&__fixunstfti, "__fixunskfti"); | ||
| 322 | symbol(&__fixunstfei, "__fixunskfei"); | ||
| 323 | } else { | ||
| 324 | symbol(&__fixunstfti, "__fixunstfti"); | ||
| 325 | symbol(&__fixunstfei, "__fixunstfei"); | ||
| 326 | } | ||
| 327 | } | ||
| 328 | |||
| 329 | fn __fixunshfsi(a: compiler_rt.f16.Abi) callconv(.c) u32 { | ||
| 330 | return u32_intFromFloat_f16(compiler_rt.f16.fromAbi(a)); | ||
| 331 | } | ||
| 332 | pub fn u32_intFromFloat_f16(a: f16) u32 { | ||
| 333 | return intFromFloat(u32, a); | ||
| 334 | } | ||
| 335 | |||
| 336 | fn __fixunshfdi(a: compiler_rt.f16.Abi) callconv(.c) u64 { | ||
| 337 | return u64_intFromFloat_f16(compiler_rt.f16.fromAbi(a)); | ||
| 338 | } | ||
| 339 | pub fn u64_intFromFloat_f16(a: f16) u64 { | ||
| 340 | return intFromFloat(u64, a); | ||
| 341 | } | ||
| 342 | |||
| 343 | fn __fixunshfti(a: compiler_rt.f16.Abi) callconv(.c) u128 { | ||
| 344 | return u128_intFromFloat_f16(compiler_rt.f16.fromAbi(a)); | ||
| 345 | } | ||
| 346 | pub fn u128_intFromFloat_f16(a: f16) u128 { | ||
| 347 | return intFromFloat(u128, a); | ||
| 348 | } | ||
| 349 | |||
| 350 | fn __fixunshfei(r: [*]u8, bits: usize, a: compiler_rt.f16.Abi) callconv(.c) void { | ||
| 351 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | ||
| 352 | return unsigned_intFromFloat_f16(r[0..byte_size], compiler_rt.f16.fromAbi(a)); | ||
| 353 | } | ||
| 354 | pub fn unsigned_intFromFloat_f16(result: []u8, a: f16) void { | ||
| 355 | bigIntFromFloat(.unsigned, @ptrCast(@alignCast(result)), a); | ||
| 356 | } | ||
| 357 | |||
| 358 | fn __fixunssfsi(a: compiler_rt.f32.Abi) callconv(.c) u32 { | ||
| 359 | return u32_intFromFloat_f32(compiler_rt.f32.fromAbi(a)); | ||
| 360 | } | ||
| 361 | fn __aeabi_f2uiz(a: f32) callconv(.{ .arm_aapcs = .{} }) u32 { | ||
| 362 | return u32_intFromFloat_f32(a); | ||
| 363 | } | ||
| 364 | pub fn u32_intFromFloat_f32(a: f32) u32 { | ||
| 365 | return intFromFloat(u32, a); | ||
| 366 | } | ||
| 367 | |||
| 368 | fn __fixunssfdi(a: compiler_rt.f32.Abi) callconv(.c) u64 { | ||
| 369 | return u64_intFromFloat_f32(compiler_rt.f32.fromAbi(a)); | ||
| 370 | } | ||
| 371 | fn __aeabi_f2ulz(a: f32) callconv(.{ .arm_aapcs = .{} }) u64 { | ||
| 372 | return u64_intFromFloat_f32(a); | ||
| 373 | } | ||
| 374 | pub fn u64_intFromFloat_f32(a: f32) u64 { | ||
| 375 | return intFromFloat(u64, a); | ||
| 376 | } | ||
| 377 | |||
| 378 | fn __fixunssfti(a: compiler_rt.f32.Abi) callconv(.c) u128 { | ||
| 379 | return u128_intFromFloat_f32(compiler_rt.f32.fromAbi(a)); | ||
| 380 | } | ||
| 381 | fn __aeabi_fixunssfti(_: compiler_rt.f32.Abi) callconv(.naked) u128 { | ||
| 382 | switch (builtin.abi.float()) { | ||
| 383 | .soft => asm volatile ( | ||
| 384 | \\ push {r0-r4, lr} | ||
| 385 | \\ movs r1, r0 | ||
| 386 | \\ mov r0, sp | ||
| 387 | \\ bl %[__fixunssfti] | ||
| 388 | \\ pop {r0-r4, pc} | ||
| 389 | : | ||
| 390 | : [__fixunssfti] "X" (&__fixunssfti), | ||
| 391 | ), | ||
| 392 | .hard => asm volatile ( | ||
| 393 | \\ push {r0-r4, lr} | ||
| 394 | \\ mov r0, sp | ||
| 395 | \\ bl %[__fixunssfti] | ||
| 396 | \\ pop {r0-r4, pc} | ||
| 397 | : | ||
| 398 | : [__fixunssfti] "X" (&__fixunssfti), | ||
| 399 | ), | ||
| 400 | } | ||
| 401 | } | ||
| 402 | pub fn u128_intFromFloat_f32(a: f32) u128 { | ||
| 403 | return intFromFloat(u128, a); | ||
| 404 | } | ||
| 405 | |||
| 406 | fn __fixunssfei(r: [*]u8, bits: usize, a: compiler_rt.f32.Abi) callconv(.c) void { | ||
| 407 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | ||
| 408 | return unsigned_intFromFloat_f32(r[0..byte_size], compiler_rt.f32.fromAbi(a)); | ||
| 409 | } | ||
| 410 | pub fn unsigned_intFromFloat_f32(result: []u8, a: f32) void { | ||
| 411 | bigIntFromFloat(.unsigned, @ptrCast(@alignCast(result)), a); | ||
| 412 | } | ||
| 413 | |||
| 414 | fn __fixunsdfsi(a: compiler_rt.f64.Abi) callconv(.c) u32 { | ||
| 415 | return u32_intFromFloat_f64(compiler_rt.f64.fromAbi(a)); | ||
| 416 | } | ||
| 417 | fn __aeabi_d2uiz(a: f64) callconv(.{ .arm_aapcs = .{} }) u32 { | ||
| 418 | return u32_intFromFloat_f64(a); | ||
| 419 | } | ||
| 420 | pub fn u32_intFromFloat_f64(a: f64) u32 { | ||
| 421 | return intFromFloat(u32, a); | ||
| 422 | } | ||
| 423 | |||
| 424 | fn __fixunsdfdi(a: compiler_rt.f64.Abi) callconv(.c) u64 { | ||
| 425 | return u64_intFromFloat_f64(compiler_rt.f64.fromAbi(a)); | ||
| 426 | } | ||
| 427 | fn __aeabi_d2ulz(a: f64) callconv(.{ .arm_aapcs = .{} }) u64 { | ||
| 428 | return u64_intFromFloat_f64(a); | ||
| 429 | } | ||
| 430 | pub fn u64_intFromFloat_f64(a: f64) u64 { | ||
| 431 | return intFromFloat(u64, a); | ||
| 432 | } | ||
| 433 | |||
| 434 | fn __fixunsdfti(a: compiler_rt.f64.Abi) callconv(.c) u128 { | ||
| 435 | return u128_intFromFloat_f64(compiler_rt.f64.fromAbi(a)); | ||
| 436 | } | ||
| 437 | fn __aeabi_fixunsdfti(_: compiler_rt.f64.Abi) callconv(.naked) u128 { | ||
| 438 | switch (builtin.abi.float()) { | ||
| 439 | .soft => asm volatile ( | ||
| 440 | \\ push {r0-r4, lr} | ||
| 441 | \\ movs r3, r1 | ||
| 442 | \\ movs r2, r0 | ||
| 443 | \\ mov r0, sp | ||
| 444 | \\ bl %[__fixunsdfti] | ||
| 445 | \\ pop {r0-r4, pc} | ||
| 446 | : | ||
| 447 | : [__fixunsdfti] "X" (&__fixunsdfti), | ||
| 448 | ), | ||
| 449 | .hard => asm volatile ( | ||
| 450 | \\ push {r0-r4, lr} | ||
| 451 | \\ mov r0, sp | ||
| 452 | \\ bl %[__fixunsdfti] | ||
| 453 | \\ pop {r0-r4, pc} | ||
| 454 | : | ||
| 455 | : [__fixunsdfti] "X" (&__fixunsdfti), | ||
| 456 | ), | ||
| 457 | } | ||
| 458 | } | ||
| 459 | pub fn u128_intFromFloat_f64(a: f64) u128 { | ||
| 460 | return intFromFloat(u128, a); | ||
| 461 | } | ||
| 462 | |||
| 463 | fn __fixunsdfei(r: [*]u8, bits: usize, a: compiler_rt.f64.Abi) callconv(.c) void { | ||
| 464 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | ||
| 465 | return unsigned_intFromFloat_f64(r[0..byte_size], compiler_rt.f64.fromAbi(a)); | ||
| 466 | } | ||
| 467 | pub fn unsigned_intFromFloat_f64(result: []u8, a: f64) void { | ||
| 468 | bigIntFromFloat(.unsigned, @ptrCast(@alignCast(result)), a); | ||
| 469 | } | ||
| 470 | |||
| 471 | fn __fixunsxfsi(a: compiler_rt.f80.Abi) callconv(.c) u32 { | ||
| 472 | return u32_intFromFloat_f80(compiler_rt.f80.fromAbi(a)); | ||
| 473 | } | ||
| 474 | pub fn u32_intFromFloat_f80(a: f80) u32 { | ||
| 475 | return intFromFloat(u32, a); | ||
| 476 | } | ||
| 477 | |||
| 478 | fn __fixunsxfdi(a: compiler_rt.f80.Abi) callconv(.c) u64 { | ||
| 479 | return u64_intFromFloat_f80(compiler_rt.f80.fromAbi(a)); | ||
| 480 | } | ||
| 481 | pub fn u64_intFromFloat_f80(a: f80) u64 { | ||
| 482 | return intFromFloat(u64, a); | ||
| 483 | } | ||
| 484 | |||
| 485 | fn __fixunsxfti(a: compiler_rt.f80.Abi) callconv(.c) u128 { | ||
| 486 | return u128_intFromFloat_f80(compiler_rt.f80.fromAbi(a)); | ||
| 487 | } | ||
| 488 | pub fn u128_intFromFloat_f80(a: f80) u128 { | ||
| 489 | return intFromFloat(u128, a); | ||
| 490 | } | ||
| 491 | |||
| 492 | fn __fixunsxfei(r: [*]u8, bits: usize, a: compiler_rt.f80.Abi) callconv(.c) void { | ||
| 493 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | ||
| 494 | return unsigned_intFromFloat_f80(r[0..byte_size], compiler_rt.f80.fromAbi(a)); | ||
| 495 | } | ||
| 496 | pub fn unsigned_intFromFloat_f80(result: []u8, a: f80) void { | ||
| 497 | bigIntFromFloat(.unsigned, @ptrCast(@alignCast(result)), a); | ||
| 498 | } | ||
| 499 | |||
| 500 | fn __fixunstfsi(a: compiler_rt.f128.Abi) callconv(.c) u32 { | ||
| 501 | return u32_intFromFloat_f128(compiler_rt.f128.fromAbi(a)); | ||
| 502 | } | ||
| 503 | fn _Qp_qtoui(a: *const f128) callconv(.c) u32 { | ||
| 504 | return u32_intFromFloat_f128(a.*); | ||
| 505 | } | ||
| 506 | pub fn u32_intFromFloat_f128(a: f128) u32 { | ||
| 507 | return intFromFloat(u32, a); | ||
| 508 | } | ||
| 509 | |||
| 510 | fn __fixunstfdi(a: compiler_rt.f128.Abi) callconv(.c) u64 { | ||
| 511 | return u64_intFromFloat_f128(compiler_rt.f128.fromAbi(a)); | ||
| 512 | } | ||
| 513 | fn _Qp_qtoux(a: *const f128) callconv(.c) u64 { | ||
| 514 | return u64_intFromFloat_f128(a.*); | ||
| 515 | } | ||
| 516 | pub fn u64_intFromFloat_f128(a: f128) u64 { | ||
| 517 | return intFromFloat(u64, a); | ||
| 518 | } | ||
| 519 | |||
| 520 | fn __fixunstfti(a: compiler_rt.f128.Abi) callconv(.c) u128 { | ||
| 521 | return u128_intFromFloat_f128(compiler_rt.f128.fromAbi(a)); | ||
| 522 | } | ||
| 523 | pub fn u128_intFromFloat_f128(a: f128) u128 { | ||
| 524 | return intFromFloat(u128, a); | ||
| 525 | } | ||
| 526 | |||
| 527 | fn __fixunstfei(r: [*]u8, bits: usize, a: compiler_rt.f128.Abi) callconv(.c) void { | ||
| 528 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | ||
| 529 | return unsigned_intFromFloat_f128(r[0..byte_size], compiler_rt.f128.fromAbi(a)); | ||
| 530 | } | ||
| 531 | pub fn unsigned_intFromFloat_f128(result: []u8, a: f128) void { | ||
| 532 | bigIntFromFloat(.unsigned, @ptrCast(@alignCast(result)), a); | ||
| 533 | } | ||
| 534 | |||
| 535 | inline fn intFromFloat(comptime I: type, a: anytype) I { | ||
| 32 | const F = @TypeOf(a); | 536 | const F = @TypeOf(a); |
| 33 | const float_bits = @typeInfo(F).float.bits; | 537 | const float_bits = @typeInfo(F).float.bits; |
| 34 | const int_bits = @typeInfo(I).int.bits; | 538 | const int_bits = @typeInfo(I).int.bits; |
| ... | @@ -76,13 +580,14 @@ pub inline fn intFromFloat(comptime I: type, a: anytype) I { | ... | @@ -76,13 +580,14 @@ pub inline fn intFromFloat(comptime I: type, a: anytype) I { |
| 76 | return result; | 580 | return result; |
| 77 | } | 581 | } |
| 78 | 582 | ||
| 79 | pub inline fn bigIntFromFloat(comptime signedness: std.builtin.Signedness, result: []u32, a: anytype) void { | 583 | inline fn bigIntFromFloat(comptime signedness: std.lang.Signedness, result: []u32, a: anytype) void { |
| 584 | const endian = builtin.cpu.arch.endian(); | ||
| 80 | switch (result.len) { | 585 | switch (result.len) { |
| 81 | 0 => return, | 586 | 0 => return, |
| 82 | inline 1...4 => |limbs_len| { | 587 | inline 1...4 => |limbs_len| { |
| 83 | const I = @Int(signedness, 32 * limbs_len); | 588 | const I = @Int(signedness, 32 * limbs_len); |
| 84 | const low_to_high: [limbs_len]u32 = @bitCast(@as(I, @intFromFloat(a))); | 589 | const low_to_high: [limbs_len]u32 = @bitCast(@as(I, @intFromFloat(a))); |
| 85 | result[0..limbs_len].* = switch (@import("builtin").cpu.arch.endian()) { | 590 | result[0..limbs_len].* = switch (endian) { |
| 86 | .little => low_to_high, | 591 | .little => low_to_high, |
| 87 | .big => switch (limbs_len) { | 592 | .big => switch (limbs_len) { |
| 88 | 1 => .{low_to_high[0]}, | 593 | 1 => .{low_to_high[0]}, |
| ... | @@ -111,7 +616,6 @@ pub inline fn bigIntFromFloat(comptime signedness: std.builtin.Signedness, resul | ... | @@ -111,7 +616,6 @@ pub inline fn bigIntFromFloat(comptime signedness: std.builtin.Signedness, resul |
| 111 | }); | 616 | }); |
| 112 | switch (signedness) { | 617 | switch (signedness) { |
| 113 | .signed => { | 618 | .signed => { |
| 114 | const endian = @import("builtin").cpu.arch.endian(); | ||
| 115 | const exponent_limb = switch (endian) { | 619 | const exponent_limb = switch (endian) { |
| 116 | .little => exponent / 32, | 620 | .little => exponent / 32, |
| 117 | .big => result.len - 1 - exponent / 32, | 621 | .big => result.len - 1 - exponent / 32, |
lib/compiler_rt/int_from_float_test.zig+913-897| ... | @@ -2,1023 +2,1039 @@ const std = @import("std"); | ... | @@ -2,1023 +2,1039 @@ const std = @import("std"); |
| 2 | const testing = std.testing; | 2 | const testing = std.testing; |
| 3 | const math = std.math; | 3 | const math = std.math; |
| 4 | 4 | ||
| 5 | const __fixunshfti = @import("fixunshfti.zig").__fixunshfti; | 5 | const impl = @import("int_from_float.zig"); |
| 6 | const __fixunsxfti = @import("fixunsxfti.zig").__fixunsxfti; | 6 | |
| 7 | 7 | const i32_intFromFloat_f16 = impl.i32_intFromFloat_f16; | |
| 8 | // Conversion from f32 | 8 | const u32_intFromFloat_f16 = impl.u32_intFromFloat_f16; |
| 9 | const __fixsfsi = @import("fixsfsi.zig").__fixsfsi; | 9 | const i64_intFromFloat_f16 = impl.i64_intFromFloat_f16; |
| 10 | const __fixunssfsi = @import("fixunssfsi.zig").__fixunssfsi; | 10 | const u64_intFromFloat_f16 = impl.u64_intFromFloat_f16; |
| 11 | const __fixsfdi = @import("fixsfdi.zig").__fixsfdi; | 11 | const i128_intFromFloat_f16 = impl.i128_intFromFloat_f16; |
| 12 | const __fixunssfdi = @import("fixunssfdi.zig").__fixunssfdi; | 12 | const u128_intFromFloat_f16 = impl.u128_intFromFloat_f16; |
| 13 | const __fixsfti = @import("fixsfti.zig").__fixsfti; | 13 | const signed_intFromFloat_f16 = impl.signed_intFromFloat_f16; |
| 14 | const __fixunssfti = @import("fixunssfti.zig").__fixunssfti; | 14 | const unsigned_intFromFloat_f16 = impl.unsigned_intFromFloat_f16; |
| 15 | const __fixsfei = @import("fixsfei.zig").__fixsfei; | 15 | |
| 16 | const __fixunssfei = @import("fixunssfei.zig").__fixunssfei; | 16 | const i32_intFromFloat_f32 = impl.i32_intFromFloat_f32; |
| 17 | 17 | const u32_intFromFloat_f32 = impl.u32_intFromFloat_f32; | |
| 18 | // Conversion from f64 | 18 | const i64_intFromFloat_f32 = impl.i64_intFromFloat_f32; |
| 19 | const __fixdfsi = @import("fixdfsi.zig").__fixdfsi; | 19 | const u64_intFromFloat_f32 = impl.u64_intFromFloat_f32; |
| 20 | const __fixunsdfsi = @import("fixunsdfsi.zig").__fixunsdfsi; | 20 | const i128_intFromFloat_f32 = impl.i128_intFromFloat_f32; |
| 21 | const __fixdfdi = @import("fixdfdi.zig").__fixdfdi; | 21 | const u128_intFromFloat_f32 = impl.u128_intFromFloat_f32; |
| 22 | const __fixunsdfdi = @import("fixunsdfdi.zig").__fixunsdfdi; | 22 | const signed_intFromFloat_f32 = impl.signed_intFromFloat_f32; |
| 23 | const __fixdfti = @import("fixdfti.zig").__fixdfti; | 23 | const unsigned_intFromFloat_f32 = impl.unsigned_intFromFloat_f32; |
| 24 | const __fixunsdfti = @import("fixunsdfti.zig").__fixunsdfti; | 24 | |
| 25 | const __fixdfei = @import("fixdfei.zig").__fixdfei; | 25 | const i32_intFromFloat_f64 = impl.i32_intFromFloat_f64; |
| 26 | const __fixunsdfei = @import("fixunsdfei.zig").__fixunsdfei; | 26 | const u32_intFromFloat_f64 = impl.u32_intFromFloat_f64; |
| 27 | 27 | const i64_intFromFloat_f64 = impl.i64_intFromFloat_f64; | |
| 28 | // Conversion from f128 | 28 | const u64_intFromFloat_f64 = impl.u64_intFromFloat_f64; |
| 29 | const __fixtfsi = @import("fixtfsi.zig").__fixtfsi; | 29 | const i128_intFromFloat_f64 = impl.i128_intFromFloat_f64; |
| 30 | const __fixunstfsi = @import("fixunstfsi.zig").__fixunstfsi; | 30 | const u128_intFromFloat_f64 = impl.u128_intFromFloat_f64; |
| 31 | const __fixtfdi = @import("fixtfdi.zig").__fixtfdi; | 31 | const signed_intFromFloat_f64 = impl.signed_intFromFloat_f64; |
| 32 | const __fixunstfdi = @import("fixunstfdi.zig").__fixunstfdi; | 32 | const unsigned_intFromFloat_f64 = impl.unsigned_intFromFloat_f64; |
| 33 | const __fixtfti = @import("fixtfti.zig").__fixtfti; | 33 | |
| 34 | const __fixunstfti = @import("fixunstfti.zig").__fixunstfti; | 34 | const i32_intFromFloat_f80 = impl.i32_intFromFloat_f80; |
| 35 | 35 | const u32_intFromFloat_f80 = impl.u32_intFromFloat_f80; | |
| 36 | fn test__fixsfsi(a: f32, expected: i32) !void { | 36 | const i64_intFromFloat_f80 = impl.i64_intFromFloat_f80; |
| 37 | const x = __fixsfsi(a); | 37 | const u64_intFromFloat_f80 = impl.u64_intFromFloat_f80; |
| 38 | const i128_intFromFloat_f80 = impl.i128_intFromFloat_f80; | ||
| 39 | const u128_intFromFloat_f80 = impl.u128_intFromFloat_f80; | ||
| 40 | const signed_intFromFloat_f80 = impl.signed_intFromFloat_f80; | ||
| 41 | const unsigned_intFromFloat_f80 = impl.unsigned_intFromFloat_f80; | ||
| 42 | |||
| 43 | const i32_intFromFloat_f128 = impl.i32_intFromFloat_f128; | ||
| 44 | const u32_intFromFloat_f128 = impl.u32_intFromFloat_f128; | ||
| 45 | const i64_intFromFloat_f128 = impl.i64_intFromFloat_f128; | ||
| 46 | const u64_intFromFloat_f128 = impl.u64_intFromFloat_f128; | ||
| 47 | const i128_intFromFloat_f128 = impl.i128_intFromFloat_f128; | ||
| 48 | const u128_intFromFloat_f128 = impl.u128_intFromFloat_f128; | ||
| 49 | const signed_intFromFloat_f128 = impl.signed_intFromFloat_f128; | ||
| 50 | const unsigned_intFromFloat_f128 = impl.unsigned_intFromFloat_f128; | ||
| 51 | |||
| 52 | fn test_i32_intFromFloat_f32(a: f32, expected: i32) !void { | ||
| 53 | const x = i32_intFromFloat_f32(a); | ||
| 38 | try testing.expect(x == expected); | 54 | try testing.expect(x == expected); |
| 39 | } | 55 | } |
| 40 | 56 | ||
| 41 | fn test__fixunssfsi(a: f32, expected: u32) !void { | 57 | fn test_u32_intFromFloat_f32(a: f32, expected: u32) !void { |
| 42 | const x = __fixunssfsi(a); | 58 | const x = u32_intFromFloat_f32(a); |
| 43 | try testing.expect(x == expected); | 59 | try testing.expect(x == expected); |
| 44 | } | 60 | } |
| 45 | 61 | ||
| 46 | test "fixsfsi" { | 62 | test i32_intFromFloat_f32 { |
| 47 | try test__fixsfsi(-math.floatMax(f32), math.minInt(i32)); | 63 | try test_i32_intFromFloat_f32(-math.floatMax(f32), math.minInt(i32)); |
| 48 | 64 | ||
| 49 | try test__fixsfsi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32)); | 65 | try test_i32_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32)); |
| 50 | try test__fixsfsi(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000); | 66 | try test_i32_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000); |
| 51 | 67 | ||
| 52 | try test__fixsfsi(-0x1.0000000000000p+127, -0x80000000); | 68 | try test_i32_intFromFloat_f32(-0x1.0000000000000p+127, -0x80000000); |
| 53 | try test__fixsfsi(-0x1.FFFFFFFFFFFFFp+126, -0x80000000); | 69 | try test_i32_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+126, -0x80000000); |
| 54 | try test__fixsfsi(-0x1.FFFFFFFFFFFFEp+126, -0x80000000); | 70 | try test_i32_intFromFloat_f32(-0x1.FFFFFFFFFFFFEp+126, -0x80000000); |
| 55 | 71 | ||
| 56 | try test__fixsfsi(-0x1.0000000000001p+63, -0x80000000); | 72 | try test_i32_intFromFloat_f32(-0x1.0000000000001p+63, -0x80000000); |
| 57 | try test__fixsfsi(-0x1.0000000000000p+63, -0x80000000); | 73 | try test_i32_intFromFloat_f32(-0x1.0000000000000p+63, -0x80000000); |
| 58 | try test__fixsfsi(-0x1.FFFFFFFFFFFFFp+62, -0x80000000); | 74 | try test_i32_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+62, -0x80000000); |
| 59 | try test__fixsfsi(-0x1.FFFFFFFFFFFFEp+62, -0x80000000); | 75 | try test_i32_intFromFloat_f32(-0x1.FFFFFFFFFFFFEp+62, -0x80000000); |
| 60 | 76 | ||
| 61 | try test__fixsfsi(-0x1.FFFFFEp+62, -0x80000000); | 77 | try test_i32_intFromFloat_f32(-0x1.FFFFFEp+62, -0x80000000); |
| 62 | try test__fixsfsi(-0x1.FFFFFCp+62, -0x80000000); | 78 | try test_i32_intFromFloat_f32(-0x1.FFFFFCp+62, -0x80000000); |
| 63 | 79 | ||
| 64 | try test__fixsfsi(-0x1.000000p+31, -0x80000000); | 80 | try test_i32_intFromFloat_f32(-0x1.000000p+31, -0x80000000); |
| 65 | try test__fixsfsi(-0x1.FFFFFFp+30, -0x80000000); | 81 | try test_i32_intFromFloat_f32(-0x1.FFFFFFp+30, -0x80000000); |
| 66 | try test__fixsfsi(-0x1.FFFFFEp+30, -0x7FFFFF80); | 82 | try test_i32_intFromFloat_f32(-0x1.FFFFFEp+30, -0x7FFFFF80); |
| 67 | try test__fixsfsi(-0x1.FFFFFCp+30, -0x7FFFFF00); | 83 | try test_i32_intFromFloat_f32(-0x1.FFFFFCp+30, -0x7FFFFF00); |
| 68 | 84 | ||
| 69 | try test__fixsfsi(-2.01, -2); | 85 | try test_i32_intFromFloat_f32(-2.01, -2); |
| 70 | try test__fixsfsi(-2.0, -2); | 86 | try test_i32_intFromFloat_f32(-2.0, -2); |
| 71 | try test__fixsfsi(-1.99, -1); | 87 | try test_i32_intFromFloat_f32(-1.99, -1); |
| 72 | try test__fixsfsi(-1.0, -1); | 88 | try test_i32_intFromFloat_f32(-1.0, -1); |
| 73 | try test__fixsfsi(-0.99, 0); | 89 | try test_i32_intFromFloat_f32(-0.99, 0); |
| 74 | try test__fixsfsi(-0.5, 0); | 90 | try test_i32_intFromFloat_f32(-0.5, 0); |
| 75 | 91 | ||
| 76 | try test__fixsfsi(-math.floatMin(f32), 0); | 92 | try test_i32_intFromFloat_f32(-math.floatMin(f32), 0); |
| 77 | try test__fixsfsi(0.0, 0); | 93 | try test_i32_intFromFloat_f32(0.0, 0); |
| 78 | try test__fixsfsi(math.floatMin(f32), 0); | 94 | try test_i32_intFromFloat_f32(math.floatMin(f32), 0); |
| 79 | try test__fixsfsi(0.5, 0); | 95 | try test_i32_intFromFloat_f32(0.5, 0); |
| 80 | try test__fixsfsi(0.99, 0); | 96 | try test_i32_intFromFloat_f32(0.99, 0); |
| 81 | try test__fixsfsi(1.0, 1); | 97 | try test_i32_intFromFloat_f32(1.0, 1); |
| 82 | try test__fixsfsi(1.5, 1); | 98 | try test_i32_intFromFloat_f32(1.5, 1); |
| 83 | try test__fixsfsi(1.99, 1); | 99 | try test_i32_intFromFloat_f32(1.99, 1); |
| 84 | try test__fixsfsi(2.0, 2); | 100 | try test_i32_intFromFloat_f32(2.0, 2); |
| 85 | try test__fixsfsi(2.01, 2); | 101 | try test_i32_intFromFloat_f32(2.01, 2); |
| 86 | 102 | ||
| 87 | try test__fixsfsi(0x1.FFFFFCp+30, 0x7FFFFF00); | 103 | try test_i32_intFromFloat_f32(0x1.FFFFFCp+30, 0x7FFFFF00); |
| 88 | try test__fixsfsi(0x1.FFFFFEp+30, 0x7FFFFF80); | 104 | try test_i32_intFromFloat_f32(0x1.FFFFFEp+30, 0x7FFFFF80); |
| 89 | try test__fixsfsi(0x1.FFFFFFp+30, 0x7FFFFFFF); | 105 | try test_i32_intFromFloat_f32(0x1.FFFFFFp+30, 0x7FFFFFFF); |
| 90 | try test__fixsfsi(0x1.000000p+31, 0x7FFFFFFF); | 106 | try test_i32_intFromFloat_f32(0x1.000000p+31, 0x7FFFFFFF); |
| 91 | 107 | ||
| 92 | try test__fixsfsi(0x1.FFFFFCp+62, 0x7FFFFFFF); | 108 | try test_i32_intFromFloat_f32(0x1.FFFFFCp+62, 0x7FFFFFFF); |
| 93 | try test__fixsfsi(0x1.FFFFFEp+62, 0x7FFFFFFF); | 109 | try test_i32_intFromFloat_f32(0x1.FFFFFEp+62, 0x7FFFFFFF); |
| 94 | 110 | ||
| 95 | try test__fixsfsi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFF); | 111 | try test_i32_intFromFloat_f32(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFF); |
| 96 | try test__fixsfsi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFF); | 112 | try test_i32_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFF); |
| 97 | try test__fixsfsi(0x1.0000000000000p+63, 0x7FFFFFFF); | 113 | try test_i32_intFromFloat_f32(0x1.0000000000000p+63, 0x7FFFFFFF); |
| 98 | try test__fixsfsi(0x1.0000000000001p+63, 0x7FFFFFFF); | 114 | try test_i32_intFromFloat_f32(0x1.0000000000001p+63, 0x7FFFFFFF); |
| 99 | 115 | ||
| 100 | try test__fixsfsi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFF); | 116 | try test_i32_intFromFloat_f32(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFF); |
| 101 | try test__fixsfsi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFF); | 117 | try test_i32_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFF); |
| 102 | try test__fixsfsi(0x1.0000000000000p+127, 0x7FFFFFFF); | 118 | try test_i32_intFromFloat_f32(0x1.0000000000000p+127, 0x7FFFFFFF); |
| 103 | 119 | ||
| 104 | try test__fixsfsi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF); | 120 | try test_i32_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF); |
| 105 | try test__fixsfsi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32)); | 121 | try test_i32_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32)); |
| 106 | 122 | ||
| 107 | try test__fixsfsi(math.floatMax(f32), math.maxInt(i32)); | 123 | try test_i32_intFromFloat_f32(math.floatMax(f32), math.maxInt(i32)); |
| 108 | } | 124 | } |
| 109 | 125 | ||
| 110 | test "fixunssfsi" { | 126 | test u32_intFromFloat_f32 { |
| 111 | try test__fixunssfsi(0.0, 0); | 127 | try test_u32_intFromFloat_f32(0.0, 0); |
| 112 | 128 | ||
| 113 | try test__fixunssfsi(0.5, 0); | 129 | try test_u32_intFromFloat_f32(0.5, 0); |
| 114 | try test__fixunssfsi(0.99, 0); | 130 | try test_u32_intFromFloat_f32(0.99, 0); |
| 115 | try test__fixunssfsi(1.0, 1); | 131 | try test_u32_intFromFloat_f32(1.0, 1); |
| 116 | try test__fixunssfsi(1.5, 1); | 132 | try test_u32_intFromFloat_f32(1.5, 1); |
| 117 | try test__fixunssfsi(1.99, 1); | 133 | try test_u32_intFromFloat_f32(1.99, 1); |
| 118 | try test__fixunssfsi(2.0, 2); | 134 | try test_u32_intFromFloat_f32(2.0, 2); |
| 119 | try test__fixunssfsi(2.01, 2); | 135 | try test_u32_intFromFloat_f32(2.01, 2); |
| 120 | try test__fixunssfsi(-0.5, 0); | 136 | try test_u32_intFromFloat_f32(-0.5, 0); |
| 121 | try test__fixunssfsi(-0.99, 0); | 137 | try test_u32_intFromFloat_f32(-0.99, 0); |
| 122 | 138 | ||
| 123 | try test__fixunssfsi(-1.0, 0); | 139 | try test_u32_intFromFloat_f32(-1.0, 0); |
| 124 | try test__fixunssfsi(-1.5, 0); | 140 | try test_u32_intFromFloat_f32(-1.5, 0); |
| 125 | try test__fixunssfsi(-1.99, 0); | 141 | try test_u32_intFromFloat_f32(-1.99, 0); |
| 126 | try test__fixunssfsi(-2.0, 0); | 142 | try test_u32_intFromFloat_f32(-2.0, 0); |
| 127 | try test__fixunssfsi(-2.01, 0); | 143 | try test_u32_intFromFloat_f32(-2.01, 0); |
| 128 | 144 | ||
| 129 | try test__fixunssfsi(0x1.000000p+31, 0x80000000); | 145 | try test_u32_intFromFloat_f32(0x1.000000p+31, 0x80000000); |
| 130 | try test__fixunssfsi(0x1.000000p+32, 0xFFFFFFFF); | 146 | try test_u32_intFromFloat_f32(0x1.000000p+32, 0xFFFFFFFF); |
| 131 | try test__fixunssfsi(0x1.FFFFFEp+31, 0xFFFFFF00); | 147 | try test_u32_intFromFloat_f32(0x1.FFFFFEp+31, 0xFFFFFF00); |
| 132 | try test__fixunssfsi(0x1.FFFFFEp+30, 0x7FFFFF80); | 148 | try test_u32_intFromFloat_f32(0x1.FFFFFEp+30, 0x7FFFFF80); |
| 133 | try test__fixunssfsi(0x1.FFFFFCp+30, 0x7FFFFF00); | 149 | try test_u32_intFromFloat_f32(0x1.FFFFFCp+30, 0x7FFFFF00); |
| 134 | 150 | ||
| 135 | try test__fixunssfsi(-0x1.FFFFFEp+30, 0); | 151 | try test_u32_intFromFloat_f32(-0x1.FFFFFEp+30, 0); |
| 136 | try test__fixunssfsi(-0x1.FFFFFCp+30, 0); | 152 | try test_u32_intFromFloat_f32(-0x1.FFFFFCp+30, 0); |
| 137 | } | 153 | } |
| 138 | 154 | ||
| 139 | fn test__fixsfdi(a: f32, expected: i64) !void { | 155 | fn test_i64_intFromFloat_f32(a: f32, expected: i64) !void { |
| 140 | const x = __fixsfdi(a); | 156 | const x = i64_intFromFloat_f32(a); |
| 141 | try testing.expect(x == expected); | 157 | try testing.expect(x == expected); |
| 142 | } | 158 | } |
| 143 | 159 | ||
| 144 | fn test__fixunssfdi(a: f32, expected: u64) !void { | 160 | fn test_u64_intFromFloat_f32(a: f32, expected: u64) !void { |
| 145 | const x = __fixunssfdi(a); | 161 | const x = u64_intFromFloat_f32(a); |
| 146 | try testing.expect(x == expected); | 162 | try testing.expect(x == expected); |
| 147 | } | 163 | } |
| 148 | 164 | ||
| 149 | test "fixsfdi" { | 165 | test i64_intFromFloat_f32 { |
| 150 | try test__fixsfdi(-math.floatMax(f32), math.minInt(i64)); | 166 | try test_i64_intFromFloat_f32(-math.floatMax(f32), math.minInt(i64)); |
| 151 | 167 | ||
| 152 | try test__fixsfdi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64)); | 168 | try test_i64_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64)); |
| 153 | try test__fixsfdi(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000); | 169 | try test_i64_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000); |
| 154 | 170 | ||
| 155 | try test__fixsfdi(-0x1.0000000000000p+127, -0x8000000000000000); | 171 | try test_i64_intFromFloat_f32(-0x1.0000000000000p+127, -0x8000000000000000); |
| 156 | try test__fixsfdi(-0x1.FFFFFFFFFFFFFp+126, -0x8000000000000000); | 172 | try test_i64_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+126, -0x8000000000000000); |
| 157 | try test__fixsfdi(-0x1.FFFFFFFFFFFFEp+126, -0x8000000000000000); | 173 | try test_i64_intFromFloat_f32(-0x1.FFFFFFFFFFFFEp+126, -0x8000000000000000); |
| 158 | 174 | ||
| 159 | try test__fixsfdi(-0x1.0000000000001p+63, -0x8000000000000000); | 175 | try test_i64_intFromFloat_f32(-0x1.0000000000001p+63, -0x8000000000000000); |
| 160 | try test__fixsfdi(-0x1.0000000000000p+63, -0x8000000000000000); | 176 | try test_i64_intFromFloat_f32(-0x1.0000000000000p+63, -0x8000000000000000); |
| 161 | try test__fixsfdi(-0x1.FFFFFFFFFFFFFp+62, -0x8000000000000000); | 177 | try test_i64_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+62, -0x8000000000000000); |
| 162 | try test__fixsfdi(-0x1.FFFFFFFFFFFFEp+62, -0x8000000000000000); | 178 | try test_i64_intFromFloat_f32(-0x1.FFFFFFFFFFFFEp+62, -0x8000000000000000); |
| 163 | 179 | ||
| 164 | try test__fixsfdi(-0x1.FFFFFFp+62, -0x8000000000000000); | 180 | try test_i64_intFromFloat_f32(-0x1.FFFFFFp+62, -0x8000000000000000); |
| 165 | try test__fixsfdi(-0x1.FFFFFEp+62, -0x7fffff8000000000); | 181 | try test_i64_intFromFloat_f32(-0x1.FFFFFEp+62, -0x7fffff8000000000); |
| 166 | try test__fixsfdi(-0x1.FFFFFCp+62, -0x7fffff0000000000); | 182 | try test_i64_intFromFloat_f32(-0x1.FFFFFCp+62, -0x7fffff0000000000); |
| 167 | 183 | ||
| 168 | try test__fixsfdi(-2.01, -2); | 184 | try test_i64_intFromFloat_f32(-2.01, -2); |
| 169 | try test__fixsfdi(-2.0, -2); | 185 | try test_i64_intFromFloat_f32(-2.0, -2); |
| 170 | try test__fixsfdi(-1.99, -1); | 186 | try test_i64_intFromFloat_f32(-1.99, -1); |
| 171 | try test__fixsfdi(-1.0, -1); | 187 | try test_i64_intFromFloat_f32(-1.0, -1); |
| 172 | try test__fixsfdi(-0.99, 0); | 188 | try test_i64_intFromFloat_f32(-0.99, 0); |
| 173 | try test__fixsfdi(-0.5, 0); | 189 | try test_i64_intFromFloat_f32(-0.5, 0); |
| 174 | try test__fixsfdi(-math.floatMin(f32), 0); | 190 | try test_i64_intFromFloat_f32(-math.floatMin(f32), 0); |
| 175 | try test__fixsfdi(0.0, 0); | 191 | try test_i64_intFromFloat_f32(0.0, 0); |
| 176 | try test__fixsfdi(math.floatMin(f32), 0); | 192 | try test_i64_intFromFloat_f32(math.floatMin(f32), 0); |
| 177 | try test__fixsfdi(0.5, 0); | 193 | try test_i64_intFromFloat_f32(0.5, 0); |
| 178 | try test__fixsfdi(0.99, 0); | 194 | try test_i64_intFromFloat_f32(0.99, 0); |
| 179 | try test__fixsfdi(1.0, 1); | 195 | try test_i64_intFromFloat_f32(1.0, 1); |
| 180 | try test__fixsfdi(1.5, 1); | 196 | try test_i64_intFromFloat_f32(1.5, 1); |
| 181 | try test__fixsfdi(1.99, 1); | 197 | try test_i64_intFromFloat_f32(1.99, 1); |
| 182 | try test__fixsfdi(2.0, 2); | 198 | try test_i64_intFromFloat_f32(2.0, 2); |
| 183 | try test__fixsfdi(2.01, 2); | 199 | try test_i64_intFromFloat_f32(2.01, 2); |
| 184 | 200 | ||
| 185 | try test__fixsfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000); | 201 | try test_i64_intFromFloat_f32(0x1.FFFFFCp+62, 0x7FFFFF0000000000); |
| 186 | try test__fixsfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000); | 202 | try test_i64_intFromFloat_f32(0x1.FFFFFEp+62, 0x7FFFFF8000000000); |
| 187 | try test__fixsfdi(0x1.FFFFFFp+62, 0x7FFFFFFFFFFFFFFF); | 203 | try test_i64_intFromFloat_f32(0x1.FFFFFFp+62, 0x7FFFFFFFFFFFFFFF); |
| 188 | 204 | ||
| 189 | try test__fixsfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFFFFF); | 205 | try test_i64_intFromFloat_f32(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFFFFF); |
| 190 | try test__fixsfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFFFF); | 206 | try test_i64_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFFFF); |
| 191 | try test__fixsfdi(0x1.0000000000000p+63, 0x7FFFFFFFFFFFFFFF); | 207 | try test_i64_intFromFloat_f32(0x1.0000000000000p+63, 0x7FFFFFFFFFFFFFFF); |
| 192 | try test__fixsfdi(0x1.0000000000001p+63, 0x7FFFFFFFFFFFFFFF); | 208 | try test_i64_intFromFloat_f32(0x1.0000000000001p+63, 0x7FFFFFFFFFFFFFFF); |
| 193 | 209 | ||
| 194 | try test__fixsfdi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFF); | 210 | try test_i64_intFromFloat_f32(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFF); |
| 195 | try test__fixsfdi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFF); | 211 | try test_i64_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFF); |
| 196 | try test__fixsfdi(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFF); | 212 | try test_i64_intFromFloat_f32(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFF); |
| 197 | 213 | ||
| 198 | try test__fixsfdi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF); | 214 | try test_i64_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF); |
| 199 | try test__fixsfdi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64)); | 215 | try test_i64_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64)); |
| 200 | 216 | ||
| 201 | try test__fixsfdi(math.floatMax(f32), math.maxInt(i64)); | 217 | try test_i64_intFromFloat_f32(math.floatMax(f32), math.maxInt(i64)); |
| 202 | } | 218 | } |
| 203 | 219 | ||
| 204 | test "fixunssfdi" { | 220 | test u64_intFromFloat_f32 { |
| 205 | try test__fixunssfdi(0.0, 0); | 221 | try test_u64_intFromFloat_f32(0.0, 0); |
| 206 | 222 | ||
| 207 | try test__fixunssfdi(0.5, 0); | 223 | try test_u64_intFromFloat_f32(0.5, 0); |
| 208 | try test__fixunssfdi(0.99, 0); | 224 | try test_u64_intFromFloat_f32(0.99, 0); |
| 209 | try test__fixunssfdi(1.0, 1); | 225 | try test_u64_intFromFloat_f32(1.0, 1); |
| 210 | try test__fixunssfdi(1.5, 1); | 226 | try test_u64_intFromFloat_f32(1.5, 1); |
| 211 | try test__fixunssfdi(1.99, 1); | 227 | try test_u64_intFromFloat_f32(1.99, 1); |
| 212 | try test__fixunssfdi(2.0, 2); | 228 | try test_u64_intFromFloat_f32(2.0, 2); |
| 213 | try test__fixunssfdi(2.01, 2); | 229 | try test_u64_intFromFloat_f32(2.01, 2); |
| 214 | try test__fixunssfdi(-0.5, 0); | 230 | try test_u64_intFromFloat_f32(-0.5, 0); |
| 215 | try test__fixunssfdi(-0.99, 0); | 231 | try test_u64_intFromFloat_f32(-0.99, 0); |
| 216 | 232 | ||
| 217 | try test__fixunssfdi(-1.0, 0); | 233 | try test_u64_intFromFloat_f32(-1.0, 0); |
| 218 | try test__fixunssfdi(-1.5, 0); | 234 | try test_u64_intFromFloat_f32(-1.5, 0); |
| 219 | try test__fixunssfdi(-1.99, 0); | 235 | try test_u64_intFromFloat_f32(-1.99, 0); |
| 220 | try test__fixunssfdi(-2.0, 0); | 236 | try test_u64_intFromFloat_f32(-2.0, 0); |
| 221 | try test__fixunssfdi(-2.01, 0); | 237 | try test_u64_intFromFloat_f32(-2.01, 0); |
| 222 | 238 | ||
| 223 | try test__fixunssfdi(0x1.FFFFFEp+63, 0xFFFFFF0000000000); | 239 | try test_u64_intFromFloat_f32(0x1.FFFFFEp+63, 0xFFFFFF0000000000); |
| 224 | try test__fixunssfdi(0x1.000000p+63, 0x8000000000000000); | 240 | try test_u64_intFromFloat_f32(0x1.000000p+63, 0x8000000000000000); |
| 225 | try test__fixunssfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000); | 241 | try test_u64_intFromFloat_f32(0x1.FFFFFEp+62, 0x7FFFFF8000000000); |
| 226 | try test__fixunssfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000); | 242 | try test_u64_intFromFloat_f32(0x1.FFFFFCp+62, 0x7FFFFF0000000000); |
| 227 | 243 | ||
| 228 | try test__fixunssfdi(-0x1.FFFFFEp+62, 0x0000000000000000); | 244 | try test_u64_intFromFloat_f32(-0x1.FFFFFEp+62, 0x0000000000000000); |
| 229 | try test__fixunssfdi(-0x1.FFFFFCp+62, 0x0000000000000000); | 245 | try test_u64_intFromFloat_f32(-0x1.FFFFFCp+62, 0x0000000000000000); |
| 230 | } | 246 | } |
| 231 | 247 | ||
| 232 | fn test__fixsfti(a: f32, expected: i128) !void { | 248 | fn test_i128_intFromFloat_f32(a: f32, expected: i128) !void { |
| 233 | const x = __fixsfti(a); | 249 | const x = i128_intFromFloat_f32(a); |
| 234 | try testing.expect(x == expected); | 250 | try testing.expect(x == expected); |
| 235 | } | 251 | } |
| 236 | 252 | ||
| 237 | fn test__fixunssfti(a: f32, expected: u128) !void { | 253 | fn test_u128_intFromFloat_f32(a: f32, expected: u128) !void { |
| 238 | const x = __fixunssfti(a); | 254 | const x = u128_intFromFloat_f32(a); |
| 239 | try testing.expect(x == expected); | 255 | try testing.expect(x == expected); |
| 240 | } | 256 | } |
| 241 | 257 | ||
| 242 | test "fixsfti" { | 258 | test i128_intFromFloat_f32 { |
| 243 | try test__fixsfti(-math.floatMax(f32), math.minInt(i128)); | 259 | try test_i128_intFromFloat_f32(-math.floatMax(f32), math.minInt(i128)); |
| 244 | 260 | ||
| 245 | try test__fixsfti(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128)); | 261 | try test_i128_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128)); |
| 246 | try test__fixsfti(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000); | 262 | try test_i128_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000); |
| 247 | 263 | ||
| 248 | try test__fixsfti(-0x1.0000000000000p+127, -0x80000000000000000000000000000000); | 264 | try test_i128_intFromFloat_f32(-0x1.0000000000000p+127, -0x80000000000000000000000000000000); |
| 249 | try test__fixsfti(-0x1.FFFFFFFFFFFFFp+126, -0x80000000000000000000000000000000); | 265 | try test_i128_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+126, -0x80000000000000000000000000000000); |
| 250 | try test__fixsfti(-0x1.FFFFFFFFFFFFEp+126, -0x80000000000000000000000000000000); | 266 | try test_i128_intFromFloat_f32(-0x1.FFFFFFFFFFFFEp+126, -0x80000000000000000000000000000000); |
| 251 | try test__fixsfti(-0x1.FFFFFF0000000p+126, -0x80000000000000000000000000000000); | 267 | try test_i128_intFromFloat_f32(-0x1.FFFFFF0000000p+126, -0x80000000000000000000000000000000); |
| 252 | try test__fixsfti(-0x1.FFFFFE0000000p+126, -0x7FFFFF80000000000000000000000000); | 268 | try test_i128_intFromFloat_f32(-0x1.FFFFFE0000000p+126, -0x7FFFFF80000000000000000000000000); |
| 253 | try test__fixsfti(-0x1.FFFFFC0000000p+126, -0x7FFFFF00000000000000000000000000); | 269 | try test_i128_intFromFloat_f32(-0x1.FFFFFC0000000p+126, -0x7FFFFF00000000000000000000000000); |
| 254 | 270 | ||
| 255 | try test__fixsfti(-0x1.0000000000001p+63, -0x8000000000000000); | 271 | try test_i128_intFromFloat_f32(-0x1.0000000000001p+63, -0x8000000000000000); |
| 256 | try test__fixsfti(-0x1.0000000000000p+63, -0x8000000000000000); | 272 | try test_i128_intFromFloat_f32(-0x1.0000000000000p+63, -0x8000000000000000); |
| 257 | try test__fixsfti(-0x1.FFFFFFFFFFFFFp+62, -0x8000000000000000); | 273 | try test_i128_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+62, -0x8000000000000000); |
| 258 | try test__fixsfti(-0x1.FFFFFFFFFFFFEp+62, -0x8000000000000000); | 274 | try test_i128_intFromFloat_f32(-0x1.FFFFFFFFFFFFEp+62, -0x8000000000000000); |
| 259 | 275 | ||
| 260 | try test__fixsfti(-0x1.FFFFFFp+62, -0x8000000000000000); | 276 | try test_i128_intFromFloat_f32(-0x1.FFFFFFp+62, -0x8000000000000000); |
| 261 | try test__fixsfti(-0x1.FFFFFEp+62, -0x7fffff8000000000); | 277 | try test_i128_intFromFloat_f32(-0x1.FFFFFEp+62, -0x7fffff8000000000); |
| 262 | try test__fixsfti(-0x1.FFFFFCp+62, -0x7fffff0000000000); | 278 | try test_i128_intFromFloat_f32(-0x1.FFFFFCp+62, -0x7fffff0000000000); |
| 263 | 279 | ||
| 264 | try test__fixsfti(-0x1.000000p+31, -0x80000000); | 280 | try test_i128_intFromFloat_f32(-0x1.000000p+31, -0x80000000); |
| 265 | try test__fixsfti(-0x1.FFFFFFp+30, -0x80000000); | 281 | try test_i128_intFromFloat_f32(-0x1.FFFFFFp+30, -0x80000000); |
| 266 | try test__fixsfti(-0x1.FFFFFEp+30, -0x7FFFFF80); | 282 | try test_i128_intFromFloat_f32(-0x1.FFFFFEp+30, -0x7FFFFF80); |
| 267 | try test__fixsfti(-0x1.FFFFFCp+30, -0x7FFFFF00); | 283 | try test_i128_intFromFloat_f32(-0x1.FFFFFCp+30, -0x7FFFFF00); |
| 268 | 284 | ||
| 269 | try test__fixsfti(-2.01, -2); | 285 | try test_i128_intFromFloat_f32(-2.01, -2); |
| 270 | try test__fixsfti(-2.0, -2); | 286 | try test_i128_intFromFloat_f32(-2.0, -2); |
| 271 | try test__fixsfti(-1.99, -1); | 287 | try test_i128_intFromFloat_f32(-1.99, -1); |
| 272 | try test__fixsfti(-1.0, -1); | 288 | try test_i128_intFromFloat_f32(-1.0, -1); |
| 273 | try test__fixsfti(-0.99, 0); | 289 | try test_i128_intFromFloat_f32(-0.99, 0); |
| 274 | try test__fixsfti(-0.5, 0); | 290 | try test_i128_intFromFloat_f32(-0.5, 0); |
| 275 | try test__fixsfti(-math.floatMin(f32), 0); | 291 | try test_i128_intFromFloat_f32(-math.floatMin(f32), 0); |
| 276 | try test__fixsfti(0.0, 0); | 292 | try test_i128_intFromFloat_f32(0.0, 0); |
| 277 | try test__fixsfti(math.floatMin(f32), 0); | 293 | try test_i128_intFromFloat_f32(math.floatMin(f32), 0); |
| 278 | try test__fixsfti(0.5, 0); | 294 | try test_i128_intFromFloat_f32(0.5, 0); |
| 279 | try test__fixsfti(0.99, 0); | 295 | try test_i128_intFromFloat_f32(0.99, 0); |
| 280 | try test__fixsfti(1.0, 1); | 296 | try test_i128_intFromFloat_f32(1.0, 1); |
| 281 | try test__fixsfti(1.5, 1); | 297 | try test_i128_intFromFloat_f32(1.5, 1); |
| 282 | try test__fixsfti(1.99, 1); | 298 | try test_i128_intFromFloat_f32(1.99, 1); |
| 283 | try test__fixsfti(2.0, 2); | 299 | try test_i128_intFromFloat_f32(2.0, 2); |
| 284 | try test__fixsfti(2.01, 2); | 300 | try test_i128_intFromFloat_f32(2.01, 2); |
| 285 | 301 | ||
| 286 | try test__fixsfti(0x1.FFFFFCp+30, 0x7FFFFF00); | 302 | try test_i128_intFromFloat_f32(0x1.FFFFFCp+30, 0x7FFFFF00); |
| 287 | try test__fixsfti(0x1.FFFFFEp+30, 0x7FFFFF80); | 303 | try test_i128_intFromFloat_f32(0x1.FFFFFEp+30, 0x7FFFFF80); |
| 288 | try test__fixsfti(0x1.FFFFFFp+30, 0x80000000); | 304 | try test_i128_intFromFloat_f32(0x1.FFFFFFp+30, 0x80000000); |
| 289 | try test__fixsfti(0x1.000000p+31, 0x80000000); | 305 | try test_i128_intFromFloat_f32(0x1.000000p+31, 0x80000000); |
| 290 | 306 | ||
| 291 | try test__fixsfti(0x1.FFFFFCp+62, 0x7FFFFF0000000000); | 307 | try test_i128_intFromFloat_f32(0x1.FFFFFCp+62, 0x7FFFFF0000000000); |
| 292 | try test__fixsfti(0x1.FFFFFEp+62, 0x7FFFFF8000000000); | 308 | try test_i128_intFromFloat_f32(0x1.FFFFFEp+62, 0x7FFFFF8000000000); |
| 293 | try test__fixsfti(0x1.FFFFFFp+62, 0x8000000000000000); | 309 | try test_i128_intFromFloat_f32(0x1.FFFFFFp+62, 0x8000000000000000); |
| 294 | 310 | ||
| 295 | try test__fixsfti(0x1.FFFFFFFFFFFFEp+62, 0x8000000000000000); | 311 | try test_i128_intFromFloat_f32(0x1.FFFFFFFFFFFFEp+62, 0x8000000000000000); |
| 296 | try test__fixsfti(0x1.FFFFFFFFFFFFFp+62, 0x8000000000000000); | 312 | try test_i128_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+62, 0x8000000000000000); |
| 297 | try test__fixsfti(0x1.0000000000000p+63, 0x8000000000000000); | 313 | try test_i128_intFromFloat_f32(0x1.0000000000000p+63, 0x8000000000000000); |
| 298 | try test__fixsfti(0x1.0000000000001p+63, 0x8000000000000000); | 314 | try test_i128_intFromFloat_f32(0x1.0000000000001p+63, 0x8000000000000000); |
| 299 | 315 | ||
| 300 | try test__fixsfti(0x1.FFFFFC0000000p+126, 0x7FFFFF00000000000000000000000000); | 316 | try test_i128_intFromFloat_f32(0x1.FFFFFC0000000p+126, 0x7FFFFF00000000000000000000000000); |
| 301 | try test__fixsfti(0x1.FFFFFE0000000p+126, 0x7FFFFF80000000000000000000000000); | 317 | try test_i128_intFromFloat_f32(0x1.FFFFFE0000000p+126, 0x7FFFFF80000000000000000000000000); |
| 302 | try test__fixsfti(0x1.FFFFFF0000000p+126, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); | 318 | try test_i128_intFromFloat_f32(0x1.FFFFFF0000000p+126, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); |
| 303 | try test__fixsfti(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); | 319 | try test_i128_intFromFloat_f32(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); |
| 304 | try test__fixsfti(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); | 320 | try test_i128_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); |
| 305 | try test__fixsfti(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); | 321 | try test_i128_intFromFloat_f32(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); |
| 306 | 322 | ||
| 307 | try test__fixsfti(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); | 323 | try test_i128_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); |
| 308 | try test__fixsfti(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128)); | 324 | try test_i128_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128)); |
| 309 | 325 | ||
| 310 | try test__fixsfti(math.floatMax(f32), math.maxInt(i128)); | 326 | try test_i128_intFromFloat_f32(math.floatMax(f32), math.maxInt(i128)); |
| 311 | } | 327 | } |
| 312 | 328 | ||
| 313 | test "fixunssfti" { | 329 | test u128_intFromFloat_f32 { |
| 314 | try test__fixunssfti(0.0, 0); | 330 | try test_u128_intFromFloat_f32(0.0, 0); |
| 315 | 331 | ||
| 316 | try test__fixunssfti(0.5, 0); | 332 | try test_u128_intFromFloat_f32(0.5, 0); |
| 317 | try test__fixunssfti(0.99, 0); | 333 | try test_u128_intFromFloat_f32(0.99, 0); |
| 318 | try test__fixunssfti(1.0, 1); | 334 | try test_u128_intFromFloat_f32(1.0, 1); |
| 319 | try test__fixunssfti(1.5, 1); | 335 | try test_u128_intFromFloat_f32(1.5, 1); |
| 320 | try test__fixunssfti(1.99, 1); | 336 | try test_u128_intFromFloat_f32(1.99, 1); |
| 321 | try test__fixunssfti(2.0, 2); | 337 | try test_u128_intFromFloat_f32(2.0, 2); |
| 322 | try test__fixunssfti(2.01, 2); | 338 | try test_u128_intFromFloat_f32(2.01, 2); |
| 323 | try test__fixunssfti(-0.5, 0); | 339 | try test_u128_intFromFloat_f32(-0.5, 0); |
| 324 | try test__fixunssfti(-0.99, 0); | 340 | try test_u128_intFromFloat_f32(-0.99, 0); |
| 325 | 341 | ||
| 326 | try test__fixunssfti(-1.0, 0); | 342 | try test_u128_intFromFloat_f32(-1.0, 0); |
| 327 | try test__fixunssfti(-1.5, 0); | 343 | try test_u128_intFromFloat_f32(-1.5, 0); |
| 328 | try test__fixunssfti(-1.99, 0); | 344 | try test_u128_intFromFloat_f32(-1.99, 0); |
| 329 | try test__fixunssfti(-2.0, 0); | 345 | try test_u128_intFromFloat_f32(-2.0, 0); |
| 330 | try test__fixunssfti(-2.01, 0); | 346 | try test_u128_intFromFloat_f32(-2.01, 0); |
| 331 | 347 | ||
| 332 | try test__fixunssfti(0x1.FFFFFEp+63, 0xFFFFFF0000000000); | 348 | try test_u128_intFromFloat_f32(0x1.FFFFFEp+63, 0xFFFFFF0000000000); |
| 333 | try test__fixunssfti(0x1.000000p+63, 0x8000000000000000); | 349 | try test_u128_intFromFloat_f32(0x1.000000p+63, 0x8000000000000000); |
| 334 | try test__fixunssfti(0x1.FFFFFEp+62, 0x7FFFFF8000000000); | 350 | try test_u128_intFromFloat_f32(0x1.FFFFFEp+62, 0x7FFFFF8000000000); |
| 335 | try test__fixunssfti(0x1.FFFFFCp+62, 0x7FFFFF0000000000); | 351 | try test_u128_intFromFloat_f32(0x1.FFFFFCp+62, 0x7FFFFF0000000000); |
| 336 | try test__fixunssfti(0x1.FFFFFEp+127, 0xFFFFFF00000000000000000000000000); | 352 | try test_u128_intFromFloat_f32(0x1.FFFFFEp+127, 0xFFFFFF00000000000000000000000000); |
| 337 | try test__fixunssfti(0x1.000000p+127, 0x80000000000000000000000000000000); | 353 | try test_u128_intFromFloat_f32(0x1.000000p+127, 0x80000000000000000000000000000000); |
| 338 | try test__fixunssfti(0x1.FFFFFEp+126, 0x7FFFFF80000000000000000000000000); | 354 | try test_u128_intFromFloat_f32(0x1.FFFFFEp+126, 0x7FFFFF80000000000000000000000000); |
| 339 | try test__fixunssfti(0x1.FFFFFCp+126, 0x7FFFFF00000000000000000000000000); | 355 | try test_u128_intFromFloat_f32(0x1.FFFFFCp+126, 0x7FFFFF00000000000000000000000000); |
| 340 | 356 | ||
| 341 | try test__fixunssfti(-0x1.FFFFFEp+62, 0x0000000000000000); | 357 | try test_u128_intFromFloat_f32(-0x1.FFFFFEp+62, 0x0000000000000000); |
| 342 | try test__fixunssfti(-0x1.FFFFFCp+62, 0x0000000000000000); | 358 | try test_u128_intFromFloat_f32(-0x1.FFFFFCp+62, 0x0000000000000000); |
| 343 | try test__fixunssfti(-0x1.FFFFFEp+126, 0x0000000000000000); | 359 | try test_u128_intFromFloat_f32(-0x1.FFFFFEp+126, 0x0000000000000000); |
| 344 | try test__fixunssfti(-0x1.FFFFFCp+126, 0x0000000000000000); | 360 | try test_u128_intFromFloat_f32(-0x1.FFFFFCp+126, 0x0000000000000000); |
| 345 | try test__fixunssfti(math.floatMax(f32), 0xffffff00000000000000000000000000); | 361 | try test_u128_intFromFloat_f32(math.floatMax(f32), 0xffffff00000000000000000000000000); |
| 346 | try test__fixunssfti(math.inf(f32), math.maxInt(u128)); | 362 | try test_u128_intFromFloat_f32(math.inf(f32), math.maxInt(u128)); |
| 347 | } | 363 | } |
| 348 | 364 | ||
| 349 | fn test_fixsfei(comptime T: type, expected: T, a: f32) !void { | 365 | fn test_intFromFloat_f32(comptime T: type, expected: T, a: f32) !void { |
| 350 | const int = @typeInfo(T).int; | 366 | const int = @typeInfo(T).int; |
| 351 | var actual: T = undefined; | 367 | var actual: T = undefined; |
| 352 | _ = switch (int.signedness) { | 368 | _ = switch (int.signedness) { |
| 353 | .signed => __fixsfei, | 369 | .signed => signed_intFromFloat_f32, |
| 354 | .unsigned => __fixunssfei, | 370 | .unsigned => unsigned_intFromFloat_f32, |
| 355 | }(@ptrCast(&actual), int.bits, a); | 371 | }(@ptrCast(&actual), a); |
| 356 | try testing.expect(expected == actual); | 372 | try testing.expect(expected == actual); |
| 357 | } | 373 | } |
| 358 | 374 | ||
| 359 | test "fixsfei" { | 375 | test signed_intFromFloat_f32 { |
| 360 | try test_fixsfei(i256, -1 << 127, -0x1p127); | 376 | try test_intFromFloat_f32(i256, -1 << 127, -0x1p127); |
| 361 | try test_fixsfei(i256, -1 << 100, -0x1p100); | 377 | try test_intFromFloat_f32(i256, -1 << 100, -0x1p100); |
| 362 | try test_fixsfei(i256, -1 << 50, -0x1p50); | 378 | try test_intFromFloat_f32(i256, -1 << 50, -0x1p50); |
| 363 | try test_fixsfei(i256, -1 << 1, -0x1p1); | 379 | try test_intFromFloat_f32(i256, -1 << 1, -0x1p1); |
| 364 | try test_fixsfei(i256, -1 << 0, -0x1p0); | 380 | try test_intFromFloat_f32(i256, -1 << 0, -0x1p0); |
| 365 | try test_fixsfei(i256, 0, 0); | 381 | try test_intFromFloat_f32(i256, 0, 0); |
| 366 | try test_fixsfei(i256, 1 << 0, 0x1p0); | 382 | try test_intFromFloat_f32(i256, 1 << 0, 0x1p0); |
| 367 | try test_fixsfei(i256, 1 << 1, 0x1p1); | 383 | try test_intFromFloat_f32(i256, 1 << 1, 0x1p1); |
| 368 | try test_fixsfei(i256, 1 << 50, 0x1p50); | 384 | try test_intFromFloat_f32(i256, 1 << 50, 0x1p50); |
| 369 | try test_fixsfei(i256, 1 << 100, 0x1p100); | 385 | try test_intFromFloat_f32(i256, 1 << 100, 0x1p100); |
| 370 | try test_fixsfei(i256, 1 << 127, 0x1p127); | 386 | try test_intFromFloat_f32(i256, 1 << 127, 0x1p127); |
| 371 | } | 387 | } |
| 372 | 388 | ||
| 373 | test "fixunsfei" { | 389 | test unsigned_intFromFloat_f32 { |
| 374 | try test_fixsfei(u256, 0, 0); | 390 | try test_intFromFloat_f32(u256, 0, 0); |
| 375 | try test_fixsfei(u256, 1 << 0, 0x1p0); | 391 | try test_intFromFloat_f32(u256, 1 << 0, 0x1p0); |
| 376 | try test_fixsfei(u256, 1 << 1, 0x1p1); | 392 | try test_intFromFloat_f32(u256, 1 << 1, 0x1p1); |
| 377 | try test_fixsfei(u256, 1 << 50, 0x1p50); | 393 | try test_intFromFloat_f32(u256, 1 << 50, 0x1p50); |
| 378 | try test_fixsfei(u256, 1 << 100, 0x1p100); | 394 | try test_intFromFloat_f32(u256, 1 << 100, 0x1p100); |
| 379 | try test_fixsfei(u256, 1 << 127, 0x1p127); | 395 | try test_intFromFloat_f32(u256, 1 << 127, 0x1p127); |
| 380 | } | 396 | } |
| 381 | 397 | ||
| 382 | fn test__fixdfsi(a: f64, expected: i32) !void { | 398 | fn test_i32_intFromFloat_f64(a: f64, expected: i32) !void { |
| 383 | const x = __fixdfsi(a); | 399 | const x = i32_intFromFloat_f64(a); |
| 384 | try testing.expect(x == expected); | 400 | try testing.expect(x == expected); |
| 385 | } | 401 | } |
| 386 | 402 | ||
| 387 | fn test__fixunsdfsi(a: f64, expected: u32) !void { | 403 | fn test_u32_intFromFloat_f64(a: f64, expected: u32) !void { |
| 388 | const x = __fixunsdfsi(a); | 404 | const x = u32_intFromFloat_f64(a); |
| 389 | try testing.expect(x == expected); | 405 | try testing.expect(x == expected); |
| 390 | } | 406 | } |
| 391 | 407 | ||
| 392 | test "fixdfsi" { | 408 | test i32_intFromFloat_f64 { |
| 393 | try test__fixdfsi(-math.floatMax(f64), math.minInt(i32)); | 409 | try test_i32_intFromFloat_f64(-math.floatMax(f64), math.minInt(i32)); |
| 394 | 410 | ||
| 395 | try test__fixdfsi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32)); | 411 | try test_i32_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32)); |
| 396 | try test__fixdfsi(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000); | 412 | try test_i32_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000); |
| 397 | 413 | ||
| 398 | try test__fixdfsi(-0x1.0000000000000p+127, -0x80000000); | 414 | try test_i32_intFromFloat_f64(-0x1.0000000000000p+127, -0x80000000); |
| 399 | try test__fixdfsi(-0x1.FFFFFFFFFFFFFp+126, -0x80000000); | 415 | try test_i32_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+126, -0x80000000); |
| 400 | try test__fixdfsi(-0x1.FFFFFFFFFFFFEp+126, -0x80000000); | 416 | try test_i32_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+126, -0x80000000); |
| 401 | 417 | ||
| 402 | try test__fixdfsi(-0x1.0000000000001p+63, -0x80000000); | 418 | try test_i32_intFromFloat_f64(-0x1.0000000000001p+63, -0x80000000); |
| 403 | try test__fixdfsi(-0x1.0000000000000p+63, -0x80000000); | 419 | try test_i32_intFromFloat_f64(-0x1.0000000000000p+63, -0x80000000); |
| 404 | try test__fixdfsi(-0x1.FFFFFFFFFFFFFp+62, -0x80000000); | 420 | try test_i32_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+62, -0x80000000); |
| 405 | try test__fixdfsi(-0x1.FFFFFFFFFFFFEp+62, -0x80000000); | 421 | try test_i32_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+62, -0x80000000); |
| 406 | 422 | ||
| 407 | try test__fixdfsi(-0x1.FFFFFEp+62, -0x80000000); | 423 | try test_i32_intFromFloat_f64(-0x1.FFFFFEp+62, -0x80000000); |
| 408 | try test__fixdfsi(-0x1.FFFFFCp+62, -0x80000000); | 424 | try test_i32_intFromFloat_f64(-0x1.FFFFFCp+62, -0x80000000); |
| 409 | 425 | ||
| 410 | try test__fixdfsi(-0x1.000000p+31, -0x80000000); | 426 | try test_i32_intFromFloat_f64(-0x1.000000p+31, -0x80000000); |
| 411 | try test__fixdfsi(-0x1.FFFFFFp+30, -0x7FFFFFC0); | 427 | try test_i32_intFromFloat_f64(-0x1.FFFFFFp+30, -0x7FFFFFC0); |
| 412 | try test__fixdfsi(-0x1.FFFFFEp+30, -0x7FFFFF80); | 428 | try test_i32_intFromFloat_f64(-0x1.FFFFFEp+30, -0x7FFFFF80); |
| 413 | 429 | ||
| 414 | try test__fixdfsi(-2.01, -2); | 430 | try test_i32_intFromFloat_f64(-2.01, -2); |
| 415 | try test__fixdfsi(-2.0, -2); | 431 | try test_i32_intFromFloat_f64(-2.0, -2); |
| 416 | try test__fixdfsi(-1.99, -1); | 432 | try test_i32_intFromFloat_f64(-1.99, -1); |
| 417 | try test__fixdfsi(-1.0, -1); | 433 | try test_i32_intFromFloat_f64(-1.0, -1); |
| 418 | try test__fixdfsi(-0.99, 0); | 434 | try test_i32_intFromFloat_f64(-0.99, 0); |
| 419 | try test__fixdfsi(-0.5, 0); | 435 | try test_i32_intFromFloat_f64(-0.5, 0); |
| 420 | try test__fixdfsi(-math.floatMin(f64), 0); | 436 | try test_i32_intFromFloat_f64(-math.floatMin(f64), 0); |
| 421 | try test__fixdfsi(0.0, 0); | 437 | try test_i32_intFromFloat_f64(0.0, 0); |
| 422 | try test__fixdfsi(math.floatMin(f64), 0); | 438 | try test_i32_intFromFloat_f64(math.floatMin(f64), 0); |
| 423 | try test__fixdfsi(0.5, 0); | 439 | try test_i32_intFromFloat_f64(0.5, 0); |
| 424 | try test__fixdfsi(0.99, 0); | 440 | try test_i32_intFromFloat_f64(0.99, 0); |
| 425 | try test__fixdfsi(1.0, 1); | 441 | try test_i32_intFromFloat_f64(1.0, 1); |
| 426 | try test__fixdfsi(1.5, 1); | 442 | try test_i32_intFromFloat_f64(1.5, 1); |
| 427 | try test__fixdfsi(1.99, 1); | 443 | try test_i32_intFromFloat_f64(1.99, 1); |
| 428 | try test__fixdfsi(2.0, 2); | 444 | try test_i32_intFromFloat_f64(2.0, 2); |
| 429 | try test__fixdfsi(2.01, 2); | 445 | try test_i32_intFromFloat_f64(2.01, 2); |
| 430 | 446 | ||
| 431 | try test__fixdfsi(0x1.FFFFFEp+30, 0x7FFFFF80); | 447 | try test_i32_intFromFloat_f64(0x1.FFFFFEp+30, 0x7FFFFF80); |
| 432 | try test__fixdfsi(0x1.FFFFFFp+30, 0x7FFFFFC0); | 448 | try test_i32_intFromFloat_f64(0x1.FFFFFFp+30, 0x7FFFFFC0); |
| 433 | try test__fixdfsi(0x1.000000p+31, 0x7FFFFFFF); | 449 | try test_i32_intFromFloat_f64(0x1.000000p+31, 0x7FFFFFFF); |
| 434 | 450 | ||
| 435 | try test__fixdfsi(0x1.FFFFFCp+62, 0x7FFFFFFF); | 451 | try test_i32_intFromFloat_f64(0x1.FFFFFCp+62, 0x7FFFFFFF); |
| 436 | try test__fixdfsi(0x1.FFFFFEp+62, 0x7FFFFFFF); | 452 | try test_i32_intFromFloat_f64(0x1.FFFFFEp+62, 0x7FFFFFFF); |
| 437 | 453 | ||
| 438 | try test__fixdfsi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFF); | 454 | try test_i32_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFF); |
| 439 | try test__fixdfsi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFF); | 455 | try test_i32_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFF); |
| 440 | try test__fixdfsi(0x1.0000000000000p+63, 0x7FFFFFFF); | 456 | try test_i32_intFromFloat_f64(0x1.0000000000000p+63, 0x7FFFFFFF); |
| 441 | try test__fixdfsi(0x1.0000000000001p+63, 0x7FFFFFFF); | 457 | try test_i32_intFromFloat_f64(0x1.0000000000001p+63, 0x7FFFFFFF); |
| 442 | 458 | ||
| 443 | try test__fixdfsi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFF); | 459 | try test_i32_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFF); |
| 444 | try test__fixdfsi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFF); | 460 | try test_i32_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFF); |
| 445 | try test__fixdfsi(0x1.0000000000000p+127, 0x7FFFFFFF); | 461 | try test_i32_intFromFloat_f64(0x1.0000000000000p+127, 0x7FFFFFFF); |
| 446 | 462 | ||
| 447 | try test__fixdfsi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF); | 463 | try test_i32_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF); |
| 448 | try test__fixdfsi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32)); | 464 | try test_i32_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32)); |
| 449 | 465 | ||
| 450 | try test__fixdfsi(math.floatMax(f64), math.maxInt(i32)); | 466 | try test_i32_intFromFloat_f64(math.floatMax(f64), math.maxInt(i32)); |
| 451 | } | 467 | } |
| 452 | 468 | ||
| 453 | test "fixunsdfsi" { | 469 | test u32_intFromFloat_f64 { |
| 454 | try test__fixunsdfsi(0.0, 0); | 470 | try test_u32_intFromFloat_f64(0.0, 0); |
| 455 | 471 | ||
| 456 | try test__fixunsdfsi(0.5, 0); | 472 | try test_u32_intFromFloat_f64(0.5, 0); |
| 457 | try test__fixunsdfsi(0.99, 0); | 473 | try test_u32_intFromFloat_f64(0.99, 0); |
| 458 | try test__fixunsdfsi(1.0, 1); | 474 | try test_u32_intFromFloat_f64(1.0, 1); |
| 459 | try test__fixunsdfsi(1.5, 1); | 475 | try test_u32_intFromFloat_f64(1.5, 1); |
| 460 | try test__fixunsdfsi(1.99, 1); | 476 | try test_u32_intFromFloat_f64(1.99, 1); |
| 461 | try test__fixunsdfsi(2.0, 2); | 477 | try test_u32_intFromFloat_f64(2.0, 2); |
| 462 | try test__fixunsdfsi(2.01, 2); | 478 | try test_u32_intFromFloat_f64(2.01, 2); |
| 463 | try test__fixunsdfsi(-0.5, 0); | 479 | try test_u32_intFromFloat_f64(-0.5, 0); |
| 464 | try test__fixunsdfsi(-0.99, 0); | 480 | try test_u32_intFromFloat_f64(-0.99, 0); |
| 465 | try test__fixunsdfsi(-1.0, 0); | 481 | try test_u32_intFromFloat_f64(-1.0, 0); |
| 466 | try test__fixunsdfsi(-1.5, 0); | 482 | try test_u32_intFromFloat_f64(-1.5, 0); |
| 467 | try test__fixunsdfsi(-1.99, 0); | 483 | try test_u32_intFromFloat_f64(-1.99, 0); |
| 468 | try test__fixunsdfsi(-2.0, 0); | 484 | try test_u32_intFromFloat_f64(-2.0, 0); |
| 469 | try test__fixunsdfsi(-2.01, 0); | 485 | try test_u32_intFromFloat_f64(-2.01, 0); |
| 470 | 486 | ||
| 471 | try test__fixunsdfsi(0x1.000000p+31, 0x80000000); | 487 | try test_u32_intFromFloat_f64(0x1.000000p+31, 0x80000000); |
| 472 | try test__fixunsdfsi(0x1.000000p+32, 0xFFFFFFFF); | 488 | try test_u32_intFromFloat_f64(0x1.000000p+32, 0xFFFFFFFF); |
| 473 | try test__fixunsdfsi(0x1.FFFFFEp+31, 0xFFFFFF00); | 489 | try test_u32_intFromFloat_f64(0x1.FFFFFEp+31, 0xFFFFFF00); |
| 474 | try test__fixunsdfsi(0x1.FFFFFEp+30, 0x7FFFFF80); | 490 | try test_u32_intFromFloat_f64(0x1.FFFFFEp+30, 0x7FFFFF80); |
| 475 | try test__fixunsdfsi(0x1.FFFFFCp+30, 0x7FFFFF00); | 491 | try test_u32_intFromFloat_f64(0x1.FFFFFCp+30, 0x7FFFFF00); |
| 476 | 492 | ||
| 477 | try test__fixunsdfsi(-0x1.FFFFFEp+30, 0); | 493 | try test_u32_intFromFloat_f64(-0x1.FFFFFEp+30, 0); |
| 478 | try test__fixunsdfsi(-0x1.FFFFFCp+30, 0); | 494 | try test_u32_intFromFloat_f64(-0x1.FFFFFCp+30, 0); |
| 479 | 495 | ||
| 480 | try test__fixunsdfsi(0x1.FFFFFFFEp+31, 0xFFFFFFFF); | 496 | try test_u32_intFromFloat_f64(0x1.FFFFFFFEp+31, 0xFFFFFFFF); |
| 481 | try test__fixunsdfsi(0x1.FFFFFFFC00000p+30, 0x7FFFFFFF); | 497 | try test_u32_intFromFloat_f64(0x1.FFFFFFFC00000p+30, 0x7FFFFFFF); |
| 482 | try test__fixunsdfsi(0x1.FFFFFFF800000p+30, 0x7FFFFFFE); | 498 | try test_u32_intFromFloat_f64(0x1.FFFFFFF800000p+30, 0x7FFFFFFE); |
| 483 | } | 499 | } |
| 484 | 500 | ||
| 485 | fn test__fixdfdi(a: f64, expected: i64) !void { | 501 | fn test_i64_intFromFloat_f64(a: f64, expected: i64) !void { |
| 486 | const x = __fixdfdi(a); | 502 | const x = i64_intFromFloat_f64(a); |
| 487 | try testing.expect(x == expected); | 503 | try testing.expect(x == expected); |
| 488 | } | 504 | } |
| 489 | 505 | ||
| 490 | fn test__fixunsdfdi(a: f64, expected: u64) !void { | 506 | fn test_u64_intFromFloat_f64(a: f64, expected: u64) !void { |
| 491 | const x = __fixunsdfdi(a); | 507 | const x = u64_intFromFloat_f64(a); |
| 492 | try testing.expect(x == expected); | 508 | try testing.expect(x == expected); |
| 493 | } | 509 | } |
| 494 | 510 | ||
| 495 | test "fixdfdi" { | 511 | test i64_intFromFloat_f64 { |
| 496 | try test__fixdfdi(-math.floatMax(f64), math.minInt(i64)); | 512 | try test_i64_intFromFloat_f64(-math.floatMax(f64), math.minInt(i64)); |
| 497 | 513 | ||
| 498 | try test__fixdfdi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64)); | 514 | try test_i64_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64)); |
| 499 | try test__fixdfdi(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000); | 515 | try test_i64_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000); |
| 500 | 516 | ||
| 501 | try test__fixdfdi(-0x1.0000000000000p+127, -0x8000000000000000); | 517 | try test_i64_intFromFloat_f64(-0x1.0000000000000p+127, -0x8000000000000000); |
| 502 | try test__fixdfdi(-0x1.FFFFFFFFFFFFFp+126, -0x8000000000000000); | 518 | try test_i64_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+126, -0x8000000000000000); |
| 503 | try test__fixdfdi(-0x1.FFFFFFFFFFFFEp+126, -0x8000000000000000); | 519 | try test_i64_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+126, -0x8000000000000000); |
| 504 | 520 | ||
| 505 | try test__fixdfdi(-0x1.0000000000001p+63, -0x8000000000000000); | 521 | try test_i64_intFromFloat_f64(-0x1.0000000000001p+63, -0x8000000000000000); |
| 506 | try test__fixdfdi(-0x1.0000000000000p+63, -0x8000000000000000); | 522 | try test_i64_intFromFloat_f64(-0x1.0000000000000p+63, -0x8000000000000000); |
| 507 | try test__fixdfdi(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00); | 523 | try test_i64_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00); |
| 508 | try test__fixdfdi(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800); | 524 | try test_i64_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800); |
| 509 | 525 | ||
| 510 | try test__fixdfdi(-0x1.FFFFFEp+62, -0x7fffff8000000000); | 526 | try test_i64_intFromFloat_f64(-0x1.FFFFFEp+62, -0x7fffff8000000000); |
| 511 | try test__fixdfdi(-0x1.FFFFFCp+62, -0x7fffff0000000000); | 527 | try test_i64_intFromFloat_f64(-0x1.FFFFFCp+62, -0x7fffff0000000000); |
| 512 | 528 | ||
| 513 | try test__fixdfdi(-2.01, -2); | 529 | try test_i64_intFromFloat_f64(-2.01, -2); |
| 514 | try test__fixdfdi(-2.0, -2); | 530 | try test_i64_intFromFloat_f64(-2.0, -2); |
| 515 | try test__fixdfdi(-1.99, -1); | 531 | try test_i64_intFromFloat_f64(-1.99, -1); |
| 516 | try test__fixdfdi(-1.0, -1); | 532 | try test_i64_intFromFloat_f64(-1.0, -1); |
| 517 | try test__fixdfdi(-0.99, 0); | 533 | try test_i64_intFromFloat_f64(-0.99, 0); |
| 518 | try test__fixdfdi(-0.5, 0); | 534 | try test_i64_intFromFloat_f64(-0.5, 0); |
| 519 | try test__fixdfdi(-math.floatMin(f64), 0); | 535 | try test_i64_intFromFloat_f64(-math.floatMin(f64), 0); |
| 520 | try test__fixdfdi(0.0, 0); | 536 | try test_i64_intFromFloat_f64(0.0, 0); |
| 521 | try test__fixdfdi(math.floatMin(f64), 0); | 537 | try test_i64_intFromFloat_f64(math.floatMin(f64), 0); |
| 522 | try test__fixdfdi(0.5, 0); | 538 | try test_i64_intFromFloat_f64(0.5, 0); |
| 523 | try test__fixdfdi(0.99, 0); | 539 | try test_i64_intFromFloat_f64(0.99, 0); |
| 524 | try test__fixdfdi(1.0, 1); | 540 | try test_i64_intFromFloat_f64(1.0, 1); |
| 525 | try test__fixdfdi(1.5, 1); | 541 | try test_i64_intFromFloat_f64(1.5, 1); |
| 526 | try test__fixdfdi(1.99, 1); | 542 | try test_i64_intFromFloat_f64(1.99, 1); |
| 527 | try test__fixdfdi(2.0, 2); | 543 | try test_i64_intFromFloat_f64(2.0, 2); |
| 528 | try test__fixdfdi(2.01, 2); | 544 | try test_i64_intFromFloat_f64(2.01, 2); |
| 529 | 545 | ||
| 530 | try test__fixdfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000); | 546 | try test_i64_intFromFloat_f64(0x1.FFFFFCp+62, 0x7FFFFF0000000000); |
| 531 | try test__fixdfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000); | 547 | try test_i64_intFromFloat_f64(0x1.FFFFFEp+62, 0x7FFFFF8000000000); |
| 532 | 548 | ||
| 533 | try test__fixdfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); | 549 | try test_i64_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); |
| 534 | try test__fixdfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); | 550 | try test_i64_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); |
| 535 | try test__fixdfdi(0x1.0000000000000p+63, 0x7FFFFFFFFFFFFFFF); | 551 | try test_i64_intFromFloat_f64(0x1.0000000000000p+63, 0x7FFFFFFFFFFFFFFF); |
| 536 | try test__fixdfdi(0x1.0000000000001p+63, 0x7FFFFFFFFFFFFFFF); | 552 | try test_i64_intFromFloat_f64(0x1.0000000000001p+63, 0x7FFFFFFFFFFFFFFF); |
| 537 | 553 | ||
| 538 | try test__fixdfdi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFF); | 554 | try test_i64_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFF); |
| 539 | try test__fixdfdi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFF); | 555 | try test_i64_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFF); |
| 540 | try test__fixdfdi(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFF); | 556 | try test_i64_intFromFloat_f64(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFF); |
| 541 | 557 | ||
| 542 | try test__fixdfdi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF); | 558 | try test_i64_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF); |
| 543 | try test__fixdfdi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64)); | 559 | try test_i64_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64)); |
| 544 | 560 | ||
| 545 | try test__fixdfdi(math.floatMax(f64), math.maxInt(i64)); | 561 | try test_i64_intFromFloat_f64(math.floatMax(f64), math.maxInt(i64)); |
| 546 | } | 562 | } |
| 547 | 563 | ||
| 548 | test "fixunsdfdi" { | 564 | test u64_intFromFloat_f64 { |
| 549 | try test__fixunsdfdi(0.0, 0); | 565 | try test_u64_intFromFloat_f64(0.0, 0); |
| 550 | try test__fixunsdfdi(0.5, 0); | 566 | try test_u64_intFromFloat_f64(0.5, 0); |
| 551 | try test__fixunsdfdi(0.99, 0); | 567 | try test_u64_intFromFloat_f64(0.99, 0); |
| 552 | try test__fixunsdfdi(1.0, 1); | 568 | try test_u64_intFromFloat_f64(1.0, 1); |
| 553 | try test__fixunsdfdi(1.5, 1); | 569 | try test_u64_intFromFloat_f64(1.5, 1); |
| 554 | try test__fixunsdfdi(1.99, 1); | 570 | try test_u64_intFromFloat_f64(1.99, 1); |
| 555 | try test__fixunsdfdi(2.0, 2); | 571 | try test_u64_intFromFloat_f64(2.0, 2); |
| 556 | try test__fixunsdfdi(2.01, 2); | 572 | try test_u64_intFromFloat_f64(2.01, 2); |
| 557 | try test__fixunsdfdi(-0.5, 0); | 573 | try test_u64_intFromFloat_f64(-0.5, 0); |
| 558 | try test__fixunsdfdi(-0.99, 0); | 574 | try test_u64_intFromFloat_f64(-0.99, 0); |
| 559 | try test__fixunsdfdi(-1.0, 0); | 575 | try test_u64_intFromFloat_f64(-1.0, 0); |
| 560 | try test__fixunsdfdi(-1.5, 0); | 576 | try test_u64_intFromFloat_f64(-1.5, 0); |
| 561 | try test__fixunsdfdi(-1.99, 0); | 577 | try test_u64_intFromFloat_f64(-1.99, 0); |
| 562 | try test__fixunsdfdi(-2.0, 0); | 578 | try test_u64_intFromFloat_f64(-2.0, 0); |
| 563 | try test__fixunsdfdi(-2.01, 0); | 579 | try test_u64_intFromFloat_f64(-2.01, 0); |
| 564 | 580 | ||
| 565 | try test__fixunsdfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000); | 581 | try test_u64_intFromFloat_f64(0x1.FFFFFEp+62, 0x7FFFFF8000000000); |
| 566 | try test__fixunsdfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000); | 582 | try test_u64_intFromFloat_f64(0x1.FFFFFCp+62, 0x7FFFFF0000000000); |
| 567 | 583 | ||
| 568 | try test__fixunsdfdi(-0x1.FFFFFEp+62, 0); | 584 | try test_u64_intFromFloat_f64(-0x1.FFFFFEp+62, 0); |
| 569 | try test__fixunsdfdi(-0x1.FFFFFCp+62, 0); | 585 | try test_u64_intFromFloat_f64(-0x1.FFFFFCp+62, 0); |
| 570 | 586 | ||
| 571 | try test__fixunsdfdi(0x1.FFFFFFFFFFFFFp+63, 0xFFFFFFFFFFFFF800); | 587 | try test_u64_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+63, 0xFFFFFFFFFFFFF800); |
| 572 | try test__fixunsdfdi(0x1.0000000000000p+63, 0x8000000000000000); | 588 | try test_u64_intFromFloat_f64(0x1.0000000000000p+63, 0x8000000000000000); |
| 573 | try test__fixunsdfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); | 589 | try test_u64_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); |
| 574 | try test__fixunsdfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); | 590 | try test_u64_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); |
| 575 | 591 | ||
| 576 | try test__fixunsdfdi(-0x1.FFFFFFFFFFFFFp+62, 0); | 592 | try test_u64_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+62, 0); |
| 577 | try test__fixunsdfdi(-0x1.FFFFFFFFFFFFEp+62, 0); | 593 | try test_u64_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+62, 0); |
| 578 | } | 594 | } |
| 579 | 595 | ||
| 580 | fn test__fixdfti(a: f64, expected: i128) !void { | 596 | fn test_i128_intFromFloat_f64(a: f64, expected: i128) !void { |
| 581 | const x = __fixdfti(a); | 597 | const x = i128_intFromFloat_f64(a); |
| 582 | try testing.expect(x == expected); | 598 | try testing.expect(x == expected); |
| 583 | } | 599 | } |
| 584 | 600 | ||
| 585 | fn test__fixunsdfti(a: f64, expected: u128) !void { | 601 | fn test_u128_intFromFloat_f64(a: f64, expected: u128) !void { |
| 586 | const x = __fixunsdfti(a); | 602 | const x = u128_intFromFloat_f64(a); |
| 587 | try testing.expect(x == expected); | 603 | try testing.expect(x == expected); |
| 588 | } | 604 | } |
| 589 | 605 | ||
| 590 | test "fixdfti" { | 606 | test i128_intFromFloat_f64 { |
| 591 | try test__fixdfti(-math.floatMax(f64), math.minInt(i128)); | 607 | try test_i128_intFromFloat_f64(-math.floatMax(f64), math.minInt(i128)); |
| 592 | 608 | ||
| 593 | try test__fixdfti(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128)); | 609 | try test_i128_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128)); |
| 594 | try test__fixdfti(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000); | 610 | try test_i128_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000); |
| 595 | 611 | ||
| 596 | try test__fixdfti(-0x1.0000000000000p+127, -0x80000000000000000000000000000000); | 612 | try test_i128_intFromFloat_f64(-0x1.0000000000000p+127, -0x80000000000000000000000000000000); |
| 597 | try test__fixdfti(-0x1.FFFFFFFFFFFFFp+126, -0x7FFFFFFFFFFFFC000000000000000000); | 613 | try test_i128_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+126, -0x7FFFFFFFFFFFFC000000000000000000); |
| 598 | try test__fixdfti(-0x1.FFFFFFFFFFFFEp+126, -0x7FFFFFFFFFFFF8000000000000000000); | 614 | try test_i128_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+126, -0x7FFFFFFFFFFFF8000000000000000000); |
| 599 | 615 | ||
| 600 | try test__fixdfti(-0x1.0000000000001p+63, -0x8000000000000800); | 616 | try test_i128_intFromFloat_f64(-0x1.0000000000001p+63, -0x8000000000000800); |
| 601 | try test__fixdfti(-0x1.0000000000000p+63, -0x8000000000000000); | 617 | try test_i128_intFromFloat_f64(-0x1.0000000000000p+63, -0x8000000000000000); |
| 602 | try test__fixdfti(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00); | 618 | try test_i128_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00); |
| 603 | try test__fixdfti(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800); | 619 | try test_i128_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800); |
| 604 | 620 | ||
| 605 | try test__fixdfti(-0x1.FFFFFEp+62, -0x7fffff8000000000); | 621 | try test_i128_intFromFloat_f64(-0x1.FFFFFEp+62, -0x7fffff8000000000); |
| 606 | try test__fixdfti(-0x1.FFFFFCp+62, -0x7fffff0000000000); | 622 | try test_i128_intFromFloat_f64(-0x1.FFFFFCp+62, -0x7fffff0000000000); |
| 607 | 623 | ||
| 608 | try test__fixdfti(-2.01, -2); | 624 | try test_i128_intFromFloat_f64(-2.01, -2); |
| 609 | try test__fixdfti(-2.0, -2); | 625 | try test_i128_intFromFloat_f64(-2.0, -2); |
| 610 | try test__fixdfti(-1.99, -1); | 626 | try test_i128_intFromFloat_f64(-1.99, -1); |
| 611 | try test__fixdfti(-1.0, -1); | 627 | try test_i128_intFromFloat_f64(-1.0, -1); |
| 612 | try test__fixdfti(-0.99, 0); | 628 | try test_i128_intFromFloat_f64(-0.99, 0); |
| 613 | try test__fixdfti(-0.5, 0); | 629 | try test_i128_intFromFloat_f64(-0.5, 0); |
| 614 | try test__fixdfti(-math.floatMin(f64), 0); | 630 | try test_i128_intFromFloat_f64(-math.floatMin(f64), 0); |
| 615 | try test__fixdfti(0.0, 0); | 631 | try test_i128_intFromFloat_f64(0.0, 0); |
| 616 | try test__fixdfti(math.floatMin(f64), 0); | 632 | try test_i128_intFromFloat_f64(math.floatMin(f64), 0); |
| 617 | try test__fixdfti(0.5, 0); | 633 | try test_i128_intFromFloat_f64(0.5, 0); |
| 618 | try test__fixdfti(0.99, 0); | 634 | try test_i128_intFromFloat_f64(0.99, 0); |
| 619 | try test__fixdfti(1.0, 1); | 635 | try test_i128_intFromFloat_f64(1.0, 1); |
| 620 | try test__fixdfti(1.5, 1); | 636 | try test_i128_intFromFloat_f64(1.5, 1); |
| 621 | try test__fixdfti(1.99, 1); | 637 | try test_i128_intFromFloat_f64(1.99, 1); |
| 622 | try test__fixdfti(2.0, 2); | 638 | try test_i128_intFromFloat_f64(2.0, 2); |
| 623 | try test__fixdfti(2.01, 2); | 639 | try test_i128_intFromFloat_f64(2.01, 2); |
| 624 | 640 | ||
| 625 | try test__fixdfti(0x1.FFFFFCp+62, 0x7FFFFF0000000000); | 641 | try test_i128_intFromFloat_f64(0x1.FFFFFCp+62, 0x7FFFFF0000000000); |
| 626 | try test__fixdfti(0x1.FFFFFEp+62, 0x7FFFFF8000000000); | 642 | try test_i128_intFromFloat_f64(0x1.FFFFFEp+62, 0x7FFFFF8000000000); |
| 627 | 643 | ||
| 628 | try test__fixdfti(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); | 644 | try test_i128_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); |
| 629 | try test__fixdfti(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); | 645 | try test_i128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); |
| 630 | try test__fixdfti(0x1.0000000000000p+63, 0x8000000000000000); | 646 | try test_i128_intFromFloat_f64(0x1.0000000000000p+63, 0x8000000000000000); |
| 631 | try test__fixdfti(0x1.0000000000001p+63, 0x8000000000000800); | 647 | try test_i128_intFromFloat_f64(0x1.0000000000001p+63, 0x8000000000000800); |
| 632 | 648 | ||
| 633 | try test__fixdfti(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFF8000000000000000000); | 649 | try test_i128_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFF8000000000000000000); |
| 634 | try test__fixdfti(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFC000000000000000000); | 650 | try test_i128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFC000000000000000000); |
| 635 | try test__fixdfti(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); | 651 | try test_i128_intFromFloat_f64(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); |
| 636 | 652 | ||
| 637 | try test__fixdfti(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); | 653 | try test_i128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); |
| 638 | try test__fixdfti(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128)); | 654 | try test_i128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128)); |
| 639 | 655 | ||
| 640 | try test__fixdfti(math.floatMax(f64), math.maxInt(i128)); | 656 | try test_i128_intFromFloat_f64(math.floatMax(f64), math.maxInt(i128)); |
| 641 | } | 657 | } |
| 642 | 658 | ||
| 643 | test "fixunsdfti" { | 659 | test u128_intFromFloat_f64 { |
| 644 | try test__fixunsdfti(0.0, 0); | 660 | try test_u128_intFromFloat_f64(0.0, 0); |
| 645 | 661 | ||
| 646 | try test__fixunsdfti(0.5, 0); | 662 | try test_u128_intFromFloat_f64(0.5, 0); |
| 647 | try test__fixunsdfti(0.99, 0); | 663 | try test_u128_intFromFloat_f64(0.99, 0); |
| 648 | try test__fixunsdfti(1.0, 1); | 664 | try test_u128_intFromFloat_f64(1.0, 1); |
| 649 | try test__fixunsdfti(1.5, 1); | 665 | try test_u128_intFromFloat_f64(1.5, 1); |
| 650 | try test__fixunsdfti(1.99, 1); | 666 | try test_u128_intFromFloat_f64(1.99, 1); |
| 651 | try test__fixunsdfti(2.0, 2); | 667 | try test_u128_intFromFloat_f64(2.0, 2); |
| 652 | try test__fixunsdfti(2.01, 2); | 668 | try test_u128_intFromFloat_f64(2.01, 2); |
| 653 | try test__fixunsdfti(-0.5, 0); | 669 | try test_u128_intFromFloat_f64(-0.5, 0); |
| 654 | try test__fixunsdfti(-0.99, 0); | 670 | try test_u128_intFromFloat_f64(-0.99, 0); |
| 655 | try test__fixunsdfti(-1.0, 0); | 671 | try test_u128_intFromFloat_f64(-1.0, 0); |
| 656 | try test__fixunsdfti(-1.5, 0); | 672 | try test_u128_intFromFloat_f64(-1.5, 0); |
| 657 | try test__fixunsdfti(-1.99, 0); | 673 | try test_u128_intFromFloat_f64(-1.99, 0); |
| 658 | try test__fixunsdfti(-2.0, 0); | 674 | try test_u128_intFromFloat_f64(-2.0, 0); |
| 659 | try test__fixunsdfti(-2.01, 0); | 675 | try test_u128_intFromFloat_f64(-2.01, 0); |
| 660 | 676 | ||
| 661 | try test__fixunsdfti(0x1.FFFFFEp+62, 0x7FFFFF8000000000); | 677 | try test_u128_intFromFloat_f64(0x1.FFFFFEp+62, 0x7FFFFF8000000000); |
| 662 | try test__fixunsdfti(0x1.FFFFFCp+62, 0x7FFFFF0000000000); | 678 | try test_u128_intFromFloat_f64(0x1.FFFFFCp+62, 0x7FFFFF0000000000); |
| 663 | 679 | ||
| 664 | try test__fixunsdfti(-0x1.FFFFFEp+62, 0); | 680 | try test_u128_intFromFloat_f64(-0x1.FFFFFEp+62, 0); |
| 665 | try test__fixunsdfti(-0x1.FFFFFCp+62, 0); | 681 | try test_u128_intFromFloat_f64(-0x1.FFFFFCp+62, 0); |
| 666 | 682 | ||
| 667 | try test__fixunsdfti(0x1.FFFFFFFFFFFFFp+63, 0xFFFFFFFFFFFFF800); | 683 | try test_u128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+63, 0xFFFFFFFFFFFFF800); |
| 668 | try test__fixunsdfti(0x1.0000000000000p+63, 0x8000000000000000); | 684 | try test_u128_intFromFloat_f64(0x1.0000000000000p+63, 0x8000000000000000); |
| 669 | try test__fixunsdfti(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); | 685 | try test_u128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); |
| 670 | try test__fixunsdfti(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); | 686 | try test_u128_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); |
| 671 | 687 | ||
| 672 | try test__fixunsdfti(0x1.FFFFFFFFFFFFFp+127, 0xFFFFFFFFFFFFF8000000000000000000); | 688 | try test_u128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+127, 0xFFFFFFFFFFFFF8000000000000000000); |
| 673 | try test__fixunsdfti(0x1.0000000000000p+127, 0x80000000000000000000000000000000); | 689 | try test_u128_intFromFloat_f64(0x1.0000000000000p+127, 0x80000000000000000000000000000000); |
| 674 | try test__fixunsdfti(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFC000000000000000000); | 690 | try test_u128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFC000000000000000000); |
| 675 | try test__fixunsdfti(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFF8000000000000000000); | 691 | try test_u128_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFF8000000000000000000); |
| 676 | try test__fixunsdfti(0x1.0000000000000p+128, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); | 692 | try test_u128_intFromFloat_f64(0x1.0000000000000p+128, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); |
| 677 | 693 | ||
| 678 | try test__fixunsdfti(-0x1.FFFFFFFFFFFFFp+62, 0); | 694 | try test_u128_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+62, 0); |
| 679 | try test__fixunsdfti(-0x1.FFFFFFFFFFFFEp+62, 0); | 695 | try test_u128_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+62, 0); |
| 680 | } | 696 | } |
| 681 | 697 | ||
| 682 | fn test_fixdfei(comptime T: type, expected: T, a: f64) !void { | 698 | fn test_intFromFloat_f64(comptime T: type, expected: T, a: f64) !void { |
| 683 | const int = @typeInfo(T).int; | 699 | const int = @typeInfo(T).int; |
| 684 | var actual: T = undefined; | 700 | var actual: T = undefined; |
| 685 | _ = switch (int.signedness) { | 701 | _ = switch (int.signedness) { |
| 686 | .signed => __fixdfei, | 702 | .signed => signed_intFromFloat_f64, |
| 687 | .unsigned => __fixunsdfei, | 703 | .unsigned => unsigned_intFromFloat_f64, |
| 688 | }(@ptrCast(&actual), int.bits, a); | 704 | }(@ptrCast(&actual), a); |
| 689 | try testing.expect(expected == actual); | 705 | try testing.expect(expected == actual); |
| 690 | } | 706 | } |
| 691 | 707 | ||
| 692 | test "fixdfei" { | 708 | test signed_intFromFloat_f64 { |
| 693 | try test_fixdfei(i256, -1 << 255, -0x1p255); | 709 | try test_intFromFloat_f64(i256, -1 << 255, -0x1p255); |
| 694 | try test_fixdfei(i256, -1 << 127, -0x1p127); | 710 | try test_intFromFloat_f64(i256, -1 << 127, -0x1p127); |
| 695 | try test_fixdfei(i256, -1 << 100, -0x1p100); | 711 | try test_intFromFloat_f64(i256, -1 << 100, -0x1p100); |
| 696 | try test_fixdfei(i256, -1 << 50, -0x1p50); | 712 | try test_intFromFloat_f64(i256, -1 << 50, -0x1p50); |
| 697 | try test_fixdfei(i256, -1 << 1, -0x1p1); | 713 | try test_intFromFloat_f64(i256, -1 << 1, -0x1p1); |
| 698 | try test_fixdfei(i256, -1 << 0, -0x1p0); | 714 | try test_intFromFloat_f64(i256, -1 << 0, -0x1p0); |
| 699 | try test_fixdfei(i256, 0, 0); | 715 | try test_intFromFloat_f64(i256, 0, 0); |
| 700 | try test_fixdfei(i256, 1 << 0, 0x1p0); | 716 | try test_intFromFloat_f64(i256, 1 << 0, 0x1p0); |
| 701 | try test_fixdfei(i256, 1 << 1, 0x1p1); | 717 | try test_intFromFloat_f64(i256, 1 << 1, 0x1p1); |
| 702 | try test_fixdfei(i256, 1 << 50, 0x1p50); | 718 | try test_intFromFloat_f64(i256, 1 << 50, 0x1p50); |
| 703 | try test_fixdfei(i256, 1 << 100, 0x1p100); | 719 | try test_intFromFloat_f64(i256, 1 << 100, 0x1p100); |
| 704 | try test_fixdfei(i256, 1 << 127, 0x1p127); | 720 | try test_intFromFloat_f64(i256, 1 << 127, 0x1p127); |
| 705 | try test_fixdfei(i256, 1 << 254, 0x1p254); | 721 | try test_intFromFloat_f64(i256, 1 << 254, 0x1p254); |
| 706 | } | 722 | } |
| 707 | 723 | ||
| 708 | test "fixundfei" { | 724 | test unsigned_intFromFloat_f64 { |
| 709 | try test_fixdfei(u256, 0, 0); | 725 | try test_intFromFloat_f64(u256, 0, 0); |
| 710 | try test_fixdfei(u256, 1 << 0, 0x1p0); | 726 | try test_intFromFloat_f64(u256, 1 << 0, 0x1p0); |
| 711 | try test_fixdfei(u256, 1 << 1, 0x1p1); | 727 | try test_intFromFloat_f64(u256, 1 << 1, 0x1p1); |
| 712 | try test_fixdfei(u256, 1 << 50, 0x1p50); | 728 | try test_intFromFloat_f64(u256, 1 << 50, 0x1p50); |
| 713 | try test_fixdfei(u256, 1 << 100, 0x1p100); | 729 | try test_intFromFloat_f64(u256, 1 << 100, 0x1p100); |
| 714 | try test_fixdfei(u256, 1 << 127, 0x1p127); | 730 | try test_intFromFloat_f64(u256, 1 << 127, 0x1p127); |
| 715 | try test_fixdfei(u256, 1 << 255, 0x1p255); | 731 | try test_intFromFloat_f64(u256, 1 << 255, 0x1p255); |
| 716 | } | 732 | } |
| 717 | 733 | ||
| 718 | fn test__fixtfsi(a: f128, expected: i32) !void { | 734 | fn test_i32_intFromFloat_f128(a: f128, expected: i32) !void { |
| 719 | const x = __fixtfsi(a); | 735 | const x = i32_intFromFloat_f128(a); |
| 720 | try testing.expect(x == expected); | 736 | try testing.expect(x == expected); |
| 721 | } | 737 | } |
| 722 | 738 | ||
| 723 | fn test__fixunstfsi(a: f128, expected: u32) !void { | 739 | fn test_u32_intFromFloat_f128(a: f128, expected: u32) !void { |
| 724 | const x = __fixunstfsi(a); | 740 | const x = u32_intFromFloat_f128(a); |
| 725 | try testing.expect(x == expected); | 741 | try testing.expect(x == expected); |
| 726 | } | 742 | } |
| 727 | 743 | ||
| 728 | test "fixtfsi" { | 744 | test i32_intFromFloat_f128 { |
| 729 | try test__fixtfsi(-math.floatMax(f128), math.minInt(i32)); | 745 | try test_i32_intFromFloat_f128(-math.floatMax(f128), math.minInt(i32)); |
| 730 | 746 | ||
| 731 | try test__fixtfsi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32)); | 747 | try test_i32_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32)); |
| 732 | try test__fixtfsi(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000); | 748 | try test_i32_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000); |
| 733 | 749 | ||
| 734 | try test__fixtfsi(-0x1.0000000000000p+127, -0x80000000); | 750 | try test_i32_intFromFloat_f128(-0x1.0000000000000p+127, -0x80000000); |
| 735 | try test__fixtfsi(-0x1.FFFFFFFFFFFFFp+126, -0x80000000); | 751 | try test_i32_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+126, -0x80000000); |
| 736 | try test__fixtfsi(-0x1.FFFFFFFFFFFFEp+126, -0x80000000); | 752 | try test_i32_intFromFloat_f128(-0x1.FFFFFFFFFFFFEp+126, -0x80000000); |
| 737 | 753 | ||
| 738 | try test__fixtfsi(-0x1.0000000000001p+63, -0x80000000); | 754 | try test_i32_intFromFloat_f128(-0x1.0000000000001p+63, -0x80000000); |
| 739 | try test__fixtfsi(-0x1.0000000000000p+63, -0x80000000); | 755 | try test_i32_intFromFloat_f128(-0x1.0000000000000p+63, -0x80000000); |
| 740 | try test__fixtfsi(-0x1.FFFFFFFFFFFFFp+62, -0x80000000); | 756 | try test_i32_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+62, -0x80000000); |
| 741 | try test__fixtfsi(-0x1.FFFFFFFFFFFFEp+62, -0x80000000); | 757 | try test_i32_intFromFloat_f128(-0x1.FFFFFFFFFFFFEp+62, -0x80000000); |
| 742 | 758 | ||
| 743 | try test__fixtfsi(-0x1.FFFFFEp+62, -0x80000000); | 759 | try test_i32_intFromFloat_f128(-0x1.FFFFFEp+62, -0x80000000); |
| 744 | try test__fixtfsi(-0x1.FFFFFCp+62, -0x80000000); | 760 | try test_i32_intFromFloat_f128(-0x1.FFFFFCp+62, -0x80000000); |
| 745 | 761 | ||
| 746 | try test__fixtfsi(-0x1.000000p+31, -0x80000000); | 762 | try test_i32_intFromFloat_f128(-0x1.000000p+31, -0x80000000); |
| 747 | try test__fixtfsi(-0x1.FFFFFFp+30, -0x7FFFFFC0); | 763 | try test_i32_intFromFloat_f128(-0x1.FFFFFFp+30, -0x7FFFFFC0); |
| 748 | try test__fixtfsi(-0x1.FFFFFEp+30, -0x7FFFFF80); | 764 | try test_i32_intFromFloat_f128(-0x1.FFFFFEp+30, -0x7FFFFF80); |
| 749 | try test__fixtfsi(-0x1.FFFFFCp+30, -0x7FFFFF00); | 765 | try test_i32_intFromFloat_f128(-0x1.FFFFFCp+30, -0x7FFFFF00); |
| 750 | 766 | ||
| 751 | try test__fixtfsi(-2.01, -2); | 767 | try test_i32_intFromFloat_f128(-2.01, -2); |
| 752 | try test__fixtfsi(-2.0, -2); | 768 | try test_i32_intFromFloat_f128(-2.0, -2); |
| 753 | try test__fixtfsi(-1.99, -1); | 769 | try test_i32_intFromFloat_f128(-1.99, -1); |
| 754 | try test__fixtfsi(-1.0, -1); | 770 | try test_i32_intFromFloat_f128(-1.0, -1); |
| 755 | try test__fixtfsi(-0.99, 0); | 771 | try test_i32_intFromFloat_f128(-0.99, 0); |
| 756 | try test__fixtfsi(-0.5, 0); | 772 | try test_i32_intFromFloat_f128(-0.5, 0); |
| 757 | try test__fixtfsi(-math.floatMin(f32), 0); | 773 | try test_i32_intFromFloat_f128(-math.floatMin(f32), 0); |
| 758 | try test__fixtfsi(0.0, 0); | 774 | try test_i32_intFromFloat_f128(0.0, 0); |
| 759 | try test__fixtfsi(math.floatMin(f32), 0); | 775 | try test_i32_intFromFloat_f128(math.floatMin(f32), 0); |
| 760 | try test__fixtfsi(0.5, 0); | 776 | try test_i32_intFromFloat_f128(0.5, 0); |
| 761 | try test__fixtfsi(0.99, 0); | 777 | try test_i32_intFromFloat_f128(0.99, 0); |
| 762 | try test__fixtfsi(1.0, 1); | 778 | try test_i32_intFromFloat_f128(1.0, 1); |
| 763 | try test__fixtfsi(1.5, 1); | 779 | try test_i32_intFromFloat_f128(1.5, 1); |
| 764 | try test__fixtfsi(1.99, 1); | 780 | try test_i32_intFromFloat_f128(1.99, 1); |
| 765 | try test__fixtfsi(2.0, 2); | 781 | try test_i32_intFromFloat_f128(2.0, 2); |
| 766 | try test__fixtfsi(2.01, 2); | 782 | try test_i32_intFromFloat_f128(2.01, 2); |
| 767 | 783 | ||
| 768 | try test__fixtfsi(0x1.FFFFFCp+30, 0x7FFFFF00); | 784 | try test_i32_intFromFloat_f128(0x1.FFFFFCp+30, 0x7FFFFF00); |
| 769 | try test__fixtfsi(0x1.FFFFFEp+30, 0x7FFFFF80); | 785 | try test_i32_intFromFloat_f128(0x1.FFFFFEp+30, 0x7FFFFF80); |
| 770 | try test__fixtfsi(0x1.FFFFFFp+30, 0x7FFFFFC0); | 786 | try test_i32_intFromFloat_f128(0x1.FFFFFFp+30, 0x7FFFFFC0); |
| 771 | try test__fixtfsi(0x1.000000p+31, 0x7FFFFFFF); | 787 | try test_i32_intFromFloat_f128(0x1.000000p+31, 0x7FFFFFFF); |
| 772 | 788 | ||
| 773 | try test__fixtfsi(0x1.FFFFFCp+62, 0x7FFFFFFF); | 789 | try test_i32_intFromFloat_f128(0x1.FFFFFCp+62, 0x7FFFFFFF); |
| 774 | try test__fixtfsi(0x1.FFFFFEp+62, 0x7FFFFFFF); | 790 | try test_i32_intFromFloat_f128(0x1.FFFFFEp+62, 0x7FFFFFFF); |
| 775 | 791 | ||
| 776 | try test__fixtfsi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFF); | 792 | try test_i32_intFromFloat_f128(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFF); |
| 777 | try test__fixtfsi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFF); | 793 | try test_i32_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFF); |
| 778 | try test__fixtfsi(0x1.0000000000000p+63, 0x7FFFFFFF); | 794 | try test_i32_intFromFloat_f128(0x1.0000000000000p+63, 0x7FFFFFFF); |
| 779 | try test__fixtfsi(0x1.0000000000001p+63, 0x7FFFFFFF); | 795 | try test_i32_intFromFloat_f128(0x1.0000000000001p+63, 0x7FFFFFFF); |
| 780 | 796 | ||
| 781 | try test__fixtfsi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFF); | 797 | try test_i32_intFromFloat_f128(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFF); |
| 782 | try test__fixtfsi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFF); | 798 | try test_i32_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFF); |
| 783 | try test__fixtfsi(0x1.0000000000000p+127, 0x7FFFFFFF); | 799 | try test_i32_intFromFloat_f128(0x1.0000000000000p+127, 0x7FFFFFFF); |
| 784 | 800 | ||
| 785 | try test__fixtfsi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF); | 801 | try test_i32_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF); |
| 786 | try test__fixtfsi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32)); | 802 | try test_i32_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32)); |
| 787 | 803 | ||
| 788 | try test__fixtfsi(math.floatMax(f128), math.maxInt(i32)); | 804 | try test_i32_intFromFloat_f128(math.floatMax(f128), math.maxInt(i32)); |
| 789 | } | 805 | } |
| 790 | 806 | ||
| 791 | test "fixunstfsi" { | 807 | test u32_intFromFloat_f128 { |
| 792 | try test__fixunstfsi(math.inf(f128), 0xffffffff); | 808 | try test_u32_intFromFloat_f128(math.inf(f128), 0xffffffff); |
| 793 | try test__fixunstfsi(0, 0x0); | 809 | try test_u32_intFromFloat_f128(0, 0x0); |
| 794 | try test__fixunstfsi(0x1.23456789abcdefp+5, 0x24); | 810 | try test_u32_intFromFloat_f128(0x1.23456789abcdefp+5, 0x24); |
| 795 | try test__fixunstfsi(0x1.23456789abcdefp-3, 0x0); | 811 | try test_u32_intFromFloat_f128(0x1.23456789abcdefp-3, 0x0); |
| 796 | try test__fixunstfsi(0x1.23456789abcdefp+20, 0x123456); | 812 | try test_u32_intFromFloat_f128(0x1.23456789abcdefp+20, 0x123456); |
| 797 | try test__fixunstfsi(0x1.23456789abcdefp+40, 0xffffffff); | 813 | try test_u32_intFromFloat_f128(0x1.23456789abcdefp+40, 0xffffffff); |
| 798 | try test__fixunstfsi(0x1.23456789abcdefp+256, 0xffffffff); | 814 | try test_u32_intFromFloat_f128(0x1.23456789abcdefp+256, 0xffffffff); |
| 799 | try test__fixunstfsi(-0x1.23456789abcdefp+3, 0x0); | 815 | try test_u32_intFromFloat_f128(-0x1.23456789abcdefp+3, 0x0); |
| 800 | 816 | ||
| 801 | try test__fixunstfsi(0x1p+32, 0xFFFFFFFF); | 817 | try test_u32_intFromFloat_f128(0x1p+32, 0xFFFFFFFF); |
| 802 | } | 818 | } |
| 803 | 819 | ||
| 804 | fn test__fixtfdi(a: f128, expected: i64) !void { | 820 | fn test_i64_intFromFloat_f128(a: f128, expected: i64) !void { |
| 805 | const x = __fixtfdi(a); | 821 | const x = i64_intFromFloat_f128(a); |
| 806 | try testing.expect(x == expected); | 822 | try testing.expect(x == expected); |
| 807 | } | 823 | } |
| 808 | 824 | ||
| 809 | fn test__fixunstfdi(a: f128, expected: u64) !void { | 825 | fn test_u64_intFromFloat_f128(a: f128, expected: u64) !void { |
| 810 | const x = __fixunstfdi(a); | 826 | const x = u64_intFromFloat_f128(a); |
| 811 | try testing.expect(x == expected); | 827 | try testing.expect(x == expected); |
| 812 | } | 828 | } |
| 813 | 829 | ||
| 814 | test "fixtfdi" { | 830 | test i64_intFromFloat_f128 { |
| 815 | try test__fixtfdi(-math.floatMax(f128), math.minInt(i64)); | 831 | try test_i64_intFromFloat_f128(-math.floatMax(f128), math.minInt(i64)); |
| 816 | 832 | ||
| 817 | try test__fixtfdi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64)); | 833 | try test_i64_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64)); |
| 818 | try test__fixtfdi(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000); | 834 | try test_i64_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000); |
| 819 | 835 | ||
| 820 | try test__fixtfdi(-0x1.0000000000000p+127, -0x8000000000000000); | 836 | try test_i64_intFromFloat_f128(-0x1.0000000000000p+127, -0x8000000000000000); |
| 821 | try test__fixtfdi(-0x1.FFFFFFFFFFFFFp+126, -0x8000000000000000); | 837 | try test_i64_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+126, -0x8000000000000000); |
| 822 | try test__fixtfdi(-0x1.FFFFFFFFFFFFEp+126, -0x8000000000000000); | 838 | try test_i64_intFromFloat_f128(-0x1.FFFFFFFFFFFFEp+126, -0x8000000000000000); |
| 823 | 839 | ||
| 824 | try test__fixtfdi(-0x1.0000000000001p+63, -0x8000000000000000); | 840 | try test_i64_intFromFloat_f128(-0x1.0000000000001p+63, -0x8000000000000000); |
| 825 | try test__fixtfdi(-0x1.0000000000000p+63, -0x8000000000000000); | 841 | try test_i64_intFromFloat_f128(-0x1.0000000000000p+63, -0x8000000000000000); |
| 826 | try test__fixtfdi(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00); | 842 | try test_i64_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00); |
| 827 | try test__fixtfdi(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800); | 843 | try test_i64_intFromFloat_f128(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800); |
| 828 | 844 | ||
| 829 | try test__fixtfdi(-0x1.FFFFFEp+62, -0x7FFFFF8000000000); | 845 | try test_i64_intFromFloat_f128(-0x1.FFFFFEp+62, -0x7FFFFF8000000000); |
| 830 | try test__fixtfdi(-0x1.FFFFFCp+62, -0x7FFFFF0000000000); | 846 | try test_i64_intFromFloat_f128(-0x1.FFFFFCp+62, -0x7FFFFF0000000000); |
| 831 | 847 | ||
| 832 | try test__fixtfdi(-0x1.000000p+31, -0x80000000); | 848 | try test_i64_intFromFloat_f128(-0x1.000000p+31, -0x80000000); |
| 833 | try test__fixtfdi(-0x1.FFFFFFp+30, -0x7FFFFFC0); | 849 | try test_i64_intFromFloat_f128(-0x1.FFFFFFp+30, -0x7FFFFFC0); |
| 834 | try test__fixtfdi(-0x1.FFFFFEp+30, -0x7FFFFF80); | 850 | try test_i64_intFromFloat_f128(-0x1.FFFFFEp+30, -0x7FFFFF80); |
| 835 | try test__fixtfdi(-0x1.FFFFFCp+30, -0x7FFFFF00); | 851 | try test_i64_intFromFloat_f128(-0x1.FFFFFCp+30, -0x7FFFFF00); |
| 836 | 852 | ||
| 837 | try test__fixtfdi(-2.01, -2); | 853 | try test_i64_intFromFloat_f128(-2.01, -2); |
| 838 | try test__fixtfdi(-2.0, -2); | 854 | try test_i64_intFromFloat_f128(-2.0, -2); |
| 839 | try test__fixtfdi(-1.99, -1); | 855 | try test_i64_intFromFloat_f128(-1.99, -1); |
| 840 | try test__fixtfdi(-1.0, -1); | 856 | try test_i64_intFromFloat_f128(-1.0, -1); |
| 841 | try test__fixtfdi(-0.99, 0); | 857 | try test_i64_intFromFloat_f128(-0.99, 0); |
| 842 | try test__fixtfdi(-0.5, 0); | 858 | try test_i64_intFromFloat_f128(-0.5, 0); |
| 843 | try test__fixtfdi(-math.floatMin(f64), 0); | 859 | try test_i64_intFromFloat_f128(-math.floatMin(f64), 0); |
| 844 | try test__fixtfdi(0.0, 0); | 860 | try test_i64_intFromFloat_f128(0.0, 0); |
| 845 | try test__fixtfdi(math.floatMin(f64), 0); | 861 | try test_i64_intFromFloat_f128(math.floatMin(f64), 0); |
| 846 | try test__fixtfdi(0.5, 0); | 862 | try test_i64_intFromFloat_f128(0.5, 0); |
| 847 | try test__fixtfdi(0.99, 0); | 863 | try test_i64_intFromFloat_f128(0.99, 0); |
| 848 | try test__fixtfdi(1.0, 1); | 864 | try test_i64_intFromFloat_f128(1.0, 1); |
| 849 | try test__fixtfdi(1.5, 1); | 865 | try test_i64_intFromFloat_f128(1.5, 1); |
| 850 | try test__fixtfdi(1.99, 1); | 866 | try test_i64_intFromFloat_f128(1.99, 1); |
| 851 | try test__fixtfdi(2.0, 2); | 867 | try test_i64_intFromFloat_f128(2.0, 2); |
| 852 | try test__fixtfdi(2.01, 2); | 868 | try test_i64_intFromFloat_f128(2.01, 2); |
| 853 | 869 | ||
| 854 | try test__fixtfdi(0x1.FFFFFCp+30, 0x7FFFFF00); | 870 | try test_i64_intFromFloat_f128(0x1.FFFFFCp+30, 0x7FFFFF00); |
| 855 | try test__fixtfdi(0x1.FFFFFEp+30, 0x7FFFFF80); | 871 | try test_i64_intFromFloat_f128(0x1.FFFFFEp+30, 0x7FFFFF80); |
| 856 | try test__fixtfdi(0x1.FFFFFFp+30, 0x7FFFFFC0); | 872 | try test_i64_intFromFloat_f128(0x1.FFFFFFp+30, 0x7FFFFFC0); |
| 857 | try test__fixtfdi(0x1.000000p+31, 0x80000000); | 873 | try test_i64_intFromFloat_f128(0x1.000000p+31, 0x80000000); |
| 858 | 874 | ||
| 859 | try test__fixtfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000); | 875 | try test_i64_intFromFloat_f128(0x1.FFFFFCp+62, 0x7FFFFF0000000000); |
| 860 | try test__fixtfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000); | 876 | try test_i64_intFromFloat_f128(0x1.FFFFFEp+62, 0x7FFFFF8000000000); |
| 861 | 877 | ||
| 862 | try test__fixtfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); | 878 | try test_i64_intFromFloat_f128(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); |
| 863 | try test__fixtfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); | 879 | try test_i64_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); |
| 864 | try test__fixtfdi(0x1.0000000000000p+63, 0x7FFFFFFFFFFFFFFF); | 880 | try test_i64_intFromFloat_f128(0x1.0000000000000p+63, 0x7FFFFFFFFFFFFFFF); |
| 865 | try test__fixtfdi(0x1.0000000000001p+63, 0x7FFFFFFFFFFFFFFF); | 881 | try test_i64_intFromFloat_f128(0x1.0000000000001p+63, 0x7FFFFFFFFFFFFFFF); |
| 866 | 882 | ||
| 867 | try test__fixtfdi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFF); | 883 | try test_i64_intFromFloat_f128(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFF); |
| 868 | try test__fixtfdi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFF); | 884 | try test_i64_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFF); |
| 869 | try test__fixtfdi(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFF); | 885 | try test_i64_intFromFloat_f128(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFF); |
| 870 | 886 | ||
| 871 | try test__fixtfdi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF); | 887 | try test_i64_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF); |
| 872 | try test__fixtfdi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64)); | 888 | try test_i64_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64)); |
| 873 | 889 | ||
| 874 | try test__fixtfdi(math.floatMax(f128), math.maxInt(i64)); | 890 | try test_i64_intFromFloat_f128(math.floatMax(f128), math.maxInt(i64)); |
| 875 | } | 891 | } |
| 876 | 892 | ||
| 877 | test "fixunstfdi" { | 893 | test u64_intFromFloat_f128 { |
| 878 | try test__fixunstfdi(0.0, 0); | 894 | try test_u64_intFromFloat_f128(0.0, 0); |
| 879 | 895 | ||
| 880 | try test__fixunstfdi(0.5, 0); | 896 | try test_u64_intFromFloat_f128(0.5, 0); |
| 881 | try test__fixunstfdi(0.99, 0); | 897 | try test_u64_intFromFloat_f128(0.99, 0); |
| 882 | try test__fixunstfdi(1.0, 1); | 898 | try test_u64_intFromFloat_f128(1.0, 1); |
| 883 | try test__fixunstfdi(1.5, 1); | 899 | try test_u64_intFromFloat_f128(1.5, 1); |
| 884 | try test__fixunstfdi(1.99, 1); | 900 | try test_u64_intFromFloat_f128(1.99, 1); |
| 885 | try test__fixunstfdi(2.0, 2); | 901 | try test_u64_intFromFloat_f128(2.0, 2); |
| 886 | try test__fixunstfdi(2.01, 2); | 902 | try test_u64_intFromFloat_f128(2.01, 2); |
| 887 | try test__fixunstfdi(-0.5, 0); | 903 | try test_u64_intFromFloat_f128(-0.5, 0); |
| 888 | try test__fixunstfdi(-0.99, 0); | 904 | try test_u64_intFromFloat_f128(-0.99, 0); |
| 889 | try test__fixunstfdi(-1.0, 0); | 905 | try test_u64_intFromFloat_f128(-1.0, 0); |
| 890 | try test__fixunstfdi(-1.5, 0); | 906 | try test_u64_intFromFloat_f128(-1.5, 0); |
| 891 | try test__fixunstfdi(-1.99, 0); | 907 | try test_u64_intFromFloat_f128(-1.99, 0); |
| 892 | try test__fixunstfdi(-2.0, 0); | 908 | try test_u64_intFromFloat_f128(-2.0, 0); |
| 893 | try test__fixunstfdi(-2.01, 0); | 909 | try test_u64_intFromFloat_f128(-2.01, 0); |
| 894 | 910 | ||
| 895 | try test__fixunstfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000); | 911 | try test_u64_intFromFloat_f128(0x1.FFFFFEp+62, 0x7FFFFF8000000000); |
| 896 | try test__fixunstfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000); | 912 | try test_u64_intFromFloat_f128(0x1.FFFFFCp+62, 0x7FFFFF0000000000); |
| 897 | 913 | ||
| 898 | try test__fixunstfdi(-0x1.FFFFFEp+62, 0); | 914 | try test_u64_intFromFloat_f128(-0x1.FFFFFEp+62, 0); |
| 899 | try test__fixunstfdi(-0x1.FFFFFCp+62, 0); | 915 | try test_u64_intFromFloat_f128(-0x1.FFFFFCp+62, 0); |
| 900 | 916 | ||
| 901 | try test__fixunstfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); | 917 | try test_u64_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); |
| 902 | try test__fixunstfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); | 918 | try test_u64_intFromFloat_f128(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); |
| 903 | 919 | ||
| 904 | try test__fixunstfdi(-0x1.FFFFFFFFFFFFFp+62, 0); | 920 | try test_u64_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+62, 0); |
| 905 | try test__fixunstfdi(-0x1.FFFFFFFFFFFFEp+62, 0); | 921 | try test_u64_intFromFloat_f128(-0x1.FFFFFFFFFFFFEp+62, 0); |
| 906 | 922 | ||
| 907 | try test__fixunstfdi(0x1.FFFFFFFFFFFFFFFEp+63, 0xFFFFFFFFFFFFFFFF); | 923 | try test_u64_intFromFloat_f128(0x1.FFFFFFFFFFFFFFFEp+63, 0xFFFFFFFFFFFFFFFF); |
| 908 | try test__fixunstfdi(0x1.0000000000000002p+63, 0x8000000000000001); | 924 | try test_u64_intFromFloat_f128(0x1.0000000000000002p+63, 0x8000000000000001); |
| 909 | try test__fixunstfdi(0x1.0000000000000000p+63, 0x8000000000000000); | 925 | try test_u64_intFromFloat_f128(0x1.0000000000000000p+63, 0x8000000000000000); |
| 910 | try test__fixunstfdi(0x1.FFFFFFFFFFFFFFFCp+62, 0x7FFFFFFFFFFFFFFF); | 926 | try test_u64_intFromFloat_f128(0x1.FFFFFFFFFFFFFFFCp+62, 0x7FFFFFFFFFFFFFFF); |
| 911 | try test__fixunstfdi(0x1.FFFFFFFFFFFFFFF8p+62, 0x7FFFFFFFFFFFFFFE); | 927 | try test_u64_intFromFloat_f128(0x1.FFFFFFFFFFFFFFF8p+62, 0x7FFFFFFFFFFFFFFE); |
| 912 | try test__fixunstfdi(0x1p+64, 0xFFFFFFFFFFFFFFFF); | 928 | try test_u64_intFromFloat_f128(0x1p+64, 0xFFFFFFFFFFFFFFFF); |
| 913 | 929 | ||
| 914 | try test__fixunstfdi(-0x1.0000000000000000p+63, 0); | 930 | try test_u64_intFromFloat_f128(-0x1.0000000000000000p+63, 0); |
| 915 | try test__fixunstfdi(-0x1.FFFFFFFFFFFFFFFCp+62, 0); | 931 | try test_u64_intFromFloat_f128(-0x1.FFFFFFFFFFFFFFFCp+62, 0); |
| 916 | try test__fixunstfdi(-0x1.FFFFFFFFFFFFFFF8p+62, 0); | 932 | try test_u64_intFromFloat_f128(-0x1.FFFFFFFFFFFFFFF8p+62, 0); |
| 917 | } | 933 | } |
| 918 | 934 | ||
| 919 | fn test__fixtfti(a: f128, expected: i128) !void { | 935 | fn test_i128_intFromFloat_f128(a: f128, expected: i128) !void { |
| 920 | const x = __fixtfti(a); | 936 | const x = i128_intFromFloat_f128(a); |
| 921 | try testing.expect(x == expected); | 937 | try testing.expect(x == expected); |
| 922 | } | 938 | } |
| 923 | 939 | ||
| 924 | fn test__fixunstfti(a: f128, expected: u128) !void { | 940 | fn test_u128_intFromFloat_f128(a: f128, expected: u128) !void { |
| 925 | const x = __fixunstfti(a); | 941 | const x = u128_intFromFloat_f128(a); |
| 926 | try testing.expect(x == expected); | 942 | try testing.expect(x == expected); |
| 927 | } | 943 | } |
| 928 | 944 | ||
| 929 | test "fixtfti" { | 945 | test i128_intFromFloat_f128 { |
| 930 | try test__fixtfti(-math.floatMax(f128), math.minInt(i128)); | 946 | try test_i128_intFromFloat_f128(-math.floatMax(f128), math.minInt(i128)); |
| 931 | 947 | ||
| 932 | try test__fixtfti(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128)); | 948 | try test_i128_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128)); |
| 933 | try test__fixtfti(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000); | 949 | try test_i128_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000); |
| 934 | 950 | ||
| 935 | try test__fixtfti(-0x1.0000000000000p+127, -0x80000000000000000000000000000000); | 951 | try test_i128_intFromFloat_f128(-0x1.0000000000000p+127, -0x80000000000000000000000000000000); |
| 936 | try test__fixtfti(-0x1.FFFFFFFFFFFFFp+126, -0x7FFFFFFFFFFFFC000000000000000000); | 952 | try test_i128_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+126, -0x7FFFFFFFFFFFFC000000000000000000); |
| 937 | try test__fixtfti(-0x1.FFFFFFFFFFFFEp+126, -0x7FFFFFFFFFFFF8000000000000000000); | 953 | try test_i128_intFromFloat_f128(-0x1.FFFFFFFFFFFFEp+126, -0x7FFFFFFFFFFFF8000000000000000000); |
| 938 | 954 | ||
| 939 | try test__fixtfti(-0x1.0000000000001p+63, -0x8000000000000800); | 955 | try test_i128_intFromFloat_f128(-0x1.0000000000001p+63, -0x8000000000000800); |
| 940 | try test__fixtfti(-0x1.0000000000000p+63, -0x8000000000000000); | 956 | try test_i128_intFromFloat_f128(-0x1.0000000000000p+63, -0x8000000000000000); |
| 941 | try test__fixtfti(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00); | 957 | try test_i128_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00); |
| 942 | try test__fixtfti(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800); | 958 | try test_i128_intFromFloat_f128(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800); |
| 943 | 959 | ||
| 944 | try test__fixtfti(-0x1.FFFFFEp+62, -0x7fffff8000000000); | 960 | try test_i128_intFromFloat_f128(-0x1.FFFFFEp+62, -0x7fffff8000000000); |
| 945 | try test__fixtfti(-0x1.FFFFFCp+62, -0x7fffff0000000000); | 961 | try test_i128_intFromFloat_f128(-0x1.FFFFFCp+62, -0x7fffff0000000000); |
| 946 | 962 | ||
| 947 | try test__fixtfti(-2.01, -2); | 963 | try test_i128_intFromFloat_f128(-2.01, -2); |
| 948 | try test__fixtfti(-2.0, -2); | 964 | try test_i128_intFromFloat_f128(-2.0, -2); |
| 949 | try test__fixtfti(-1.99, -1); | 965 | try test_i128_intFromFloat_f128(-1.99, -1); |
| 950 | try test__fixtfti(-1.0, -1); | 966 | try test_i128_intFromFloat_f128(-1.0, -1); |
| 951 | try test__fixtfti(-0.99, 0); | 967 | try test_i128_intFromFloat_f128(-0.99, 0); |
| 952 | try test__fixtfti(-0.5, 0); | 968 | try test_i128_intFromFloat_f128(-0.5, 0); |
| 953 | try test__fixtfti(-math.floatMin(f128), 0); | 969 | try test_i128_intFromFloat_f128(-math.floatMin(f128), 0); |
| 954 | try test__fixtfti(0.0, 0); | 970 | try test_i128_intFromFloat_f128(0.0, 0); |
| 955 | try test__fixtfti(math.floatMin(f128), 0); | 971 | try test_i128_intFromFloat_f128(math.floatMin(f128), 0); |
| 956 | try test__fixtfti(0.5, 0); | 972 | try test_i128_intFromFloat_f128(0.5, 0); |
| 957 | try test__fixtfti(0.99, 0); | 973 | try test_i128_intFromFloat_f128(0.99, 0); |
| 958 | try test__fixtfti(1.0, 1); | 974 | try test_i128_intFromFloat_f128(1.0, 1); |
| 959 | try test__fixtfti(1.5, 1); | 975 | try test_i128_intFromFloat_f128(1.5, 1); |
| 960 | try test__fixtfti(1.99, 1); | 976 | try test_i128_intFromFloat_f128(1.99, 1); |
| 961 | try test__fixtfti(2.0, 2); | 977 | try test_i128_intFromFloat_f128(2.0, 2); |
| 962 | try test__fixtfti(2.01, 2); | 978 | try test_i128_intFromFloat_f128(2.01, 2); |
| 963 | 979 | ||
| 964 | try test__fixtfti(0x1.FFFFFCp+62, 0x7FFFFF0000000000); | 980 | try test_i128_intFromFloat_f128(0x1.FFFFFCp+62, 0x7FFFFF0000000000); |
| 965 | try test__fixtfti(0x1.FFFFFEp+62, 0x7FFFFF8000000000); | 981 | try test_i128_intFromFloat_f128(0x1.FFFFFEp+62, 0x7FFFFF8000000000); |
| 966 | 982 | ||
| 967 | try test__fixtfti(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); | 983 | try test_i128_intFromFloat_f128(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); |
| 968 | try test__fixtfti(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); | 984 | try test_i128_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); |
| 969 | try test__fixtfti(0x1.0000000000000p+63, 0x8000000000000000); | 985 | try test_i128_intFromFloat_f128(0x1.0000000000000p+63, 0x8000000000000000); |
| 970 | try test__fixtfti(0x1.0000000000001p+63, 0x8000000000000800); | 986 | try test_i128_intFromFloat_f128(0x1.0000000000001p+63, 0x8000000000000800); |
| 971 | 987 | ||
| 972 | try test__fixtfti(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFF8000000000000000000); | 988 | try test_i128_intFromFloat_f128(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFF8000000000000000000); |
| 973 | try test__fixtfti(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFC000000000000000000); | 989 | try test_i128_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFC000000000000000000); |
| 974 | try test__fixtfti(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); | 990 | try test_i128_intFromFloat_f128(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); |
| 975 | 991 | ||
| 976 | try test__fixtfti(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); | 992 | try test_i128_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); |
| 977 | try test__fixtfti(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128)); | 993 | try test_i128_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128)); |
| 978 | 994 | ||
| 979 | try test__fixtfti(math.floatMax(f128), math.maxInt(i128)); | 995 | try test_i128_intFromFloat_f128(math.floatMax(f128), math.maxInt(i128)); |
| 980 | } | 996 | } |
| 981 | 997 | ||
| 982 | test "fixunstfti" { | 998 | test u128_intFromFloat_f128 { |
| 983 | try test__fixunstfti(math.inf(f128), 0xffffffffffffffffffffffffffffffff); | 999 | try test_u128_intFromFloat_f128(math.inf(f128), 0xffffffffffffffffffffffffffffffff); |
| 984 | 1000 | ||
| 985 | try test__fixunstfti(0.0, 0); | 1001 | try test_u128_intFromFloat_f128(0.0, 0); |
| 986 | 1002 | ||
| 987 | try test__fixunstfti(0.5, 0); | 1003 | try test_u128_intFromFloat_f128(0.5, 0); |
| 988 | try test__fixunstfti(0.99, 0); | 1004 | try test_u128_intFromFloat_f128(0.99, 0); |
| 989 | try test__fixunstfti(1.0, 1); | 1005 | try test_u128_intFromFloat_f128(1.0, 1); |
| 990 | try test__fixunstfti(1.5, 1); | 1006 | try test_u128_intFromFloat_f128(1.5, 1); |
| 991 | try test__fixunstfti(1.99, 1); | 1007 | try test_u128_intFromFloat_f128(1.99, 1); |
| 992 | try test__fixunstfti(2.0, 2); | 1008 | try test_u128_intFromFloat_f128(2.0, 2); |
| 993 | try test__fixunstfti(2.01, 2); | 1009 | try test_u128_intFromFloat_f128(2.01, 2); |
| 994 | try test__fixunstfti(-0.01, 0); | 1010 | try test_u128_intFromFloat_f128(-0.01, 0); |
| 995 | try test__fixunstfti(-0.99, 0); | 1011 | try test_u128_intFromFloat_f128(-0.99, 0); |
| 996 | 1012 | ||
| 997 | try test__fixunstfti(0x1p+128, 0xffffffffffffffffffffffffffffffff); | 1013 | try test_u128_intFromFloat_f128(0x1p+128, 0xffffffffffffffffffffffffffffffff); |
| 998 | 1014 | ||
| 999 | try test__fixunstfti(0x1.FFFFFEp+126, 0x7fffff80000000000000000000000000); | 1015 | try test_u128_intFromFloat_f128(0x1.FFFFFEp+126, 0x7fffff80000000000000000000000000); |
| 1000 | try test__fixunstfti(0x1.FFFFFEp+127, 0xffffff00000000000000000000000000); | 1016 | try test_u128_intFromFloat_f128(0x1.FFFFFEp+127, 0xffffff00000000000000000000000000); |
| 1001 | try test__fixunstfti(0x1.FFFFFEp+128, 0xffffffffffffffffffffffffffffffff); | 1017 | try test_u128_intFromFloat_f128(0x1.FFFFFEp+128, 0xffffffffffffffffffffffffffffffff); |
| 1002 | try test__fixunstfti(0x1.FFFFFEp+129, 0xffffffffffffffffffffffffffffffff); | 1018 | try test_u128_intFromFloat_f128(0x1.FFFFFEp+129, 0xffffffffffffffffffffffffffffffff); |
| 1003 | } | 1019 | } |
| 1004 | 1020 | ||
| 1005 | fn test__fixunshfti(a: f16, expected: u128) !void { | 1021 | fn test_u128_intFromFloat_f16(a: f16, expected: u128) !void { |
| 1006 | const x = __fixunshfti(a); | 1022 | const x = impl.u128_intFromFloat_f16(a); |
| 1007 | try testing.expect(x == expected); | 1023 | try testing.expect(x == expected); |
| 1008 | } | 1024 | } |
| 1009 | 1025 | ||
| 1010 | test "fixunshfti for f16" { | 1026 | test u128_intFromFloat_f16 { |
| 1011 | try test__fixunshfti(math.inf(f16), math.maxInt(u128)); | 1027 | try test_u128_intFromFloat_f16(math.inf(f16), math.maxInt(u128)); |
| 1012 | try test__fixunshfti(math.floatMax(f16), 65504); | 1028 | try test_u128_intFromFloat_f16(math.floatMax(f16), 65504); |
| 1013 | } | 1029 | } |
| 1014 | 1030 | ||
| 1015 | fn test__fixunsxfti(a: f80, expected: u128) !void { | 1031 | fn test_u128_intFromFloat_f80(a: f80, expected: u128) !void { |
| 1016 | const x = __fixunsxfti(a); | 1032 | const x = impl.u128_intFromFloat_f80(a); |
| 1017 | try testing.expect(x == expected); | 1033 | try testing.expect(x == expected); |
| 1018 | } | 1034 | } |
| 1019 | 1035 | ||
| 1020 | test "fixunsxfti for f80" { | 1036 | test u128_intFromFloat_f80 { |
| 1021 | try test__fixunsxfti(math.inf(f80), math.maxInt(u128)); | 1037 | try test_u128_intFromFloat_f80(math.inf(f80), math.maxInt(u128)); |
| 1022 | try test__fixunsxfti(math.floatMax(f80), math.maxInt(u128)); | 1038 | try test_u128_intFromFloat_f80(math.floatMax(f80), math.maxInt(u128)); |
| 1023 | try test__fixunsxfti(math.maxInt(u64), math.maxInt(u64)); | 1039 | try test_u128_intFromFloat_f80(math.maxInt(u64), math.maxInt(u64)); |
| 1024 | } | 1040 | } |
lib/compiler_rt/limb64.zig+1-1| ... | @@ -6,7 +6,7 @@ const minInt = std.math.minInt; | ... | @@ -6,7 +6,7 @@ const minInt = std.math.minInt; |
| 6 | 6 | ||
| 7 | const builtin = @import("builtin"); | 7 | const builtin = @import("builtin"); |
| 8 | const compiler_rt = @import("../compiler_rt.zig"); | 8 | const compiler_rt = @import("../compiler_rt.zig"); |
| 9 | const symbol = @import("../compiler_rt.zig").symbol; | 9 | const symbol = compiler_rt.symbol; |
| 10 | 10 | ||
| 11 | const endian = builtin.cpu.arch.endian(); | 11 | const endian = builtin.cpu.arch.endian(); |
| 12 | 12 |
lib/compiler_rt/log.zig+113-101| ... | @@ -11,26 +11,29 @@ const expectEqual = std.testing.expectEqual; | ... | @@ -11,26 +11,29 @@ const expectEqual = std.testing.expectEqual; |
| 11 | const expectApproxEqRel = std.testing.expectApproxEqRel; | 11 | const expectApproxEqRel = std.testing.expectApproxEqRel; |
| 12 | 12 | ||
| 13 | const compiler_rt = @import("../compiler_rt.zig"); | 13 | const compiler_rt = @import("../compiler_rt.zig"); |
| 14 | const symbol = @import("../compiler_rt.zig").symbol; | 14 | const symbol = compiler_rt.symbol; |
| 15 | 15 | ||
| 16 | comptime { | 16 | comptime { |
| 17 | symbol(&__logh, "__logh"); | 17 | symbol(&__logh, "__logh"); |
| 18 | symbol(&logf, "logf"); | 18 | symbol(&logf, "logf"); |
| 19 | symbol(&log, "log"); | 19 | symbol(&log, "log"); |
| 20 | symbol(&__logx, "__logx"); | 20 | symbol(&__logx, "__logx"); |
| 21 | if (compiler_rt.want_ppc_abi) { | 21 | symbol(&logq, "logf128"); |
| 22 | symbol(&logq, "logf128"); | ||
| 23 | } | ||
| 24 | symbol(&logq, "logq"); | ||
| 25 | symbol(&logl, "logl"); | 22 | symbol(&logl, "logl"); |
| 26 | } | 23 | } |
| 27 | 24 | ||
| 28 | pub fn __logh(a: f16) callconv(.c) f16 { | 25 | fn __logh(a: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { |
| 26 | return compiler_rt.f16.toAbi(log_f16(compiler_rt.f16.fromAbi(a))); | ||
| 27 | } | ||
| 28 | pub fn log_f16(a: f16) f16 { | ||
| 29 | // TODO: more efficient implementation | 29 | // TODO: more efficient implementation |
| 30 | return @floatCast(logf(a)); | 30 | return @floatCast(log_f32(a)); |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | pub fn logf(x_: f32) callconv(.c) f32 { | 33 | fn logf(a: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { |
| 34 | return compiler_rt.f32.toAbi(log_f32(compiler_rt.f32.fromAbi(a))); | ||
| 35 | } | ||
| 36 | pub fn log_f32(x_: f32) f32 { | ||
| 34 | const ln2_hi: f32 = 6.9313812256e-01; | 37 | const ln2_hi: f32 = 6.9313812256e-01; |
| 35 | const ln2_lo: f32 = 9.0580006145e-06; | 38 | const ln2_lo: f32 = 9.0580006145e-06; |
| 36 | const Lg1: f32 = 0xaaaaaa.0p-24; | 39 | const Lg1: f32 = 0xaaaaaa.0p-24; |
| ... | @@ -82,7 +85,10 @@ pub fn logf(x_: f32) callconv(.c) f32 { | ... | @@ -82,7 +85,10 @@ pub fn logf(x_: f32) callconv(.c) f32 { |
| 82 | return s * (hfsq + R) + dk * ln2_lo - hfsq + f + dk * ln2_hi; | 85 | return s * (hfsq + R) + dk * ln2_lo - hfsq + f + dk * ln2_hi; |
| 83 | } | 86 | } |
| 84 | 87 | ||
| 85 | pub fn log(x: f64) callconv(.c) f64 { | 88 | fn log(a: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { |
| 89 | return compiler_rt.f64.toAbi(log_f64(compiler_rt.f64.fromAbi(a))); | ||
| 90 | } | ||
| 91 | pub fn log_f64(x: f64) f64 { | ||
| 86 | const poly1 = [_]f64{ | 92 | const poly1 = [_]f64{ |
| 87 | -0x1p-1, | 93 | -0x1p-1, |
| 88 | 0x1.5555555555577p-2, | 94 | 0x1.5555555555577p-2, |
| ... | @@ -432,11 +438,17 @@ pub fn log(x: f64) callconv(.c) f64 { | ... | @@ -432,11 +438,17 @@ pub fn log(x: f64) callconv(.c) f64 { |
| 432 | return @bitCast(y); | 438 | return @bitCast(y); |
| 433 | } | 439 | } |
| 434 | 440 | ||
| 435 | pub fn __logx(a: f80) callconv(.c) f80 { | 441 | fn __logx(a: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { |
| 442 | return compiler_rt.f80.toAbi(log_f80(compiler_rt.f80.fromAbi(a))); | ||
| 443 | } | ||
| 444 | pub fn log_f80(a: f80) f80 { | ||
| 436 | // TODO: more efficient implementation | 445 | // TODO: more efficient implementation |
| 437 | return @floatCast(logq(a)); | 446 | return @floatCast(log_f128(a)); |
| 438 | } | 447 | } |
| 439 | 448 | ||
| 449 | fn logq(a: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { | ||
| 450 | return compiler_rt.f128.toAbi(log_f128(compiler_rt.f128.fromAbi(a))); | ||
| 451 | } | ||
| 440 | /// Implementation of "Table-driven implementation of the logarithm function in IEEE floating-point arithmetic" | 452 | /// Implementation of "Table-driven implementation of the logarithm function in IEEE floating-point arithmetic" |
| 441 | /// by PTP Tang in ACM Transactions on Mathematical Software (TOMS), 1990 | 453 | /// by PTP Tang in ACM Transactions on Mathematical Software (TOMS), 1990 |
| 442 | /// | 454 | /// |
| ... | @@ -449,7 +461,7 @@ pub fn __logx(a: f80) callconv(.c) f80 { | ... | @@ -449,7 +461,7 @@ pub fn __logx(a: f80) callconv(.c) f80 { |
| 449 | /// | 461 | /// |
| 450 | /// Accuracy on 10 million random numbers near x = 1 (testing the proc2 case): | 462 | /// Accuracy on 10 million random numbers near x = 1 (testing the proc2 case): |
| 451 | /// <= 0.5 ulp: 99.96%, worst case <= 0.528 ulp | 463 | /// <= 0.5 ulp: 99.96%, worst case <= 0.528 ulp |
| 452 | pub fn logq(x: f128) callconv(.c) f128 { | 464 | pub fn log_f128(x: f128) f128 { |
| 453 | const impl = @import("log_f128.zig"); | 465 | const impl = @import("log_f128.zig"); |
| 454 | 466 | ||
| 455 | if (impl.specialCases(x)) |y| | 467 | if (impl.specialCases(x)) |y| |
| ... | @@ -626,123 +638,123 @@ pub fn logq(x: f128) callconv(.c) f128 { | ... | @@ -626,123 +638,123 @@ pub fn logq(x: f128) callconv(.c) f128 { |
| 626 | 638 | ||
| 627 | pub fn logl(x: c_longdouble) callconv(.c) c_longdouble { | 639 | pub fn logl(x: c_longdouble) callconv(.c) c_longdouble { |
| 628 | switch (@typeInfo(c_longdouble).float.bits) { | 640 | switch (@typeInfo(c_longdouble).float.bits) { |
| 629 | 64 => return log(x), | 641 | 64 => return log_f64(x), |
| 630 | 80 => return __logx(x), | 642 | 80 => return log_f80(x), |
| 631 | 128 => return logq(x), | 643 | 128 => return log_f128(x), |
| 632 | else => @compileError("unreachable"), | 644 | else => comptime unreachable, |
| 633 | } | 645 | } |
| 634 | } | 646 | } |
| 635 | 647 | ||
| 636 | test "logf() special" { | 648 | test "logf() special" { |
| 637 | try expectEqual(logf(0.0), -math.inf(f32)); | 649 | try expectEqual(log_f32(0.0), -math.inf(f32)); |
| 638 | try expectEqual(logf(-0.0), -math.inf(f32)); | 650 | try expectEqual(log_f32(-0.0), -math.inf(f32)); |
| 639 | try expect(math.isPositiveZero(logf(1.0))); | 651 | try expect(math.isPositiveZero(log_f32(1.0))); |
| 640 | try expectEqual(logf(math.e), 1.0); | 652 | try expectEqual(log_f32(math.e), 1.0); |
| 641 | try expectEqual(logf(math.inf(f32)), math.inf(f32)); | 653 | try expectEqual(log_f32(math.inf(f32)), math.inf(f32)); |
| 642 | try expect(math.isNan(logf(-1.0))); | 654 | try expect(math.isNan(log_f32(-1.0))); |
| 643 | try expect(math.isNan(logf(-math.inf(f32)))); | 655 | try expect(math.isNan(log_f32(-math.inf(f32)))); |
| 644 | try expect(math.isNan(logf(math.nan(f32)))); | 656 | try expect(math.isNan(log_f32(math.nan(f32)))); |
| 645 | try expect(math.isNan(logf(math.snan(f32)))); | 657 | try expect(math.isNan(log_f32(math.snan(f32)))); |
| 646 | } | 658 | } |
| 647 | 659 | ||
| 648 | test "logf() sanity" { | 660 | test "logf() sanity" { |
| 649 | try expect(math.isNan(logf(-0x1.0223a0p+3))); | 661 | try expect(math.isNan(log_f32(-0x1.0223a0p+3))); |
| 650 | try expectEqual(logf(0x1.161868p+2), 0x1.7815b0p+0); | 662 | try expectEqual(log_f32(0x1.161868p+2), 0x1.7815b0p+0); |
| 651 | try expect(math.isNan(logf(-0x1.0c34b4p+3))); | 663 | try expect(math.isNan(log_f32(-0x1.0c34b4p+3))); |
| 652 | try expect(math.isNan(logf(-0x1.a206f0p+2))); | 664 | try expect(math.isNan(log_f32(-0x1.a206f0p+2))); |
| 653 | try expectEqual(logf(0x1.288bbcp+3), 0x1.1cfcd6p+1); | 665 | try expectEqual(log_f32(0x1.288bbcp+3), 0x1.1cfcd6p+1); |
| 654 | try expectEqual(logf(0x1.52efd0p-1), -0x1.a6694cp-2); | 666 | try expectEqual(log_f32(0x1.52efd0p-1), -0x1.a6694cp-2); |
| 655 | try expect(math.isNan(logf(-0x1.a05cc8p-2))); | 667 | try expect(math.isNan(log_f32(-0x1.a05cc8p-2))); |
| 656 | try expectEqual(logf(0x1.1f9efap-1), -0x1.2742bap-1); | 668 | try expectEqual(log_f32(0x1.1f9efap-1), -0x1.2742bap-1); |
| 657 | try expectEqual(logf(0x1.8c5db0p-1), -0x1.062160p-2); | 669 | try expectEqual(log_f32(0x1.8c5db0p-1), -0x1.062160p-2); |
| 658 | try expect(math.isNan(logf(-0x1.5b86eap-1))); | 670 | try expect(math.isNan(log_f32(-0x1.5b86eap-1))); |
| 659 | } | 671 | } |
| 660 | 672 | ||
| 661 | test "logf() boundary" { | 673 | test "logf() boundary" { |
| 662 | try expectEqual(logf(0x1.fffffep+127), 0x1.62e430p+6); // Max input value | 674 | try expectEqual(log_f32(0x1.fffffep+127), 0x1.62e430p+6); // Max input value |
| 663 | try expectEqual(logf(0x1p-149), -0x1.9d1da0p+6); // Min positive input value | 675 | try expectEqual(log_f32(0x1p-149), -0x1.9d1da0p+6); // Min positive input value |
| 664 | try expect(math.isNan(logf(-0x1p-149))); // Min negative input value | 676 | try expect(math.isNan(log_f32(-0x1p-149))); // Min negative input value |
| 665 | try expectEqual(logf(0x1.000002p+0), 0x1.fffffep-24); // Last value before result reaches +0 | 677 | try expectEqual(log_f32(0x1.000002p+0), 0x1.fffffep-24); // Last value before result reaches +0 |
| 666 | try expectEqual(logf(0x1.fffffep-1), -0x1p-24); // Last value before result reaches -0 | 678 | try expectEqual(log_f32(0x1.fffffep-1), -0x1p-24); // Last value before result reaches -0 |
| 667 | try expectEqual(logf(0x1p-126), -0x1.5d58a0p+6); // First subnormal | 679 | try expectEqual(log_f32(0x1p-126), -0x1.5d58a0p+6); // First subnormal |
| 668 | try expect(math.isNan(logf(-0x1p-126))); // First negative subnormal | 680 | try expect(math.isNan(log_f32(-0x1p-126))); // First negative subnormal |
| 669 | } | 681 | } |
| 670 | 682 | ||
| 671 | test "log() special" { | 683 | test "log() special" { |
| 672 | try expectEqual(log(0.0), -math.inf(f64)); | 684 | try expectEqual(log_f64(0.0), -math.inf(f64)); |
| 673 | try expectEqual(log(-0.0), -math.inf(f64)); | 685 | try expectEqual(log_f64(-0.0), -math.inf(f64)); |
| 674 | try expect(math.isPositiveZero(log(1.0))); | 686 | try expect(math.isPositiveZero(log_f64(1.0))); |
| 675 | try expectEqual(log(math.e), 1.0); | 687 | try expectEqual(log_f64(math.e), 1.0); |
| 676 | try expectEqual(log(math.inf(f64)), math.inf(f64)); | 688 | try expectEqual(log_f64(math.inf(f64)), math.inf(f64)); |
| 677 | try expect(math.isNan(log(-1.0))); | 689 | try expect(math.isNan(log_f64(-1.0))); |
| 678 | try expect(math.isNan(log(-math.inf(f64)))); | 690 | try expect(math.isNan(log_f64(-math.inf(f64)))); |
| 679 | try expect(math.isNan(log(math.nan(f64)))); | 691 | try expect(math.isNan(log_f64(math.nan(f64)))); |
| 680 | try expect(math.isNan(log(math.snan(f64)))); | 692 | try expect(math.isNan(log_f64(math.snan(f64)))); |
| 681 | } | 693 | } |
| 682 | 694 | ||
| 683 | test "log() sanity" { | 695 | test "log() sanity" { |
| 684 | try expect(math.isNan(log(-0x1.02239f3c6a8f1p+3))); | 696 | try expect(math.isNan(log_f64(-0x1.02239f3c6a8f1p+3))); |
| 685 | try expectEqual(log(0x1.161868e18bc67p+2), 0x1.7815b08f99c65p+0); | 697 | try expectEqual(log_f64(0x1.161868e18bc67p+2), 0x1.7815b08f99c65p+0); |
| 686 | try expect(math.isNan(log(-0x1.0c34b3e01e6e7p+3))); | 698 | try expect(math.isNan(log_f64(-0x1.0c34b3e01e6e7p+3))); |
| 687 | try expect(math.isNan(log(-0x1.a206f0a19dcc4p+2))); | 699 | try expect(math.isNan(log_f64(-0x1.a206f0a19dcc4p+2))); |
| 688 | try expectEqual(log(0x1.288bbb0d6a1e6p+3), 0x1.1cfcd53d72604p+1); | 700 | try expectEqual(log_f64(0x1.288bbb0d6a1e6p+3), 0x1.1cfcd53d72604p+1); |
| 689 | try expectEqual(log(0x1.52efd0cd80497p-1), -0x1.a6694a4a85621p-2); | 701 | try expectEqual(log_f64(0x1.52efd0cd80497p-1), -0x1.a6694a4a85621p-2); |
| 690 | try expect(math.isNan(log(-0x1.a05cc754481d1p-2))); | 702 | try expect(math.isNan(log_f64(-0x1.a05cc754481d1p-2))); |
| 691 | try expectEqual(log(0x1.1f9ef934745cbp-1), -0x1.2742bc03d02ddp-1); | 703 | try expectEqual(log_f64(0x1.1f9ef934745cbp-1), -0x1.2742bc03d02ddp-1); |
| 692 | try expectEqual(log(0x1.8c5db097f7442p-1), -0x1.06215de4a3f92p-2); | 704 | try expectEqual(log_f64(0x1.8c5db097f7442p-1), -0x1.06215de4a3f92p-2); |
| 693 | try expect(math.isNan(log(-0x1.5b86ea8118a0ep-1))); | 705 | try expect(math.isNan(log_f64(-0x1.5b86ea8118a0ep-1))); |
| 694 | } | 706 | } |
| 695 | 707 | ||
| 696 | test "log() boundary" { | 708 | test "log() boundary" { |
| 697 | try expectEqual(log(0x1.fffffffffffffp+1023), 0x1.62e42fefa39efp+9); // Max input value | 709 | try expectEqual(log_f64(0x1.fffffffffffffp+1023), 0x1.62e42fefa39efp+9); // Max input value |
| 698 | try expectEqual(log(0x1p-1074), -0x1.74385446d71c3p+9); // Min positive input value | 710 | try expectEqual(log_f64(0x1p-1074), -0x1.74385446d71c3p+9); // Min positive input value |
| 699 | try expect(math.isNan(log(-0x1p-1074))); // Min negative input value | 711 | try expect(math.isNan(log_f64(-0x1p-1074))); // Min negative input value |
| 700 | try expectEqual(log(0x1.0000000000001p+0), 0x1.fffffffffffffp-53); // Last value before result reaches +0 | 712 | try expectEqual(log_f64(0x1.0000000000001p+0), 0x1.fffffffffffffp-53); // Last value before result reaches +0 |
| 701 | try expectEqual(log(0x1.fffffffffffffp-1), -0x1p-53); // Last value before result reaches -0 | 713 | try expectEqual(log_f64(0x1.fffffffffffffp-1), -0x1p-53); // Last value before result reaches -0 |
| 702 | try expectEqual(log(0x1p-1022), -0x1.6232bdd7abcd2p+9); // First subnormal | 714 | try expectEqual(log_f64(0x1p-1022), -0x1.6232bdd7abcd2p+9); // First subnormal |
| 703 | try expect(math.isNan(log(-0x1p-1022))); // First negative subnormal | 715 | try expect(math.isNan(log_f64(-0x1p-1022))); // First negative subnormal |
| 704 | } | 716 | } |
| 705 | 717 | ||
| 706 | test "logq() special" { | 718 | test "logq() special" { |
| 707 | try expectEqual(logq(0.0), -math.inf(f128)); | 719 | try expectEqual(log_f128(0.0), -math.inf(f128)); |
| 708 | try expectEqual(logq(-0.0), -math.inf(f128)); | 720 | try expectEqual(log_f128(-0.0), -math.inf(f128)); |
| 709 | try expect(math.isPositiveZero(logq(1.0))); | 721 | try expect(math.isPositiveZero(log_f128(1.0))); |
| 710 | // Sadly, the rounding gods decided that 0.9999999999999999999999999999999999 | 722 | // Sadly, the rounding gods decided that 0.9999999999999999999999999999999999 |
| 711 | // is the correctly rounded value of logq(math.e) | 723 | // is the correctly rounded value of log_f128(math.e) |
| 712 | try expectApproxEqRel(logq(math.e), 1.0, math.floatEpsAt(f128, 1.0)); | 724 | try expectApproxEqRel(log_f128(math.e), 1.0, math.floatEpsAt(f128, 1.0)); |
| 713 | try expectEqual(logq(math.inf(f128)), math.inf(f128)); | 725 | try expectEqual(log_f128(math.inf(f128)), math.inf(f128)); |
| 714 | try expect(math.isNan(logq(-1.0))); | 726 | try expect(math.isNan(log_f128(-1.0))); |
| 715 | try expect(math.isNan(logq(-math.inf(f128)))); | 727 | try expect(math.isNan(log_f128(-math.inf(f128)))); |
| 716 | try expect(math.isNan(logq(math.nan(f128)))); | 728 | try expect(math.isNan(log_f128(math.nan(f128)))); |
| 717 | try expect(math.isNan(logq(math.snan(f128)))); | 729 | try expect(math.isNan(log_f128(math.snan(f128)))); |
| 718 | } | 730 | } |
| 719 | 731 | ||
| 720 | test "logq() boundary" { | 732 | test "logq() boundary" { |
| 721 | try expectEqual(logq(0x1.ffffffffffffffffffffffffffffp16383), 0x1.62e42fefa39ef35793c7673007e6p13); // Max input value | 733 | try expectEqual(log_f128(0x1.ffffffffffffffffffffffffffffp16383), 0x1.62e42fefa39ef35793c7673007e6p13); // Max input value |
| 722 | try expectEqual(logq(0x1p-16494), -0x1.6546282207802c89d24d65e96274p13); // Min positive input value | 734 | try expectEqual(log_f128(0x1p-16494), -0x1.6546282207802c89d24d65e96274p13); // Min positive input value |
| 723 | try expect(math.isNan(logq(-0x1p-16494))); // Min negative input value | 735 | try expect(math.isNan(log_f128(-0x1p-16494))); // Min negative input value |
| 724 | try expectEqual(logq(0x1.0000000000000000000000000001p0), 0x1.ffffffffffffffffffffffffffffp-113); // Last value before result reaches +0 | 736 | try expectEqual(log_f128(0x1.0000000000000000000000000001p0), 0x1.ffffffffffffffffffffffffffffp-113); // Last value before result reaches +0 |
| 725 | try expectEqual(logq(0x1.ffffffffffffffffffffffffffffp-1), -0x1p-113); // Last value before result reaches -0 | 737 | try expectEqual(log_f128(0x1.ffffffffffffffffffffffffffffp-1), -0x1p-113); // Last value before result reaches -0 |
| 726 | try expectEqual(logq(0x1p-16382), -0x1.62d918ce2421d65ff90ac8f4ce66p13); // First subnormal | 738 | try expectEqual(log_f128(0x1p-16382), -0x1.62d918ce2421d65ff90ac8f4ce66p13); // First subnormal |
| 727 | try expect(math.isNan(logq(-0x1p-16382))); // First negative subnormal | 739 | try expect(math.isNan(log_f128(-0x1p-16382))); // First negative subnormal |
| 728 | } | 740 | } |
| 729 | 741 | ||
| 730 | test "logq() sanity" { | 742 | test "logq() sanity" { |
| 731 | try expectEqual(logq(4.151135979023751199079583784623537e-4), -7.7869583453055243113993340258295346e0); | 743 | try expectEqual(log_f128(4.151135979023751199079583784623537e-4), -7.7869583453055243113993340258295346e0); |
| 732 | try expectEqual(logq(9.614234245933828353176667689130293e-14), -2.9972946567656004014786271559909435e1); | 744 | try expectEqual(log_f128(9.614234245933828353176667689130293e-14), -2.9972946567656004014786271559909435e1); |
| 733 | try expectEqual(logq(1.012889803704721484375e13), 2.9946413646144315985379677542014356e1); | 745 | try expectEqual(log_f128(1.012889803704721484375e13), 2.9946413646144315985379677542014356e1); |
| 734 | try expectEqual(logq(2.397741857206453154086912e24), 5.613656963346284538829358703465392e1); | 746 | try expectEqual(log_f128(2.397741857206453154086912e24), 5.613656963346284538829358703465392e1); |
| 735 | try expectEqual(logq(3.442377567808290806386655232e27), 6.3405959896920645453203836625419693e1); | 747 | try expectEqual(log_f128(3.442377567808290806386655232e27), 6.3405959896920645453203836625419693e1); |
| 736 | try expectEqual(logq(1.0689155158234028407981544637594257e-8), -1.835403614606774451014272772421113e1); | 748 | try expectEqual(log_f128(1.0689155158234028407981544637594257e-8), -1.835403614606774451014272772421113e1); |
| 737 | try expectEqual(logq(1.4813913545768791536741499811327596e-10), -2.263286917934202003739900705050399e1); | 749 | try expectEqual(log_f128(1.4813913545768791536741499811327596e-10), -2.263286917934202003739900705050399e1); |
| 738 | try expectEqual(logq(4.518948965781299591064453125e10), 2.453413036705097282892685629562292e1); | 750 | try expectEqual(log_f128(4.518948965781299591064453125e10), 2.453413036705097282892685629562292e1); |
| 739 | try expectEqual(logq(1.200355637363589375e14), 3.2418809179272977400408325788186897e1); | 751 | try expectEqual(log_f128(1.200355637363589375e14), 3.2418809179272977400408325788186897e1); |
| 740 | try expectEqual(logq(6.6145398293682003021240234375e9), 2.261253606737223221601998075023261e1); | 752 | try expectEqual(log_f128(6.6145398293682003021240234375e9), 2.261253606737223221601998075023261e1); |
| 741 | try expectEqual(logq(5.16179116383965741056e20), 4.7692985503915646405875629300054525e1); | 753 | try expectEqual(log_f128(5.16179116383965741056e20), 4.7692985503915646405875629300054525e1); |
| 742 | // testing near 1 | 754 | // testing near 1 |
| 743 | try expectEqual(logq(1.026586845186097528392910049888087e0), 2.6239557099466251374193777672800004e-2); | 755 | try expectEqual(log_f128(1.026586845186097528392910049888087e0), 2.6239557099466251374193777672800004e-2); |
| 744 | try expectEqual(logq(9.878220373715243107115568932385941e-1), -1.2252721576456821219120474521538944e-2); | 756 | try expectEqual(log_f128(9.878220373715243107115568932385941e-1), -1.2252721576456821219120474521538944e-2); |
| 745 | try expectEqual(logq(9.417921077517196685541245315675951e-1), -5.997072116986790367958922503195352e-2); | 757 | try expectEqual(log_f128(9.417921077517196685541245315675951e-1), -5.997072116986790367958922503195352e-2); |
| 746 | try expectEqual(logq(1.043095786320424537962914257605007e0), 4.219300911769055080390811808602425e-2); | 758 | try expectEqual(log_f128(1.043095786320424537962914257605007e0), 4.219300911769055080390811808602425e-2); |
| 747 | try expectEqual(logq(1.019043049323190694932517175175235e0), 1.8863999985309781522599012445793722e-2); | 759 | try expectEqual(log_f128(1.019043049323190694932517175175235e0), 1.8863999985309781522599012445793722e-2); |
| 748 | } | 760 | } |
lib/compiler_rt/log10.zig+114-102| ... | @@ -18,19 +18,22 @@ comptime { | ... | @@ -18,19 +18,22 @@ comptime { |
| 18 | symbol(&log10f, "log10f"); | 18 | symbol(&log10f, "log10f"); |
| 19 | symbol(&log10, "log10"); | 19 | symbol(&log10, "log10"); |
| 20 | symbol(&__log10x, "__log10x"); | 20 | symbol(&__log10x, "__log10x"); |
| 21 | if (compiler_rt.want_ppc_abi) { | 21 | symbol(&log10q, "log10f128"); |
| 22 | symbol(&log10q, "log10f128"); | ||
| 23 | } | ||
| 24 | symbol(&log10q, "log10q"); | ||
| 25 | symbol(&log10l, "log10l"); | 22 | symbol(&log10l, "log10l"); |
| 26 | } | 23 | } |
| 27 | 24 | ||
| 28 | pub fn __log10h(a: f16) callconv(.c) f16 { | 25 | fn __log10h(a: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { |
| 26 | return compiler_rt.f16.toAbi(log10_f16(compiler_rt.f16.fromAbi(a))); | ||
| 27 | } | ||
| 28 | pub fn log10_f16(a: f16) f16 { | ||
| 29 | // TODO: more efficient implementation | 29 | // TODO: more efficient implementation |
| 30 | return @floatCast(log10f(a)); | 30 | return @floatCast(log10_f32(a)); |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | pub fn log10f(x_: f32) callconv(.c) f32 { | 33 | fn log10f(a: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { |
| 34 | return compiler_rt.f32.toAbi(log10_f32(compiler_rt.f32.fromAbi(a))); | ||
| 35 | } | ||
| 36 | pub fn log10_f32(x_: f32) f32 { | ||
| 34 | const ivln10hi: f32 = 4.3432617188e-01; | 37 | const ivln10hi: f32 = 4.3432617188e-01; |
| 35 | const ivln10lo: f32 = -3.1689971365e-05; | 38 | const ivln10lo: f32 = -3.1689971365e-05; |
| 36 | const log10_2hi: f32 = 3.0102920532e-01; | 39 | const log10_2hi: f32 = 3.0102920532e-01; |
| ... | @@ -90,7 +93,10 @@ pub fn log10f(x_: f32) callconv(.c) f32 { | ... | @@ -90,7 +93,10 @@ pub fn log10f(x_: f32) callconv(.c) f32 { |
| 90 | return dk * log10_2lo + (lo + hi) * ivln10lo + lo * ivln10hi + hi * ivln10hi + dk * log10_2hi; | 93 | return dk * log10_2lo + (lo + hi) * ivln10lo + lo * ivln10hi + hi * ivln10hi + dk * log10_2hi; |
| 91 | } | 94 | } |
| 92 | 95 | ||
| 93 | pub fn log10(x_: f64) callconv(.c) f64 { | 96 | fn log10(a: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { |
| 97 | return compiler_rt.f64.toAbi(log10_f64(compiler_rt.f64.fromAbi(a))); | ||
| 98 | } | ||
| 99 | pub fn log10_f64(x_: f64) f64 { | ||
| 94 | const ivln10hi: f64 = 4.34294481878168880939e-01; | 100 | const ivln10hi: f64 = 4.34294481878168880939e-01; |
| 95 | const ivln10lo: f64 = 2.50829467116452752298e-11; | 101 | const ivln10lo: f64 = 2.50829467116452752298e-11; |
| 96 | const log10_2hi: f64 = 3.01029995663611771306e-01; | 102 | const log10_2hi: f64 = 3.01029995663611771306e-01; |
| ... | @@ -165,11 +171,17 @@ pub fn log10(x_: f64) callconv(.c) f64 { | ... | @@ -165,11 +171,17 @@ pub fn log10(x_: f64) callconv(.c) f64 { |
| 165 | return val_lo + val_hi; | 171 | return val_lo + val_hi; |
| 166 | } | 172 | } |
| 167 | 173 | ||
| 168 | pub fn __log10x(a: f80) callconv(.c) f80 { | 174 | fn __log10x(a: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { |
| 175 | return compiler_rt.f80.toAbi(log10_f80(compiler_rt.f80.fromAbi(a))); | ||
| 176 | } | ||
| 177 | pub fn log10_f80(a: f80) f80 { | ||
| 169 | // TODO: more efficient implementation | 178 | // TODO: more efficient implementation |
| 170 | return @floatCast(log10q(a)); | 179 | return @floatCast(log10_f128(a)); |
| 171 | } | 180 | } |
| 172 | 181 | ||
| 182 | fn log10q(a: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { | ||
| 183 | return compiler_rt.f128.toAbi(log10_f128(compiler_rt.f128.fromAbi(a))); | ||
| 184 | } | ||
| 173 | /// Implementation of "Table-driven implementation of the logarithm function in IEEE floating-point arithmetic" | 185 | /// Implementation of "Table-driven implementation of the logarithm function in IEEE floating-point arithmetic" |
| 174 | /// by PTP Tang in ACM Transactions on Mathematical Software (TOMS), 1990 | 186 | /// by PTP Tang in ACM Transactions on Mathematical Software (TOMS), 1990 |
| 175 | /// | 187 | /// |
| ... | @@ -182,7 +194,7 @@ pub fn __log10x(a: f80) callconv(.c) f80 { | ... | @@ -182,7 +194,7 @@ pub fn __log10x(a: f80) callconv(.c) f80 { |
| 182 | /// | 194 | /// |
| 183 | /// Accuracy on 10 million random numbers near x = 1 (testing the proc2 case): | 195 | /// Accuracy on 10 million random numbers near x = 1 (testing the proc2 case): |
| 184 | /// <= 0.5 ulp: 99.96%, worst case <= 0.565 ulp | 196 | /// <= 0.5 ulp: 99.96%, worst case <= 0.565 ulp |
| 185 | pub fn log10q(x: f128) callconv(.c) f128 { | 197 | pub fn log10_f128(x: f128) f128 { |
| 186 | const impl = @import("log_f128.zig"); | 198 | const impl = @import("log_f128.zig"); |
| 187 | 199 | ||
| 188 | if (impl.specialCases(x)) |y| | 200 | if (impl.specialCases(x)) |y| |
| ... | @@ -359,124 +371,124 @@ pub fn log10q(x: f128) callconv(.c) f128 { | ... | @@ -359,124 +371,124 @@ pub fn log10q(x: f128) callconv(.c) f128 { |
| 359 | 371 | ||
| 360 | pub fn log10l(x: c_longdouble) callconv(.c) c_longdouble { | 372 | pub fn log10l(x: c_longdouble) callconv(.c) c_longdouble { |
| 361 | switch (@typeInfo(c_longdouble).float.bits) { | 373 | switch (@typeInfo(c_longdouble).float.bits) { |
| 362 | 64 => return log10(x), | 374 | 64 => return log10_f64(x), |
| 363 | 80 => return __log10x(x), | 375 | 80 => return log10_f80(x), |
| 364 | 128 => return log10q(x), | 376 | 128 => return log10_f128(x), |
| 365 | else => @compileError("unreachable"), | 377 | else => comptime unreachable, |
| 366 | } | 378 | } |
| 367 | } | 379 | } |
| 368 | 380 | ||
| 369 | test "log10f() special" { | 381 | test "log10f() special" { |
| 370 | try expectEqual(log10f(0.0), -math.inf(f32)); | 382 | try expectEqual(log10_f32(0.0), -math.inf(f32)); |
| 371 | try expectEqual(log10f(-0.0), -math.inf(f32)); | 383 | try expectEqual(log10_f32(-0.0), -math.inf(f32)); |
| 372 | try expect(math.isPositiveZero(log10f(1.0))); | 384 | try expect(math.isPositiveZero(log10_f32(1.0))); |
| 373 | try expectEqual(log10f(10.0), 1.0); | 385 | try expectEqual(log10_f32(10.0), 1.0); |
| 374 | try expectEqual(log10f(0.1), -1.0); | 386 | try expectEqual(log10_f32(0.1), -1.0); |
| 375 | try expectEqual(log10f(math.inf(f32)), math.inf(f32)); | 387 | try expectEqual(log10_f32(math.inf(f32)), math.inf(f32)); |
| 376 | try expect(math.isNan(log10f(-1.0))); | 388 | try expect(math.isNan(log10_f32(-1.0))); |
| 377 | try expect(math.isNan(log10f(-math.inf(f32)))); | 389 | try expect(math.isNan(log10_f32(-math.inf(f32)))); |
| 378 | try expect(math.isNan(log10f(math.nan(f32)))); | 390 | try expect(math.isNan(log10_f32(math.nan(f32)))); |
| 379 | try expect(math.isNan(log10f(math.snan(f32)))); | 391 | try expect(math.isNan(log10_f32(math.snan(f32)))); |
| 380 | } | 392 | } |
| 381 | 393 | ||
| 382 | test "log10f() sanity" { | 394 | test "log10f() sanity" { |
| 383 | try expect(math.isNan(log10f(-0x1.0223a0p+3))); | 395 | try expect(math.isNan(log10_f32(-0x1.0223a0p+3))); |
| 384 | try expectEqual(log10f(0x1.161868p+2), 0x1.46a9bcp-1); | 396 | try expectEqual(log10_f32(0x1.161868p+2), 0x1.46a9bcp-1); |
| 385 | try expect(math.isNan(log10f(-0x1.0c34b4p+3))); | 397 | try expect(math.isNan(log10_f32(-0x1.0c34b4p+3))); |
| 386 | try expect(math.isNan(log10f(-0x1.a206f0p+2))); | 398 | try expect(math.isNan(log10_f32(-0x1.a206f0p+2))); |
| 387 | try expectEqual(log10f(0x1.288bbcp+3), 0x1.ef1300p-1); | 399 | try expectEqual(log10_f32(0x1.288bbcp+3), 0x1.ef1300p-1); |
| 388 | try expectEqual(log10f(0x1.52efd0p-1), -0x1.6ee6dcp-3); // Disagrees with GCC in last bit | 400 | try expectEqual(log10_f32(0x1.52efd0p-1), -0x1.6ee6dcp-3); // Disagrees with GCC in last bit |
| 389 | try expect(math.isNan(log10f(-0x1.a05cc8p-2))); | 401 | try expect(math.isNan(log10_f32(-0x1.a05cc8p-2))); |
| 390 | try expectEqual(log10f(0x1.1f9efap-1), -0x1.0075ccp-2); | 402 | try expectEqual(log10_f32(0x1.1f9efap-1), -0x1.0075ccp-2); |
| 391 | try expectEqual(log10f(0x1.8c5db0p-1), -0x1.c75df8p-4); | 403 | try expectEqual(log10_f32(0x1.8c5db0p-1), -0x1.c75df8p-4); |
| 392 | try expect(math.isNan(log10f(-0x1.5b86eap-1))); | 404 | try expect(math.isNan(log10_f32(-0x1.5b86eap-1))); |
| 393 | } | 405 | } |
| 394 | 406 | ||
| 395 | test "log10f() boundary" { | 407 | test "log10f() boundary" { |
| 396 | try expectEqual(log10f(0x1.fffffep+127), 0x1.344136p+5); // Max input value | 408 | try expectEqual(log10_f32(0x1.fffffep+127), 0x1.344136p+5); // Max input value |
| 397 | try expectEqual(log10f(0x1p-149), -0x1.66d3e8p+5); // Min positive input value | 409 | try expectEqual(log10_f32(0x1p-149), -0x1.66d3e8p+5); // Min positive input value |
| 398 | try expect(math.isNan(log10f(-0x1p-149))); // Min negative input value | 410 | try expect(math.isNan(log10_f32(-0x1p-149))); // Min negative input value |
| 399 | try expectEqual(log10f(0x1.000002p+0), 0x1.bcb7b0p-25); // Last value before result reaches +0 | 411 | try expectEqual(log10_f32(0x1.000002p+0), 0x1.bcb7b0p-25); // Last value before result reaches +0 |
| 400 | try expectEqual(log10f(0x1.fffffep-1), -0x1.bcb7b2p-26); // Last value before result reaches -0 | 412 | try expectEqual(log10_f32(0x1.fffffep-1), -0x1.bcb7b2p-26); // Last value before result reaches -0 |
| 401 | try expectEqual(log10f(0x1p-126), -0x1.2f7030p+5); // First subnormal | 413 | try expectEqual(log10_f32(0x1p-126), -0x1.2f7030p+5); // First subnormal |
| 402 | try expect(math.isNan(log10f(-0x1p-126))); // First negative subnormal | 414 | try expect(math.isNan(log10_f32(-0x1p-126))); // First negative subnormal |
| 403 | } | 415 | } |
| 404 | 416 | ||
| 405 | test "log10() special" { | 417 | test "log10() special" { |
| 406 | try expectEqual(log10(0.0), -math.inf(f64)); | 418 | try expectEqual(log10_f64(0.0), -math.inf(f64)); |
| 407 | try expectEqual(log10(-0.0), -math.inf(f64)); | 419 | try expectEqual(log10_f64(-0.0), -math.inf(f64)); |
| 408 | try expect(math.isPositiveZero(log10(1.0))); | 420 | try expect(math.isPositiveZero(log10_f64(1.0))); |
| 409 | try expectEqual(log10(10.0), 1.0); | 421 | try expectEqual(log10_f64(10.0), 1.0); |
| 410 | try expectEqual(log10(0.1), -1.0); | 422 | try expectEqual(log10_f64(0.1), -1.0); |
| 411 | try expectEqual(log10(math.inf(f64)), math.inf(f64)); | 423 | try expectEqual(log10_f64(math.inf(f64)), math.inf(f64)); |
| 412 | try expect(math.isNan(log10(-1.0))); | 424 | try expect(math.isNan(log10_f64(-1.0))); |
| 413 | try expect(math.isNan(log10(-math.inf(f64)))); | 425 | try expect(math.isNan(log10_f64(-math.inf(f64)))); |
| 414 | try expect(math.isNan(log10(math.nan(f64)))); | 426 | try expect(math.isNan(log10_f64(math.nan(f64)))); |
| 415 | try expect(math.isNan(log10(math.snan(f64)))); | 427 | try expect(math.isNan(log10_f64(math.snan(f64)))); |
| 416 | } | 428 | } |
| 417 | 429 | ||
| 418 | test "log10() sanity" { | 430 | test "log10() sanity" { |
| 419 | try expect(math.isNan(log10(-0x1.02239f3c6a8f1p+3))); | 431 | try expect(math.isNan(log10_f64(-0x1.02239f3c6a8f1p+3))); |
| 420 | try expectEqual(log10(0x1.161868e18bc67p+2), 0x1.46a9bd1d2eb87p-1); | 432 | try expectEqual(log10_f64(0x1.161868e18bc67p+2), 0x1.46a9bd1d2eb87p-1); |
| 421 | try expect(math.isNan(log10(-0x1.0c34b3e01e6e7p+3))); | 433 | try expect(math.isNan(log10_f64(-0x1.0c34b3e01e6e7p+3))); |
| 422 | try expect(math.isNan(log10(-0x1.a206f0a19dcc4p+2))); | 434 | try expect(math.isNan(log10_f64(-0x1.a206f0a19dcc4p+2))); |
| 423 | try expectEqual(log10(0x1.288bbb0d6a1e6p+3), 0x1.ef12fff994862p-1); | 435 | try expectEqual(log10_f64(0x1.288bbb0d6a1e6p+3), 0x1.ef12fff994862p-1); |
| 424 | try expectEqual(log10(0x1.52efd0cd80497p-1), -0x1.6ee6db5a155cbp-3); | 436 | try expectEqual(log10_f64(0x1.52efd0cd80497p-1), -0x1.6ee6db5a155cbp-3); |
| 425 | try expect(math.isNan(log10(-0x1.a05cc754481d1p-2))); | 437 | try expect(math.isNan(log10_f64(-0x1.a05cc754481d1p-2))); |
| 426 | try expectEqual(log10(0x1.1f9ef934745cbp-1), -0x1.0075cda79d321p-2); | 438 | try expectEqual(log10_f64(0x1.1f9ef934745cbp-1), -0x1.0075cda79d321p-2); |
| 427 | try expectEqual(log10(0x1.8c5db097f7442p-1), -0x1.c75df6442465ap-4); | 439 | try expectEqual(log10_f64(0x1.8c5db097f7442p-1), -0x1.c75df6442465ap-4); |
| 428 | try expect(math.isNan(log10(-0x1.5b86ea8118a0ep-1))); | 440 | try expect(math.isNan(log10_f64(-0x1.5b86ea8118a0ep-1))); |
| 429 | } | 441 | } |
| 430 | 442 | ||
| 431 | test "log10() boundary" { | 443 | test "log10() boundary" { |
| 432 | try expectEqual(log10(0x1.fffffffffffffp+1023), 0x1.34413509f79ffp+8); // Max input value | 444 | try expectEqual(log10_f64(0x1.fffffffffffffp+1023), 0x1.34413509f79ffp+8); // Max input value |
| 433 | try expectEqual(log10(0x1p-1074), -0x1.434e6420f4374p+8); // Min positive input value | 445 | try expectEqual(log10_f64(0x1p-1074), -0x1.434e6420f4374p+8); // Min positive input value |
| 434 | try expect(math.isNan(log10(-0x1p-1074))); // Min negative input value | 446 | try expect(math.isNan(log10_f64(-0x1p-1074))); // Min negative input value |
| 435 | try expectEqual(log10(0x1.0000000000001p+0), 0x1.bcb7b1526e50dp-54); // Last value before result reaches +0 | 447 | try expectEqual(log10_f64(0x1.0000000000001p+0), 0x1.bcb7b1526e50dp-54); // Last value before result reaches +0 |
| 436 | try expectEqual(log10(0x1.fffffffffffffp-1), -0x1.bcb7b1526e50fp-55); // Last value before result reaches -0 | 448 | try expectEqual(log10_f64(0x1.fffffffffffffp-1), -0x1.bcb7b1526e50fp-55); // Last value before result reaches -0 |
| 437 | try expectEqual(log10(0x1p-1022), -0x1.33a7146f72a42p+8); // First subnormal | 449 | try expectEqual(log10_f64(0x1p-1022), -0x1.33a7146f72a42p+8); // First subnormal |
| 438 | try expect(math.isNan(log10(-0x1p-1022))); // First negative subnormal | 450 | try expect(math.isNan(log10_f64(-0x1p-1022))); // First negative subnormal |
| 439 | } | 451 | } |
| 440 | 452 | ||
| 441 | test "log10q() special" { | 453 | test "log10q() special" { |
| 442 | try expectEqual(log10q(0.0), -math.inf(f128)); | 454 | try expectEqual(log10_f128(0.0), -math.inf(f128)); |
| 443 | try expectEqual(log10q(-0.0), -math.inf(f128)); | 455 | try expectEqual(log10_f128(-0.0), -math.inf(f128)); |
| 444 | try expect(math.isPositiveZero(log10q(1.0))); | 456 | try expect(math.isPositiveZero(log10_f128(1.0))); |
| 445 | try expectEqual(log10q(10.0), 1.0); | 457 | try expectEqual(log10_f128(10.0), 1.0); |
| 446 | try expectEqual(log10q(0.1), -1.0); | 458 | try expectEqual(log10_f128(0.1), -1.0); |
| 447 | try expectEqual(log10q(math.inf(f128)), math.inf(f128)); | 459 | try expectEqual(log10_f128(math.inf(f128)), math.inf(f128)); |
| 448 | try expect(math.isNan(log10q(-1.0))); | 460 | try expect(math.isNan(log10_f128(-1.0))); |
| 449 | try expect(math.isNan(log10q(-math.inf(f128)))); | 461 | try expect(math.isNan(log10_f128(-math.inf(f128)))); |
| 450 | try expect(math.isNan(log10q(math.nan(f128)))); | 462 | try expect(math.isNan(log10_f128(math.nan(f128)))); |
| 451 | try expect(math.isNan(log10q(math.snan(f128)))); | 463 | try expect(math.isNan(log10_f128(math.snan(f128)))); |
| 452 | } | 464 | } |
| 453 | 465 | ||
| 454 | test "log10q() sanity" { | 466 | test "log10q() sanity" { |
| 455 | try expectEqual(log10q(2.1744503117482705706605762784484114e1949), 1.949337349488073972035715318447419e3); | 467 | try expectEqual(log10_f128(2.1744503117482705706605762784484114e1949), 1.949337349488073972035715318447419e3); |
| 456 | try expectEqual(log10q(2.3695331993665660983204066767386505e2150), 2.1503746627979481420243846411400265e3); | 468 | try expectEqual(log10_f128(2.3695331993665660983204066767386505e2150), 2.1503746627979481420243846411400265e3); |
| 457 | try expectEqual(log10q(1.8071775728314983136779370752110857e612), 6.122570008283284411311428111991705e2); | 469 | try expectEqual(log10_f128(1.8071775728314983136779370752110857e612), 6.122570008283284411311428111991705e2); |
| 458 | try expectEqual(log10q(2.612170297226630737309271722008693e-2629), -2.628582998513179919647069989114319e3); | 470 | try expectEqual(log10_f128(2.612170297226630737309271722008693e-2629), -2.628582998513179919647069989114319e3); |
| 459 | try expectEqual(log10q(8.485091636263895897993044621224502e-3748), -3.7470713434630800881474518447042895e3); | 471 | try expectEqual(log10_f128(8.485091636263895897993044621224502e-3748), -3.7470713434630800881474518447042895e3); |
| 460 | try expectEqual(log10q(4.3668077579803801413736022136116655e-4051), -4.0503598359268068567757367259544416e3); | 472 | try expectEqual(log10_f128(4.3668077579803801413736022136116655e-4051), -4.0503598359268068567757367259544416e3); |
| 461 | try expectEqual(log10q(2.9321353260885285826237030859036923e4830), 4.830467184010313310864606285356782e3); | 473 | try expectEqual(log10_f128(2.9321353260885285826237030859036923e4830), 4.830467184010313310864606285356782e3); |
| 462 | try expectEqual(log10q(6.6119754254652455408442826553161645e-1417), -1.416179668769227128601620567685071e3); | 474 | try expectEqual(log10_f128(6.6119754254652455408442826553161645e-1417), -1.416179668769227128601620567685071e3); |
| 463 | try expectEqual(log10q(5.2459104673488555418645321788108695e4178), 4.178719820874155944446586083585479e3); | 475 | try expectEqual(log10_f128(5.2459104673488555418645321788108695e4178), 4.178719820874155944446586083585479e3); |
| 464 | try expectEqual(log10q(7.809812890804996586377267218360886e-418), -4.1710735937091966815220294599598215e2); | 476 | try expectEqual(log10_f128(7.809812890804996586377267218360886e-418), -4.1710735937091966815220294599598215e2); |
| 465 | // testing near 1 | 477 | // testing near 1 |
| 466 | try expectEqual(log10q(1.0291437165967803055610652052109798e0), 1.2476026819466393459130418401605807e-2); | 478 | try expectEqual(log10_f128(1.0291437165967803055610652052109798e0), 1.2476026819466393459130418401605807e-2); |
| 467 | try expectEqual(log10q(1.043095786320424537962914257605007e0), 1.8324191034706598279642145362763252e-2); | 479 | try expectEqual(log10_f128(1.043095786320424537962914257605007e0), 1.8324191034706598279642145362763252e-2); |
| 468 | try expectEqual(log10q(9.900264873754467234601150948947179e-1), -4.3531860417287584780652055666513634e-3); | 480 | try expectEqual(log10_f128(9.900264873754467234601150948947179e-1), -4.3531860417287584780652055666513634e-3); |
| 469 | try expectEqual(log10q(1.038295346547007736348611217636062e0), 1.6320907588397540309035279023485962e-2); | 481 | try expectEqual(log10_f128(1.038295346547007736348611217636062e0), 1.6320907588397540309035279023485962e-2); |
| 470 | try expectEqual(log10q(9.821701941230028324703038578036285e-1), -7.813249520562034832371814409278784e-3); | 482 | try expectEqual(log10_f128(9.821701941230028324703038578036285e-1), -7.813249520562034832371814409278784e-3); |
| 471 | try expectEqual(log10q(9.593555263530179895381522214847791e-1), -1.8020418356217558657107271163588764e-2); | 483 | try expectEqual(log10_f128(9.593555263530179895381522214847791e-1), -1.8020418356217558657107271163588764e-2); |
| 472 | } | 484 | } |
| 473 | 485 | ||
| 474 | test "log10q() boundary" { | 486 | test "log10q() boundary" { |
| 475 | try expectEqual(log10q(0x1.ffffffffffffffffffffffffffffp16383), 0x1.34413509f79fef311f12b35816f9p12); // Max input value | 487 | try expectEqual(log10_f128(0x1.ffffffffffffffffffffffffffffp16383), 0x1.34413509f79fef311f12b35816f9p12); // Max input value |
| 476 | try expectEqual(log10q(0x1p-16494), -0x1.3653051d20c18a143b801b7c5661p12); // Min positive input value | 488 | try expectEqual(log10_f128(0x1p-16494), -0x1.3653051d20c18a143b801b7c5661p12); // Min positive input value |
| 477 | try expect(math.isNan(log10q(-0x1p-16494))); // Min negative input value | 489 | try expect(math.isNan(log10_f128(-0x1p-16494))); // Min negative input value |
| 478 | try expectEqual(log10q(0x1.0000000000000000000000000001p0), 0x1.bcb7b1526e50e32a6ab7555f5a67p-114); // Last value before result reaches +0 | 490 | try expectEqual(log10_f128(0x1.0000000000000000000000000001p0), 0x1.bcb7b1526e50e32a6ab7555f5a67p-114); // Last value before result reaches +0 |
| 479 | try expectEqual(log10q(0x1.ffffffffffffffffffffffffffffp-1), -0x1.bcb7b1526e50e32a6ab7555f5a68p-115); // Last value before result reaches -0 | 491 | try expectEqual(log10_f128(0x1.ffffffffffffffffffffffffffffp-1), -0x1.bcb7b1526e50e32a6ab7555f5a68p-115); // Last value before result reaches -0 |
| 480 | try expectEqual(log10q(0x1p-16382), -0x1.343793004f503231a589bac27c38p12); // First subnormal | 492 | try expectEqual(log10_f128(0x1p-16382), -0x1.343793004f503231a589bac27c38p12); // First subnormal |
| 481 | try expect(math.isNan(log10q(-0x1p-16382))); // First negative subnormal | 493 | try expect(math.isNan(log10_f128(-0x1p-16382))); // First negative subnormal |
| 482 | } | 494 | } |
lib/compiler_rt/log2.zig+106-94| ... | @@ -19,19 +19,22 @@ comptime { | ... | @@ -19,19 +19,22 @@ comptime { |
| 19 | symbol(&log2f, "log2f"); | 19 | symbol(&log2f, "log2f"); |
| 20 | symbol(&log2, "log2"); | 20 | symbol(&log2, "log2"); |
| 21 | symbol(&__log2x, "__log2x"); | 21 | symbol(&__log2x, "__log2x"); |
| 22 | if (compiler_rt.want_ppc_abi) { | 22 | symbol(&log2q, "log2f128"); |
| 23 | symbol(&log2q, "log2f128"); | ||
| 24 | } | ||
| 25 | symbol(&log2q, "log2q"); | ||
| 26 | symbol(&log2l, "log2l"); | 23 | symbol(&log2l, "log2l"); |
| 27 | } | 24 | } |
| 28 | 25 | ||
| 29 | pub fn __log2h(a: f16) callconv(.c) f16 { | 26 | fn __log2h(a: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { |
| 27 | return compiler_rt.f16.toAbi(log2_f16(compiler_rt.f16.fromAbi(a))); | ||
| 28 | } | ||
| 29 | pub fn log2_f16(a: f16) f16 { | ||
| 30 | // TODO: more efficient implementation | 30 | // TODO: more efficient implementation |
| 31 | return @floatCast(log2f(a)); | 31 | return @floatCast(log2_f32(a)); |
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | pub fn log2f(x_: f32) callconv(.c) f32 { | 34 | fn log2f(a: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { |
| 35 | return compiler_rt.f32.toAbi(log2_f32(compiler_rt.f32.fromAbi(a))); | ||
| 36 | } | ||
| 37 | pub fn log2_f32(x_: f32) f32 { | ||
| 35 | const ivln2hi: f32 = 1.4428710938e+00; | 38 | const ivln2hi: f32 = 1.4428710938e+00; |
| 36 | const ivln2lo: f32 = -1.7605285393e-04; | 39 | const ivln2lo: f32 = -1.7605285393e-04; |
| 37 | const Lg1: f32 = 0xaaaaaa.0p-24; | 40 | const Lg1: f32 = 0xaaaaaa.0p-24; |
| ... | @@ -87,7 +90,10 @@ pub fn log2f(x_: f32) callconv(.c) f32 { | ... | @@ -87,7 +90,10 @@ pub fn log2f(x_: f32) callconv(.c) f32 { |
| 87 | return (lo + hi) * ivln2lo + lo * ivln2hi + hi * ivln2hi + @as(f32, @floatFromInt(k)); | 90 | return (lo + hi) * ivln2lo + lo * ivln2hi + hi * ivln2hi + @as(f32, @floatFromInt(k)); |
| 88 | } | 91 | } |
| 89 | 92 | ||
| 90 | pub fn log2(x_: f64) callconv(.c) f64 { | 93 | fn log2(a: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { |
| 94 | return compiler_rt.f64.toAbi(log2_f64(compiler_rt.f64.fromAbi(a))); | ||
| 95 | } | ||
| 96 | pub fn log2_f64(x_: f64) f64 { | ||
| 91 | const ivln2hi: f64 = 1.44269504072144627571e+00; | 97 | const ivln2hi: f64 = 1.44269504072144627571e+00; |
| 92 | const ivln2lo: f64 = 1.67517131648865118353e-10; | 98 | const ivln2lo: f64 = 1.67517131648865118353e-10; |
| 93 | const Lg1: f64 = 6.666666666666735130e-01; | 99 | const Lg1: f64 = 6.666666666666735130e-01; |
| ... | @@ -158,11 +164,17 @@ pub fn log2(x_: f64) callconv(.c) f64 { | ... | @@ -158,11 +164,17 @@ pub fn log2(x_: f64) callconv(.c) f64 { |
| 158 | return val_lo + val_hi; | 164 | return val_lo + val_hi; |
| 159 | } | 165 | } |
| 160 | 166 | ||
| 161 | pub fn __log2x(a: f80) callconv(.c) f80 { | 167 | fn __log2x(a: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { |
| 168 | return compiler_rt.f80.toAbi(log2_f80(compiler_rt.f80.fromAbi(a))); | ||
| 169 | } | ||
| 170 | pub fn log2_f80(a: f80) f80 { | ||
| 162 | // TODO: more efficient implementation | 171 | // TODO: more efficient implementation |
| 163 | return @floatCast(log2q(a)); | 172 | return @floatCast(log2_f128(a)); |
| 164 | } | 173 | } |
| 165 | 174 | ||
| 175 | fn log2q(a: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { | ||
| 176 | return compiler_rt.f128.toAbi(log2_f128(compiler_rt.f128.fromAbi(a))); | ||
| 177 | } | ||
| 166 | /// Implementation of "Table-driven implementation of the logarithm function in IEEE floating-point arithmetic" | 178 | /// Implementation of "Table-driven implementation of the logarithm function in IEEE floating-point arithmetic" |
| 167 | /// by PTP Tang in ACM Transactions on Mathematical Software (TOMS), 1990 | 179 | /// by PTP Tang in ACM Transactions on Mathematical Software (TOMS), 1990 |
| 168 | /// | 180 | /// |
| ... | @@ -175,7 +187,7 @@ pub fn __log2x(a: f80) callconv(.c) f80 { | ... | @@ -175,7 +187,7 @@ pub fn __log2x(a: f80) callconv(.c) f80 { |
| 175 | /// | 187 | /// |
| 176 | /// Accuracy on 10 million random numbers near x = 1 (testing the proc2 case): | 188 | /// Accuracy on 10 million random numbers near x = 1 (testing the proc2 case): |
| 177 | /// <= 0.5 ulp: 99.86%, worst case <= 0.546 ulp | 189 | /// <= 0.5 ulp: 99.86%, worst case <= 0.546 ulp |
| 178 | pub fn log2q(x: f128) callconv(.c) f128 { | 190 | pub fn log2_f128(x: f128) f128 { |
| 179 | const impl = @import("log_f128.zig"); | 191 | const impl = @import("log_f128.zig"); |
| 180 | 192 | ||
| 181 | if (impl.specialCases(x)) |y| | 193 | if (impl.specialCases(x)) |y| |
| ... | @@ -351,117 +363,117 @@ pub fn log2q(x: f128) callconv(.c) f128 { | ... | @@ -351,117 +363,117 @@ pub fn log2q(x: f128) callconv(.c) f128 { |
| 351 | 363 | ||
| 352 | pub fn log2l(x: c_longdouble) callconv(.c) c_longdouble { | 364 | pub fn log2l(x: c_longdouble) callconv(.c) c_longdouble { |
| 353 | switch (@typeInfo(c_longdouble).float.bits) { | 365 | switch (@typeInfo(c_longdouble).float.bits) { |
| 354 | 64 => return log2(x), | 366 | 64 => return log2_f64(x), |
| 355 | 80 => return __log2x(x), | 367 | 80 => return log2_f80(x), |
| 356 | 128 => return log2q(x), | 368 | 128 => return log2_f128(x), |
| 357 | else => @compileError("unreachable"), | 369 | else => comptime unreachable, |
| 358 | } | 370 | } |
| 359 | } | 371 | } |
| 360 | 372 | ||
| 361 | test "log2f() special" { | 373 | test "log2f() special" { |
| 362 | try expectEqual(log2f(0.0), -math.inf(f32)); | 374 | try expectEqual(log2_f32(0.0), -math.inf(f32)); |
| 363 | try expectEqual(log2f(-0.0), -math.inf(f32)); | 375 | try expectEqual(log2_f32(-0.0), -math.inf(f32)); |
| 364 | try expect(math.isPositiveZero(log2f(1.0))); | 376 | try expect(math.isPositiveZero(log2_f32(1.0))); |
| 365 | try expectEqual(log2f(2.0), 1.0); | 377 | try expectEqual(log2_f32(2.0), 1.0); |
| 366 | try expectEqual(log2f(math.inf(f32)), math.inf(f32)); | 378 | try expectEqual(log2_f32(math.inf(f32)), math.inf(f32)); |
| 367 | try expect(math.isNan(log2f(-1.0))); | 379 | try expect(math.isNan(log2_f32(-1.0))); |
| 368 | try expect(math.isNan(log2f(-math.inf(f32)))); | 380 | try expect(math.isNan(log2_f32(-math.inf(f32)))); |
| 369 | try expect(math.isNan(log2f(math.nan(f32)))); | 381 | try expect(math.isNan(log2_f32(math.nan(f32)))); |
| 370 | try expect(math.isNan(log2f(math.snan(f32)))); | 382 | try expect(math.isNan(log2_f32(math.snan(f32)))); |
| 371 | } | 383 | } |
| 372 | 384 | ||
| 373 | test "log2f() sanity" { | 385 | test "log2f() sanity" { |
| 374 | try expect(math.isNan(log2f(-0x1.0223a0p+3))); | 386 | try expect(math.isNan(log2_f32(-0x1.0223a0p+3))); |
| 375 | try expectEqual(log2f(0x1.161868p+2), 0x1.0f49acp+1); | 387 | try expectEqual(log2_f32(0x1.161868p+2), 0x1.0f49acp+1); |
| 376 | try expect(math.isNan(log2f(-0x1.0c34b4p+3))); | 388 | try expect(math.isNan(log2_f32(-0x1.0c34b4p+3))); |
| 377 | try expect(math.isNan(log2f(-0x1.a206f0p+2))); | 389 | try expect(math.isNan(log2_f32(-0x1.a206f0p+2))); |
| 378 | try expectEqual(log2f(0x1.288bbcp+3), 0x1.9b2676p+1); | 390 | try expectEqual(log2_f32(0x1.288bbcp+3), 0x1.9b2676p+1); |
| 379 | try expectEqual(log2f(0x1.52efd0p-1), -0x1.30b494p-1); // Disagrees with GCC in last bit | 391 | try expectEqual(log2_f32(0x1.52efd0p-1), -0x1.30b494p-1); // Disagrees with GCC in last bit |
| 380 | try expect(math.isNan(log2f(-0x1.a05cc8p-2))); | 392 | try expect(math.isNan(log2_f32(-0x1.a05cc8p-2))); |
| 381 | try expectEqual(log2f(0x1.1f9efap-1), -0x1.a9f89ap-1); | 393 | try expectEqual(log2_f32(0x1.1f9efap-1), -0x1.a9f89ap-1); |
| 382 | try expectEqual(log2f(0x1.8c5db0p-1), -0x1.7a2c96p-2); | 394 | try expectEqual(log2_f32(0x1.8c5db0p-1), -0x1.7a2c96p-2); |
| 383 | try expect(math.isNan(log2f(-0x1.5b86eap-1))); | 395 | try expect(math.isNan(log2_f32(-0x1.5b86eap-1))); |
| 384 | } | 396 | } |
| 385 | 397 | ||
| 386 | test "log2f() boundary" { | 398 | test "log2f() boundary" { |
| 387 | try expectEqual(log2f(0x1.fffffep+127), 0x1p+7); // Max input value | 399 | try expectEqual(log2_f32(0x1.fffffep+127), 0x1p+7); // Max input value |
| 388 | try expectEqual(log2f(0x1p-149), -0x1.2ap+7); // Min positive input value | 400 | try expectEqual(log2_f32(0x1p-149), -0x1.2ap+7); // Min positive input value |
| 389 | try expect(math.isNan(log2f(-0x1p-149))); // Min negative input value | 401 | try expect(math.isNan(log2_f32(-0x1p-149))); // Min negative input value |
| 390 | try expectEqual(log2f(0x1.000002p+0), 0x1.715474p-23); // Last value before result reaches +0 | 402 | try expectEqual(log2_f32(0x1.000002p+0), 0x1.715474p-23); // Last value before result reaches +0 |
| 391 | try expectEqual(log2f(0x1.fffffep-1), -0x1.715478p-24); // Last value before result reaches -0 | 403 | try expectEqual(log2_f32(0x1.fffffep-1), -0x1.715478p-24); // Last value before result reaches -0 |
| 392 | try expectEqual(log2f(0x1p-126), -0x1.f8p+6); // First subnormal | 404 | try expectEqual(log2_f32(0x1p-126), -0x1.f8p+6); // First subnormal |
| 393 | try expect(math.isNan(log2f(-0x1p-126))); // First negative subnormal | 405 | try expect(math.isNan(log2_f32(-0x1p-126))); // First negative subnormal |
| 394 | 406 | ||
| 395 | } | 407 | } |
| 396 | 408 | ||
| 397 | test "log2() special" { | 409 | test "log2() special" { |
| 398 | try expectEqual(log2(0.0), -math.inf(f64)); | 410 | try expectEqual(log2_f64(0.0), -math.inf(f64)); |
| 399 | try expectEqual(log2(-0.0), -math.inf(f64)); | 411 | try expectEqual(log2_f64(-0.0), -math.inf(f64)); |
| 400 | try expect(math.isPositiveZero(log2(1.0))); | 412 | try expect(math.isPositiveZero(log2_f64(1.0))); |
| 401 | try expectEqual(log2(2.0), 1.0); | 413 | try expectEqual(log2_f64(2.0), 1.0); |
| 402 | try expectEqual(log2(math.inf(f64)), math.inf(f64)); | 414 | try expectEqual(log2_f64(math.inf(f64)), math.inf(f64)); |
| 403 | try expect(math.isNan(log2(-1.0))); | 415 | try expect(math.isNan(log2_f64(-1.0))); |
| 404 | try expect(math.isNan(log2(-math.inf(f64)))); | 416 | try expect(math.isNan(log2_f64(-math.inf(f64)))); |
| 405 | try expect(math.isNan(log2(math.nan(f64)))); | 417 | try expect(math.isNan(log2_f64(math.nan(f64)))); |
| 406 | try expect(math.isNan(log2(math.snan(f64)))); | 418 | try expect(math.isNan(log2_f64(math.snan(f64)))); |
| 407 | } | 419 | } |
| 408 | 420 | ||
| 409 | test "log2() sanity" { | 421 | test "log2() sanity" { |
| 410 | try expect(math.isNan(log2(-0x1.02239f3c6a8f1p+3))); | 422 | try expect(math.isNan(log2_f64(-0x1.02239f3c6a8f1p+3))); |
| 411 | try expectEqual(log2(0x1.161868e18bc67p+2), 0x1.0f49ac3838580p+1); | 423 | try expectEqual(log2_f64(0x1.161868e18bc67p+2), 0x1.0f49ac3838580p+1); |
| 412 | try expect(math.isNan(log2(-0x1.0c34b3e01e6e7p+3))); | 424 | try expect(math.isNan(log2_f64(-0x1.0c34b3e01e6e7p+3))); |
| 413 | try expect(math.isNan(log2(-0x1.a206f0a19dcc4p+2))); | 425 | try expect(math.isNan(log2_f64(-0x1.a206f0a19dcc4p+2))); |
| 414 | try expectEqual(log2(0x1.288bbb0d6a1e6p+3), 0x1.9b26760c2a57ep+1); | 426 | try expectEqual(log2_f64(0x1.288bbb0d6a1e6p+3), 0x1.9b26760c2a57ep+1); |
| 415 | try expectEqual(log2(0x1.52efd0cd80497p-1), -0x1.30b490ef684c7p-1); | 427 | try expectEqual(log2_f64(0x1.52efd0cd80497p-1), -0x1.30b490ef684c7p-1); |
| 416 | try expect(math.isNan(log2(-0x1.a05cc754481d1p-2))); | 428 | try expect(math.isNan(log2_f64(-0x1.a05cc754481d1p-2))); |
| 417 | try expectEqual(log2(0x1.1f9ef934745cbp-1), -0x1.a9f89b5f5acb8p-1); | 429 | try expectEqual(log2_f64(0x1.1f9ef934745cbp-1), -0x1.a9f89b5f5acb8p-1); |
| 418 | try expectEqual(log2(0x1.8c5db097f7442p-1), -0x1.7a2c947173f06p-2); | 430 | try expectEqual(log2_f64(0x1.8c5db097f7442p-1), -0x1.7a2c947173f06p-2); |
| 419 | try expect(math.isNan(log2(-0x1.5b86ea8118a0ep-1))); | 431 | try expect(math.isNan(log2_f64(-0x1.5b86ea8118a0ep-1))); |
| 420 | } | 432 | } |
| 421 | 433 | ||
| 422 | test "log2() boundary" { | 434 | test "log2() boundary" { |
| 423 | try expectEqual(log2(0x1.fffffffffffffp+1023), 0x1p+10); // Max input value | 435 | try expectEqual(log2_f64(0x1.fffffffffffffp+1023), 0x1p+10); // Max input value |
| 424 | try expectEqual(log2(0x1p-1074), -0x1.0c8p+10); // Min positive input value | 436 | try expectEqual(log2_f64(0x1p-1074), -0x1.0c8p+10); // Min positive input value |
| 425 | try expect(math.isNan(log2(-0x1p-1074))); // Min negative input value | 437 | try expect(math.isNan(log2_f64(-0x1p-1074))); // Min negative input value |
| 426 | try expectEqual(log2(0x1.0000000000001p+0), 0x1.71547652b82fdp-52); // Last value before result reaches +0 | 438 | try expectEqual(log2_f64(0x1.0000000000001p+0), 0x1.71547652b82fdp-52); // Last value before result reaches +0 |
| 427 | try expectEqual(log2(0x1.fffffffffffffp-1), -0x1.71547652b82fep-53); // Last value before result reaches -0 | 439 | try expectEqual(log2_f64(0x1.fffffffffffffp-1), -0x1.71547652b82fep-53); // Last value before result reaches -0 |
| 428 | try expectEqual(log2(0x1p-1022), -0x1.ffp+9); // First subnormal | 440 | try expectEqual(log2_f64(0x1p-1022), -0x1.ffp+9); // First subnormal |
| 429 | try expect(math.isNan(log2(-0x1p-1022))); // First negative subnormal | 441 | try expect(math.isNan(log2_f64(-0x1p-1022))); // First negative subnormal |
| 430 | } | 442 | } |
| 431 | 443 | ||
| 432 | test "log2q() special" { | 444 | test "log2q() special" { |
| 433 | try expectEqual(log2q(0.0), -math.inf(f128)); | 445 | try expectEqual(log2_f128(0.0), -math.inf(f128)); |
| 434 | try expectEqual(log2q(-0.0), -math.inf(f128)); | 446 | try expectEqual(log2_f128(-0.0), -math.inf(f128)); |
| 435 | try expect(math.isPositiveZero(log2q(1.0))); | 447 | try expect(math.isPositiveZero(log2_f128(1.0))); |
| 436 | try expectEqual(log2q(2.0), 1.0); | 448 | try expectEqual(log2_f128(2.0), 1.0); |
| 437 | try expectEqual(log2q(math.inf(f128)), math.inf(f128)); | 449 | try expectEqual(log2_f128(math.inf(f128)), math.inf(f128)); |
| 438 | try expect(math.isNan(log2q(-1.0))); | 450 | try expect(math.isNan(log2_f128(-1.0))); |
| 439 | try expect(math.isNan(log2q(-math.inf(f128)))); | 451 | try expect(math.isNan(log2_f128(-math.inf(f128)))); |
| 440 | try expect(math.isNan(log2q(math.nan(f128)))); | 452 | try expect(math.isNan(log2_f128(math.nan(f128)))); |
| 441 | try expect(math.isNan(log2q(math.snan(f128)))); | 453 | try expect(math.isNan(log2_f128(math.snan(f128)))); |
| 442 | } | 454 | } |
| 443 | 455 | ||
| 444 | test "log2q() boundary" { | 456 | test "log2q() boundary" { |
| 445 | try expectEqual(log2q(0x1.ffffffffffffffffffffffffffffp16383), 0x1p14); // Max input value | 457 | try expectEqual(log2_f128(0x1.ffffffffffffffffffffffffffffp16383), 0x1p14); // Max input value |
| 446 | try expectEqual(log2q(0x1p-16494), -0x1.01b8p14); // Min positive input value | 458 | try expectEqual(log2_f128(0x1p-16494), -0x1.01b8p14); // Min positive input value |
| 447 | try expect(math.isNan(log2q(-0x1p-16494))); // Min negative input value | 459 | try expect(math.isNan(log2_f128(-0x1p-16494))); // Min negative input value |
| 448 | try expectEqual(log2q(0x1.0000000000000000000000000001p0), 0x1.71547652b82fe1777d0ffda0d23ap-112); // Last value before result reaches +0 | 460 | try expectEqual(log2_f128(0x1.0000000000000000000000000001p0), 0x1.71547652b82fe1777d0ffda0d23ap-112); // Last value before result reaches +0 |
| 449 | try expectEqual(log2q(0x1.ffffffffffffffffffffffffffffp-1), -0x1.71547652b82fe1777d0ffda0d23bp-113); // Last value before result reaches -0 | 461 | try expectEqual(log2_f128(0x1.ffffffffffffffffffffffffffffp-1), -0x1.71547652b82fe1777d0ffda0d23bp-113); // Last value before result reaches -0 |
| 450 | try expectEqual(log2q(0x1p-16382), -0x1.fffp13); // First subnormal | 462 | try expectEqual(log2_f128(0x1p-16382), -0x1.fffp13); // First subnormal |
| 451 | try expect(math.isNan(log2q(-0x1p-16382))); // First negative subnormal | 463 | try expect(math.isNan(log2_f128(-0x1p-16382))); // First negative subnormal |
| 452 | } | 464 | } |
| 453 | 465 | ||
| 454 | test "log2q() sanity" { | 466 | test "log2q() sanity" { |
| 455 | try expectEqual(log2q(8.0965013884643408203125e11), 3.955850767769801288865582596068254e1); | 467 | try expectEqual(log2_f128(8.0965013884643408203125e11), 3.955850767769801288865582596068254e1); |
| 456 | try expectEqual(log2q(8.346531942223744e15), 5.28900982928636641107356163006646e1); | 468 | try expectEqual(log2_f128(8.346531942223744e15), 5.28900982928636641107356163006646e1); |
| 457 | try expectEqual(log2q(9.707809913413123613777865431464565e-20), -6.315941603809020445822192336703809e1); | 469 | try expectEqual(log2_f128(9.707809913413123613777865431464565e-20), -6.315941603809020445822192336703809e1); |
| 458 | try expectEqual(log2q(1.9179565888043380306021427656243352e-24), -7.878670421065570557450089031998522e1); | 470 | try expectEqual(log2_f128(1.9179565888043380306021427656243352e-24), -7.878670421065570557450089031998522e1); |
| 459 | try expectEqual(log2q(2.5260048200126556877075044745936796e-25), -8.17113449801679676275805009400338e1); | 471 | try expectEqual(log2_f128(2.5260048200126556877075044745936796e-25), -8.17113449801679676275805009400338e1); |
| 460 | try expectEqual(log2q(3.1170134002568967640399932861328125e7), 2.489366102143423848582774267206741e1); | 472 | try expectEqual(log2_f128(3.1170134002568967640399932861328125e7), 2.489366102143423848582774267206741e1); |
| 461 | // test near 1 | 473 | // test near 1 |
| 462 | try expectEqual(log2q(1.026586845186097528392910049888087e0), 3.7855678902522753591699367969189364e-2); | 474 | try expectEqual(log2_f128(1.026586845186097528392910049888087e0), 3.7855678902522753591699367969189364e-2); |
| 463 | try expectEqual(log2q(1.0005582850578053877743656130405725e0), 8.052103367568488432896147152682078e-4); | 475 | try expectEqual(log2_f128(1.0005582850578053877743656130405725e0), 8.052103367568488432896147152682078e-4); |
| 464 | try expectEqual(log2q(1.0370174103591254835765589348284266e0), 5.244011558596899945639244281954306e-2); | 476 | try expectEqual(log2_f128(1.0370174103591254835765589348284266e0), 5.244011558596899945639244281954306e-2); |
| 465 | try expectEqual(log2q(1.0429996503525671713075162472250667e0), 6.073867421942172944687194557176633e-2); | 477 | try expectEqual(log2_f128(1.0429996503525671713075162472250667e0), 6.073867421942172944687194557176633e-2); |
| 466 | try expectEqual(log2q(1.0383384027961064621892184334228659e0), 5.4276706191956281784022630732940314e-2); | 478 | try expectEqual(log2_f128(1.0383384027961064621892184334228659e0), 5.4276706191956281784022630732940314e-2); |
| 467 | } | 479 | } |
lib/compiler_rt/memcpy.zig+1-1| ... | @@ -11,7 +11,7 @@ comptime { | ... | @@ -11,7 +11,7 @@ comptime { |
| 11 | .visibility = compiler_rt.visibility, | 11 | .visibility = compiler_rt.visibility, |
| 12 | }; | 12 | }; |
| 13 | 13 | ||
| 14 | if (builtin.mode == .ReleaseSmall or builtin.zig_backend == .stage2_aarch64) | 14 | if (builtin.mode == .small or builtin.zig_backend == .stage2_aarch64) |
| 15 | @export(&memcpySmall, export_options) | 15 | @export(&memcpySmall, export_options) |
| 16 | else | 16 | else |
| 17 | @export(&memcpyFast, export_options); | 17 | @export(&memcpyFast, export_options); |
lib/compiler_rt/memmove.zig+1-1| ... | @@ -14,7 +14,7 @@ comptime { | ... | @@ -14,7 +14,7 @@ comptime { |
| 14 | .visibility = compiler_rt.visibility, | 14 | .visibility = compiler_rt.visibility, |
| 15 | }; | 15 | }; |
| 16 | 16 | ||
| 17 | if (builtin.mode == .ReleaseSmall or builtin.zig_backend == .stage2_aarch64) | 17 | if (builtin.mode == .small or builtin.zig_backend == .stage2_aarch64) |
| 18 | @export(&memmoveSmall, export_options) | 18 | @export(&memmoveSmall, export_options) |
| 19 | else | 19 | else |
| 20 | @export(&memmoveFast, export_options); | 20 | @export(&memmoveFast, export_options); |
lib/compiler_rt/mulc3.zig+75-10| ... | @@ -3,19 +3,80 @@ const isNan = std.math.isNan; | ... | @@ -3,19 +3,80 @@ const isNan = std.math.isNan; |
| 3 | const isInf = std.math.isInf; | 3 | const isInf = std.math.isInf; |
| 4 | const copysign = std.math.copysign; | 4 | const copysign = std.math.copysign; |
| 5 | 5 | ||
| 6 | pub fn Complex(comptime T: type) type { | 6 | const compiler_rt = @import("../compiler_rt.zig"); |
| 7 | return extern struct { | 7 | const symbol = compiler_rt.symbol; |
| 8 | real: T, | 8 | const Complex = compiler_rt.Complex; |
| 9 | imag: T, | 9 | |
| 10 | }; | 10 | comptime { |
| 11 | if (@import("builtin").zig_backend != .stage2_c) { | ||
| 12 | symbol(&__mulhc3, "__mulhc3"); | ||
| 13 | symbol(&__mulsc3, "__mulsc3"); | ||
| 14 | symbol(&__muldc3, "__muldc3"); | ||
| 15 | symbol(&__mulxc3, "__mulxc3"); | ||
| 16 | if (compiler_rt.want_ppc_abi) { | ||
| 17 | symbol(&__multc3, "__mulkc3"); | ||
| 18 | } else { | ||
| 19 | symbol(&__multc3, "__multc3"); | ||
| 20 | } | ||
| 21 | } | ||
| 22 | } | ||
| 23 | |||
| 24 | fn __mulhc3(lhs_real: compiler_rt.f16.Abi, lhs_imag: compiler_rt.f16.Abi, rhs_real: compiler_rt.f16.Abi, rhs_imag: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.complex.Abi { | ||
| 25 | return compiler_rt.f16.complex.toAbi(mul_cf16( | ||
| 26 | compiler_rt.f16.complex.fromAbi(.{ .real = lhs_real, .imag = lhs_imag }), | ||
| 27 | compiler_rt.f16.complex.fromAbi(.{ .real = rhs_real, .imag = rhs_imag }), | ||
| 28 | )); | ||
| 29 | } | ||
| 30 | pub fn mul_cf16(a: Complex(f16), b: Complex(f16)) Complex(f16) { | ||
| 31 | return mulc3(f16, a, b); | ||
| 32 | } | ||
| 33 | |||
| 34 | fn __mulsc3(lhs_real: compiler_rt.f32.Abi, lhs_imag: compiler_rt.f32.Abi, rhs_real: compiler_rt.f32.Abi, rhs_imag: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.complex.Abi { | ||
| 35 | return compiler_rt.f32.complex.toAbi(mul_cf32( | ||
| 36 | compiler_rt.f32.complex.fromAbi(.{ .real = lhs_real, .imag = lhs_imag }), | ||
| 37 | compiler_rt.f32.complex.fromAbi(.{ .real = rhs_real, .imag = rhs_imag }), | ||
| 38 | )); | ||
| 39 | } | ||
| 40 | pub fn mul_cf32(a: Complex(f32), b: Complex(f32)) Complex(f32) { | ||
| 41 | return mulc3(f32, a, b); | ||
| 42 | } | ||
| 43 | |||
| 44 | fn __muldc3(lhs_real: compiler_rt.f64.Abi, lhs_imag: compiler_rt.f64.Abi, rhs_real: compiler_rt.f64.Abi, rhs_imag: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.complex.Abi { | ||
| 45 | return compiler_rt.f64.complex.toAbi(mul_cf64( | ||
| 46 | compiler_rt.f64.complex.fromAbi(.{ .real = lhs_real, .imag = lhs_imag }), | ||
| 47 | compiler_rt.f64.complex.fromAbi(.{ .real = rhs_real, .imag = rhs_imag }), | ||
| 48 | )); | ||
| 49 | } | ||
| 50 | pub fn mul_cf64(a: Complex(f64), b: Complex(f64)) Complex(f64) { | ||
| 51 | return mulc3(f64, a, b); | ||
| 52 | } | ||
| 53 | |||
| 54 | fn __mulxc3(lhs_real: compiler_rt.f80.Abi, lhs_imag: compiler_rt.f80.Abi, rhs_real: compiler_rt.f80.Abi, rhs_imag: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.complex.Abi { | ||
| 55 | return compiler_rt.f80.complex.toAbi(mul_cf80( | ||
| 56 | compiler_rt.f80.complex.fromAbi(.{ .real = lhs_real, .imag = lhs_imag }), | ||
| 57 | compiler_rt.f80.complex.fromAbi(.{ .real = rhs_real, .imag = rhs_imag }), | ||
| 58 | )); | ||
| 59 | } | ||
| 60 | pub fn mul_cf80(a: Complex(f80), b: Complex(f80)) Complex(f80) { | ||
| 61 | return mulc3(f80, a, b); | ||
| 62 | } | ||
| 63 | |||
| 64 | fn __multc3(lhs_real: compiler_rt.f128.Abi, lhs_imag: compiler_rt.f128.Abi, rhs_real: compiler_rt.f128.Abi, rhs_imag: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.complex.Abi { | ||
| 65 | return compiler_rt.f128.complex.toAbi(mul_cf128( | ||
| 66 | compiler_rt.f128.complex.fromAbi(.{ .real = lhs_real, .imag = lhs_imag }), | ||
| 67 | compiler_rt.f128.complex.fromAbi(.{ .real = rhs_real, .imag = rhs_imag }), | ||
| 68 | )); | ||
| 69 | } | ||
| 70 | pub fn mul_cf128(a: Complex(f128), b: Complex(f128)) Complex(f128) { | ||
| 71 | return mulc3(f128, a, b); | ||
| 11 | } | 72 | } |
| 12 | 73 | ||
| 13 | /// Implementation based on Annex G of C17 Standard (N2176) | 74 | /// Implementation based on Annex G of C17 Standard (N2176) |
| 14 | pub inline fn mulc3(comptime T: type, a_in: T, b_in: T, c_in: T, d_in: T) Complex(T) { | 75 | inline fn mulc3(comptime T: type, lhs: Complex(T), rhs: Complex(T)) Complex(T) { |
| 15 | var a = a_in; | 76 | var a = lhs.real; |
| 16 | var b = b_in; | 77 | var b = lhs.imag; |
| 17 | var c = c_in; | 78 | var c = rhs.real; |
| 18 | var d = d_in; | 79 | var d = rhs.imag; |
| 19 | 80 | ||
| 20 | const ac = a * c; | 81 | const ac = a * c; |
| 21 | const bd = b * d; | 82 | const bd = b * d; |
| ... | @@ -77,3 +138,7 @@ pub inline fn mulc3(comptime T: type, a_in: T, b_in: T, c_in: T, d_in: T) Comple | ... | @@ -77,3 +138,7 @@ pub inline fn mulc3(comptime T: type, a_in: T, b_in: T, c_in: T, d_in: T) Comple |
| 77 | } | 138 | } |
| 78 | return z; | 139 | return z; |
| 79 | } | 140 | } |
| 141 | |||
| 142 | test { | ||
| 143 | _ = @import("mulc3_test.zig"); | ||
| 144 | } |
lib/compiler_rt/mulc3_test.zig+23-42| ... | @@ -2,64 +2,45 @@ const std = @import("std"); | ... | @@ -2,64 +2,45 @@ const std = @import("std"); |
| 2 | const math = std.math; | 2 | const math = std.math; |
| 3 | const expect = std.testing.expect; | 3 | const expect = std.testing.expect; |
| 4 | 4 | ||
| 5 | const Complex = @import("./mulc3.zig").Complex; | 5 | const Complex = @import("../compiler_rt.zig").Complex; |
| 6 | const __mulhc3 = @import("./mulhc3.zig").__mulhc3; | 6 | const impl = @import("mulc3.zig"); |
| 7 | const __mulsc3 = @import("./mulsc3.zig").__mulsc3; | 7 | const mul_cf16 = impl.mul_cf16; |
| 8 | const __muldc3 = @import("./muldc3.zig").__muldc3; | 8 | const mul_cf32 = impl.mul_cf32; |
| 9 | const __mulxc3 = @import("./mulxc3.zig").__mulxc3; | 9 | const mul_cf64 = impl.mul_cf64; |
| 10 | const __multc3 = @import("./multc3.zig").__multc3; | 10 | const mul_cf80 = impl.mul_cf80; |
| 11 | const mul_cf128 = impl.mul_cf128; | ||
| 11 | 12 | ||
| 12 | test "mulc3" { | 13 | test "mulc3" { |
| 13 | try testMul(f16, __mulhc3); | 14 | try testMul(f16, mul_cf16); |
| 14 | try testMul(f32, __mulsc3); | 15 | try testMul(f32, mul_cf32); |
| 15 | try testMul(f64, __muldc3); | 16 | try testMul(f64, mul_cf64); |
| 16 | try testMul(f80, __mulxc3); | 17 | try testMul(f80, mul_cf80); |
| 17 | try testMul(f128, __multc3); | 18 | try testMul(f128, mul_cf128); |
| 18 | } | 19 | } |
| 19 | 20 | ||
| 20 | fn testMul(comptime T: type, comptime f: fn (T, T, T, T) callconv(.c) Complex(T)) !void { | 21 | fn testMul(comptime T: type, comptime f: fn (Complex(T), Complex(T)) Complex(T)) !void { |
| 21 | { | 22 | { |
| 22 | const a: T = 1.0; | 23 | const result = f(.{ .real = 1.0, .imag = 0.0 }, .{ .real = -1.0, .imag = 0.0 }); |
| 23 | const b: T = 0.0; | ||
| 24 | const c: T = -1.0; | ||
| 25 | const d: T = 0.0; | ||
| 26 | |||
| 27 | const result = f(a, b, c, d); | ||
| 28 | try expect(result.real == -1.0); | 24 | try expect(result.real == -1.0); |
| 29 | try expect(result.imag == 0.0); | 25 | try expect(math.isPositiveZero(result.imag)); |
| 30 | } | 26 | } |
| 31 | { | 27 | { |
| 32 | const a: T = 1.0; | 28 | const result = f(.{ .real = 1.0, .imag = 0.0 }, .{ .real = -4.0, .imag = 0.0 }); |
| 33 | const b: T = 0.0; | ||
| 34 | const c: T = -4.0; | ||
| 35 | const d: T = 0.0; | ||
| 36 | |||
| 37 | const result = f(a, b, c, d); | ||
| 38 | try expect(result.real == -4.0); | 29 | try expect(result.real == -4.0); |
| 39 | try expect(result.imag == 0.0); | 30 | try expect(math.isPositiveZero(result.imag)); |
| 40 | } | 31 | } |
| 41 | { | 32 | { |
| 42 | // if one operand is an infinity and the other operand is a nonzero finite number or an infinity, | 33 | // if one operand is an infinity and the other operand is a nonzero finite number or an infinity, |
| 43 | // then the result of the * operator is an infinity; | 34 | // then the result of the * operator is an infinity; |
| 44 | const a: T = math.inf(T); | 35 | const result = f(.{ .real = math.inf(T), .imag = -math.inf(T) }, .{ .real = 1.0, .imag = 0.0 }); |
| 45 | const b: T = -math.inf(T); | 36 | try expect(math.isPositiveInf(result.real)); |
| 46 | const c: T = 1.0; | 37 | try expect(math.isNegativeInf(result.imag)); |
| 47 | const d: T = 0.0; | ||
| 48 | |||
| 49 | const result = f(a, b, c, d); | ||
| 50 | try expect(result.real == math.inf(T)); | ||
| 51 | try expect(result.imag == -math.inf(T)); | ||
| 52 | } | 38 | } |
| 53 | { | 39 | { |
| 54 | // if one operand is an infinity and the other operand is a nonzero finite number or an infinity, | 40 | // if one operand is an infinity and the other operand is a nonzero finite number or an infinity, |
| 55 | // then the result of the * operator is an infinity; | 41 | // then the result of the * operator is an infinity; |
| 56 | const a: T = math.inf(T); | 42 | const result = f(.{ .real = math.inf(T), .imag = -1.0 }, .{ .real = 1.0, .imag = math.inf(T) }); |
| 57 | const b: T = -1.0; | 43 | try expect(math.isPositiveInf(result.real)); |
| 58 | const c: T = 1.0; | 44 | try expect(math.isPositiveInf(result.imag)); |
| 59 | const d: T = math.inf(T); | ||
| 60 | |||
| 61 | const result = f(a, b, c, d); | ||
| 62 | try expect(result.real == math.inf(T)); | ||
| 63 | try expect(result.imag == math.inf(T)); | ||
| 64 | } | 45 | } |
| 65 | } | 46 | } |
lib/compiler_rt/muldc3.zig deleted-12| ... | @@ -1,12 +0,0 @@ | ||
| 1 | const mulc3 = @import("./mulc3.zig"); | ||
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 3 | |||
| 4 | comptime { | ||
| 5 | if (@import("builtin").zig_backend != .stage2_c) { | ||
| 6 | symbol(&__muldc3, "__muldc3"); | ||
| 7 | } | ||
| 8 | } | ||
| 9 | |||
| 10 | pub fn __muldc3(a: f64, b: f64, c: f64, d: f64) callconv(.c) mulc3.Complex(f64) { | ||
| 11 | return mulc3.mulc3(f64, a, b, c, d); | ||
| 12 | } | ||
lib/compiler_rt/muldf3.zig deleted-19| ... | @@ -1,19 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 3 | const mulf3 = @import("./mulf3.zig").mulf3; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_aeabi) { | ||
| 7 | symbol(&__aeabi_dmul, "__aeabi_dmul"); | ||
| 8 | } else { | ||
| 9 | symbol(&__muldf3, "__muldf3"); | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | pub fn __muldf3(a: f64, b: f64) callconv(.c) f64 { | ||
| 14 | return mulf3(f64, a, b); | ||
| 15 | } | ||
| 16 | |||
| 17 | fn __aeabi_dmul(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 { | ||
| 18 | return mulf3(f64, a, b); | ||
| 19 | } | ||
lib/compiler_rt/mulf3.zig+67-1| ... | @@ -2,10 +2,76 @@ const std = @import("std"); | ... | @@ -2,10 +2,76 @@ const std = @import("std"); |
| 2 | const math = std.math; | 2 | const math = std.math; |
| 3 | const builtin = @import("builtin"); | 3 | const builtin = @import("builtin"); |
| 4 | const compiler_rt = @import("../compiler_rt.zig"); | 4 | const compiler_rt = @import("../compiler_rt.zig"); |
| 5 | const symbol = compiler_rt.symbol; | ||
| 6 | |||
| 7 | comptime { | ||
| 8 | symbol(&__mulhf3, "__mulhf3"); | ||
| 9 | if (compiler_rt.want_aeabi) { | ||
| 10 | symbol(&__aeabi_fmul, "__aeabi_fmul"); | ||
| 11 | symbol(&__aeabi_dmul, "__aeabi_dmul"); | ||
| 12 | } else { | ||
| 13 | symbol(&__mulsf3, "__mulsf3"); | ||
| 14 | symbol(&__muldf3, "__muldf3"); | ||
| 15 | } | ||
| 16 | symbol(&__mulxf3, "__mulxf3"); | ||
| 17 | if (compiler_rt.want_ppc_abi) { | ||
| 18 | symbol(&__multf3, "__mulkf3"); | ||
| 19 | } else if (compiler_rt.want_sparc64_abi) { | ||
| 20 | symbol(&_Qp_mul, "_Qp_mul"); | ||
| 21 | } else if (compiler_rt.want_sparc32_abi) { | ||
| 22 | symbol(&__multf3, "_Q_mul"); | ||
| 23 | } else { | ||
| 24 | symbol(&__multf3, "__multf3"); | ||
| 25 | } | ||
| 26 | } | ||
| 27 | |||
| 28 | fn __mulhf3(a: compiler_rt.f16.Abi, b: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { | ||
| 29 | return compiler_rt.f16.toAbi(mul_f16(compiler_rt.f16.fromAbi(a), compiler_rt.f16.fromAbi(b))); | ||
| 30 | } | ||
| 31 | pub fn mul_f16(a: f16, b: f16) f16 { | ||
| 32 | return mulf3(f16, a, b); | ||
| 33 | } | ||
| 34 | |||
| 35 | fn __mulsf3(a: compiler_rt.f32.Abi, b: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { | ||
| 36 | return compiler_rt.f32.toAbi(mul_f32(compiler_rt.f32.fromAbi(a), compiler_rt.f32.fromAbi(b))); | ||
| 37 | } | ||
| 38 | fn __aeabi_fmul(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 { | ||
| 39 | return mul_f32(a, b); | ||
| 40 | } | ||
| 41 | pub fn mul_f32(a: f32, b: f32) f32 { | ||
| 42 | return mulf3(f32, a, b); | ||
| 43 | } | ||
| 44 | |||
| 45 | fn __muldf3(a: compiler_rt.f64.Abi, b: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { | ||
| 46 | return compiler_rt.f64.toAbi(mul_f64(compiler_rt.f64.fromAbi(a), compiler_rt.f64.fromAbi(b))); | ||
| 47 | } | ||
| 48 | fn __aeabi_dmul(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 { | ||
| 49 | return mul_f64(a, b); | ||
| 50 | } | ||
| 51 | pub fn mul_f64(a: f64, b: f64) f64 { | ||
| 52 | return mulf3(f64, a, b); | ||
| 53 | } | ||
| 54 | |||
| 55 | fn __mulxf3(a: compiler_rt.f80.Abi, b: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { | ||
| 56 | return compiler_rt.f80.toAbi(mul_f80(compiler_rt.f80.fromAbi(a), compiler_rt.f80.fromAbi(b))); | ||
| 57 | } | ||
| 58 | pub fn mul_f80(a: f80, b: f80) f80 { | ||
| 59 | return mulf3(f80, a, b); | ||
| 60 | } | ||
| 61 | |||
| 62 | fn __multf3(a: compiler_rt.f128.Abi, b: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { | ||
| 63 | return compiler_rt.f128.toAbi(mul_f128(compiler_rt.f128.fromAbi(a), compiler_rt.f128.fromAbi(b))); | ||
| 64 | } | ||
| 65 | fn _Qp_mul(c: *f128, a: *const f128, b: *const f128) callconv(.c) void { | ||
| 66 | c.* = mul_f128(a.*, b.*); | ||
| 67 | } | ||
| 68 | pub fn mul_f128(a: f128, b: f128) f128 { | ||
| 69 | return mulf3(f128, a, b); | ||
| 70 | } | ||
| 5 | 71 | ||
| 6 | /// Ported from: | 72 | /// Ported from: |
| 7 | /// https://github.com/llvm/llvm-project/blob/2ffb1b0413efa9a24eb3c49e710e36f92e2cb50b/compiler-rt/lib/builtins/fp_mul_impl.inc | 73 | /// https://github.com/llvm/llvm-project/blob/2ffb1b0413efa9a24eb3c49e710e36f92e2cb50b/compiler-rt/lib/builtins/fp_mul_impl.inc |
| 8 | pub inline fn mulf3(comptime T: type, a: T, b: T) T { | 74 | inline fn mulf3(comptime T: type, a: T, b: T) T { |
| 9 | @setRuntimeSafety(compiler_rt.test_safety); | 75 | @setRuntimeSafety(compiler_rt.test_safety); |
| 10 | const typeWidth = @typeInfo(T).float.bits; | 76 | const typeWidth = @typeInfo(T).float.bits; |
| 11 | const significandBits = math.floatMantissaBits(T); | 77 | const significandBits = math.floatMantissaBits(T); |
lib/compiler_rt/mulf3_test.zig+48-46| ... | @@ -7,10 +7,12 @@ const math = std.math; | ... | @@ -7,10 +7,12 @@ const math = std.math; |
| 7 | const qnan128: f128 = @bitCast(@as(u128, 0x7fff800000000000) << 64); | 7 | const qnan128: f128 = @bitCast(@as(u128, 0x7fff800000000000) << 64); |
| 8 | const inf128: f128 = @bitCast(@as(u128, 0x7fff000000000000) << 64); | 8 | const inf128: f128 = @bitCast(@as(u128, 0x7fff000000000000) << 64); |
| 9 | 9 | ||
| 10 | const __multf3 = @import("multf3.zig").__multf3; | 10 | const impl = @import("mulf3.zig"); |
| 11 | const __mulxf3 = @import("mulxf3.zig").__mulxf3; | 11 | const mul_f16 = impl.mul_f16; |
| 12 | const __muldf3 = @import("muldf3.zig").__muldf3; | 12 | const mul_f32 = impl.mul_f32; |
| 13 | const __mulsf3 = @import("mulsf3.zig").__mulsf3; | 13 | const mul_f64 = impl.mul_f64; |
| 14 | const mul_f80 = impl.mul_f80; | ||
| 15 | const mul_f128 = impl.mul_f128; | ||
| 14 | 16 | ||
| 15 | // return true if equal | 17 | // return true if equal |
| 16 | // use two 64-bit integers instead of one 128-bit integer | 18 | // use two 64-bit integers instead of one 128-bit integer |
| ... | @@ -34,8 +36,8 @@ fn compareResultLD(result: f128, expectedHi: u64, expectedLo: u64) bool { | ... | @@ -34,8 +36,8 @@ fn compareResultLD(result: f128, expectedHi: u64, expectedLo: u64) bool { |
| 34 | return false; | 36 | return false; |
| 35 | } | 37 | } |
| 36 | 38 | ||
| 37 | fn test__multf3(a: f128, b: f128, expected_hi: u64, expected_lo: u64) !void { | 39 | fn test_mul_f128(a: f128, b: f128, expected_hi: u64, expected_lo: u64) !void { |
| 38 | const x = __multf3(a, b); | 40 | const x = mul_f128(a, b); |
| 39 | 41 | ||
| 40 | if (compareResultLD(x, expected_hi, expected_lo)) | 42 | if (compareResultLD(x, expected_hi, expected_lo)) |
| 41 | return; | 43 | return; |
| ... | @@ -49,68 +51,68 @@ fn makeNaN128(rand: u64) f128 { | ... | @@ -49,68 +51,68 @@ fn makeNaN128(rand: u64) f128 { |
| 49 | } | 51 | } |
| 50 | test "multf3" { | 52 | test "multf3" { |
| 51 | // qNaN * any = qNaN | 53 | // qNaN * any = qNaN |
| 52 | try test__multf3(qnan128, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0); | 54 | try test_mul_f128(qnan128, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0); |
| 53 | 55 | ||
| 54 | // NaN * any = NaN | 56 | // NaN * any = NaN |
| 55 | const a = makeNaN128(0x800030000000); | 57 | const a = makeNaN128(0x800030000000); |
| 56 | try test__multf3(a, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0); | 58 | try test_mul_f128(a, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0); |
| 57 | // inf * any = inf | 59 | // inf * any = inf |
| 58 | try test__multf3(inf128, 0x1.23456789abcdefp+5, 0x7fff000000000000, 0x0); | 60 | try test_mul_f128(inf128, 0x1.23456789abcdefp+5, 0x7fff000000000000, 0x0); |
| 59 | 61 | ||
| 60 | // any * any | 62 | // any * any |
| 61 | try test__multf3( | 63 | try test_mul_f128( |
| 62 | @as(f128, @bitCast(@as(u128, 0x40042eab345678439abcdefea5678234))), | 64 | @as(f128, @bitCast(@as(u128, 0x40042eab345678439abcdefea5678234))), |
| 63 | @as(f128, @bitCast(@as(u128, 0x3ffeedcb34a235253948765432134675))), | 65 | @as(f128, @bitCast(@as(u128, 0x3ffeedcb34a235253948765432134675))), |
| 64 | 0x400423e7f9e3c9fc, | 66 | 0x400423e7f9e3c9fc, |
| 65 | 0xd906c2c2a85777c4, | 67 | 0xd906c2c2a85777c4, |
| 66 | ); | 68 | ); |
| 67 | 69 | ||
| 68 | try test__multf3( | 70 | try test_mul_f128( |
| 69 | @as(f128, @bitCast(@as(u128, 0x3fcd353e45674d89abacc3a2ebf3ff50))), | 71 | @as(f128, @bitCast(@as(u128, 0x3fcd353e45674d89abacc3a2ebf3ff50))), |
| 70 | @as(f128, @bitCast(@as(u128, 0x3ff6ed8764648369535adf4be3214568))), | 72 | @as(f128, @bitCast(@as(u128, 0x3ff6ed8764648369535adf4be3214568))), |
| 71 | 0x3fc52a163c6223fc, | 73 | 0x3fc52a163c6223fc, |
| 72 | 0xc94c4bf0430768b4, | 74 | 0xc94c4bf0430768b4, |
| 73 | ); | 75 | ); |
| 74 | 76 | ||
| 75 | try test__multf3( | 77 | try test_mul_f128( |
| 76 | 0x1.234425696abcad34a35eeffefdcbap+456, | 78 | 0x1.234425696abcad34a35eeffefdcbap+456, |
| 77 | 0x451.ed98d76e5d46e5f24323dff21ffp+600, | 79 | 0x451.ed98d76e5d46e5f24323dff21ffp+600, |
| 78 | 0x44293a91de5e0e94, | 80 | 0x44293a91de5e0e94, |
| 79 | 0xe8ed17cc2cdf64ac, | 81 | 0xe8ed17cc2cdf64ac, |
| 80 | ); | 82 | ); |
| 81 | 83 | ||
| 82 | try test__multf3( | 84 | try test_mul_f128( |
| 83 | @as(f128, @bitCast(@as(u128, 0x3f154356473c82a9fabf2d22ace345df))), | 85 | @as(f128, @bitCast(@as(u128, 0x3f154356473c82a9fabf2d22ace345df))), |
| 84 | @as(f128, @bitCast(@as(u128, 0x3e38eda98765476743ab21da23d45679))), | 86 | @as(f128, @bitCast(@as(u128, 0x3e38eda98765476743ab21da23d45679))), |
| 85 | 0x3d4f37c1a3137cae, | 87 | 0x3d4f37c1a3137cae, |
| 86 | 0xfc6807048bc2836a, | 88 | 0xfc6807048bc2836a, |
| 87 | ); | 89 | ); |
| 88 | 90 | ||
| 89 | try test__multf3(0x1.23456734245345p-10000, 0x1.edcba524498724p-6497, 0x0, 0x0); | 91 | try test_mul_f128(0x1.23456734245345p-10000, 0x1.edcba524498724p-6497, 0x0, 0x0); |
| 90 | 92 | ||
| 91 | // Denormal operands. | 93 | // Denormal operands. |
| 92 | try test__multf3( | 94 | try test_mul_f128( |
| 93 | 0x0.0000000000000000000000000001p-16382, | 95 | 0x0.0000000000000000000000000001p-16382, |
| 94 | 0x1p16383, | 96 | 0x1p16383, |
| 95 | 0x3f90000000000000, | 97 | 0x3f90000000000000, |
| 96 | 0x0, | 98 | 0x0, |
| 97 | ); | 99 | ); |
| 98 | try test__multf3( | 100 | try test_mul_f128( |
| 99 | 0x1p16383, | 101 | 0x1p16383, |
| 100 | 0x0.0000000000000000000000000001p-16382, | 102 | 0x0.0000000000000000000000000001p-16382, |
| 101 | 0x3f90000000000000, | 103 | 0x3f90000000000000, |
| 102 | 0x0, | 104 | 0x0, |
| 103 | ); | 105 | ); |
| 104 | 106 | ||
| 105 | try test__multf3(0x1.0000_0000_0000_0000_0000_0000_0001p+0, 0x1.8p+5, 0x4004_8000_0000_0000, 0x0000_0000_0000_0002); | 107 | try test_mul_f128(0x1.0000_0000_0000_0000_0000_0000_0001p+0, 0x1.8p+5, 0x4004_8000_0000_0000, 0x0000_0000_0000_0002); |
| 106 | try test__multf3(0x1.0000_0000_0000_0000_0000_0000_0002p+0, 0x1.8p+5, 0x4004_8000_0000_0000, 0x0000_0000_0000_0003); | 108 | try test_mul_f128(0x1.0000_0000_0000_0000_0000_0000_0002p+0, 0x1.8p+5, 0x4004_8000_0000_0000, 0x0000_0000_0000_0003); |
| 107 | try test__multf3(2.0, math.floatTrueMin(f128), 0x0000_0000_0000_0000, 0x0000_0000_0000_0002); | 109 | try test_mul_f128(2.0, math.floatTrueMin(f128), 0x0000_0000_0000_0000, 0x0000_0000_0000_0002); |
| 108 | } | 110 | } |
| 109 | 111 | ||
| 110 | const qnan80: f80 = @bitCast(@as(u80, @bitCast(math.nan(f80))) | (1 << (math.floatFractionalBits(f80) - 1))); | 112 | const qnan80: f80 = @bitCast(@as(u80, @bitCast(math.nan(f80))) | (1 << (math.floatFractionalBits(f80) - 1))); |
| 111 | 113 | ||
| 112 | fn test__mulxf3(a: f80, b: f80, expected: u80) !void { | 114 | fn test_mul_f80(a: f80, b: f80, expected: u80) !void { |
| 113 | const x = __mulxf3(a, b); | 115 | const x = mul_f80(a, b); |
| 114 | const rep: u80 = @bitCast(x); | 116 | const rep: u80 = @bitCast(x); |
| 115 | 117 | ||
| 116 | if (rep == expected) | 118 | if (rep == expected) |
| ... | @@ -124,47 +126,47 @@ fn test__mulxf3(a: f80, b: f80, expected: u80) !void { | ... | @@ -124,47 +126,47 @@ fn test__mulxf3(a: f80, b: f80, expected: u80) !void { |
| 124 | 126 | ||
| 125 | test "mulxf3" { | 127 | test "mulxf3" { |
| 126 | // NaN * any = NaN | 128 | // NaN * any = NaN |
| 127 | try test__mulxf3(qnan80, 0x1.23456789abcdefp+5, @as(u80, @bitCast(qnan80))); | 129 | try test_mul_f80(qnan80, 0x1.23456789abcdefp+5, @as(u80, @bitCast(qnan80))); |
| 128 | try test__mulxf3(@as(f80, @bitCast(@as(u80, 0x7fff_8000_8000_3000_0000))), 0x1.23456789abcdefp+5, @as(u80, @bitCast(qnan80))); | 130 | try test_mul_f80(@as(f80, @bitCast(@as(u80, 0x7fff_8000_8000_3000_0000))), 0x1.23456789abcdefp+5, @as(u80, @bitCast(qnan80))); |
| 129 | 131 | ||
| 130 | // any * NaN = NaN | 132 | // any * NaN = NaN |
| 131 | try test__mulxf3(0x1.23456789abcdefp+5, qnan80, @as(u80, @bitCast(qnan80))); | 133 | try test_mul_f80(0x1.23456789abcdefp+5, qnan80, @as(u80, @bitCast(qnan80))); |
| 132 | try test__mulxf3(0x1.23456789abcdefp+5, @as(f80, @bitCast(@as(u80, 0x7fff_8000_8000_3000_0000))), @as(u80, @bitCast(qnan80))); | 134 | try test_mul_f80(0x1.23456789abcdefp+5, @as(f80, @bitCast(@as(u80, 0x7fff_8000_8000_3000_0000))), @as(u80, @bitCast(qnan80))); |
| 133 | 135 | ||
| 134 | // NaN * inf = NaN | 136 | // NaN * inf = NaN |
| 135 | try test__mulxf3(qnan80, math.inf(f80), @as(u80, @bitCast(qnan80))); | 137 | try test_mul_f80(qnan80, math.inf(f80), @as(u80, @bitCast(qnan80))); |
| 136 | 138 | ||
| 137 | // inf * NaN = NaN | 139 | // inf * NaN = NaN |
| 138 | try test__mulxf3(math.inf(f80), qnan80, @as(u80, @bitCast(qnan80))); | 140 | try test_mul_f80(math.inf(f80), qnan80, @as(u80, @bitCast(qnan80))); |
| 139 | 141 | ||
| 140 | // inf * inf = inf | 142 | // inf * inf = inf |
| 141 | try test__mulxf3(math.inf(f80), math.inf(f80), @as(u80, @bitCast(math.inf(f80)))); | 143 | try test_mul_f80(math.inf(f80), math.inf(f80), @as(u80, @bitCast(math.inf(f80)))); |
| 142 | 144 | ||
| 143 | // inf * -inf = -inf | 145 | // inf * -inf = -inf |
| 144 | try test__mulxf3(math.inf(f80), -math.inf(f80), @as(u80, @bitCast(-math.inf(f80)))); | 146 | try test_mul_f80(math.inf(f80), -math.inf(f80), @as(u80, @bitCast(-math.inf(f80)))); |
| 145 | 147 | ||
| 146 | // -inf + inf = -inf | 148 | // -inf + inf = -inf |
| 147 | try test__mulxf3(-math.inf(f80), math.inf(f80), @as(u80, @bitCast(-math.inf(f80)))); | 149 | try test_mul_f80(-math.inf(f80), math.inf(f80), @as(u80, @bitCast(-math.inf(f80)))); |
| 148 | 150 | ||
| 149 | // inf * any = inf | 151 | // inf * any = inf |
| 150 | try test__mulxf3(math.inf(f80), 0x1.2335653452436234723489432abcdefp+5, @as(u80, @bitCast(math.inf(f80)))); | 152 | try test_mul_f80(math.inf(f80), 0x1.2335653452436234723489432abcdefp+5, @as(u80, @bitCast(math.inf(f80)))); |
| 151 | 153 | ||
| 152 | // any * inf = inf | 154 | // any * inf = inf |
| 153 | try test__mulxf3(0x1.2335653452436234723489432abcdefp+5, math.inf(f80), @as(u80, @bitCast(math.inf(f80)))); | 155 | try test_mul_f80(0x1.2335653452436234723489432abcdefp+5, math.inf(f80), @as(u80, @bitCast(math.inf(f80)))); |
| 154 | 156 | ||
| 155 | // any * any | 157 | // any * any |
| 156 | try test__mulxf3(0x1.0p+0, 0x1.dcba987654321p+5, 0x4004_ee5d_4c3b_2a19_0800); | 158 | try test_mul_f80(0x1.0p+0, 0x1.dcba987654321p+5, 0x4004_ee5d_4c3b_2a19_0800); |
| 157 | try test__mulxf3(0x1.0000_0000_0000_0004p+0, 0x1.8p+5, 0x4004_C000_0000_0000_0003); // exact | 159 | try test_mul_f80(0x1.0000_0000_0000_0004p+0, 0x1.8p+5, 0x4004_C000_0000_0000_0003); // exact |
| 158 | 160 | ||
| 159 | try test__mulxf3(0x1.0000_0000_0000_0002p+0, 0x1.0p+5, 0x4004_8000_0000_0000_0001); // exact | 161 | try test_mul_f80(0x1.0000_0000_0000_0002p+0, 0x1.0p+5, 0x4004_8000_0000_0000_0001); // exact |
| 160 | try test__mulxf3(0x1.0000_0000_0000_0002p+0, 0x1.7ffep+5, 0x4004_BFFF_0000_0000_0001); // round down | 162 | try test_mul_f80(0x1.0000_0000_0000_0002p+0, 0x1.7ffep+5, 0x4004_BFFF_0000_0000_0001); // round down |
| 161 | try test__mulxf3(0x1.0000_0000_0000_0002p+0, 0x1.8p+5, 0x4004_C000_0000_0000_0002); // round up to even | 163 | try test_mul_f80(0x1.0000_0000_0000_0002p+0, 0x1.8p+5, 0x4004_C000_0000_0000_0002); // round up to even |
| 162 | try test__mulxf3(0x1.0000_0000_0000_0002p+0, 0x1.8002p+5, 0x4004_C001_0000_0000_0002); // round up | 164 | try test_mul_f80(0x1.0000_0000_0000_0002p+0, 0x1.8002p+5, 0x4004_C001_0000_0000_0002); // round up |
| 163 | try test__mulxf3(0x1.0000_0000_0000_0002p+0, 0x1.0p+6, 0x4005_8000_0000_0000_0001); // exact | 165 | try test_mul_f80(0x1.0000_0000_0000_0002p+0, 0x1.0p+6, 0x4005_8000_0000_0000_0001); // exact |
| 164 | 166 | ||
| 165 | try test__mulxf3(0x1.0000_0001p+0, 0x1.0000_0001p+0, 0x3FFF_8000_0001_0000_0000); // round down to even | 167 | try test_mul_f80(0x1.0000_0001p+0, 0x1.0000_0001p+0, 0x3FFF_8000_0001_0000_0000); // round down to even |
| 166 | try test__mulxf3(0x1.0000_0001p+0, 0x1.0000_0001_0002p+0, 0x3FFF_8000_0001_0001_0001); // round up | 168 | try test_mul_f80(0x1.0000_0001p+0, 0x1.0000_0001_0002p+0, 0x3FFF_8000_0001_0001_0001); // round up |
| 167 | try test__mulxf3(0x0.8000_0000_0000_0000p-16382, 2.0, 0x0001_8000_0000_0000_0000); // denormal -> normal | 169 | try test_mul_f80(0x0.8000_0000_0000_0000p-16382, 2.0, 0x0001_8000_0000_0000_0000); // denormal -> normal |
| 168 | try test__mulxf3(0x0.7fff_ffff_ffff_fffep-16382, 0x2.0000_0000_0000_0008p0, 0x0001_8000_0000_0000_0000); // denormal -> normal | 170 | try test_mul_f80(0x0.7fff_ffff_ffff_fffep-16382, 0x2.0000_0000_0000_0008p0, 0x0001_8000_0000_0000_0000); // denormal -> normal |
| 169 | try test__mulxf3(0x0.7fff_ffff_ffff_fffep-16382, 0x1.0000_0000_0000_0000p0, 0x0000_3FFF_FFFF_FFFF_FFFF); // denormal -> denormal | 171 | try test_mul_f80(0x0.7fff_ffff_ffff_fffep-16382, 0x1.0000_0000_0000_0000p0, 0x0000_3FFF_FFFF_FFFF_FFFF); // denormal -> denormal |
| 170 | } | 172 | } |
lib/compiler_rt/mulhc3.zig deleted-13| ... | @@ -1,13 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const mulc3 = @import("./mulc3.zig"); | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (@import("builtin").zig_backend != .stage2_c) { | ||
| 7 | symbol(&__mulhc3, "__mulhc3"); | ||
| 8 | } | ||
| 9 | } | ||
| 10 | |||
| 11 | pub fn __mulhc3(a: f16, b: f16, c: f16, d: f16) callconv(.c) mulc3.Complex(f16) { | ||
| 12 | return mulc3.mulc3(f16, a, b, c, d); | ||
| 13 | } | ||
lib/compiler_rt/mulhf3.zig deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const mulf3 = @import("./mulf3.zig").mulf3; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__mulhf3, "__mulhf3"); | ||
| 7 | } | ||
| 8 | |||
| 9 | pub fn __mulhf3(a: f16, b: f16) callconv(.c) f16 { | ||
| 10 | return mulf3(f16, a, b); | ||
| 11 | } | ||
lib/compiler_rt/mulsc3.zig deleted-12| ... | @@ -1,12 +0,0 @@ | ||
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 2 | const mulc3 = @import("./mulc3.zig"); | ||
| 3 | |||
| 4 | comptime { | ||
| 5 | if (@import("builtin").zig_backend != .stage2_c) { | ||
| 6 | symbol(&__mulsc3, "__mulsc3"); | ||
| 7 | } | ||
| 8 | } | ||
| 9 | |||
| 10 | pub fn __mulsc3(a: f32, b: f32, c: f32, d: f32) callconv(.c) mulc3.Complex(f32) { | ||
| 11 | return mulc3.mulc3(f32, a, b, c, d); | ||
| 12 | } | ||
lib/compiler_rt/mulsf3.zig deleted-19| ... | @@ -1,19 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const mulf3 = @import("./mulf3.zig").mulf3; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_aeabi) { | ||
| 7 | symbol(&__aeabi_fmul, "__aeabi_fmul"); | ||
| 8 | } else { | ||
| 9 | symbol(&__mulsf3, "__mulsf3"); | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | pub fn __mulsf3(a: f32, b: f32) callconv(.c) f32 { | ||
| 14 | return mulf3(f32, a, b); | ||
| 15 | } | ||
| 16 | |||
| 17 | fn __aeabi_fmul(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 { | ||
| 18 | return mulf3(f32, a, b); | ||
| 19 | } | ||
lib/compiler_rt/multc3.zig deleted-15| ... | @@ -1,15 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 3 | const mulc3 = @import("./mulc3.zig"); | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (@import("builtin").zig_backend != .stage2_c) { | ||
| 7 | if (compiler_rt.want_ppc_abi) | ||
| 8 | symbol(&__multc3, "__mulkc3"); | ||
| 9 | symbol(&__multc3, "__multc3"); | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | pub fn __multc3(a: f128, b: f128, c: f128, d: f128) callconv(.c) mulc3.Complex(f128) { | ||
| 14 | return mulc3.mulc3(f128, a, b, c, d); | ||
| 15 | } | ||
lib/compiler_rt/multf3.zig deleted-22| ... | @@ -1,22 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const mulf3 = @import("./mulf3.zig").mulf3; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_ppc_abi) { | ||
| 7 | symbol(&__multf3, "__mulkf3"); | ||
| 8 | } else if (compiler_rt.want_sparc64_abi) { | ||
| 9 | symbol(&_Qp_mul, "_Qp_mul"); | ||
| 10 | } else if (compiler_rt.want_sparc32_abi) { | ||
| 11 | symbol(&__multf3, "_Q_mul"); | ||
| 12 | } | ||
| 13 | symbol(&__multf3, "__multf3"); | ||
| 14 | } | ||
| 15 | |||
| 16 | pub fn __multf3(a: f128, b: f128) callconv(.c) f128 { | ||
| 17 | return mulf3(f128, a, b); | ||
| 18 | } | ||
| 19 | |||
| 20 | fn _Qp_mul(c: *f128, a: *const f128, b: *const f128) callconv(.c) void { | ||
| 21 | c.* = mulf3(f128, a.*, b.*); | ||
| 22 | } | ||
lib/compiler_rt/mulvsi3.zig+3-2| ... | @@ -1,7 +1,8 @@ | ... | @@ -1,7 +1,8 @@ |
| 1 | const testing = @import("std").testing; | 1 | const testing = @import("std").testing; |
| 2 | 2 | ||
| 3 | const mulv = @import("mulo.zig"); | 3 | const mulv = @import("mulo.zig"); |
| 4 | const symbol = @import("../compiler_rt.zig").symbol; | 4 | const compiler_rt = @import("../compiler_rt.zig"); |
| 5 | const symbol = compiler_rt.symbol; | ||
| 5 | 6 | ||
| 6 | comptime { | 7 | comptime { |
| 7 | symbol(&__mulvsi3, "__mulvsi3"); | 8 | symbol(&__mulvsi3, "__mulvsi3"); |
| ... | @@ -10,7 +11,7 @@ comptime { | ... | @@ -10,7 +11,7 @@ comptime { |
| 10 | pub fn __mulvsi3(a: i32, b: i32) callconv(.c) i32 { | 11 | pub fn __mulvsi3(a: i32, b: i32) callconv(.c) i32 { |
| 11 | var overflow: c_int = 0; | 12 | var overflow: c_int = 0; |
| 12 | const sum = mulv.__mulosi4(a, b, &overflow); | 13 | const sum = mulv.__mulosi4(a, b, &overflow); |
| 13 | if (overflow != 0) @panic("compiler-rt: integer overflow"); | 14 | if (overflow != 0) @panic("integer overflow"); |
| 14 | return sum; | 15 | return sum; |
| 15 | } | 16 | } |
| 16 | 17 |
lib/compiler_rt/mulxc3.zig deleted-13| ... | @@ -1,13 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const mulc3 = @import("./mulc3.zig"); | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (@import("builtin").zig_backend != .stage2_c) { | ||
| 7 | symbol(&__mulxc3, "__mulxc3"); | ||
| 8 | } | ||
| 9 | } | ||
| 10 | |||
| 11 | pub fn __mulxc3(a: f80, b: f80, c: f80, d: f80) callconv(.c) mulc3.Complex(f80) { | ||
| 12 | return mulc3.mulc3(f80, a, b, c, d); | ||
| 13 | } | ||
lib/compiler_rt/mulxf3.zig deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const mulf3 = @import("./mulf3.zig").mulf3; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__mulxf3, "__mulxf3"); | ||
| 7 | } | ||
| 8 | |||
| 9 | pub fn __mulxf3(a: f80, b: f80) callconv(.c) f80 { | ||
| 10 | return mulf3(f80, a, b); | ||
| 11 | } | ||
lib/compiler_rt/negv.zig+1-2| ... | @@ -33,8 +33,7 @@ inline fn negvXi(comptime ST: type, a: ST) ST { | ... | @@ -33,8 +33,7 @@ inline fn negvXi(comptime ST: type, a: ST) ST { |
| 33 | }; | 33 | }; |
| 34 | const N: UT = @bitSizeOf(ST); | 34 | const N: UT = @bitSizeOf(ST); |
| 35 | const min: ST = @as(ST, @bitCast((@as(UT, 1) << (N - 1)))); | 35 | const min: ST = @as(ST, @bitCast((@as(UT, 1) << (N - 1)))); |
| 36 | if (a == min) | 36 | if (a == min) @panic("integer overflow"); |
| 37 | @panic("compiler_rt negv: overflow"); | ||
| 38 | return -a; | 37 | return -a; |
| 39 | } | 38 | } |
| 40 | 39 |
lib/compiler_rt/os_version_check.zig-1| ... | @@ -3,7 +3,6 @@ const testing = std.testing; | ... | @@ -3,7 +3,6 @@ const testing = std.testing; |
| 3 | const builtin = @import("builtin"); | 3 | const builtin = @import("builtin"); |
| 4 | const compiler_rt = @import("../compiler_rt.zig"); | 4 | const compiler_rt = @import("../compiler_rt.zig"); |
| 5 | const symbol = compiler_rt.symbol; | 5 | const symbol = compiler_rt.symbol; |
| 6 | const panic = @import("../compiler_rt.zig").panic; | ||
| 7 | 6 | ||
| 8 | const have_availability_version_check = builtin.os.tag.isDarwin() and | 7 | const have_availability_version_check = builtin.os.tag.isDarwin() and |
| 9 | builtin.os.version_range.semver.min.order(.{ .major = 10, .minor = 15, .patch = 0 }).compare(.gte); | 8 | builtin.os.version_range.semver.min.order(.{ .major = 10, .minor = 15, .patch = 0 }).compare(.gte); |
lib/compiler_rt/parity.zig+2-1| ... | @@ -1,6 +1,7 @@ | ... | @@ -1,6 +1,7 @@ |
| 1 | //! parity - if number of bits set is even => 0, else => 1 | 1 | //! parity - if number of bits set is even => 0, else => 1 |
| 2 | //! - pariytXi2_generic for big and little endian | 2 | //! - pariytXi2_generic for big and little endian |
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | 3 | const compiler_rt = @import("../compiler_rt.zig"); |
| 4 | const symbol = compiler_rt.symbol; | ||
| 4 | 5 | ||
| 5 | comptime { | 6 | comptime { |
| 6 | symbol(&__paritysi2, "__paritysi2"); | 7 | symbol(&__paritysi2, "__paritysi2"); |
lib/compiler_rt/popcount.zig+2-1| ... | @@ -6,7 +6,8 @@ | ... | @@ -6,7 +6,8 @@ |
| 6 | //! TAOCP: Combinational Algorithms, Bitwise Tricks And Techniques, | 6 | //! TAOCP: Combinational Algorithms, Bitwise Tricks And Techniques, |
| 7 | //! subsubsection "Working with the rightmost bits" and "Sideways addition". | 7 | //! subsubsection "Working with the rightmost bits" and "Sideways addition". |
| 8 | 8 | ||
| 9 | const symbol = @import("../compiler_rt.zig").symbol; | 9 | const compiler_rt = @import("../compiler_rt.zig"); |
| 10 | const symbol = compiler_rt.symbol; | ||
| 10 | 11 | ||
| 11 | comptime { | 12 | comptime { |
| 12 | symbol(&__popcountsi2, "__popcountsi2"); | 13 | symbol(&__popcountsi2, "__popcountsi2"); |
lib/compiler_rt/powiXf2.zig+28-11| ... | @@ -4,16 +4,18 @@ | ... | @@ -4,16 +4,18 @@ |
| 4 | //! error propagation and this method is optimized for performance, not accuracy. | 4 | //! error propagation and this method is optimized for performance, not accuracy. |
| 5 | 5 | ||
| 6 | const compiler_rt = @import("../compiler_rt.zig"); | 6 | const compiler_rt = @import("../compiler_rt.zig"); |
| 7 | const symbol = @import("../compiler_rt.zig").symbol; | 7 | const symbol = compiler_rt.symbol; |
| 8 | 8 | ||
| 9 | comptime { | 9 | comptime { |
| 10 | symbol(&__powihf2, "__powihf2"); | 10 | symbol(&__powihf2, "__powihf2"); |
| 11 | symbol(&__powisf2, "__powisf2"); | 11 | symbol(&__powisf2, "__powisf2"); |
| 12 | symbol(&__powidf2, "__powidf2"); | 12 | symbol(&__powidf2, "__powidf2"); |
| 13 | if (compiler_rt.want_ppc_abi) | ||
| 14 | symbol(&__powitf2, "__powikf2"); | ||
| 15 | symbol(&__powitf2, "__powitf2"); | ||
| 16 | symbol(&__powixf2, "__powixf2"); | 13 | symbol(&__powixf2, "__powixf2"); |
| 14 | if (compiler_rt.want_ppc_abi) { | ||
| 15 | symbol(&__powitf2, "__powikf2"); | ||
| 16 | } else { | ||
| 17 | symbol(&__powitf2, "__powitf2"); | ||
| 18 | } | ||
| 17 | } | 19 | } |
| 18 | 20 | ||
| 19 | inline fn powiXf2(comptime FT: type, a: FT, b: i32) FT { | 21 | inline fn powiXf2(comptime FT: type, a: FT, b: i32) FT { |
| ... | @@ -32,26 +34,41 @@ inline fn powiXf2(comptime FT: type, a: FT, b: i32) FT { | ... | @@ -32,26 +34,41 @@ inline fn powiXf2(comptime FT: type, a: FT, b: i32) FT { |
| 32 | return if (is_recip) 1 / r else r; | 34 | return if (is_recip) 1 / r else r; |
| 33 | } | 35 | } |
| 34 | 36 | ||
| 35 | pub fn __powihf2(a: f16, b: i32) callconv(.c) f16 { | 37 | fn __powihf2(a: compiler_rt.f16.Abi, b: i32) callconv(.c) compiler_rt.f16.Abi { |
| 38 | return compiler_rt.f16.toAbi(powi_f16(compiler_rt.f16.fromAbi(a), b)); | ||
| 39 | } | ||
| 40 | pub fn powi_f16(a: f16, b: i32) f16 { | ||
| 36 | return powiXf2(f16, a, b); | 41 | return powiXf2(f16, a, b); |
| 37 | } | 42 | } |
| 38 | 43 | ||
| 39 | pub fn __powisf2(a: f32, b: i32) callconv(.c) f32 { | 44 | fn __powisf2(a: compiler_rt.f32.Abi, b: i32) callconv(.c) compiler_rt.f32.Abi { |
| 45 | return compiler_rt.f32.toAbi(powi_f32(compiler_rt.f32.fromAbi(a), b)); | ||
| 46 | } | ||
| 47 | pub fn powi_f32(a: f32, b: i32) f32 { | ||
| 40 | return powiXf2(f32, a, b); | 48 | return powiXf2(f32, a, b); |
| 41 | } | 49 | } |
| 42 | 50 | ||
| 43 | pub fn __powidf2(a: f64, b: i32) callconv(.c) f64 { | 51 | fn __powidf2(a: compiler_rt.f64.Abi, b: i32) callconv(.c) compiler_rt.f64.Abi { |
| 52 | return compiler_rt.f64.toAbi(powi_f64(compiler_rt.f64.fromAbi(a), b)); | ||
| 53 | } | ||
| 54 | pub fn powi_f64(a: f64, b: i32) f64 { | ||
| 44 | return powiXf2(f64, a, b); | 55 | return powiXf2(f64, a, b); |
| 45 | } | 56 | } |
| 46 | 57 | ||
| 47 | pub fn __powitf2(a: f128, b: i32) callconv(.c) f128 { | 58 | fn __powixf2(a: compiler_rt.f80.Abi, b: i32) callconv(.c) compiler_rt.f80.Abi { |
| 48 | return powiXf2(f128, a, b); | 59 | return compiler_rt.f80.toAbi(powi_f80(compiler_rt.f80.fromAbi(a), b)); |
| 49 | } | 60 | } |
| 50 | 61 | pub fn powi_f80(a: f80, b: i32) f80 { | |
| 51 | pub fn __powixf2(a: f80, b: i32) callconv(.c) f80 { | ||
| 52 | return powiXf2(f80, a, b); | 62 | return powiXf2(f80, a, b); |
| 53 | } | 63 | } |
| 54 | 64 | ||
| 65 | fn __powitf2(a: compiler_rt.f128.Abi, b: i32) callconv(.c) compiler_rt.f128.Abi { | ||
| 66 | return compiler_rt.f128.toAbi(powi_f128(compiler_rt.f128.fromAbi(a), b)); | ||
| 67 | } | ||
| 68 | pub fn powi_f128(a: f128, b: i32) f128 { | ||
| 69 | return powiXf2(f128, a, b); | ||
| 70 | } | ||
| 71 | |||
| 55 | test { | 72 | test { |
| 56 | _ = @import("powiXf2_test.zig"); | 73 | _ = @import("powiXf2_test.zig"); |
| 57 | } | 74 | } |
lib/compiler_rt/powiXf2_test.zig+531-525| ... | @@ -2,562 +2,568 @@ | ... | @@ -2,562 +2,568 @@ |
| 2 | // powisf2_test.c, powidf2_test.c, powitf2_test.c, powixf2_test.c | 2 | // powisf2_test.c, powidf2_test.c, powitf2_test.c, powixf2_test.c |
| 3 | // powihf2 adapted from powisf2 tests | 3 | // powihf2 adapted from powisf2 tests |
| 4 | 4 | ||
| 5 | const powiXf2 = @import("powiXf2.zig"); | ||
| 6 | const std = @import("std"); | 5 | const std = @import("std"); |
| 7 | const builtin = @import("builtin"); | ||
| 8 | const testing = std.testing; | 6 | const testing = std.testing; |
| 9 | const math = std.math; | 7 | const math = std.math; |
| 10 | 8 | ||
| 11 | fn test__powihf2(a: f16, b: i32, expected: f16) !void { | 9 | const impl = @import("powiXf2.zig"); |
| 12 | const result = powiXf2.__powihf2(a, b); | 10 | |
| 11 | const powi_f16 = impl.powi_f16; | ||
| 12 | const powi_f32 = impl.powi_f32; | ||
| 13 | const powi_f64 = impl.powi_f64; | ||
| 14 | const powi_f80 = impl.powi_f80; | ||
| 15 | const powi_f128 = impl.powi_f128; | ||
| 16 | |||
| 17 | fn test_powi_f16(a: f16, b: i32, expected: f16) !void { | ||
| 18 | const result = powi_f16(a, b); | ||
| 13 | try testing.expectEqual(expected, result); | 19 | try testing.expectEqual(expected, result); |
| 14 | } | 20 | } |
| 15 | 21 | ||
| 16 | fn test__powisf2(a: f32, b: i32, expected: f32) !void { | 22 | fn test_powi_f32(a: f32, b: i32, expected: f32) !void { |
| 17 | const result = powiXf2.__powisf2(a, b); | 23 | const result = powi_f32(a, b); |
| 18 | try testing.expectEqual(expected, result); | 24 | try testing.expectEqual(expected, result); |
| 19 | } | 25 | } |
| 20 | 26 | ||
| 21 | fn test__powidf2(a: f64, b: i32, expected: f64) !void { | 27 | fn test_powi_f64(a: f64, b: i32, expected: f64) !void { |
| 22 | const result = powiXf2.__powidf2(a, b); | 28 | const result = powi_f64(a, b); |
| 23 | try testing.expectEqual(expected, result); | 29 | try testing.expectEqual(expected, result); |
| 24 | } | 30 | } |
| 25 | 31 | ||
| 26 | fn test__powitf2(a: f128, b: i32, expected: f128) !void { | 32 | fn test_powi_f80(a: f80, b: i32, expected: f80) !void { |
| 27 | const result = powiXf2.__powitf2(a, b); | 33 | const result = powi_f80(a, b); |
| 28 | try testing.expectEqual(expected, result); | 34 | try testing.expectEqual(expected, result); |
| 29 | } | 35 | } |
| 30 | 36 | ||
| 31 | fn test__powixf2(a: f80, b: i32, expected: f80) !void { | 37 | fn test_powi_f128(a: f128, b: i32, expected: f128) !void { |
| 32 | const result = powiXf2.__powixf2(a, b); | 38 | const result = powi_f128(a, b); |
| 33 | try testing.expectEqual(expected, result); | 39 | try testing.expectEqual(expected, result); |
| 34 | } | 40 | } |
| 35 | 41 | ||
| 36 | test "powihf2" { | 42 | test powi_f16 { |
| 37 | const inf_f16 = math.inf(f16); | 43 | const inf_f16 = math.inf(f16); |
| 38 | try test__powisf2(0, 0, 1); | 44 | try test_powi_f16(0, 0, 1); |
| 39 | try test__powihf2(1, 0, 1); | 45 | try test_powi_f16(1, 0, 1); |
| 40 | try test__powihf2(1.5, 0, 1); | 46 | try test_powi_f16(1.5, 0, 1); |
| 41 | try test__powihf2(2, 0, 1); | 47 | try test_powi_f16(2, 0, 1); |
| 42 | try test__powihf2(inf_f16, 0, 1); | 48 | try test_powi_f16(inf_f16, 0, 1); |
| 43 | 49 | ||
| 44 | try test__powihf2(-0.0, 0, 1); | 50 | try test_powi_f16(-0.0, 0, 1); |
| 45 | try test__powihf2(-1, 0, 1); | 51 | try test_powi_f16(-1, 0, 1); |
| 46 | try test__powihf2(-1.5, 0, 1); | 52 | try test_powi_f16(-1.5, 0, 1); |
| 47 | try test__powihf2(-2, 0, 1); | 53 | try test_powi_f16(-2, 0, 1); |
| 48 | try test__powihf2(-inf_f16, 0, 1); | 54 | try test_powi_f16(-inf_f16, 0, 1); |
| 49 | 55 | ||
| 50 | try test__powihf2(0, 1, 0); | 56 | try test_powi_f16(0, 1, 0); |
| 51 | try test__powihf2(0, 2, 0); | 57 | try test_powi_f16(0, 2, 0); |
| 52 | try test__powihf2(0, 3, 0); | 58 | try test_powi_f16(0, 3, 0); |
| 53 | try test__powihf2(0, 4, 0); | 59 | try test_powi_f16(0, 4, 0); |
| 54 | try test__powihf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); | 60 | try test_powi_f16(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); |
| 55 | try test__powihf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0); | 61 | try test_powi_f16(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0); |
| 56 | 62 | ||
| 57 | try test__powihf2(-0.0, 1, -0.0); | 63 | try test_powi_f16(-0.0, 1, -0.0); |
| 58 | try test__powihf2(-0.0, 2, 0); | 64 | try test_powi_f16(-0.0, 2, 0); |
| 59 | try test__powihf2(-0.0, 3, -0.0); | 65 | try test_powi_f16(-0.0, 3, -0.0); |
| 60 | try test__powihf2(-0.0, 4, 0); | 66 | try test_powi_f16(-0.0, 4, 0); |
| 61 | try test__powihf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); | 67 | try test_powi_f16(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); |
| 62 | try test__powihf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0); | 68 | try test_powi_f16(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0); |
| 63 | 69 | ||
| 64 | try test__powihf2(1, 1, 1); | 70 | try test_powi_f16(1, 1, 1); |
| 65 | try test__powihf2(1, 2, 1); | 71 | try test_powi_f16(1, 2, 1); |
| 66 | try test__powihf2(1, 3, 1); | 72 | try test_powi_f16(1, 3, 1); |
| 67 | try test__powihf2(1, 4, 1); | 73 | try test_powi_f16(1, 4, 1); |
| 68 | try test__powihf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1); | 74 | try test_powi_f16(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1); |
| 69 | try test__powihf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1); | 75 | try test_powi_f16(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1); |
| 70 | 76 | ||
| 71 | try test__powihf2(inf_f16, 1, inf_f16); | 77 | try test_powi_f16(inf_f16, 1, inf_f16); |
| 72 | try test__powihf2(inf_f16, 2, inf_f16); | 78 | try test_powi_f16(inf_f16, 2, inf_f16); |
| 73 | try test__powihf2(inf_f16, 3, inf_f16); | 79 | try test_powi_f16(inf_f16, 3, inf_f16); |
| 74 | try test__powihf2(inf_f16, 4, inf_f16); | 80 | try test_powi_f16(inf_f16, 4, inf_f16); |
| 75 | try test__powihf2(inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f16); | 81 | try test_powi_f16(inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f16); |
| 76 | try test__powihf2(inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f16); | 82 | try test_powi_f16(inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f16); |
| 77 | 83 | ||
| 78 | try test__powihf2(-inf_f16, 1, -inf_f16); | 84 | try test_powi_f16(-inf_f16, 1, -inf_f16); |
| 79 | try test__powihf2(-inf_f16, 2, inf_f16); | 85 | try test_powi_f16(-inf_f16, 2, inf_f16); |
| 80 | try test__powihf2(-inf_f16, 3, -inf_f16); | 86 | try test_powi_f16(-inf_f16, 3, -inf_f16); |
| 81 | try test__powihf2(-inf_f16, 4, inf_f16); | 87 | try test_powi_f16(-inf_f16, 4, inf_f16); |
| 82 | try test__powihf2(-inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f16); | 88 | try test_powi_f16(-inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f16); |
| 83 | try test__powihf2(-inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f16); | 89 | try test_powi_f16(-inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f16); |
| 84 | // | 90 | // |
| 85 | try test__powihf2(0, -1, inf_f16); | 91 | try test_powi_f16(0, -1, inf_f16); |
| 86 | try test__powihf2(0, -2, inf_f16); | 92 | try test_powi_f16(0, -2, inf_f16); |
| 87 | try test__powihf2(0, -3, inf_f16); | 93 | try test_powi_f16(0, -3, inf_f16); |
| 88 | try test__powihf2(0, -4, inf_f16); | 94 | try test_powi_f16(0, -4, inf_f16); |
| 89 | try test__powihf2(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f16); // 0 ^ anything = +inf | 95 | try test_powi_f16(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f16); // 0 ^ anything = +inf |
| 90 | try test__powihf2(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f16); | 96 | try test_powi_f16(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f16); |
| 91 | try test__powihf2(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f16); | 97 | try test_powi_f16(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f16); |
| 92 | 98 | ||
| 93 | try test__powihf2(-0.0, -1, -inf_f16); | 99 | try test_powi_f16(-0.0, -1, -inf_f16); |
| 94 | try test__powihf2(-0.0, -2, inf_f16); | 100 | try test_powi_f16(-0.0, -2, inf_f16); |
| 95 | try test__powihf2(-0.0, -3, -inf_f16); | 101 | try test_powi_f16(-0.0, -3, -inf_f16); |
| 96 | try test__powihf2(-0.0, -4, inf_f16); | 102 | try test_powi_f16(-0.0, -4, inf_f16); |
| 97 | try test__powihf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f16); // -0 ^ anything even = +inf | 103 | try test_powi_f16(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f16); // -0 ^ anything even = +inf |
| 98 | try test__powihf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f16); // -0 ^ anything odd = -inf | 104 | try test_powi_f16(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f16); // -0 ^ anything odd = -inf |
| 99 | try test__powihf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f16); | 105 | try test_powi_f16(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f16); |
| 100 | 106 | ||
| 101 | try test__powihf2(1, -1, 1); | 107 | try test_powi_f16(1, -1, 1); |
| 102 | try test__powihf2(1, -2, 1); | 108 | try test_powi_f16(1, -2, 1); |
| 103 | try test__powihf2(1, -3, 1); | 109 | try test_powi_f16(1, -3, 1); |
| 104 | try test__powihf2(1, -4, 1); | 110 | try test_powi_f16(1, -4, 1); |
| 105 | try test__powihf2(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1); // 1.0 ^ anything = 1 | 111 | try test_powi_f16(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1); // 1.0 ^ anything = 1 |
| 106 | try test__powihf2(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1); | 112 | try test_powi_f16(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1); |
| 107 | try test__powihf2(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1); | 113 | try test_powi_f16(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1); |
| 108 | 114 | ||
| 109 | try test__powihf2(inf_f16, -1, 0); | 115 | try test_powi_f16(inf_f16, -1, 0); |
| 110 | try test__powihf2(inf_f16, -2, 0); | 116 | try test_powi_f16(inf_f16, -2, 0); |
| 111 | try test__powihf2(inf_f16, -3, 0); | 117 | try test_powi_f16(inf_f16, -3, 0); |
| 112 | try test__powihf2(inf_f16, -4, 0); | 118 | try test_powi_f16(inf_f16, -4, 0); |
| 113 | try test__powihf2(inf_f16, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); | 119 | try test_powi_f16(inf_f16, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); |
| 114 | try test__powihf2(inf_f16, @as(i32, @bitCast(@as(u32, 0x80000001))), 0); | 120 | try test_powi_f16(inf_f16, @as(i32, @bitCast(@as(u32, 0x80000001))), 0); |
| 115 | try test__powihf2(inf_f16, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); | 121 | try test_powi_f16(inf_f16, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); |
| 116 | // | 122 | // |
| 117 | try test__powihf2(-inf_f16, -1, -0.0); | 123 | try test_powi_f16(-inf_f16, -1, -0.0); |
| 118 | try test__powihf2(-inf_f16, -2, 0); | 124 | try test_powi_f16(-inf_f16, -2, 0); |
| 119 | try test__powihf2(-inf_f16, -3, -0.0); | 125 | try test_powi_f16(-inf_f16, -3, -0.0); |
| 120 | try test__powihf2(-inf_f16, -4, 0); | 126 | try test_powi_f16(-inf_f16, -4, 0); |
| 121 | try test__powihf2(-inf_f16, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); | 127 | try test_powi_f16(-inf_f16, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); |
| 122 | try test__powihf2(-inf_f16, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0); | 128 | try test_powi_f16(-inf_f16, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0); |
| 123 | try test__powihf2(-inf_f16, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); | 129 | try test_powi_f16(-inf_f16, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); |
| 124 | 130 | ||
| 125 | try test__powihf2(2, 10, 1024.0); | 131 | try test_powi_f16(2, 10, 1024.0); |
| 126 | try test__powihf2(-2, 10, 1024.0); | 132 | try test_powi_f16(-2, 10, 1024.0); |
| 127 | try test__powihf2(2, -10, 1.0 / 1024.0); | 133 | try test_powi_f16(2, -10, 1.0 / 1024.0); |
| 128 | try test__powihf2(-2, -10, 1.0 / 1024.0); | 134 | try test_powi_f16(-2, -10, 1.0 / 1024.0); |
| 129 | 135 | ||
| 130 | try test__powihf2(2, 14, 16384.0); | 136 | try test_powi_f16(2, 14, 16384.0); |
| 131 | try test__powihf2(-2, 14, 16384.0); | 137 | try test_powi_f16(-2, 14, 16384.0); |
| 132 | try test__powihf2(2, 15, 32768.0); | 138 | try test_powi_f16(2, 15, 32768.0); |
| 133 | try test__powihf2(-2, 15, -32768.0); | 139 | try test_powi_f16(-2, 15, -32768.0); |
| 134 | try test__powihf2(2, 16, inf_f16); | 140 | try test_powi_f16(2, 16, inf_f16); |
| 135 | try test__powihf2(-2, 16, inf_f16); | 141 | try test_powi_f16(-2, 16, inf_f16); |
| 136 | 142 | ||
| 137 | try test__powihf2(2, -13, 1.0 / 8192.0); | 143 | try test_powi_f16(2, -13, 1.0 / 8192.0); |
| 138 | try test__powihf2(-2, -13, -1.0 / 8192.0); | 144 | try test_powi_f16(-2, -13, -1.0 / 8192.0); |
| 139 | try test__powihf2(2, -15, 1.0 / 32768.0); | 145 | try test_powi_f16(2, -15, 1.0 / 32768.0); |
| 140 | try test__powihf2(-2, -15, -1.0 / 32768.0); | 146 | try test_powi_f16(-2, -15, -1.0 / 32768.0); |
| 141 | try test__powihf2(2, -16, 0.0); // expected = 0.0 = 1/(-2**16) | 147 | try test_powi_f16(2, -16, 0.0); // expected = 0.0 = 1/(-2**16) |
| 142 | try test__powihf2(-2, -16, 0.0); // expected = 0.0 = 1/(2**16) | 148 | try test_powi_f16(-2, -16, 0.0); // expected = 0.0 = 1/(2**16) |
| 143 | } | 149 | } |
| 144 | 150 | ||
| 145 | test "powisf2" { | 151 | test powi_f32 { |
| 146 | const inf_f32 = math.inf(f32); | 152 | const inf_f32 = math.inf(f32); |
| 147 | try test__powisf2(0, 0, 1); | 153 | try test_powi_f32(0, 0, 1); |
| 148 | try test__powisf2(1, 0, 1); | 154 | try test_powi_f32(1, 0, 1); |
| 149 | try test__powisf2(1.5, 0, 1); | 155 | try test_powi_f32(1.5, 0, 1); |
| 150 | try test__powisf2(2, 0, 1); | 156 | try test_powi_f32(2, 0, 1); |
| 151 | try test__powisf2(inf_f32, 0, 1); | 157 | try test_powi_f32(inf_f32, 0, 1); |
| 152 | 158 | ||
| 153 | try test__powisf2(-0.0, 0, 1); | 159 | try test_powi_f32(-0.0, 0, 1); |
| 154 | try test__powisf2(-1, 0, 1); | 160 | try test_powi_f32(-1, 0, 1); |
| 155 | try test__powisf2(-1.5, 0, 1); | 161 | try test_powi_f32(-1.5, 0, 1); |
| 156 | try test__powisf2(-2, 0, 1); | 162 | try test_powi_f32(-2, 0, 1); |
| 157 | try test__powisf2(-inf_f32, 0, 1); | 163 | try test_powi_f32(-inf_f32, 0, 1); |
| 158 | 164 | ||
| 159 | try test__powisf2(0, 1, 0); | 165 | try test_powi_f32(0, 1, 0); |
| 160 | try test__powisf2(0, 2, 0); | 166 | try test_powi_f32(0, 2, 0); |
| 161 | try test__powisf2(0, 3, 0); | 167 | try test_powi_f32(0, 3, 0); |
| 162 | try test__powisf2(0, 4, 0); | 168 | try test_powi_f32(0, 4, 0); |
| 163 | try test__powisf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); | 169 | try test_powi_f32(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); |
| 164 | try test__powisf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0); | 170 | try test_powi_f32(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0); |
| 165 | 171 | ||
| 166 | try test__powisf2(-0.0, 1, -0.0); | 172 | try test_powi_f32(-0.0, 1, -0.0); |
| 167 | try test__powisf2(-0.0, 2, 0); | 173 | try test_powi_f32(-0.0, 2, 0); |
| 168 | try test__powisf2(-0.0, 3, -0.0); | 174 | try test_powi_f32(-0.0, 3, -0.0); |
| 169 | try test__powisf2(-0.0, 4, 0); | 175 | try test_powi_f32(-0.0, 4, 0); |
| 170 | try test__powisf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); | 176 | try test_powi_f32(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); |
| 171 | try test__powisf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0); | 177 | try test_powi_f32(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0); |
| 172 | 178 | ||
| 173 | try test__powisf2(1, 1, 1); | 179 | try test_powi_f32(1, 1, 1); |
| 174 | try test__powisf2(1, 2, 1); | 180 | try test_powi_f32(1, 2, 1); |
| 175 | try test__powisf2(1, 3, 1); | 181 | try test_powi_f32(1, 3, 1); |
| 176 | try test__powisf2(1, 4, 1); | 182 | try test_powi_f32(1, 4, 1); |
| 177 | try test__powisf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1); | 183 | try test_powi_f32(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1); |
| 178 | try test__powisf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1); | 184 | try test_powi_f32(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1); |
| 179 | 185 | ||
| 180 | try test__powisf2(inf_f32, 1, inf_f32); | 186 | try test_powi_f32(inf_f32, 1, inf_f32); |
| 181 | try test__powisf2(inf_f32, 2, inf_f32); | 187 | try test_powi_f32(inf_f32, 2, inf_f32); |
| 182 | try test__powisf2(inf_f32, 3, inf_f32); | 188 | try test_powi_f32(inf_f32, 3, inf_f32); |
| 183 | try test__powisf2(inf_f32, 4, inf_f32); | 189 | try test_powi_f32(inf_f32, 4, inf_f32); |
| 184 | try test__powisf2(inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f32); | 190 | try test_powi_f32(inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f32); |
| 185 | try test__powisf2(inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f32); | 191 | try test_powi_f32(inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f32); |
| 186 | 192 | ||
| 187 | try test__powisf2(-inf_f32, 1, -inf_f32); | 193 | try test_powi_f32(-inf_f32, 1, -inf_f32); |
| 188 | try test__powisf2(-inf_f32, 2, inf_f32); | 194 | try test_powi_f32(-inf_f32, 2, inf_f32); |
| 189 | try test__powisf2(-inf_f32, 3, -inf_f32); | 195 | try test_powi_f32(-inf_f32, 3, -inf_f32); |
| 190 | try test__powisf2(-inf_f32, 4, inf_f32); | 196 | try test_powi_f32(-inf_f32, 4, inf_f32); |
| 191 | try test__powisf2(-inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f32); | 197 | try test_powi_f32(-inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f32); |
| 192 | try test__powisf2(-inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f32); | 198 | try test_powi_f32(-inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f32); |
| 193 | 199 | ||
| 194 | try test__powisf2(0, -1, inf_f32); | 200 | try test_powi_f32(0, -1, inf_f32); |
| 195 | try test__powisf2(0, -2, inf_f32); | 201 | try test_powi_f32(0, -2, inf_f32); |
| 196 | try test__powisf2(0, -3, inf_f32); | 202 | try test_powi_f32(0, -3, inf_f32); |
| 197 | try test__powisf2(0, -4, inf_f32); | 203 | try test_powi_f32(0, -4, inf_f32); |
| 198 | try test__powisf2(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f32); | 204 | try test_powi_f32(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f32); |
| 199 | try test__powisf2(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f32); | 205 | try test_powi_f32(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f32); |
| 200 | try test__powisf2(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f32); | 206 | try test_powi_f32(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f32); |
| 201 | 207 | ||
| 202 | try test__powisf2(-0.0, -1, -inf_f32); | 208 | try test_powi_f32(-0.0, -1, -inf_f32); |
| 203 | try test__powisf2(-0.0, -2, inf_f32); | 209 | try test_powi_f32(-0.0, -2, inf_f32); |
| 204 | try test__powisf2(-0.0, -3, -inf_f32); | 210 | try test_powi_f32(-0.0, -3, -inf_f32); |
| 205 | try test__powisf2(-0.0, -4, inf_f32); | 211 | try test_powi_f32(-0.0, -4, inf_f32); |
| 206 | try test__powisf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f32); | 212 | try test_powi_f32(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f32); |
| 207 | try test__powisf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f32); | 213 | try test_powi_f32(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f32); |
| 208 | try test__powisf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f32); | 214 | try test_powi_f32(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f32); |
| 209 | 215 | ||
| 210 | try test__powisf2(1, -1, 1); | 216 | try test_powi_f32(1, -1, 1); |
| 211 | try test__powisf2(1, -2, 1); | 217 | try test_powi_f32(1, -2, 1); |
| 212 | try test__powisf2(1, -3, 1); | 218 | try test_powi_f32(1, -3, 1); |
| 213 | try test__powisf2(1, -4, 1); | 219 | try test_powi_f32(1, -4, 1); |
| 214 | try test__powisf2(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1); | 220 | try test_powi_f32(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1); |
| 215 | try test__powisf2(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1); | 221 | try test_powi_f32(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1); |
| 216 | try test__powisf2(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1); | 222 | try test_powi_f32(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1); |
| 217 | 223 | ||
| 218 | try test__powisf2(inf_f32, -1, 0); | 224 | try test_powi_f32(inf_f32, -1, 0); |
| 219 | try test__powisf2(inf_f32, -2, 0); | 225 | try test_powi_f32(inf_f32, -2, 0); |
| 220 | try test__powisf2(inf_f32, -3, 0); | 226 | try test_powi_f32(inf_f32, -3, 0); |
| 221 | try test__powisf2(inf_f32, -4, 0); | 227 | try test_powi_f32(inf_f32, -4, 0); |
| 222 | try test__powisf2(inf_f32, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); | 228 | try test_powi_f32(inf_f32, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); |
| 223 | try test__powisf2(inf_f32, @as(i32, @bitCast(@as(u32, 0x80000001))), 0); | 229 | try test_powi_f32(inf_f32, @as(i32, @bitCast(@as(u32, 0x80000001))), 0); |
| 224 | try test__powisf2(inf_f32, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); | 230 | try test_powi_f32(inf_f32, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); |
| 225 | 231 | ||
| 226 | try test__powisf2(-inf_f32, -1, -0.0); | 232 | try test_powi_f32(-inf_f32, -1, -0.0); |
| 227 | try test__powisf2(-inf_f32, -2, 0); | 233 | try test_powi_f32(-inf_f32, -2, 0); |
| 228 | try test__powisf2(-inf_f32, -3, -0.0); | 234 | try test_powi_f32(-inf_f32, -3, -0.0); |
| 229 | try test__powisf2(-inf_f32, -4, 0); | 235 | try test_powi_f32(-inf_f32, -4, 0); |
| 230 | try test__powisf2(-inf_f32, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); | 236 | try test_powi_f32(-inf_f32, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); |
| 231 | try test__powisf2(-inf_f32, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0); | 237 | try test_powi_f32(-inf_f32, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0); |
| 232 | try test__powisf2(-inf_f32, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); | 238 | try test_powi_f32(-inf_f32, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); |
| 233 | 239 | ||
| 234 | try test__powisf2(2.0, 10, 1024.0); | 240 | try test_powi_f32(2.0, 10, 1024.0); |
| 235 | try test__powisf2(-2, 10, 1024.0); | 241 | try test_powi_f32(-2, 10, 1024.0); |
| 236 | try test__powisf2(2, -10, 1.0 / 1024.0); | 242 | try test_powi_f32(2, -10, 1.0 / 1024.0); |
| 237 | try test__powisf2(-2, -10, 1.0 / 1024.0); | 243 | try test_powi_f32(-2, -10, 1.0 / 1024.0); |
| 238 | // | 244 | // |
| 239 | try test__powisf2(2, 19, 524288.0); | 245 | try test_powi_f32(2, 19, 524288.0); |
| 240 | try test__powisf2(-2, 19, -524288.0); | 246 | try test_powi_f32(-2, 19, -524288.0); |
| 241 | try test__powisf2(2, -19, 1.0 / 524288.0); | 247 | try test_powi_f32(2, -19, 1.0 / 524288.0); |
| 242 | try test__powisf2(-2, -19, -1.0 / 524288.0); | 248 | try test_powi_f32(-2, -19, -1.0 / 524288.0); |
| 243 | 249 | ||
| 244 | try test__powisf2(2, 31, 2147483648.0); | 250 | try test_powi_f32(2, 31, 2147483648.0); |
| 245 | try test__powisf2(-2, 31, -2147483648.0); | 251 | try test_powi_f32(-2, 31, -2147483648.0); |
| 246 | try test__powisf2(2, -31, 1.0 / 2147483648.0); | 252 | try test_powi_f32(2, -31, 1.0 / 2147483648.0); |
| 247 | try test__powisf2(-2, -31, -1.0 / 2147483648.0); | 253 | try test_powi_f32(-2, -31, -1.0 / 2147483648.0); |
| 248 | } | 254 | } |
| 249 | 255 | ||
| 250 | test "powidf2" { | 256 | test powi_f64 { |
| 251 | const inf_f64 = math.inf(f64); | 257 | const inf_f64 = math.inf(f64); |
| 252 | try test__powidf2(0, 0, 1); | 258 | try test_powi_f64(0, 0, 1); |
| 253 | try test__powidf2(1, 0, 1); | 259 | try test_powi_f64(1, 0, 1); |
| 254 | try test__powidf2(1.5, 0, 1); | 260 | try test_powi_f64(1.5, 0, 1); |
| 255 | try test__powidf2(2, 0, 1); | 261 | try test_powi_f64(2, 0, 1); |
| 256 | try test__powidf2(inf_f64, 0, 1); | 262 | try test_powi_f64(inf_f64, 0, 1); |
| 257 | 263 | ||
| 258 | try test__powidf2(-0.0, 0, 1); | 264 | try test_powi_f64(-0.0, 0, 1); |
| 259 | try test__powidf2(-1, 0, 1); | 265 | try test_powi_f64(-1, 0, 1); |
| 260 | try test__powidf2(-1.5, 0, 1); | 266 | try test_powi_f64(-1.5, 0, 1); |
| 261 | try test__powidf2(-2, 0, 1); | 267 | try test_powi_f64(-2, 0, 1); |
| 262 | try test__powidf2(-inf_f64, 0, 1); | 268 | try test_powi_f64(-inf_f64, 0, 1); |
| 263 | 269 | ||
| 264 | try test__powidf2(0, 1, 0); | 270 | try test_powi_f64(0, 1, 0); |
| 265 | try test__powidf2(0, 2, 0); | 271 | try test_powi_f64(0, 2, 0); |
| 266 | try test__powidf2(0, 3, 0); | 272 | try test_powi_f64(0, 3, 0); |
| 267 | try test__powidf2(0, 4, 0); | 273 | try test_powi_f64(0, 4, 0); |
| 268 | try test__powidf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); | 274 | try test_powi_f64(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); |
| 269 | try test__powidf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0); | 275 | try test_powi_f64(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0); |
| 270 | 276 | ||
| 271 | try test__powidf2(-0.0, 1, -0.0); | 277 | try test_powi_f64(-0.0, 1, -0.0); |
| 272 | try test__powidf2(-0.0, 2, 0); | 278 | try test_powi_f64(-0.0, 2, 0); |
| 273 | try test__powidf2(-0.0, 3, -0.0); | 279 | try test_powi_f64(-0.0, 3, -0.0); |
| 274 | try test__powidf2(-0.0, 4, 0); | 280 | try test_powi_f64(-0.0, 4, 0); |
| 275 | try test__powidf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); | 281 | try test_powi_f64(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); |
| 276 | try test__powidf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0); | 282 | try test_powi_f64(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0); |
| 277 | 283 | ||
| 278 | try test__powidf2(1, 1, 1); | 284 | try test_powi_f64(1, 1, 1); |
| 279 | try test__powidf2(1, 2, 1); | 285 | try test_powi_f64(1, 2, 1); |
| 280 | try test__powidf2(1, 3, 1); | 286 | try test_powi_f64(1, 3, 1); |
| 281 | try test__powidf2(1, 4, 1); | 287 | try test_powi_f64(1, 4, 1); |
| 282 | try test__powidf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1); | 288 | try test_powi_f64(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1); |
| 283 | try test__powidf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1); | 289 | try test_powi_f64(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1); |
| 284 | 290 | ||
| 285 | try test__powidf2(inf_f64, 1, inf_f64); | 291 | try test_powi_f64(inf_f64, 1, inf_f64); |
| 286 | try test__powidf2(inf_f64, 2, inf_f64); | 292 | try test_powi_f64(inf_f64, 2, inf_f64); |
| 287 | try test__powidf2(inf_f64, 3, inf_f64); | 293 | try test_powi_f64(inf_f64, 3, inf_f64); |
| 288 | try test__powidf2(inf_f64, 4, inf_f64); | 294 | try test_powi_f64(inf_f64, 4, inf_f64); |
| 289 | try test__powidf2(inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f64); | 295 | try test_powi_f64(inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f64); |
| 290 | try test__powidf2(inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f64); | 296 | try test_powi_f64(inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f64); |
| 291 | 297 | ||
| 292 | try test__powidf2(-inf_f64, 1, -inf_f64); | 298 | try test_powi_f64(-inf_f64, 1, -inf_f64); |
| 293 | try test__powidf2(-inf_f64, 2, inf_f64); | 299 | try test_powi_f64(-inf_f64, 2, inf_f64); |
| 294 | try test__powidf2(-inf_f64, 3, -inf_f64); | 300 | try test_powi_f64(-inf_f64, 3, -inf_f64); |
| 295 | try test__powidf2(-inf_f64, 4, inf_f64); | 301 | try test_powi_f64(-inf_f64, 4, inf_f64); |
| 296 | try test__powidf2(-inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f64); | 302 | try test_powi_f64(-inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f64); |
| 297 | try test__powidf2(-inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f64); | 303 | try test_powi_f64(-inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f64); |
| 298 | 304 | ||
| 299 | try test__powidf2(0, -1, inf_f64); | 305 | try test_powi_f64(0, -1, inf_f64); |
| 300 | try test__powidf2(0, -2, inf_f64); | 306 | try test_powi_f64(0, -2, inf_f64); |
| 301 | try test__powidf2(0, -3, inf_f64); | 307 | try test_powi_f64(0, -3, inf_f64); |
| 302 | try test__powidf2(0, -4, inf_f64); | 308 | try test_powi_f64(0, -4, inf_f64); |
| 303 | try test__powidf2(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f64); | 309 | try test_powi_f64(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f64); |
| 304 | try test__powidf2(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f64); | 310 | try test_powi_f64(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f64); |
| 305 | try test__powidf2(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f64); | 311 | try test_powi_f64(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f64); |
| 306 | 312 | ||
| 307 | try test__powidf2(-0.0, -1, -inf_f64); | 313 | try test_powi_f64(-0.0, -1, -inf_f64); |
| 308 | try test__powidf2(-0.0, -2, inf_f64); | 314 | try test_powi_f64(-0.0, -2, inf_f64); |
| 309 | try test__powidf2(-0.0, -3, -inf_f64); | 315 | try test_powi_f64(-0.0, -3, -inf_f64); |
| 310 | try test__powidf2(-0.0, -4, inf_f64); | 316 | try test_powi_f64(-0.0, -4, inf_f64); |
| 311 | try test__powidf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f64); | 317 | try test_powi_f64(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f64); |
| 312 | try test__powidf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f64); | 318 | try test_powi_f64(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f64); |
| 313 | try test__powidf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f64); | 319 | try test_powi_f64(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f64); |
| 314 | 320 | ||
| 315 | try test__powidf2(1, -1, 1); | 321 | try test_powi_f64(1, -1, 1); |
| 316 | try test__powidf2(1, -2, 1); | 322 | try test_powi_f64(1, -2, 1); |
| 317 | try test__powidf2(1, -3, 1); | 323 | try test_powi_f64(1, -3, 1); |
| 318 | try test__powidf2(1, -4, 1); | 324 | try test_powi_f64(1, -4, 1); |
| 319 | try test__powidf2(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1); | 325 | try test_powi_f64(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1); |
| 320 | try test__powidf2(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1); | 326 | try test_powi_f64(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1); |
| 321 | try test__powidf2(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1); | 327 | try test_powi_f64(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1); |
| 322 | 328 | ||
| 323 | try test__powidf2(inf_f64, -1, 0); | 329 | try test_powi_f64(inf_f64, -1, 0); |
| 324 | try test__powidf2(inf_f64, -2, 0); | 330 | try test_powi_f64(inf_f64, -2, 0); |
| 325 | try test__powidf2(inf_f64, -3, 0); | 331 | try test_powi_f64(inf_f64, -3, 0); |
| 326 | try test__powidf2(inf_f64, -4, 0); | 332 | try test_powi_f64(inf_f64, -4, 0); |
| 327 | try test__powidf2(inf_f64, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); | 333 | try test_powi_f64(inf_f64, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); |
| 328 | try test__powidf2(inf_f64, @as(i32, @bitCast(@as(u32, 0x80000001))), 0); | 334 | try test_powi_f64(inf_f64, @as(i32, @bitCast(@as(u32, 0x80000001))), 0); |
| 329 | try test__powidf2(inf_f64, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); | 335 | try test_powi_f64(inf_f64, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); |
| 330 | 336 | ||
| 331 | try test__powidf2(-inf_f64, -1, -0.0); | 337 | try test_powi_f64(-inf_f64, -1, -0.0); |
| 332 | try test__powidf2(-inf_f64, -2, 0); | 338 | try test_powi_f64(-inf_f64, -2, 0); |
| 333 | try test__powidf2(-inf_f64, -3, -0.0); | 339 | try test_powi_f64(-inf_f64, -3, -0.0); |
| 334 | try test__powidf2(-inf_f64, -4, 0); | 340 | try test_powi_f64(-inf_f64, -4, 0); |
| 335 | try test__powidf2(-inf_f64, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); | 341 | try test_powi_f64(-inf_f64, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); |
| 336 | try test__powidf2(-inf_f64, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0); | 342 | try test_powi_f64(-inf_f64, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0); |
| 337 | try test__powidf2(-inf_f64, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); | 343 | try test_powi_f64(-inf_f64, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); |
| 338 | 344 | ||
| 339 | try test__powidf2(2, 10, 1024.0); | 345 | try test_powi_f64(2, 10, 1024.0); |
| 340 | try test__powidf2(-2, 10, 1024.0); | 346 | try test_powi_f64(-2, 10, 1024.0); |
| 341 | try test__powidf2(2, -10, 1.0 / 1024.0); | 347 | try test_powi_f64(2, -10, 1.0 / 1024.0); |
| 342 | try test__powidf2(-2, -10, 1.0 / 1024.0); | 348 | try test_powi_f64(-2, -10, 1.0 / 1024.0); |
| 343 | 349 | ||
| 344 | try test__powidf2(2, 19, 524288.0); | 350 | try test_powi_f64(2, 19, 524288.0); |
| 345 | try test__powidf2(-2, 19, -524288.0); | 351 | try test_powi_f64(-2, 19, -524288.0); |
| 346 | try test__powidf2(2, -19, 1.0 / 524288.0); | 352 | try test_powi_f64(2, -19, 1.0 / 524288.0); |
| 347 | try test__powidf2(-2, -19, -1.0 / 524288.0); | 353 | try test_powi_f64(-2, -19, -1.0 / 524288.0); |
| 348 | 354 | ||
| 349 | try test__powidf2(2, 31, 2147483648.0); | 355 | try test_powi_f64(2, 31, 2147483648.0); |
| 350 | try test__powidf2(-2, 31, -2147483648.0); | 356 | try test_powi_f64(-2, 31, -2147483648.0); |
| 351 | try test__powidf2(2, -31, 1.0 / 2147483648.0); | 357 | try test_powi_f64(2, -31, 1.0 / 2147483648.0); |
| 352 | try test__powidf2(-2, -31, -1.0 / 2147483648.0); | 358 | try test_powi_f64(-2, -31, -1.0 / 2147483648.0); |
| 353 | } | 359 | } |
| 354 | 360 | ||
| 355 | test "powitf2" { | 361 | test powi_f80 { |
| 356 | const inf_f128 = math.inf(f128); | 362 | const inf_f80 = math.inf(f80); |
| 357 | try test__powitf2(0, 0, 1); | 363 | try test_powi_f80(0, 0, 1); |
| 358 | try test__powitf2(1, 0, 1); | 364 | try test_powi_f80(1, 0, 1); |
| 359 | try test__powitf2(1.5, 0, 1); | 365 | try test_powi_f80(1.5, 0, 1); |
| 360 | try test__powitf2(2, 0, 1); | 366 | try test_powi_f80(2, 0, 1); |
| 361 | try test__powitf2(inf_f128, 0, 1); | 367 | try test_powi_f80(inf_f80, 0, 1); |
| 362 | 368 | ||
| 363 | try test__powitf2(-0.0, 0, 1); | 369 | try test_powi_f80(-0.0, 0, 1); |
| 364 | try test__powitf2(-1, 0, 1); | 370 | try test_powi_f80(-1, 0, 1); |
| 365 | try test__powitf2(-1.5, 0, 1); | 371 | try test_powi_f80(-1.5, 0, 1); |
| 366 | try test__powitf2(-2, 0, 1); | 372 | try test_powi_f80(-2, 0, 1); |
| 367 | try test__powitf2(-inf_f128, 0, 1); | 373 | try test_powi_f80(-inf_f80, 0, 1); |
| 368 | 374 | ||
| 369 | try test__powitf2(0, 1, 0); | 375 | try test_powi_f80(0, 1, 0); |
| 370 | try test__powitf2(0, 2, 0); | 376 | try test_powi_f80(0, 2, 0); |
| 371 | try test__powitf2(0, 3, 0); | 377 | try test_powi_f80(0, 3, 0); |
| 372 | try test__powitf2(0, 4, 0); | 378 | try test_powi_f80(0, 4, 0); |
| 373 | try test__powitf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); | 379 | try test_powi_f80(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); |
| 374 | try test__powitf2(0, 0x7FFFFFFF, 0); | 380 | try test_powi_f80(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0); |
| 375 | 381 | ||
| 376 | try test__powitf2(-0.0, 1, -0.0); | 382 | try test_powi_f80(-0.0, 1, -0.0); |
| 377 | try test__powitf2(-0.0, 2, 0); | 383 | try test_powi_f80(-0.0, 2, 0); |
| 378 | try test__powitf2(-0.0, 3, -0.0); | 384 | try test_powi_f80(-0.0, 3, -0.0); |
| 379 | try test__powitf2(-0.0, 4, 0); | 385 | try test_powi_f80(-0.0, 4, 0); |
| 380 | try test__powitf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); | 386 | try test_powi_f80(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); |
| 381 | try test__powitf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0); | 387 | try test_powi_f80(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0); |
| 382 | 388 | ||
| 383 | try test__powitf2(1, 1, 1); | 389 | try test_powi_f80(1, 1, 1); |
| 384 | try test__powitf2(1, 2, 1); | 390 | try test_powi_f80(1, 2, 1); |
| 385 | try test__powitf2(1, 3, 1); | 391 | try test_powi_f80(1, 3, 1); |
| 386 | try test__powitf2(1, 4, 1); | 392 | try test_powi_f80(1, 4, 1); |
| 387 | try test__powitf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1); | 393 | try test_powi_f80(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1); |
| 388 | try test__powitf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1); | 394 | try test_powi_f80(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1); |
| 389 | 395 | ||
| 390 | try test__powitf2(inf_f128, 1, inf_f128); | 396 | try test_powi_f80(inf_f80, 1, inf_f80); |
| 391 | try test__powitf2(inf_f128, 2, inf_f128); | 397 | try test_powi_f80(inf_f80, 2, inf_f80); |
| 392 | try test__powitf2(inf_f128, 3, inf_f128); | 398 | try test_powi_f80(inf_f80, 3, inf_f80); |
| 393 | try test__powitf2(inf_f128, 4, inf_f128); | 399 | try test_powi_f80(inf_f80, 4, inf_f80); |
| 394 | try test__powitf2(inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f128); | 400 | try test_powi_f80(inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f80); |
| 395 | try test__powitf2(inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f128); | 401 | try test_powi_f80(inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f80); |
| 396 | 402 | ||
| 397 | try test__powitf2(-inf_f128, 1, -inf_f128); | 403 | try test_powi_f80(-inf_f80, 1, -inf_f80); |
| 398 | try test__powitf2(-inf_f128, 2, inf_f128); | 404 | try test_powi_f80(-inf_f80, 2, inf_f80); |
| 399 | try test__powitf2(-inf_f128, 3, -inf_f128); | 405 | try test_powi_f80(-inf_f80, 3, -inf_f80); |
| 400 | try test__powitf2(-inf_f128, 4, inf_f128); | 406 | try test_powi_f80(-inf_f80, 4, inf_f80); |
| 401 | try test__powitf2(-inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f128); | 407 | try test_powi_f80(-inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f80); |
| 402 | try test__powitf2(-inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f128); | 408 | try test_powi_f80(-inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f80); |
| 403 | 409 | ||
| 404 | try test__powitf2(0, -1, inf_f128); | 410 | try test_powi_f80(0, -1, inf_f80); |
| 405 | try test__powitf2(0, -2, inf_f128); | 411 | try test_powi_f80(0, -2, inf_f80); |
| 406 | try test__powitf2(0, -3, inf_f128); | 412 | try test_powi_f80(0, -3, inf_f80); |
| 407 | try test__powitf2(0, -4, inf_f128); | 413 | try test_powi_f80(0, -4, inf_f80); |
| 408 | try test__powitf2(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f128); | 414 | try test_powi_f80(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f80); |
| 409 | try test__powitf2(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f128); | 415 | try test_powi_f80(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f80); |
| 410 | try test__powitf2(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f128); | 416 | try test_powi_f80(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f80); |
| 411 | 417 | ||
| 412 | try test__powitf2(-0.0, -1, -inf_f128); | 418 | try test_powi_f80(-0.0, -1, -inf_f80); |
| 413 | try test__powitf2(-0.0, -2, inf_f128); | 419 | try test_powi_f80(-0.0, -2, inf_f80); |
| 414 | try test__powitf2(-0.0, -3, -inf_f128); | 420 | try test_powi_f80(-0.0, -3, -inf_f80); |
| 415 | try test__powitf2(-0.0, -4, inf_f128); | 421 | try test_powi_f80(-0.0, -4, inf_f80); |
| 416 | try test__powitf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f128); | 422 | try test_powi_f80(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f80); |
| 417 | try test__powitf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f128); | 423 | try test_powi_f80(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f80); |
| 418 | try test__powitf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f128); | 424 | try test_powi_f80(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f80); |
| 419 | 425 | ||
| 420 | try test__powitf2(1, -1, 1); | 426 | try test_powi_f80(1, -1, 1); |
| 421 | try test__powitf2(1, -2, 1); | 427 | try test_powi_f80(1, -2, 1); |
| 422 | try test__powitf2(1, -3, 1); | 428 | try test_powi_f80(1, -3, 1); |
| 423 | try test__powitf2(1, -4, 1); | 429 | try test_powi_f80(1, -4, 1); |
| 424 | try test__powitf2(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1); | 430 | try test_powi_f80(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1); |
| 425 | try test__powitf2(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1); | 431 | try test_powi_f80(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1); |
| 426 | try test__powitf2(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1); | 432 | try test_powi_f80(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1); |
| 427 | 433 | ||
| 428 | try test__powitf2(inf_f128, -1, 0); | 434 | try test_powi_f80(inf_f80, -1, 0); |
| 429 | try test__powitf2(inf_f128, -2, 0); | 435 | try test_powi_f80(inf_f80, -2, 0); |
| 430 | try test__powitf2(inf_f128, -3, 0); | 436 | try test_powi_f80(inf_f80, -3, 0); |
| 431 | try test__powitf2(inf_f128, -4, 0); | 437 | try test_powi_f80(inf_f80, -4, 0); |
| 432 | try test__powitf2(inf_f128, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); | 438 | try test_powi_f80(inf_f80, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); |
| 433 | try test__powitf2(inf_f128, @as(i32, @bitCast(@as(u32, 0x80000001))), 0); | 439 | try test_powi_f80(inf_f80, @as(i32, @bitCast(@as(u32, 0x80000001))), 0); |
| 434 | try test__powitf2(inf_f128, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); | 440 | try test_powi_f80(inf_f80, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); |
| 435 | 441 | ||
| 436 | try test__powitf2(-inf_f128, -1, -0.0); | 442 | try test_powi_f80(-inf_f80, -1, -0.0); |
| 437 | try test__powitf2(-inf_f128, -2, 0); | 443 | try test_powi_f80(-inf_f80, -2, 0); |
| 438 | try test__powitf2(-inf_f128, -3, -0.0); | 444 | try test_powi_f80(-inf_f80, -3, -0.0); |
| 439 | try test__powitf2(-inf_f128, -4, 0); | 445 | try test_powi_f80(-inf_f80, -4, 0); |
| 440 | try test__powitf2(-inf_f128, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); | 446 | try test_powi_f80(-inf_f80, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); |
| 441 | try test__powitf2(-inf_f128, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0); | 447 | try test_powi_f80(-inf_f80, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0); |
| 442 | try test__powitf2(-inf_f128, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); | 448 | try test_powi_f80(-inf_f80, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); |
| 443 | 449 | ||
| 444 | try test__powitf2(2, 10, 1024.0); | 450 | try test_powi_f80(2, 10, 1024.0); |
| 445 | try test__powitf2(-2, 10, 1024.0); | 451 | try test_powi_f80(-2, 10, 1024.0); |
| 446 | try test__powitf2(2, -10, 1.0 / 1024.0); | 452 | try test_powi_f80(2, -10, 1.0 / 1024.0); |
| 447 | try test__powitf2(-2, -10, 1.0 / 1024.0); | 453 | try test_powi_f80(-2, -10, 1.0 / 1024.0); |
| 448 | 454 | ||
| 449 | try test__powitf2(2, 19, 524288.0); | 455 | try test_powi_f80(2, 19, 524288.0); |
| 450 | try test__powitf2(-2, 19, -524288.0); | 456 | try test_powi_f80(-2, 19, -524288.0); |
| 451 | try test__powitf2(2, -19, 1.0 / 524288.0); | 457 | try test_powi_f80(2, -19, 1.0 / 524288.0); |
| 452 | try test__powitf2(-2, -19, -1.0 / 524288.0); | 458 | try test_powi_f80(-2, -19, -1.0 / 524288.0); |
| 453 | 459 | ||
| 454 | try test__powitf2(2, 31, 2147483648.0); | 460 | try test_powi_f80(2, 31, 2147483648.0); |
| 455 | try test__powitf2(-2, 31, -2147483648.0); | 461 | try test_powi_f80(-2, 31, -2147483648.0); |
| 456 | try test__powitf2(2, -31, 1.0 / 2147483648.0); | 462 | try test_powi_f80(2, -31, 1.0 / 2147483648.0); |
| 457 | try test__powitf2(-2, -31, -1.0 / 2147483648.0); | 463 | try test_powi_f80(-2, -31, -1.0 / 2147483648.0); |
| 458 | } | 464 | } |
| 459 | 465 | ||
| 460 | test "powixf2" { | 466 | test powi_f128 { |
| 461 | const inf_f80 = math.inf(f80); | 467 | const inf_f128 = math.inf(f128); |
| 462 | try test__powixf2(0, 0, 1); | 468 | try test_powi_f128(0, 0, 1); |
| 463 | try test__powixf2(1, 0, 1); | 469 | try test_powi_f128(1, 0, 1); |
| 464 | try test__powixf2(1.5, 0, 1); | 470 | try test_powi_f128(1.5, 0, 1); |
| 465 | try test__powixf2(2, 0, 1); | 471 | try test_powi_f128(2, 0, 1); |
| 466 | try test__powixf2(inf_f80, 0, 1); | 472 | try test_powi_f128(inf_f128, 0, 1); |
| 467 | 473 | ||
| 468 | try test__powixf2(-0.0, 0, 1); | 474 | try test_powi_f128(-0.0, 0, 1); |
| 469 | try test__powixf2(-1, 0, 1); | 475 | try test_powi_f128(-1, 0, 1); |
| 470 | try test__powixf2(-1.5, 0, 1); | 476 | try test_powi_f128(-1.5, 0, 1); |
| 471 | try test__powixf2(-2, 0, 1); | 477 | try test_powi_f128(-2, 0, 1); |
| 472 | try test__powixf2(-inf_f80, 0, 1); | 478 | try test_powi_f128(-inf_f128, 0, 1); |
| 473 | 479 | ||
| 474 | try test__powixf2(0, 1, 0); | 480 | try test_powi_f128(0, 1, 0); |
| 475 | try test__powixf2(0, 2, 0); | 481 | try test_powi_f128(0, 2, 0); |
| 476 | try test__powixf2(0, 3, 0); | 482 | try test_powi_f128(0, 3, 0); |
| 477 | try test__powixf2(0, 4, 0); | 483 | try test_powi_f128(0, 4, 0); |
| 478 | try test__powixf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); | 484 | try test_powi_f128(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); |
| 479 | try test__powixf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0); | 485 | try test_powi_f128(0, 0x7FFFFFFF, 0); |
| 480 | 486 | ||
| 481 | try test__powixf2(-0.0, 1, -0.0); | 487 | try test_powi_f128(-0.0, 1, -0.0); |
| 482 | try test__powixf2(-0.0, 2, 0); | 488 | try test_powi_f128(-0.0, 2, 0); |
| 483 | try test__powixf2(-0.0, 3, -0.0); | 489 | try test_powi_f128(-0.0, 3, -0.0); |
| 484 | try test__powixf2(-0.0, 4, 0); | 490 | try test_powi_f128(-0.0, 4, 0); |
| 485 | try test__powixf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); | 491 | try test_powi_f128(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); |
| 486 | try test__powixf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0); | 492 | try test_powi_f128(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0); |
| 487 | 493 | ||
| 488 | try test__powixf2(1, 1, 1); | 494 | try test_powi_f128(1, 1, 1); |
| 489 | try test__powixf2(1, 2, 1); | 495 | try test_powi_f128(1, 2, 1); |
| 490 | try test__powixf2(1, 3, 1); | 496 | try test_powi_f128(1, 3, 1); |
| 491 | try test__powixf2(1, 4, 1); | 497 | try test_powi_f128(1, 4, 1); |
| 492 | try test__powixf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1); | 498 | try test_powi_f128(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1); |
| 493 | try test__powixf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1); | 499 | try test_powi_f128(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1); |
| 494 | 500 | ||
| 495 | try test__powixf2(inf_f80, 1, inf_f80); | 501 | try test_powi_f128(inf_f128, 1, inf_f128); |
| 496 | try test__powixf2(inf_f80, 2, inf_f80); | 502 | try test_powi_f128(inf_f128, 2, inf_f128); |
| 497 | try test__powixf2(inf_f80, 3, inf_f80); | 503 | try test_powi_f128(inf_f128, 3, inf_f128); |
| 498 | try test__powixf2(inf_f80, 4, inf_f80); | 504 | try test_powi_f128(inf_f128, 4, inf_f128); |
| 499 | try test__powixf2(inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f80); | 505 | try test_powi_f128(inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f128); |
| 500 | try test__powixf2(inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f80); | 506 | try test_powi_f128(inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f128); |
| 501 | 507 | ||
| 502 | try test__powixf2(-inf_f80, 1, -inf_f80); | 508 | try test_powi_f128(-inf_f128, 1, -inf_f128); |
| 503 | try test__powixf2(-inf_f80, 2, inf_f80); | 509 | try test_powi_f128(-inf_f128, 2, inf_f128); |
| 504 | try test__powixf2(-inf_f80, 3, -inf_f80); | 510 | try test_powi_f128(-inf_f128, 3, -inf_f128); |
| 505 | try test__powixf2(-inf_f80, 4, inf_f80); | 511 | try test_powi_f128(-inf_f128, 4, inf_f128); |
| 506 | try test__powixf2(-inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f80); | 512 | try test_powi_f128(-inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f128); |
| 507 | try test__powixf2(-inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f80); | 513 | try test_powi_f128(-inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f128); |
| 508 | 514 | ||
| 509 | try test__powixf2(0, -1, inf_f80); | 515 | try test_powi_f128(0, -1, inf_f128); |
| 510 | try test__powixf2(0, -2, inf_f80); | 516 | try test_powi_f128(0, -2, inf_f128); |
| 511 | try test__powixf2(0, -3, inf_f80); | 517 | try test_powi_f128(0, -3, inf_f128); |
| 512 | try test__powixf2(0, -4, inf_f80); | 518 | try test_powi_f128(0, -4, inf_f128); |
| 513 | try test__powixf2(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f80); | 519 | try test_powi_f128(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f128); |
| 514 | try test__powixf2(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f80); | 520 | try test_powi_f128(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f128); |
| 515 | try test__powixf2(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f80); | 521 | try test_powi_f128(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f128); |
| 516 | 522 | ||
| 517 | try test__powixf2(-0.0, -1, -inf_f80); | 523 | try test_powi_f128(-0.0, -1, -inf_f128); |
| 518 | try test__powixf2(-0.0, -2, inf_f80); | 524 | try test_powi_f128(-0.0, -2, inf_f128); |
| 519 | try test__powixf2(-0.0, -3, -inf_f80); | 525 | try test_powi_f128(-0.0, -3, -inf_f128); |
| 520 | try test__powixf2(-0.0, -4, inf_f80); | 526 | try test_powi_f128(-0.0, -4, inf_f128); |
| 521 | try test__powixf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f80); | 527 | try test_powi_f128(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f128); |
| 522 | try test__powixf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f80); | 528 | try test_powi_f128(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f128); |
| 523 | try test__powixf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f80); | 529 | try test_powi_f128(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f128); |
| 524 | 530 | ||
| 525 | try test__powixf2(1, -1, 1); | 531 | try test_powi_f128(1, -1, 1); |
| 526 | try test__powixf2(1, -2, 1); | 532 | try test_powi_f128(1, -2, 1); |
| 527 | try test__powixf2(1, -3, 1); | 533 | try test_powi_f128(1, -3, 1); |
| 528 | try test__powixf2(1, -4, 1); | 534 | try test_powi_f128(1, -4, 1); |
| 529 | try test__powixf2(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1); | 535 | try test_powi_f128(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1); |
| 530 | try test__powixf2(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1); | 536 | try test_powi_f128(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1); |
| 531 | try test__powixf2(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1); | 537 | try test_powi_f128(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1); |
| 532 | 538 | ||
| 533 | try test__powixf2(inf_f80, -1, 0); | 539 | try test_powi_f128(inf_f128, -1, 0); |
| 534 | try test__powixf2(inf_f80, -2, 0); | 540 | try test_powi_f128(inf_f128, -2, 0); |
| 535 | try test__powixf2(inf_f80, -3, 0); | 541 | try test_powi_f128(inf_f128, -3, 0); |
| 536 | try test__powixf2(inf_f80, -4, 0); | 542 | try test_powi_f128(inf_f128, -4, 0); |
| 537 | try test__powixf2(inf_f80, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); | 543 | try test_powi_f128(inf_f128, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); |
| 538 | try test__powixf2(inf_f80, @as(i32, @bitCast(@as(u32, 0x80000001))), 0); | 544 | try test_powi_f128(inf_f128, @as(i32, @bitCast(@as(u32, 0x80000001))), 0); |
| 539 | try test__powixf2(inf_f80, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); | 545 | try test_powi_f128(inf_f128, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); |
| 540 | 546 | ||
| 541 | try test__powixf2(-inf_f80, -1, -0.0); | 547 | try test_powi_f128(-inf_f128, -1, -0.0); |
| 542 | try test__powixf2(-inf_f80, -2, 0); | 548 | try test_powi_f128(-inf_f128, -2, 0); |
| 543 | try test__powixf2(-inf_f80, -3, -0.0); | 549 | try test_powi_f128(-inf_f128, -3, -0.0); |
| 544 | try test__powixf2(-inf_f80, -4, 0); | 550 | try test_powi_f128(-inf_f128, -4, 0); |
| 545 | try test__powixf2(-inf_f80, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); | 551 | try test_powi_f128(-inf_f128, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); |
| 546 | try test__powixf2(-inf_f80, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0); | 552 | try test_powi_f128(-inf_f128, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0); |
| 547 | try test__powixf2(-inf_f80, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); | 553 | try test_powi_f128(-inf_f128, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); |
| 548 | 554 | ||
| 549 | try test__powixf2(2, 10, 1024.0); | 555 | try test_powi_f128(2, 10, 1024.0); |
| 550 | try test__powixf2(-2, 10, 1024.0); | 556 | try test_powi_f128(-2, 10, 1024.0); |
| 551 | try test__powixf2(2, -10, 1.0 / 1024.0); | 557 | try test_powi_f128(2, -10, 1.0 / 1024.0); |
| 552 | try test__powixf2(-2, -10, 1.0 / 1024.0); | 558 | try test_powi_f128(-2, -10, 1.0 / 1024.0); |
| 553 | 559 | ||
| 554 | try test__powixf2(2, 19, 524288.0); | 560 | try test_powi_f128(2, 19, 524288.0); |
| 555 | try test__powixf2(-2, 19, -524288.0); | 561 | try test_powi_f128(-2, 19, -524288.0); |
| 556 | try test__powixf2(2, -19, 1.0 / 524288.0); | 562 | try test_powi_f128(2, -19, 1.0 / 524288.0); |
| 557 | try test__powixf2(-2, -19, -1.0 / 524288.0); | 563 | try test_powi_f128(-2, -19, -1.0 / 524288.0); |
| 558 | 564 | ||
| 559 | try test__powixf2(2, 31, 2147483648.0); | 565 | try test_powi_f128(2, 31, 2147483648.0); |
| 560 | try test__powixf2(-2, 31, -2147483648.0); | 566 | try test_powi_f128(-2, 31, -2147483648.0); |
| 561 | try test__powixf2(2, -31, 1.0 / 2147483648.0); | 567 | try test_powi_f128(2, -31, 1.0 / 2147483648.0); |
| 562 | try test__powixf2(-2, -31, -1.0 / 2147483648.0); | 568 | try test_powi_f128(-2, -31, -1.0 / 2147483648.0); |
| 563 | } | 569 | } |
lib/compiler_rt/round.zig+87-50| ... | @@ -18,19 +18,22 @@ comptime { | ... | @@ -18,19 +18,22 @@ comptime { |
| 18 | symbol(&roundf, "roundf"); | 18 | symbol(&roundf, "roundf"); |
| 19 | symbol(&round, "round"); | 19 | symbol(&round, "round"); |
| 20 | symbol(&__roundx, "__roundx"); | 20 | symbol(&__roundx, "__roundx"); |
| 21 | if (compiler_rt.want_ppc_abi) { | 21 | symbol(&roundq, "roundf128"); |
| 22 | symbol(&roundq, "roundf128"); | ||
| 23 | } | ||
| 24 | symbol(&roundq, "roundq"); | ||
| 25 | symbol(&roundl, "roundl"); | 22 | symbol(&roundl, "roundl"); |
| 26 | } | 23 | } |
| 27 | 24 | ||
| 28 | pub fn __roundh(x: f16) callconv(.c) f16 { | 25 | fn __roundh(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { |
| 26 | return compiler_rt.f16.toAbi(round_f16(compiler_rt.f16.fromAbi(x))); | ||
| 27 | } | ||
| 28 | pub fn round_f16(x: f16) f16 { | ||
| 29 | // TODO: more efficient implementation | 29 | // TODO: more efficient implementation |
| 30 | return @floatCast(roundf(x)); | 30 | return @floatCast(round_f32(x)); |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | pub fn roundf(x_: f32) callconv(.c) f32 { | 33 | fn roundf(x: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { |
| 34 | return compiler_rt.f32.toAbi(round_f32(compiler_rt.f32.fromAbi(x))); | ||
| 35 | } | ||
| 36 | pub fn round_f32(x_: f32) f32 { | ||
| 34 | const f32_toint = 1.0 / math.floatEps(f32); | 37 | const f32_toint = 1.0 / math.floatEps(f32); |
| 35 | 38 | ||
| 36 | var x = x_; | 39 | var x = x_; |
| ... | @@ -65,7 +68,10 @@ pub fn roundf(x_: f32) callconv(.c) f32 { | ... | @@ -65,7 +68,10 @@ pub fn roundf(x_: f32) callconv(.c) f32 { |
| 65 | } | 68 | } |
| 66 | } | 69 | } |
| 67 | 70 | ||
| 68 | pub fn round(x_: f64) callconv(.c) f64 { | 71 | fn round(x: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { |
| 72 | return compiler_rt.f64.toAbi(round_f64(compiler_rt.f64.fromAbi(x))); | ||
| 73 | } | ||
| 74 | pub fn round_f64(x_: f64) f64 { | ||
| 69 | const f64_toint = 1.0 / math.floatEps(f64); | 75 | const f64_toint = 1.0 / math.floatEps(f64); |
| 70 | 76 | ||
| 71 | var x = x_; | 77 | var x = x_; |
| ... | @@ -100,12 +106,18 @@ pub fn round(x_: f64) callconv(.c) f64 { | ... | @@ -100,12 +106,18 @@ pub fn round(x_: f64) callconv(.c) f64 { |
| 100 | } | 106 | } |
| 101 | } | 107 | } |
| 102 | 108 | ||
| 103 | pub fn __roundx(x: f80) callconv(.c) f80 { | 109 | fn __roundx(x: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { |
| 110 | return compiler_rt.f80.toAbi(round_f80(compiler_rt.f80.fromAbi(x))); | ||
| 111 | } | ||
| 112 | pub fn round_f80(x: f80) f80 { | ||
| 104 | // TODO: more efficient implementation | 113 | // TODO: more efficient implementation |
| 105 | return @floatCast(roundq(x)); | 114 | return @floatCast(round_f128(x)); |
| 106 | } | 115 | } |
| 107 | 116 | ||
| 108 | pub fn roundq(x_: f128) callconv(.c) f128 { | 117 | fn roundq(x: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { |
| 118 | return compiler_rt.f128.toAbi(round_f128(compiler_rt.f128.fromAbi(x))); | ||
| 119 | } | ||
| 120 | pub fn round_f128(x_: f128) f128 { | ||
| 109 | const f128_toint = 1.0 / math.floatEps(f128); | 121 | const f128_toint = 1.0 / math.floatEps(f128); |
| 110 | 122 | ||
| 111 | var x = x_; | 123 | var x = x_; |
| ... | @@ -142,54 +154,79 @@ pub fn roundq(x_: f128) callconv(.c) f128 { | ... | @@ -142,54 +154,79 @@ pub fn roundq(x_: f128) callconv(.c) f128 { |
| 142 | 154 | ||
| 143 | pub fn roundl(x: c_longdouble) callconv(.c) c_longdouble { | 155 | pub fn roundl(x: c_longdouble) callconv(.c) c_longdouble { |
| 144 | switch (@typeInfo(c_longdouble).float.bits) { | 156 | switch (@typeInfo(c_longdouble).float.bits) { |
| 145 | 64 => return round(x), | 157 | 64 => return round_f64(x), |
| 146 | 80 => return __roundx(x), | 158 | 80 => return round_f80(x), |
| 147 | 128 => return roundq(x), | 159 | 128 => return round_f128(x), |
| 148 | else => @compileError("unreachable"), | 160 | else => comptime unreachable, |
| 149 | } | 161 | } |
| 150 | } | 162 | } |
| 151 | 163 | ||
| 152 | test "round32" { | 164 | test round_f16 { |
| 153 | try expect(roundf(1.3) == 1.0); | 165 | try expect(round_f16(1.3) == 1.0); |
| 154 | try expect(roundf(-1.3) == -1.0); | 166 | try expect(round_f16(-1.3) == -1.0); |
| 155 | try expect(roundf(0.2) == 0.0); | 167 | try expect(round_f16(1.8) == 2.0); |
| 156 | try expect(roundf(1.8) == 2.0); | 168 | try expect(round_f16(-1.8) == -2.0); |
| 157 | } | 169 | try expect(math.isPositiveZero(round_f16(0.2))); |
| 158 | 170 | try expect(math.isNegativeZero(round_f16(-0.2))); | |
| 159 | test "round64" { | 171 | try expect(math.isPositiveZero(round_f16(0.0))); |
| 160 | try expect(round(1.3) == 1.0); | 172 | try expect(math.isNegativeZero(round_f16(-0.0))); |
| 161 | try expect(round(-1.3) == -1.0); | 173 | try expect(math.isPositiveInf(round_f16(math.inf(f32)))); |
| 162 | try expect(round(0.2) == 0.0); | 174 | try expect(math.isNegativeInf(round_f16(-math.inf(f32)))); |
| 163 | try expect(round(1.8) == 2.0); | 175 | try expect(math.isNan(round_f16(math.nan(f32)))); |
| 164 | } | 176 | } |
| 165 | 177 | ||
| 166 | test "round128" { | 178 | test round_f32 { |
| 167 | try expect(roundq(1.3) == 1.0); | 179 | try expect(round_f32(1.3) == 1.0); |
| 168 | try expect(roundq(-1.3) == -1.0); | 180 | try expect(round_f32(-1.3) == -1.0); |
| 169 | try expect(roundq(0.2) == 0.0); | 181 | try expect(round_f32(1.8) == 2.0); |
| 170 | try expect(roundq(1.8) == 2.0); | 182 | try expect(round_f32(-1.8) == -2.0); |
| 183 | try expect(math.isPositiveZero(round_f32(0.2))); | ||
| 184 | try expect(math.isNegativeZero(round_f32(-0.2))); | ||
| 185 | try expect(math.isPositiveZero(round_f32(0.0))); | ||
| 186 | try expect(math.isNegativeZero(round_f32(-0.0))); | ||
| 187 | try expect(math.isPositiveInf(round_f32(math.inf(f32)))); | ||
| 188 | try expect(math.isNegativeInf(round_f32(-math.inf(f32)))); | ||
| 189 | try expect(math.isNan(round_f32(math.nan(f32)))); | ||
| 171 | } | 190 | } |
| 172 | 191 | ||
| 173 | test "round32.special" { | 192 | test round_f64 { |
| 174 | try expect(roundf(0.0) == 0.0); | 193 | try expect(round_f64(1.3) == 1.0); |
| 175 | try expect(roundf(-0.0) == -0.0); | 194 | try expect(round_f64(-1.3) == -1.0); |
| 176 | try expect(math.isPositiveInf(roundf(math.inf(f32)))); | 195 | try expect(round_f64(1.8) == 2.0); |
| 177 | try expect(math.isNegativeInf(roundf(-math.inf(f32)))); | 196 | try expect(round_f64(-1.8) == -2.0); |
| 178 | try expect(math.isNan(roundf(math.nan(f32)))); | 197 | try expect(math.isPositiveZero(round_f64(0.2))); |
| 198 | try expect(math.isNegativeZero(round_f64(-0.2))); | ||
| 199 | try expect(math.isPositiveZero(round_f64(0.0))); | ||
| 200 | try expect(math.isNegativeZero(round_f64(-0.0))); | ||
| 201 | try expect(math.isPositiveInf(round_f64(math.inf(f64)))); | ||
| 202 | try expect(math.isNegativeInf(round_f64(-math.inf(f64)))); | ||
| 203 | try expect(math.isNan(round_f64(math.nan(f64)))); | ||
| 179 | } | 204 | } |
| 180 | 205 | ||
| 181 | test "round64.special" { | 206 | test round_f80 { |
| 182 | try expect(round(0.0) == 0.0); | 207 | try expect(round_f80(1.3) == 1.0); |
| 183 | try expect(round(-0.0) == -0.0); | 208 | try expect(round_f80(-1.3) == -1.0); |
| 184 | try expect(math.isPositiveInf(round(math.inf(f64)))); | 209 | try expect(round_f80(1.8) == 2.0); |
| 185 | try expect(math.isNegativeInf(round(-math.inf(f64)))); | 210 | try expect(round_f80(-1.8) == -2.0); |
| 186 | try expect(math.isNan(round(math.nan(f64)))); | 211 | try expect(math.isPositiveZero(round_f80(0.2))); |
| 212 | try expect(math.isNegativeZero(round_f80(-0.2))); | ||
| 213 | try expect(math.isPositiveZero(round_f80(0.0))); | ||
| 214 | try expect(math.isNegativeZero(round_f80(-0.0))); | ||
| 215 | try expect(math.isPositiveInf(round_f80(math.inf(f64)))); | ||
| 216 | try expect(math.isNegativeInf(round_f80(-math.inf(f64)))); | ||
| 217 | try expect(math.isNan(round_f80(math.nan(f64)))); | ||
| 187 | } | 218 | } |
| 188 | 219 | ||
| 189 | test "round128.special" { | 220 | test round_f128 { |
| 190 | try expect(roundq(0.0) == 0.0); | 221 | try expect(round_f128(1.3) == 1.0); |
| 191 | try expect(roundq(-0.0) == -0.0); | 222 | try expect(round_f128(-1.3) == -1.0); |
| 192 | try expect(math.isPositiveInf(roundq(math.inf(f128)))); | 223 | try expect(round_f128(1.8) == 2.0); |
| 193 | try expect(math.isNegativeInf(roundq(-math.inf(f128)))); | 224 | try expect(round_f128(-1.8) == -2.0); |
| 194 | try expect(math.isNan(roundq(math.nan(f128)))); | 225 | try expect(math.isPositiveZero(round_f128(0.2))); |
| 226 | try expect(math.isNegativeZero(round_f128(-0.2))); | ||
| 227 | try expect(math.isPositiveZero(round_f128(0.0))); | ||
| 228 | try expect(math.isNegativeZero(round_f128(-0.0))); | ||
| 229 | try expect(math.isPositiveInf(round_f128(math.inf(f128)))); | ||
| 230 | try expect(math.isNegativeInf(round_f128(-math.inf(f128)))); | ||
| 231 | try expect(math.isNan(round_f128(math.nan(f128)))); | ||
| 195 | } | 232 | } |
lib/compiler_rt/sin.zig+66-53| ... | @@ -13,31 +13,34 @@ const expect = std.testing.expect; | ... | @@ -13,31 +13,34 @@ const expect = std.testing.expect; |
| 13 | const expectApproxEqAbs = std.testing.expectApproxEqAbs; | 13 | const expectApproxEqAbs = std.testing.expectApproxEqAbs; |
| 14 | 14 | ||
| 15 | const compiler_rt = @import("../compiler_rt.zig"); | 15 | const compiler_rt = @import("../compiler_rt.zig"); |
| 16 | const symbol = @import("../compiler_rt.zig").symbol; | 16 | const symbol = compiler_rt.symbol; |
| 17 | const trig = @import("trig.zig"); | 17 | const trig = @import("trig.zig"); |
| 18 | const rem_pio2 = @import("rem_pio2.zig").rem_pio2; | 18 | const rem_pio2 = @import("rem_pio2.zig").rem_pio2; |
| 19 | const rem_pio2f = @import("rem_pio2f.zig").rem_pio2f; | 19 | const rem_pio2f = @import("rem_pio2f.zig").rem_pio2f; |
| 20 | const rem_pio2l = @import("rem_pio2l.zig").rem_pio2l; | 20 | const rem_pio2l = @import("rem_pio2l.zig").rem_pio2l; |
| 21 | 21 | ||
| 22 | comptime { | 22 | comptime { |
| 23 | symbol(&sinh, "__sinh"); | 23 | symbol(&__sinh, "__sinh"); |
| 24 | symbol(&sinl, "__sinl"); | ||
| 25 | symbol(&sinf, "sinf"); | 24 | symbol(&sinf, "sinf"); |
| 26 | symbol(&sin, "sin"); | 25 | symbol(&sin, "sin"); |
| 27 | symbol(&sinx, "__sinx"); | 26 | symbol(&__sinx, "__sinx"); |
| 28 | if (compiler_rt.want_ppc_abi) { | 27 | symbol(&sinq, "sinf128"); |
| 29 | symbol(&sinq, "sinf128"); | ||
| 30 | } | ||
| 31 | symbol(&sinq, "sinq"); | ||
| 32 | symbol(&sinl, "sinl"); | 28 | symbol(&sinl, "sinl"); |
| 29 | symbol(&sinl, "__sinl"); // required by musl | ||
| 33 | } | 30 | } |
| 34 | 31 | ||
| 35 | pub fn sinh(x: f16) callconv(.c) f16 { | 32 | fn __sinh(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { |
| 33 | return compiler_rt.f16.toAbi(sin_f16(compiler_rt.f16.fromAbi(x))); | ||
| 34 | } | ||
| 35 | pub fn sin_f16(x: f16) f16 { | ||
| 36 | // TODO: more efficient implementation | 36 | // TODO: more efficient implementation |
| 37 | return @floatCast(sinf(x)); | 37 | return @floatCast(sin_f32(x)); |
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | pub fn sinf(x: f32) callconv(.c) f32 { | 40 | fn sinf(x: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { |
| 41 | return compiler_rt.f32.toAbi(sin_f32(compiler_rt.f32.fromAbi(x))); | ||
| 42 | } | ||
| 43 | pub fn sin_f32(x: f32) f32 { | ||
| 41 | // Small multiples of pi/2 rounded to double precision. | 44 | // Small multiples of pi/2 rounded to double precision. |
| 42 | const s1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D18 | 45 | const s1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D18 |
| 43 | const s2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D18 | 46 | const s2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D18 |
| ... | @@ -98,7 +101,10 @@ pub fn sinf(x: f32) callconv(.c) f32 { | ... | @@ -98,7 +101,10 @@ pub fn sinf(x: f32) callconv(.c) f32 { |
| 98 | }; | 101 | }; |
| 99 | } | 102 | } |
| 100 | 103 | ||
| 101 | pub fn sin(x: f64) callconv(.c) f64 { | 104 | fn sin(x: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { |
| 105 | return compiler_rt.f64.toAbi(sin_f64(compiler_rt.f64.fromAbi(x))); | ||
| 106 | } | ||
| 107 | pub fn sin_f64(x: f64) f64 { | ||
| 102 | var ix = @as(u64, @bitCast(x)) >> 32; | 108 | var ix = @as(u64, @bitCast(x)) >> 32; |
| 103 | ix &= 0x7fffffff; | 109 | ix &= 0x7fffffff; |
| 104 | 110 | ||
| ... | @@ -133,7 +139,10 @@ pub fn sin(x: f64) callconv(.c) f64 { | ... | @@ -133,7 +139,10 @@ pub fn sin(x: f64) callconv(.c) f64 { |
| 133 | }; | 139 | }; |
| 134 | } | 140 | } |
| 135 | 141 | ||
| 136 | fn sinx(x: f80) callconv(.c) f80 { | 142 | fn __sinx(x: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { |
| 143 | return compiler_rt.f80.toAbi(sin_f80(compiler_rt.f80.fromAbi(x))); | ||
| 144 | } | ||
| 145 | pub fn sin_f80(x: f80) f80 { | ||
| 137 | const se = ld.signExponent(x) & 0x7fff; | 146 | const se = ld.signExponent(x) & 0x7fff; |
| 138 | if (se == 0x7fff) { | 147 | if (se == 0x7fff) { |
| 139 | return x - x; | 148 | return x - x; |
| ... | @@ -160,7 +169,10 @@ fn sinx(x: f80) callconv(.c) f80 { | ... | @@ -160,7 +169,10 @@ fn sinx(x: f80) callconv(.c) f80 { |
| 160 | }; | 169 | }; |
| 161 | } | 170 | } |
| 162 | 171 | ||
| 163 | pub fn sinq(x: f128) callconv(.c) f128 { | 172 | fn sinq(x: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { |
| 173 | return compiler_rt.f128.toAbi(sin_f128(compiler_rt.f128.fromAbi(x))); | ||
| 174 | } | ||
| 175 | pub fn sin_f128(x: f128) f128 { | ||
| 164 | const se = ld.signExponent(x) & 0x7fff; | 176 | const se = ld.signExponent(x) & 0x7fff; |
| 165 | if (se == 0x7fff) { | 177 | if (se == 0x7fff) { |
| 166 | return x - x; | 178 | return x - x; |
| ... | @@ -189,20 +201,21 @@ pub fn sinq(x: f128) callconv(.c) f128 { | ... | @@ -189,20 +201,21 @@ pub fn sinq(x: f128) callconv(.c) f128 { |
| 189 | 201 | ||
| 190 | pub fn sinl(x: c_longdouble) callconv(.c) c_longdouble { | 202 | pub fn sinl(x: c_longdouble) callconv(.c) c_longdouble { |
| 191 | switch (@typeInfo(c_longdouble).float.bits) { | 203 | switch (@typeInfo(c_longdouble).float.bits) { |
| 192 | 64 => return sin(x), | 204 | 64 => return sin_f64(x), |
| 193 | 80 => return sinx(x), | 205 | 80 => return sin_f80(x), |
| 194 | 128 => return sinq(x), | 206 | 128 => return sin_f128(x), |
| 195 | else => @compileError("unreachable"), | 207 | else => comptime unreachable, |
| 196 | } | 208 | } |
| 197 | } | 209 | } |
| 198 | 210 | ||
| 199 | fn testSinSpecial(comptime T: type) !void { | 211 | fn testSinSpecial(comptime T: type) !void { |
| 200 | const f = switch (T) { | 212 | const f = switch (T) { |
| 201 | f32 => sinf, | 213 | f16 => sin_f16, |
| 202 | f64 => sin, | 214 | f32 => sin_f32, |
| 203 | f80 => sinx, | 215 | f64 => sin_f64, |
| 204 | f128 => sinq, | 216 | f80 => sin_f80, |
| 205 | else => @compileError("unimplemented"), | 217 | f128 => sin_f128, |
| 218 | else => comptime unreachable, | ||
| 206 | }; | 219 | }; |
| 207 | 220 | ||
| 208 | try expect(math.isPositiveZero(f(0.0))); | 221 | try expect(math.isPositiveZero(f(0.0))); |
| ... | @@ -214,13 +227,13 @@ fn testSinSpecial(comptime T: type) !void { | ... | @@ -214,13 +227,13 @@ fn testSinSpecial(comptime T: type) !void { |
| 214 | 227 | ||
| 215 | test "sin32.normal" { | 228 | test "sin32.normal" { |
| 216 | const epsilon = math.floatEps(f32); | 229 | const epsilon = math.floatEps(f32); |
| 217 | try expectApproxEqAbs(@as(f32, 0.0), sinf(0.0), epsilon); | 230 | try expectApproxEqAbs(@as(f32, 0.0), sin_f32(0.0), epsilon); |
| 218 | try expectApproxEqAbs(@as(f32, 0.19866933), sinf(0.2), epsilon); | 231 | try expectApproxEqAbs(@as(f32, 0.19866933), sin_f32(0.2), epsilon); |
| 219 | try expectApproxEqAbs(@as(f32, 0.77851737), sinf(0.8923), epsilon); | 232 | try expectApproxEqAbs(@as(f32, 0.77851737), sin_f32(0.8923), epsilon); |
| 220 | try expectApproxEqAbs(@as(f32, 0.997495), sinf(1.5), epsilon); | 233 | try expectApproxEqAbs(@as(f32, 0.997495), sin_f32(1.5), epsilon); |
| 221 | try expectApproxEqAbs(@as(f32, -0.997495), sinf(-1.5), epsilon); | 234 | try expectApproxEqAbs(@as(f32, -0.997495), sin_f32(-1.5), epsilon); |
| 222 | try expectApproxEqAbs(@as(f32, -0.24654257), sinf(37.45), epsilon); | 235 | try expectApproxEqAbs(@as(f32, -0.24654257), sin_f32(37.45), epsilon); |
| 223 | try expectApproxEqAbs(@as(f32, 0.9161657), sinf(89.123), epsilon); | 236 | try expectApproxEqAbs(@as(f32, 0.9161657), sin_f32(89.123), epsilon); |
| 224 | } | 237 | } |
| 225 | 238 | ||
| 226 | test "sin32.special" { | 239 | test "sin32.special" { |
| ... | @@ -229,13 +242,13 @@ test "sin32.special" { | ... | @@ -229,13 +242,13 @@ test "sin32.special" { |
| 229 | 242 | ||
| 230 | test "sin64.normal" { | 243 | test "sin64.normal" { |
| 231 | const epsilon = math.floatEps(f64); | 244 | const epsilon = math.floatEps(f64); |
| 232 | try expectApproxEqAbs(@as(f64, 0.0), sin(0.0), epsilon); | 245 | try expectApproxEqAbs(@as(f64, 0.0), sin_f64(0.0), epsilon); |
| 233 | try expectApproxEqAbs(@as(f64, 0.19866933079506122), sin(0.2), epsilon); | 246 | try expectApproxEqAbs(@as(f64, 0.19866933079506122), sin_f64(0.2), epsilon); |
| 234 | try expectApproxEqAbs(@as(f64, 0.7785173385577349), sin(0.8923), epsilon); | 247 | try expectApproxEqAbs(@as(f64, 0.7785173385577349), sin_f64(0.8923), epsilon); |
| 235 | try expectApproxEqAbs(@as(f64, 0.9974949866040544), sin(1.5), epsilon); | 248 | try expectApproxEqAbs(@as(f64, 0.9974949866040544), sin_f64(1.5), epsilon); |
| 236 | try expectApproxEqAbs(@as(f64, -0.9974949866040544), sin(-1.5), epsilon); | 249 | try expectApproxEqAbs(@as(f64, -0.9974949866040544), sin_f64(-1.5), epsilon); |
| 237 | try expectApproxEqAbs(@as(f64, -0.24654331551411082), sin(37.45), epsilon); | 250 | try expectApproxEqAbs(@as(f64, -0.24654331551411082), sin_f64(37.45), epsilon); |
| 238 | try expectApproxEqAbs(@as(f64, 0.9161652766622714), sin(89.123), epsilon); | 251 | try expectApproxEqAbs(@as(f64, 0.9161652766622714), sin_f64(89.123), epsilon); |
| 239 | } | 252 | } |
| 240 | 253 | ||
| 241 | test "sin64.special" { | 254 | test "sin64.special" { |
| ... | @@ -244,13 +257,13 @@ test "sin64.special" { | ... | @@ -244,13 +257,13 @@ test "sin64.special" { |
| 244 | 257 | ||
| 245 | test "sin80.normal" { | 258 | test "sin80.normal" { |
| 246 | const epsilon = math.floatEps(f80); | 259 | const epsilon = math.floatEps(f80); |
| 247 | try expectApproxEqAbs(@as(f80, 0.0), sinx(0.0), epsilon); | 260 | try expectApproxEqAbs(@as(f80, 0.0), sin_f80(0.0), epsilon); |
| 248 | try expectApproxEqAbs(@as(f80, 0.19866933079506121545941262711838975), sinx(0.2), epsilon); | 261 | try expectApproxEqAbs(@as(f80, 0.19866933079506121545941262711838975), sin_f80(0.2), epsilon); |
| 249 | try expectApproxEqAbs(@as(f80, 0.77851733855773487830689285621486050), sinx(0.8923), epsilon); | 262 | try expectApproxEqAbs(@as(f80, 0.77851733855773487830689285621486050), sin_f80(0.8923), epsilon); |
| 250 | try expectApproxEqAbs(@as(f80, 0.99749498660405443094172337114148732), sinx(1.5), epsilon); | 263 | try expectApproxEqAbs(@as(f80, 0.99749498660405443094172337114148732), sin_f80(1.5), epsilon); |
| 251 | try expectApproxEqAbs(@as(f80, -0.99749498660405443094172337114148732), sinx(-1.5), epsilon); | 264 | try expectApproxEqAbs(@as(f80, -0.99749498660405443094172337114148732), sin_f80(-1.5), epsilon); |
| 252 | try expectApproxEqAbs(@as(f80, -0.24654331551411356504), sinx(37.45), epsilon); | 265 | try expectApproxEqAbs(@as(f80, -0.24654331551411356504), sin_f80(37.45), epsilon); |
| 253 | try expectApproxEqAbs(@as(f80, 0.91616527666226951006), sinx(89.123), epsilon); | 266 | try expectApproxEqAbs(@as(f80, 0.91616527666226951006), sin_f80(89.123), epsilon); |
| 254 | } | 267 | } |
| 255 | 268 | ||
| 256 | test "sin80.special" { | 269 | test "sin80.special" { |
| ... | @@ -259,13 +272,13 @@ test "sin80.special" { | ... | @@ -259,13 +272,13 @@ test "sin80.special" { |
| 259 | 272 | ||
| 260 | test "sin128.normal" { | 273 | test "sin128.normal" { |
| 261 | const epsilon = math.floatEps(f128); | 274 | const epsilon = math.floatEps(f128); |
| 262 | try expectApproxEqAbs(@as(f128, 0.0), sinq(0.0), epsilon); | 275 | try expectApproxEqAbs(@as(f128, 0.0), sin_f128(0.0), epsilon); |
| 263 | try expectApproxEqAbs(@as(f128, 0.19866933079506121545941262711838975), sinq(0.2), epsilon); | 276 | try expectApproxEqAbs(@as(f128, 0.19866933079506121545941262711838975), sin_f128(0.2), epsilon); |
| 264 | try expectApproxEqAbs(@as(f128, 0.77851733855773487830689285621486050), sinq(0.8923), epsilon); | 277 | try expectApproxEqAbs(@as(f128, 0.77851733855773487830689285621486050), sin_f128(0.8923), epsilon); |
| 265 | try expectApproxEqAbs(@as(f128, 0.99749498660405443094172337114148732), sinq(1.5), epsilon); | 278 | try expectApproxEqAbs(@as(f128, 0.99749498660405443094172337114148732), sin_f128(1.5), epsilon); |
| 266 | try expectApproxEqAbs(@as(f128, -0.99749498660405443094172337114148732), sinq(-1.5), epsilon); | 279 | try expectApproxEqAbs(@as(f128, -0.99749498660405443094172337114148732), sin_f128(-1.5), epsilon); |
| 267 | try expectApproxEqAbs(@as(f128, -0.24654331551411356571238581321661085), sinq(37.45), epsilon); | 280 | try expectApproxEqAbs(@as(f128, -0.24654331551411356571238581321661085), sin_f128(37.45), epsilon); |
| 268 | try expectApproxEqAbs(@as(f128, 0.91616527666226951075019849560482170), sinq(89.123), epsilon); | 281 | try expectApproxEqAbs(@as(f128, 0.91616527666226951075019849560482170), sin_f128(89.123), epsilon); |
| 269 | } | 282 | } |
| 270 | 283 | ||
| 271 | test "sin128.special" { | 284 | test "sin128.special" { |
| ... | @@ -274,10 +287,10 @@ test "sin128.special" { | ... | @@ -274,10 +287,10 @@ test "sin128.special" { |
| 274 | 287 | ||
| 275 | test "sin32 #9901" { | 288 | test "sin32 #9901" { |
| 276 | const float: f32 = @bitCast(@as(u32, 0b11100011111111110000000000000000)); | 289 | const float: f32 = @bitCast(@as(u32, 0b11100011111111110000000000000000)); |
| 277 | _ = sinf(float); | 290 | _ = sin_f32(float); |
| 278 | } | 291 | } |
| 279 | 292 | ||
| 280 | test "sin64 #9901" { | 293 | test "sin64 #9901" { |
| 281 | const float: f64 = @bitCast(@as(u64, 0b1111111101000001000000001111110111111111100000000000000000000001)); | 294 | const float: f64 = @bitCast(@as(u64, 0b1111111101000001000000001111110111111111100000000000000000000001)); |
| 282 | _ = sin(float); | 295 | _ = sin_f64(float); |
| 283 | } | 296 | } |
lib/compiler_rt/sincos.zig+125-181| ... | @@ -18,23 +18,27 @@ comptime { | ... | @@ -18,23 +18,27 @@ comptime { |
| 18 | symbol(&sincosf, "sincosf"); | 18 | symbol(&sincosf, "sincosf"); |
| 19 | symbol(&sincos, "sincos"); | 19 | symbol(&sincos, "sincos"); |
| 20 | symbol(&sincosx, "__sincosx"); | 20 | symbol(&sincosx, "__sincosx"); |
| 21 | if (compiler_rt.want_ppc_abi) { | 21 | symbol(&sincosq, "sincosf128"); |
| 22 | symbol(&sincosq, "sincosf128"); | ||
| 23 | } | ||
| 24 | symbol(&sincosq, "sincosq"); | ||
| 25 | symbol(&sincosl, "sincosl"); | 22 | symbol(&sincosl, "sincosl"); |
| 26 | } | 23 | } |
| 27 | 24 | ||
| 28 | pub fn sincosh(x: f16, r_sin: *f16, r_cos: *f16) callconv(.c) void { | 25 | fn sincosh(x: compiler_rt.f16.Abi, r_sin: *compiler_rt.f16.Abi, r_cos: *compiler_rt.f16.Abi) callconv(.c) void { |
| 26 | const s, const c = sincos_f16(compiler_rt.f16.fromAbi(x)); | ||
| 27 | r_sin.* = compiler_rt.f16.toAbi(s); | ||
| 28 | r_cos.* = compiler_rt.f16.toAbi(c); | ||
| 29 | } | ||
| 30 | pub fn sincos_f16(x: f16) struct { f16, f16 } { | ||
| 29 | // TODO: more efficient implementation | 31 | // TODO: more efficient implementation |
| 30 | var big_sin: f32 = undefined; | 32 | const s, const c = sincos_f32(x); |
| 31 | var big_cos: f32 = undefined; | 33 | return .{ @floatCast(s), @floatCast(c) }; |
| 32 | sincosf(x, &big_sin, &big_cos); | ||
| 33 | r_sin.* = @as(f16, @floatCast(big_sin)); | ||
| 34 | r_cos.* = @as(f16, @floatCast(big_cos)); | ||
| 35 | } | 34 | } |
| 36 | 35 | ||
| 37 | pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void { | 36 | fn sincosf(x: compiler_rt.f32.Abi, r_sin: *compiler_rt.f32.Abi, r_cos: *compiler_rt.f32.Abi) callconv(.c) void { |
| 37 | const s, const c = sincos_f32(compiler_rt.f32.fromAbi(x)); | ||
| 38 | r_sin.* = compiler_rt.f32.toAbi(s); | ||
| 39 | r_cos.* = compiler_rt.f32.toAbi(c); | ||
| 40 | } | ||
| 41 | pub fn sincos_f32(x: f32) struct { f32, f32 } { | ||
| 38 | const sc1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D18 | 42 | const sc1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D18 |
| 39 | const sc2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D18 | 43 | const sc2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D18 |
| 40 | const sc3pio2: f64 = 3.0 * math.pi / 2.0; // 0x4012D97C, 0x7F3321D2 | 44 | const sc3pio2: f64 = 3.0 * math.pi / 2.0; // 0x4012D97C, 0x7F3321D2 |
| ... | @@ -56,13 +60,9 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void { | ... | @@ -56,13 +60,9 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void { |
| 56 | mem.doNotOptimizeAway(x + 0x1p120); | 60 | mem.doNotOptimizeAway(x + 0x1p120); |
| 57 | } | 61 | } |
| 58 | } | 62 | } |
| 59 | r_sin.* = x; | 63 | return .{ x, 1.0 }; |
| 60 | r_cos.* = 1.0; | ||
| 61 | return; | ||
| 62 | } | 64 | } |
| 63 | r_sin.* = trig.sindf(x); | 65 | return .{ trig.sindf(x), trig.cosdf(x) }; |
| 64 | r_cos.* = trig.cosdf(x); | ||
| 65 | return; | ||
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | // |x| ~<= 5*pi/4 | 68 | // |x| ~<= 5*pi/4 |
| ... | @@ -70,18 +70,16 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void { | ... | @@ -70,18 +70,16 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void { |
| 70 | // |x| ~<= 3pi/4 | 70 | // |x| ~<= 3pi/4 |
| 71 | if (ix <= 0x4016cbe3) { | 71 | if (ix <= 0x4016cbe3) { |
| 72 | if (sign) { | 72 | if (sign) { |
| 73 | r_sin.* = -trig.cosdf(x + sc1pio2); | 73 | return .{ -trig.cosdf(x + sc1pio2), trig.sindf(x + sc1pio2) }; |
| 74 | r_cos.* = trig.sindf(x + sc1pio2); | ||
| 75 | } else { | 74 | } else { |
| 76 | r_sin.* = trig.cosdf(sc1pio2 - x); | 75 | return .{ trig.cosdf(sc1pio2 - x), trig.sindf(sc1pio2 - x) }; |
| 77 | r_cos.* = trig.sindf(sc1pio2 - x); | ||
| 78 | } | 76 | } |
| 79 | return; | ||
| 80 | } | 77 | } |
| 81 | // -sin(x+c) is not correct if x+c could be 0: -0 vs +0 | 78 | // -sin(x+c) is not correct if x+c could be 0: -0 vs +0 |
| 82 | r_sin.* = -trig.sindf(if (sign) x + sc2pio2 else x - sc2pio2); | 79 | return .{ |
| 83 | r_cos.* = -trig.cosdf(if (sign) x + sc2pio2 else x - sc2pio2); | 80 | -trig.sindf(if (sign) x + sc2pio2 else x - sc2pio2), |
| 84 | return; | 81 | -trig.cosdf(if (sign) x + sc2pio2 else x - sc2pio2), |
| 82 | }; | ||
| 85 | } | 83 | } |
| 86 | 84 | ||
| 87 | // |x| ~<= 9*pi/4 | 85 | // |x| ~<= 9*pi/4 |
| ... | @@ -89,25 +87,21 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void { | ... | @@ -89,25 +87,21 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void { |
| 89 | // |x| ~<= 7*pi/4 | 87 | // |x| ~<= 7*pi/4 |
| 90 | if (ix <= 0x40afeddf) { | 88 | if (ix <= 0x40afeddf) { |
| 91 | if (sign) { | 89 | if (sign) { |
| 92 | r_sin.* = trig.cosdf(x + sc3pio2); | 90 | return .{ trig.cosdf(x + sc3pio2), -trig.sindf(x + sc3pio2) }; |
| 93 | r_cos.* = -trig.sindf(x + sc3pio2); | ||
| 94 | } else { | 91 | } else { |
| 95 | r_sin.* = -trig.cosdf(x - sc3pio2); | 92 | return .{ -trig.cosdf(x - sc3pio2), trig.sindf(x - sc3pio2) }; |
| 96 | r_cos.* = trig.sindf(x - sc3pio2); | ||
| 97 | } | 93 | } |
| 98 | return; | ||
| 99 | } | 94 | } |
| 100 | r_sin.* = trig.sindf(if (sign) x + sc4pio2 else x - sc4pio2); | 95 | return .{ |
| 101 | r_cos.* = trig.cosdf(if (sign) x + sc4pio2 else x - sc4pio2); | 96 | trig.sindf(if (sign) x + sc4pio2 else x - sc4pio2), |
| 102 | return; | 97 | trig.cosdf(if (sign) x + sc4pio2 else x - sc4pio2), |
| 98 | }; | ||
| 103 | } | 99 | } |
| 104 | 100 | ||
| 105 | // sin(Inf or NaN) is NaN | 101 | // sin(Inf or NaN) is NaN |
| 106 | if (ix >= 0x7f800000) { | 102 | if (ix >= 0x7f800000) { |
| 107 | const result = x - x; | 103 | const result = x - x; |
| 108 | r_sin.* = result; | 104 | return .{ result, result }; |
| 109 | r_cos.* = result; | ||
| 110 | return; | ||
| 111 | } | 105 | } |
| 112 | 106 | ||
| 113 | // general argument reduction needed | 107 | // general argument reduction needed |
| ... | @@ -115,27 +109,20 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void { | ... | @@ -115,27 +109,20 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void { |
| 115 | const n = rem_pio2f(x, &y); | 109 | const n = rem_pio2f(x, &y); |
| 116 | const s = trig.sindf(y); | 110 | const s = trig.sindf(y); |
| 117 | const c = trig.cosdf(y); | 111 | const c = trig.cosdf(y); |
| 118 | switch (n & 3) { | 112 | return switch (@as(u2, @truncate(@as(u32, @bitCast(n))))) { |
| 119 | 0 => { | 113 | 0 => .{ s, c }, |
| 120 | r_sin.* = s; | 114 | 1 => .{ c, -s }, |
| 121 | r_cos.* = c; | 115 | 2 => .{ -s, -c }, |
| 122 | }, | 116 | 3 => .{ -c, s }, |
| 123 | 1 => { | 117 | }; |
| 124 | r_sin.* = c; | ||
| 125 | r_cos.* = -s; | ||
| 126 | }, | ||
| 127 | 2 => { | ||
| 128 | r_sin.* = -s; | ||
| 129 | r_cos.* = -c; | ||
| 130 | }, | ||
| 131 | else => { | ||
| 132 | r_sin.* = -c; | ||
| 133 | r_cos.* = s; | ||
| 134 | }, | ||
| 135 | } | ||
| 136 | } | 118 | } |
| 137 | 119 | ||
| 138 | pub fn sincos(x: f64, r_sin: *f64, r_cos: *f64) callconv(.c) void { | 120 | fn sincos(x: compiler_rt.f64.Abi, r_sin: *compiler_rt.f64.Abi, r_cos: *compiler_rt.f64.Abi) callconv(.c) void { |
| 121 | const s, const c = sincos_f64(compiler_rt.f64.fromAbi(x)); | ||
| 122 | r_sin.* = compiler_rt.f64.toAbi(s); | ||
| 123 | r_cos.* = compiler_rt.f64.toAbi(c); | ||
| 124 | } | ||
| 125 | pub fn sincos_f64(x: f64) struct { f64, f64 } { | ||
| 139 | const ix = @as(u32, @truncate(@as(u64, @bitCast(x)) >> 32)) & 0x7fffffff; | 126 | const ix = @as(u32, @truncate(@as(u64, @bitCast(x)) >> 32)) & 0x7fffffff; |
| 140 | 127 | ||
| 141 | // |x| ~< pi/4 | 128 | // |x| ~< pi/4 |
| ... | @@ -150,21 +137,15 @@ pub fn sincos(x: f64, r_sin: *f64, r_cos: *f64) callconv(.c) void { | ... | @@ -150,21 +137,15 @@ pub fn sincos(x: f64, r_sin: *f64, r_cos: *f64) callconv(.c) void { |
| 150 | mem.doNotOptimizeAway(x + 0x1p120); | 137 | mem.doNotOptimizeAway(x + 0x1p120); |
| 151 | } | 138 | } |
| 152 | } | 139 | } |
| 153 | r_sin.* = x; | 140 | return .{ x, 1.0 }; |
| 154 | r_cos.* = 1.0; | ||
| 155 | return; | ||
| 156 | } | 141 | } |
| 157 | r_sin.* = trig.sin(x, 0.0, 0); | 142 | return .{ trig.sin(x, 0.0, 0), trig.cos(x, 0.0) }; |
| 158 | r_cos.* = trig.cos(x, 0.0); | ||
| 159 | return; | ||
| 160 | } | 143 | } |
| 161 | 144 | ||
| 162 | // sincos(Inf or NaN) is NaN | 145 | // sincos(Inf or NaN) is NaN |
| 163 | if (ix >= 0x7ff00000) { | 146 | if (ix >= 0x7ff00000) { |
| 164 | const result = x - x; | 147 | const result = x - x; |
| 165 | r_sin.* = result; | 148 | return .{ result, result }; |
| 166 | r_cos.* = result; | ||
| 167 | return; | ||
| 168 | } | 149 | } |
| 169 | 150 | ||
| 170 | // argument reduction needed | 151 | // argument reduction needed |
| ... | @@ -172,33 +153,24 @@ pub fn sincos(x: f64, r_sin: *f64, r_cos: *f64) callconv(.c) void { | ... | @@ -172,33 +153,24 @@ pub fn sincos(x: f64, r_sin: *f64, r_cos: *f64) callconv(.c) void { |
| 172 | const n = rem_pio2(x, &y); | 153 | const n = rem_pio2(x, &y); |
| 173 | const s = trig.sin(y[0], y[1], 1); | 154 | const s = trig.sin(y[0], y[1], 1); |
| 174 | const c = trig.cos(y[0], y[1]); | 155 | const c = trig.cos(y[0], y[1]); |
| 175 | switch (n & 3) { | 156 | return switch (@as(u2, @truncate(@as(u32, @bitCast(n))))) { |
| 176 | 0 => { | 157 | 0 => .{ s, c }, |
| 177 | r_sin.* = s; | 158 | 1 => .{ c, -s }, |
| 178 | r_cos.* = c; | 159 | 2 => .{ -s, -c }, |
| 179 | }, | 160 | 3 => .{ -c, s }, |
| 180 | 1 => { | 161 | }; |
| 181 | r_sin.* = c; | ||
| 182 | r_cos.* = -s; | ||
| 183 | }, | ||
| 184 | 2 => { | ||
| 185 | r_sin.* = -s; | ||
| 186 | r_cos.* = -c; | ||
| 187 | }, | ||
| 188 | else => { | ||
| 189 | r_sin.* = -c; | ||
| 190 | r_cos.* = s; | ||
| 191 | }, | ||
| 192 | } | ||
| 193 | } | 162 | } |
| 194 | 163 | ||
| 195 | pub fn sincosx(x: f80, r_sin: *f80, r_cos: *f80) callconv(.c) void { | 164 | fn sincosx(x: compiler_rt.f80.Abi, r_sin: *compiler_rt.f80.Abi, r_cos: *compiler_rt.f80.Abi) callconv(.c) void { |
| 165 | const s, const c = sincos_f80(compiler_rt.f80.fromAbi(x)); | ||
| 166 | r_sin.* = compiler_rt.f80.toAbi(s); | ||
| 167 | r_cos.* = compiler_rt.f80.toAbi(c); | ||
| 168 | } | ||
| 169 | pub fn sincos_f80(x: f80) struct { f80, f80 } { | ||
| 196 | const se = ld.signExponent(x) & 0x7fff; | 170 | const se = ld.signExponent(x) & 0x7fff; |
| 197 | if (se == 0x7fff) { | 171 | if (se == 0x7fff) { |
| 198 | const result = x - x; | 172 | const result = x - x; |
| 199 | r_sin.* = result; | 173 | return .{ result, result }; |
| 200 | r_cos.* = result; | ||
| 201 | return; | ||
| 202 | } | 174 | } |
| 203 | 175 | ||
| 204 | if (@abs(x) < trig.pi_4) { | 176 | if (@abs(x) < trig.pi_4) { |
| ... | @@ -207,47 +179,34 @@ pub fn sincosx(x: f80, r_sin: *f80, r_cos: *f80) callconv(.c) void { | ... | @@ -207,47 +179,34 @@ pub fn sincosx(x: f80, r_sin: *f80, r_cos: *f80) callconv(.c) void { |
| 207 | if (compiler_rt.want_float_exceptions and se == 0) { | 179 | if (compiler_rt.want_float_exceptions and se == 0) { |
| 208 | mem.doNotOptimizeAway(x * 0x1p-120); | 180 | mem.doNotOptimizeAway(x * 0x1p-120); |
| 209 | } | 181 | } |
| 210 | r_sin.* = x; | ||
| 211 | // raise inexact if x!=0 | 182 | // raise inexact if x!=0 |
| 212 | r_cos.* = 1.0 + x; | 183 | return .{ x, 1.0 + x }; |
| 213 | return; | ||
| 214 | } | 184 | } |
| 215 | r_sin.* = trig.sinx(x, 0.0, 0); | 185 | return .{ trig.sinx(x, 0.0, 0), trig.cosx(x, 0.0) }; |
| 216 | r_cos.* = trig.cosx(x, 0.0); | ||
| 217 | return; | ||
| 218 | } | 186 | } |
| 219 | 187 | ||
| 220 | var y: [2]f80 = undefined; | 188 | var y: [2]f80 = undefined; |
| 221 | const n = rem_pio2l(f80, x, &y); | 189 | const n = rem_pio2l(f80, x, &y); |
| 222 | const s = trig.sinx(y[0], y[1], 1); | 190 | const s = trig.sinx(y[0], y[1], 1); |
| 223 | const c = trig.cosx(y[0], y[1]); | 191 | const c = trig.cosx(y[0], y[1]); |
| 224 | switch (n & 3) { | 192 | return switch (@as(u2, @truncate(@as(u32, @bitCast(n))))) { |
| 225 | 0 => { | 193 | 0 => .{ s, c }, |
| 226 | r_sin.* = s; | 194 | 1 => .{ c, -s }, |
| 227 | r_cos.* = c; | 195 | 2 => .{ -s, -c }, |
| 228 | }, | 196 | 3 => .{ -c, s }, |
| 229 | 1 => { | 197 | }; |
| 230 | r_sin.* = c; | ||
| 231 | r_cos.* = -s; | ||
| 232 | }, | ||
| 233 | 2 => { | ||
| 234 | r_sin.* = -s; | ||
| 235 | r_cos.* = -c; | ||
| 236 | }, | ||
| 237 | else => { | ||
| 238 | r_sin.* = -c; | ||
| 239 | r_cos.* = s; | ||
| 240 | }, | ||
| 241 | } | ||
| 242 | } | 198 | } |
| 243 | 199 | ||
| 244 | pub fn sincosq(x: f128, r_sin: *f128, r_cos: *f128) callconv(.c) void { | 200 | fn sincosq(x: compiler_rt.f128.Abi, r_sin: *compiler_rt.f128.Abi, r_cos: *compiler_rt.f128.Abi) callconv(.c) void { |
| 201 | const s, const c = sincos_f128(compiler_rt.f128.fromAbi(x)); | ||
| 202 | r_sin.* = compiler_rt.f128.toAbi(s); | ||
| 203 | r_cos.* = compiler_rt.f128.toAbi(c); | ||
| 204 | } | ||
| 205 | pub fn sincos_f128(x: f128) struct { f128, f128 } { | ||
| 245 | const se = ld.signExponent(x) & 0x7fff; | 206 | const se = ld.signExponent(x) & 0x7fff; |
| 246 | if (se == 0x7fff) { | 207 | if (se == 0x7fff) { |
| 247 | const result = x - x; | 208 | const result = x - x; |
| 248 | r_sin.* = result; | 209 | return .{ result, result }; |
| 249 | r_cos.* = result; | ||
| 250 | return; | ||
| 251 | } | 210 | } |
| 252 | 211 | ||
| 253 | if (@abs(x) < trig.pi_4) { | 212 | if (@abs(x) < trig.pi_4) { |
| ... | @@ -256,78 +215,63 @@ pub fn sincosq(x: f128, r_sin: *f128, r_cos: *f128) callconv(.c) void { | ... | @@ -256,78 +215,63 @@ pub fn sincosq(x: f128, r_sin: *f128, r_cos: *f128) callconv(.c) void { |
| 256 | if (compiler_rt.want_float_exceptions and se == 0) { | 215 | if (compiler_rt.want_float_exceptions and se == 0) { |
| 257 | mem.doNotOptimizeAway(x * 0x1p-120); | 216 | mem.doNotOptimizeAway(x * 0x1p-120); |
| 258 | } | 217 | } |
| 259 | r_sin.* = x; | ||
| 260 | // raise inexact if x!=0 | 218 | // raise inexact if x!=0 |
| 261 | r_cos.* = 1.0 + x; | 219 | return .{ x, 1.0 + x }; |
| 262 | return; | ||
| 263 | } | 220 | } |
| 264 | r_sin.* = trig.sinq(x, 0.0, 0); | 221 | return .{ trig.sinq(x, 0.0, 0), trig.cosq(x, 0.0) }; |
| 265 | r_cos.* = trig.cosq(x, 0.0); | ||
| 266 | return; | ||
| 267 | } | 222 | } |
| 268 | 223 | ||
| 269 | var y: [2]f128 = undefined; | 224 | var y: [2]f128 = undefined; |
| 270 | const n = rem_pio2l(f128, x, &y); | 225 | const n = rem_pio2l(f128, x, &y); |
| 271 | const s = trig.sinq(y[0], y[1], 1); | 226 | const s = trig.sinq(y[0], y[1], 1); |
| 272 | const c = trig.cosq(y[0], y[1]); | 227 | const c = trig.cosq(y[0], y[1]); |
| 273 | switch (n & 3) { | 228 | return switch (@as(u2, @truncate(@as(u32, @bitCast(n))))) { |
| 274 | 0 => { | 229 | 0 => .{ s, c }, |
| 275 | r_sin.* = s; | 230 | 1 => .{ c, -s }, |
| 276 | r_cos.* = c; | 231 | 2 => .{ -s, -c }, |
| 277 | }, | 232 | 3 => .{ -c, s }, |
| 278 | 1 => { | 233 | }; |
| 279 | r_sin.* = c; | ||
| 280 | r_cos.* = -s; | ||
| 281 | }, | ||
| 282 | 2 => { | ||
| 283 | r_sin.* = -s; | ||
| 284 | r_cos.* = -c; | ||
| 285 | }, | ||
| 286 | else => { | ||
| 287 | r_sin.* = -c; | ||
| 288 | r_cos.* = s; | ||
| 289 | }, | ||
| 290 | } | ||
| 291 | } | 234 | } |
| 292 | 235 | ||
| 293 | pub fn sincosl(x: c_longdouble, r_sin: *c_longdouble, r_cos: *c_longdouble) callconv(.c) void { | 236 | pub fn sincosl(x: c_longdouble, r_sin: *c_longdouble, r_cos: *c_longdouble) callconv(.c) void { |
| 294 | switch (@typeInfo(c_longdouble).float.bits) { | 237 | r_sin.*, r_cos.* = switch (@typeInfo(c_longdouble).float.bits) { |
| 295 | 64 => return sincos(x, r_sin, r_cos), | 238 | 64 => sincos_f64(x), |
| 296 | 80 => return sincosx(x, r_sin, r_cos), | 239 | 80 => sincos_f80(x), |
| 297 | 128 => return sincosq(x, r_sin, r_cos), | 240 | 128 => sincos_f128(x), |
| 298 | else => @compileError("unreachable"), | 241 | else => comptime unreachable, |
| 299 | } | 242 | }; |
| 300 | } | 243 | } |
| 301 | 244 | ||
| 302 | fn testSincosSpecial(comptime T: type) !void { | 245 | fn testSincosSpecial(comptime T: type) !void { |
| 303 | const f = switch (T) { | 246 | const f = switch (T) { |
| 304 | f32 => sincosf, | 247 | f16 => sincos_f16, |
| 305 | f64 => sincos, | 248 | f32 => sincos_f32, |
| 306 | f80 => sincosx, | 249 | f64 => sincos_f64, |
| 307 | f128 => sincosq, | 250 | f80 => sincos_f80, |
| 251 | f128 => sincos_f128, | ||
| 308 | else => @compileError("unimplemented"), | 252 | else => @compileError("unimplemented"), |
| 309 | }; | 253 | }; |
| 310 | 254 | ||
| 311 | var s: T = undefined; | 255 | var s: T = undefined; |
| 312 | var c: T = undefined; | 256 | var c: T = undefined; |
| 313 | 257 | ||
| 314 | f(0.0, &s, &c); | 258 | s, c = f(0.0); |
| 315 | try expect(math.isPositiveZero(s)); | 259 | try expect(math.isPositiveZero(s)); |
| 316 | try expect(c == 1.0); | 260 | try expect(c == 1.0); |
| 317 | 261 | ||
| 318 | f(-0.0, &s, &c); | 262 | s, c = f(-0.0); |
| 319 | try expect(math.isNegativeZero(s)); | 263 | try expect(math.isNegativeZero(s)); |
| 320 | try expect(c == 1.0); | 264 | try expect(c == 1.0); |
| 321 | 265 | ||
| 322 | f(math.inf(T), &s, &c); | 266 | s, c = f(math.inf(T)); |
| 323 | try expect(math.isNan(s)); | 267 | try expect(math.isNan(s)); |
| 324 | try expect(math.isNan(c)); | 268 | try expect(math.isNan(c)); |
| 325 | 269 | ||
| 326 | f(-math.inf(T), &s, &c); | 270 | s, c = f(-math.inf(T)); |
| 327 | try expect(math.isNan(s)); | 271 | try expect(math.isNan(s)); |
| 328 | try expect(math.isNan(c)); | 272 | try expect(math.isNan(c)); |
| 329 | 273 | ||
| 330 | f(math.nan(T), &s, &c); | 274 | s, c = f(math.nan(T)); |
| 331 | try expect(math.isNan(s)); | 275 | try expect(math.isNan(s)); |
| 332 | try expect(math.isNan(c)); | 276 | try expect(math.isNan(c)); |
| 333 | } | 277 | } |
| ... | @@ -337,31 +281,31 @@ test "sincos32.normal" { | ... | @@ -337,31 +281,31 @@ test "sincos32.normal" { |
| 337 | var s: f32 = undefined; | 281 | var s: f32 = undefined; |
| 338 | var c: f32 = undefined; | 282 | var c: f32 = undefined; |
| 339 | 283 | ||
| 340 | sincosf(0.0, &s, &c); | 284 | s, c = sincos_f32(0.0); |
| 341 | try expectApproxEqAbs(@as(f32, 0.0), s, epsilon); | 285 | try expectApproxEqAbs(@as(f32, 0.0), s, epsilon); |
| 342 | try expectApproxEqAbs(@as(f32, 1.0), c, epsilon); | 286 | try expectApproxEqAbs(@as(f32, 1.0), c, epsilon); |
| 343 | 287 | ||
| 344 | sincosf(0.2, &s, &c); | 288 | s, c = sincos_f32(0.2); |
| 345 | try expectApproxEqAbs(@as(f32, 0.19866933), s, epsilon); | 289 | try expectApproxEqAbs(@as(f32, 0.19866933), s, epsilon); |
| 346 | try expectApproxEqAbs(@as(f32, 0.9800666), c, epsilon); | 290 | try expectApproxEqAbs(@as(f32, 0.9800666), c, epsilon); |
| 347 | 291 | ||
| 348 | sincosf(0.8923, &s, &c); | 292 | s, c = sincos_f32(0.8923); |
| 349 | try expectApproxEqAbs(@as(f32, 0.77851737), s, epsilon); | 293 | try expectApproxEqAbs(@as(f32, 0.77851737), s, epsilon); |
| 350 | try expectApproxEqAbs(@as(f32, 0.6276231), c, epsilon); | 294 | try expectApproxEqAbs(@as(f32, 0.6276231), c, epsilon); |
| 351 | 295 | ||
| 352 | sincosf(1.5, &s, &c); | 296 | s, c = sincos_f32(1.5); |
| 353 | try expectApproxEqAbs(@as(f32, 0.997495), s, epsilon); | 297 | try expectApproxEqAbs(@as(f32, 0.997495), s, epsilon); |
| 354 | try expectApproxEqAbs(@as(f32, 0.0707372), c, epsilon); | 298 | try expectApproxEqAbs(@as(f32, 0.0707372), c, epsilon); |
| 355 | 299 | ||
| 356 | sincosf(-1.5, &s, &c); | 300 | s, c = sincos_f32(-1.5); |
| 357 | try expectApproxEqAbs(@as(f32, -0.997495), s, epsilon); | 301 | try expectApproxEqAbs(@as(f32, -0.997495), s, epsilon); |
| 358 | try expectApproxEqAbs(@as(f32, 0.0707372), c, epsilon); | 302 | try expectApproxEqAbs(@as(f32, 0.0707372), c, epsilon); |
| 359 | 303 | ||
| 360 | sincosf(37.45, &s, &c); | 304 | s, c = sincos_f32(37.45); |
| 361 | try expectApproxEqAbs(@as(f32, -0.24654257), s, epsilon); | 305 | try expectApproxEqAbs(@as(f32, -0.24654257), s, epsilon); |
| 362 | try expectApproxEqAbs(@as(f32, 0.96913195), c, epsilon); | 306 | try expectApproxEqAbs(@as(f32, 0.96913195), c, epsilon); |
| 363 | 307 | ||
| 364 | sincosf(89.123, &s, &c); | 308 | s, c = sincos_f32(89.123); |
| 365 | try expectApproxEqAbs(@as(f32, 0.9161657), s, epsilon); | 309 | try expectApproxEqAbs(@as(f32, 0.9161657), s, epsilon); |
| 366 | try expectApproxEqAbs(@as(f32, 0.40079966), c, epsilon); | 310 | try expectApproxEqAbs(@as(f32, 0.40079966), c, epsilon); |
| 367 | } | 311 | } |
| ... | @@ -375,31 +319,31 @@ test "sincos64.normal" { | ... | @@ -375,31 +319,31 @@ test "sincos64.normal" { |
| 375 | var s: f64 = undefined; | 319 | var s: f64 = undefined; |
| 376 | var c: f64 = undefined; | 320 | var c: f64 = undefined; |
| 377 | 321 | ||
| 378 | sincos(0.0, &s, &c); | 322 | s, c = sincos_f64(0.0); |
| 379 | try expectApproxEqAbs(@as(f64, 0.0), s, epsilon); | 323 | try expectApproxEqAbs(@as(f64, 0.0), s, epsilon); |
| 380 | try expectApproxEqAbs(@as(f64, 1.0), c, epsilon); | 324 | try expectApproxEqAbs(@as(f64, 1.0), c, epsilon); |
| 381 | 325 | ||
| 382 | sincos(0.2, &s, &c); | 326 | s, c = sincos_f64(0.2); |
| 383 | try expectApproxEqAbs(@as(f64, 0.19866933079506122), s, epsilon); | 327 | try expectApproxEqAbs(@as(f64, 0.19866933079506122), s, epsilon); |
| 384 | try expectApproxEqAbs(@as(f64, 0.9800665778412416), c, epsilon); | 328 | try expectApproxEqAbs(@as(f64, 0.9800665778412416), c, epsilon); |
| 385 | 329 | ||
| 386 | sincos(0.8923, &s, &c); | 330 | s, c = sincos_f64(0.8923); |
| 387 | try expectApproxEqAbs(@as(f64, 0.7785173385577349), s, epsilon); | 331 | try expectApproxEqAbs(@as(f64, 0.7785173385577349), s, epsilon); |
| 388 | try expectApproxEqAbs(@as(f64, 0.6276230983360804), c, epsilon); | 332 | try expectApproxEqAbs(@as(f64, 0.6276230983360804), c, epsilon); |
| 389 | 333 | ||
| 390 | sincos(1.5, &s, &c); | 334 | s, c = sincos_f64(1.5); |
| 391 | try expectApproxEqAbs(@as(f64, 0.9974949866040544), s, epsilon); | 335 | try expectApproxEqAbs(@as(f64, 0.9974949866040544), s, epsilon); |
| 392 | try expectApproxEqAbs(@as(f64, 0.0707372016677029), c, epsilon); | 336 | try expectApproxEqAbs(@as(f64, 0.0707372016677029), c, epsilon); |
| 393 | 337 | ||
| 394 | sincos(-1.5, &s, &c); | 338 | s, c = sincos_f64(-1.5); |
| 395 | try expectApproxEqAbs(@as(f64, -0.9974949866040544), s, epsilon); | 339 | try expectApproxEqAbs(@as(f64, -0.9974949866040544), s, epsilon); |
| 396 | try expectApproxEqAbs(@as(f64, 0.0707372016677029), c, epsilon); | 340 | try expectApproxEqAbs(@as(f64, 0.0707372016677029), c, epsilon); |
| 397 | 341 | ||
| 398 | sincos(37.45, &s, &c); | 342 | s, c = sincos_f64(37.45); |
| 399 | try expectApproxEqAbs(@as(f64, -0.24654331551411082), s, epsilon); | 343 | try expectApproxEqAbs(@as(f64, -0.24654331551411082), s, epsilon); |
| 400 | try expectApproxEqAbs(@as(f64, 0.9691317730707778), c, epsilon); | 344 | try expectApproxEqAbs(@as(f64, 0.9691317730707778), c, epsilon); |
| 401 | 345 | ||
| 402 | sincos(89.123, &s, &c); | 346 | s, c = sincos_f64(89.123); |
| 403 | try expectApproxEqAbs(@as(f64, 0.9161652766622714), s, epsilon); | 347 | try expectApproxEqAbs(@as(f64, 0.9161652766622714), s, epsilon); |
| 404 | try expectApproxEqAbs(@as(f64, 0.4008006809354791), c, epsilon); | 348 | try expectApproxEqAbs(@as(f64, 0.4008006809354791), c, epsilon); |
| 405 | } | 349 | } |
| ... | @@ -413,31 +357,31 @@ test "sincos80.normal" { | ... | @@ -413,31 +357,31 @@ test "sincos80.normal" { |
| 413 | var s: f80 = undefined; | 357 | var s: f80 = undefined; |
| 414 | var c: f80 = undefined; | 358 | var c: f80 = undefined; |
| 415 | 359 | ||
| 416 | sincosx(0.0, &s, &c); | 360 | s, c = sincos_f80(0.0); |
| 417 | try expectApproxEqAbs(@as(f80, 0.0), s, epsilon); | 361 | try expectApproxEqAbs(@as(f80, 0.0), s, epsilon); |
| 418 | try expectApproxEqAbs(@as(f80, 1.0), c, epsilon); | 362 | try expectApproxEqAbs(@as(f80, 1.0), c, epsilon); |
| 419 | 363 | ||
| 420 | sincosx(0.2, &s, &c); | 364 | s, c = sincos_f80(0.2); |
| 421 | try expectApproxEqAbs(@as(f80, 0.19866933079506121545941262711838975), s, epsilon); | 365 | try expectApproxEqAbs(@as(f80, 0.19866933079506121545941262711838975), s, epsilon); |
| 422 | try expectApproxEqAbs(@as(f80, 0.98006657784124163112419651674816888), c, epsilon); | 366 | try expectApproxEqAbs(@as(f80, 0.98006657784124163112419651674816888), c, epsilon); |
| 423 | 367 | ||
| 424 | sincosx(0.8923, &s, &c); | 368 | s, c = sincos_f80(0.8923); |
| 425 | try expectApproxEqAbs(@as(f80, 0.77851733855773487830689285621486050), s, epsilon); | 369 | try expectApproxEqAbs(@as(f80, 0.77851733855773487830689285621486050), s, epsilon); |
| 426 | try expectApproxEqAbs(@as(f80, 0.62762309833608037003563995939286067), c, epsilon); | 370 | try expectApproxEqAbs(@as(f80, 0.62762309833608037003563995939286067), c, epsilon); |
| 427 | 371 | ||
| 428 | sincosx(1.5, &s, &c); | 372 | s, c = sincos_f80(1.5); |
| 429 | try expectApproxEqAbs(@as(f80, 0.99749498660405443094172337114148732), s, epsilon); | 373 | try expectApproxEqAbs(@as(f80, 0.99749498660405443094172337114148732), s, epsilon); |
| 430 | try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), c, epsilon); | 374 | try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), c, epsilon); |
| 431 | 375 | ||
| 432 | sincosx(-1.5, &s, &c); | 376 | s, c = sincos_f80(-1.5); |
| 433 | try expectApproxEqAbs(@as(f80, -0.99749498660405443094172337114148732), s, epsilon); | 377 | try expectApproxEqAbs(@as(f80, -0.99749498660405443094172337114148732), s, epsilon); |
| 434 | try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), c, epsilon); | 378 | try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), c, epsilon); |
| 435 | 379 | ||
| 436 | sincosx(37.45, &s, &c); | 380 | s, c = sincos_f80(37.45); |
| 437 | try expectApproxEqAbs(@as(f80, -0.24654331551411356504), s, epsilon); | 381 | try expectApproxEqAbs(@as(f80, -0.24654331551411356504), s, epsilon); |
| 438 | try expectApproxEqAbs(@as(f80, 0.9691317730707771246), c, epsilon); | 382 | try expectApproxEqAbs(@as(f80, 0.9691317730707771246), c, epsilon); |
| 439 | 383 | ||
| 440 | sincosx(89.123, &s, &c); | 384 | s, c = sincos_f80(89.123); |
| 441 | try expectApproxEqAbs(@as(f80, 0.91616527666226951006), s, epsilon); | 385 | try expectApproxEqAbs(@as(f80, 0.91616527666226951006), s, epsilon); |
| 442 | try expectApproxEqAbs(@as(f80, 0.4008006809354834001), c, epsilon); | 386 | try expectApproxEqAbs(@as(f80, 0.4008006809354834001), c, epsilon); |
| 443 | } | 387 | } |
| ... | @@ -451,31 +395,31 @@ test "sincos128.normal" { | ... | @@ -451,31 +395,31 @@ test "sincos128.normal" { |
| 451 | var s: f128 = undefined; | 395 | var s: f128 = undefined; |
| 452 | var c: f128 = undefined; | 396 | var c: f128 = undefined; |
| 453 | 397 | ||
| 454 | sincosq(0.0, &s, &c); | 398 | s, c = sincos_f128(0.0); |
| 455 | try expectApproxEqAbs(@as(f128, 0.0), s, epsilon); | 399 | try expectApproxEqAbs(@as(f128, 0.0), s, epsilon); |
| 456 | try expectApproxEqAbs(@as(f128, 1.0), c, epsilon); | 400 | try expectApproxEqAbs(@as(f128, 1.0), c, epsilon); |
| 457 | 401 | ||
| 458 | sincosq(0.2, &s, &c); | 402 | s, c = sincos_f128(0.2); |
| 459 | try expectApproxEqAbs(@as(f128, 0.19866933079506121545941262711838975), s, epsilon); | 403 | try expectApproxEqAbs(@as(f128, 0.19866933079506121545941262711838975), s, epsilon); |
| 460 | try expectApproxEqAbs(@as(f128, 0.98006657784124163112419651674816888), c, epsilon); | 404 | try expectApproxEqAbs(@as(f128, 0.98006657784124163112419651674816888), c, epsilon); |
| 461 | 405 | ||
| 462 | sincosq(0.8923, &s, &c); | 406 | s, c = sincos_f128(0.8923); |
| 463 | try expectApproxEqAbs(@as(f128, 0.77851733855773487830689285621486050), s, epsilon); | 407 | try expectApproxEqAbs(@as(f128, 0.77851733855773487830689285621486050), s, epsilon); |
| 464 | try expectApproxEqAbs(@as(f128, 0.62762309833608037003563995939286067), c, epsilon); | 408 | try expectApproxEqAbs(@as(f128, 0.62762309833608037003563995939286067), c, epsilon); |
| 465 | 409 | ||
| 466 | sincosq(1.5, &s, &c); | 410 | s, c = sincos_f128(1.5); |
| 467 | try expectApproxEqAbs(@as(f128, 0.99749498660405443094172337114148732), s, epsilon); | 411 | try expectApproxEqAbs(@as(f128, 0.99749498660405443094172337114148732), s, epsilon); |
| 468 | try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), c, epsilon); | 412 | try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), c, epsilon); |
| 469 | 413 | ||
| 470 | sincosq(-1.5, &s, &c); | 414 | s, c = sincos_f128(-1.5); |
| 471 | try expectApproxEqAbs(@as(f128, -0.99749498660405443094172337114148732), s, epsilon); | 415 | try expectApproxEqAbs(@as(f128, -0.99749498660405443094172337114148732), s, epsilon); |
| 472 | try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), c, epsilon); | 416 | try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), c, epsilon); |
| 473 | 417 | ||
| 474 | sincosq(37.45, &s, &c); | 418 | s, c = sincos_f128(37.45); |
| 475 | try expectApproxEqAbs(@as(f128, -0.24654331551411356571238581321661085), s, epsilon); | 419 | try expectApproxEqAbs(@as(f128, -0.24654331551411356571238581321661085), s, epsilon); |
| 476 | try expectApproxEqAbs(@as(f128, 0.96913177307077712443149563847233230), c, epsilon); | 420 | try expectApproxEqAbs(@as(f128, 0.96913177307077712443149563847233230), c, epsilon); |
| 477 | 421 | ||
| 478 | sincosq(89.123, &s, &c); | 422 | s, c = sincos_f128(89.123); |
| 479 | try expectApproxEqAbs(@as(f128, 0.91616527666226951075019849560482170), s, epsilon); | 423 | try expectApproxEqAbs(@as(f128, 0.91616527666226951075019849560482170), s, epsilon); |
| 480 | try expectApproxEqAbs(@as(f128, 0.40080068093548339848199454493704702), c, epsilon); | 424 | try expectApproxEqAbs(@as(f128, 0.40080068093548339848199454493704702), c, epsilon); |
| 481 | } | 425 | } |
lib/compiler_rt/sqrt.zig+150-137| ... | @@ -17,18 +17,19 @@ comptime { | ... | @@ -17,18 +17,19 @@ comptime { |
| 17 | symbol(&sqrtf, "sqrtf"); | 17 | symbol(&sqrtf, "sqrtf"); |
| 18 | symbol(&sqrt, "sqrt"); | 18 | symbol(&sqrt, "sqrt"); |
| 19 | symbol(&__sqrtx, "__sqrtx"); | 19 | symbol(&__sqrtx, "__sqrtx"); |
| 20 | if (compiler_rt.want_ppc_abi) { | 20 | symbol(&sqrtq, "sqrtf128"); |
| 21 | symbol(&sqrtq, "sqrtf128"); | 21 | if (compiler_rt.want_sparc64_abi) { |
| 22 | } else if (compiler_rt.want_sparc64_abi) { | ||
| 23 | symbol(&_Qp_sqrt, "_Qp_sqrt"); | 22 | symbol(&_Qp_sqrt, "_Qp_sqrt"); |
| 24 | } else if (compiler_rt.want_sparc32_abi) { | 23 | } else if (compiler_rt.want_sparc32_abi) { |
| 25 | symbol(&sqrtq, "_Q_sqrt"); | 24 | symbol(&sqrtq, "_Q_sqrt"); |
| 26 | } | 25 | } |
| 27 | symbol(&sqrtq, "sqrtq"); | ||
| 28 | symbol(&sqrtl, "sqrtl"); | 26 | symbol(&sqrtl, "sqrtl"); |
| 29 | } | 27 | } |
| 30 | 28 | ||
| 31 | pub fn __sqrth(x: f16) callconv(.c) f16 { | 29 | fn __sqrth(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { |
| 30 | return compiler_rt.f16.toAbi(sqrt_f16(compiler_rt.f16.fromAbi(x))); | ||
| 31 | } | ||
| 32 | pub fn sqrt_f16(x: f16) f16 { | ||
| 32 | var ix: u16 = @bitCast(x); | 33 | var ix: u16 = @bitCast(x); |
| 33 | var top = ix >> 10; | 34 | var top = ix >> 10; |
| 34 | 35 | ||
| ... | @@ -93,7 +94,10 @@ pub fn __sqrth(x: f16) callconv(.c) f16 { | ... | @@ -93,7 +94,10 @@ pub fn __sqrth(x: f16) callconv(.c) f16 { |
| 93 | return y; | 94 | return y; |
| 94 | } | 95 | } |
| 95 | 96 | ||
| 96 | pub fn sqrtf(x: f32) callconv(.c) f32 { | 97 | fn sqrtf(x: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { |
| 98 | return compiler_rt.f32.toAbi(sqrt_f32(compiler_rt.f32.fromAbi(x))); | ||
| 99 | } | ||
| 100 | pub fn sqrt_f32(x: f32) f32 { | ||
| 97 | var ix: u32 = @bitCast(x); | 101 | var ix: u32 = @bitCast(x); |
| 98 | 102 | ||
| 99 | if (ix < @as(u32, @bitCast(@as(f32, 0x1p-126))) or @as(u32, @bitCast(std.math.inf(f32))) <= ix) { | 103 | if (ix < @as(u32, @bitCast(@as(f32, 0x1p-126))) or @as(u32, @bitCast(std.math.inf(f32))) <= ix) { |
| ... | @@ -147,7 +151,10 @@ pub fn sqrtf(x: f32) callconv(.c) f32 { | ... | @@ -147,7 +151,10 @@ pub fn sqrtf(x: f32) callconv(.c) f32 { |
| 147 | return y + t; | 151 | return y + t; |
| 148 | } | 152 | } |
| 149 | 153 | ||
| 150 | pub fn sqrt(x: f64) callconv(.c) f64 { | 154 | fn sqrt(x: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { |
| 155 | return compiler_rt.f64.toAbi(sqrt_f64(compiler_rt.f64.fromAbi(x))); | ||
| 156 | } | ||
| 157 | pub fn sqrt_f64(x: f64) f64 { | ||
| 151 | var ix: u64 = @bitCast(x); | 158 | var ix: u64 = @bitCast(x); |
| 152 | var top = ix >> 52; | 159 | var top = ix >> 52; |
| 153 | 160 | ||
| ... | @@ -284,7 +291,10 @@ pub fn sqrt(x: f64) callconv(.c) f64 { | ... | @@ -284,7 +291,10 @@ pub fn sqrt(x: f64) callconv(.c) f64 { |
| 284 | return y; | 291 | return y; |
| 285 | } | 292 | } |
| 286 | 293 | ||
| 287 | pub fn __sqrtx(x: f80) callconv(.c) f80 { | 294 | fn __sqrtx(x: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { |
| 295 | return compiler_rt.f80.toAbi(sqrt_f80(compiler_rt.f80.fromAbi(x))); | ||
| 296 | } | ||
| 297 | pub fn sqrt_f80(x: f80) f80 { | ||
| 288 | var ix: u80 = @bitCast(x); | 298 | var ix: u80 = @bitCast(x); |
| 289 | var top = ix >> 64; | 299 | var top = ix >> 64; |
| 290 | 300 | ||
| ... | @@ -381,7 +391,10 @@ pub fn __sqrtx(x: f80) callconv(.c) f80 { | ... | @@ -381,7 +391,10 @@ pub fn __sqrtx(x: f80) callconv(.c) f80 { |
| 381 | return y; | 391 | return y; |
| 382 | } | 392 | } |
| 383 | 393 | ||
| 384 | pub fn sqrtq(x: f128) callconv(.c) f128 { | 394 | fn sqrtq(x: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { |
| 395 | return compiler_rt.f128.toAbi(sqrt_f128(compiler_rt.f128.fromAbi(x))); | ||
| 396 | } | ||
| 397 | pub fn sqrt_f128(x: f128) f128 { | ||
| 385 | var ix: u128 = @bitCast(x); | 398 | var ix: u128 = @bitCast(x); |
| 386 | var top = ix >> 112; | 399 | var top = ix >> 112; |
| 387 | 400 | ||
| ... | @@ -483,10 +496,10 @@ fn _Qp_sqrt(c: *f128, a: *f128) callconv(.c) void { | ... | @@ -483,10 +496,10 @@ fn _Qp_sqrt(c: *f128, a: *f128) callconv(.c) void { |
| 483 | 496 | ||
| 484 | pub fn sqrtl(x: c_longdouble) callconv(.c) c_longdouble { | 497 | pub fn sqrtl(x: c_longdouble) callconv(.c) c_longdouble { |
| 485 | switch (@typeInfo(c_longdouble).float.bits) { | 498 | switch (@typeInfo(c_longdouble).float.bits) { |
| 486 | 64 => return sqrt(x), | 499 | 64 => return sqrt_f64(x), |
| 487 | 80 => return __sqrtx(x), | 500 | 80 => return sqrt_f80(x), |
| 488 | 128 => return sqrtq(x), | 501 | 128 => return sqrt_f128(x), |
| 489 | else => @compileError("unreachable"), | 502 | else => comptime unreachable, |
| 490 | } | 503 | } |
| 491 | } | 504 | } |
| 492 | 505 | ||
| ... | @@ -545,187 +558,187 @@ inline fn mul80_tail(a: u80, b: u80) u80 { | ... | @@ -545,187 +558,187 @@ inline fn mul80_tail(a: u80, b: u80) u80 { |
| 545 | return alo * blo +% ((ahi * blo) << 40) +% ((alo * bhi) << 40); | 558 | return alo * blo +% ((ahi * blo) << 40) +% ((alo * bhi) << 40); |
| 546 | } | 559 | } |
| 547 | 560 | ||
| 548 | test "__sqrth" { | 561 | test "sqrt_f16" { |
| 549 | // sqrt(±0) is ±0 | 562 | // sqrt(±0) is ±0 |
| 550 | try std.testing.expectEqual(__sqrth(0x0.0p0), 0x0.0p0); | 563 | try std.testing.expectEqual(sqrt_f16(0x0.0p0), 0x0.0p0); |
| 551 | try std.testing.expectEqual(__sqrth(-0x0.0p0), -0x0.0p0); | 564 | try std.testing.expectEqual(sqrt_f16(-0x0.0p0), -0x0.0p0); |
| 552 | // sqrt(+max) is finite | 565 | // sqrt(+max) is finite |
| 553 | try std.testing.expectEqual(__sqrth(0x1.FFCp15), 0x1.FFCp7); | 566 | try std.testing.expectEqual(sqrt_f16(0x1.FFCp15), 0x1.FFCp7); |
| 554 | // sqrt(4)=2 | 567 | // sqrt(4)=2 |
| 555 | try std.testing.expectEqual(__sqrth(0x1p2), 0x1p1); | 568 | try std.testing.expectEqual(sqrt_f16(0x1p2), 0x1p1); |
| 556 | // sqrt(x) for x=1, 1±ulp | 569 | // sqrt(x) for x=1, 1±ulp |
| 557 | try std.testing.expectEqual(__sqrth(0x1p0), 0x1p0); | 570 | try std.testing.expectEqual(sqrt_f16(0x1p0), 0x1p0); |
| 558 | try std.testing.expectEqual(__sqrth(0x1.004p0), 0x1p0); | 571 | try std.testing.expectEqual(sqrt_f16(0x1.004p0), 0x1p0); |
| 559 | try std.testing.expectEqual(__sqrth(0x1.FF8p-1), 0x1.FFCp-1); | 572 | try std.testing.expectEqual(sqrt_f16(0x1.FF8p-1), 0x1.FFCp-1); |
| 560 | // sqrt(+min) is non-zero | 573 | // sqrt(+min) is non-zero |
| 561 | try std.testing.expectEqual(__sqrth(0x1p-14), 0x1p-7); | 574 | try std.testing.expectEqual(sqrt_f16(0x1p-14), 0x1p-7); |
| 562 | // sqrt(min subnormal) is non-zero | 575 | // sqrt(min subnormal) is non-zero |
| 563 | try std.testing.expectEqual(__sqrth(0x0.004p-14), 0x1p-12); | 576 | try std.testing.expectEqual(sqrt_f16(0x0.004p-14), 0x1p-12); |
| 564 | // sqrt(inf) is inf | 577 | // sqrt(inf) is inf |
| 565 | try std.testing.expect(math.isInf(__sqrth(math.inf(f16)))); | 578 | try std.testing.expect(math.isInf(sqrt_f16(math.inf(f16)))); |
| 566 | // sqrt(nan) is nan | 579 | // sqrt(nan) is nan |
| 567 | try std.testing.expect(math.isNan(__sqrth(math.nan(f16)))); | 580 | try std.testing.expect(math.isNan(sqrt_f16(math.nan(f16)))); |
| 568 | // sqrt(-ve) is nan | 581 | // sqrt(-ve) is nan |
| 569 | try std.testing.expect(math.isNan(__sqrth(-0x1p-14))); | 582 | try std.testing.expect(math.isNan(sqrt_f16(-0x1p-14))); |
| 570 | try std.testing.expect(math.isNan(__sqrth(-0x1p+0))); | 583 | try std.testing.expect(math.isNan(sqrt_f16(-0x1p+0))); |
| 571 | try std.testing.expect(math.isNan(__sqrth(-math.inf(f16)))); | 584 | try std.testing.expect(math.isNan(sqrt_f16(-math.inf(f16)))); |
| 572 | // random arguments | 585 | // random arguments |
| 573 | try std.testing.expectEqual(__sqrth(0x1.1p14), 0x1.08p7); | 586 | try std.testing.expectEqual(sqrt_f16(0x1.1p14), 0x1.08p7); |
| 574 | try std.testing.expectEqual(__sqrth(0x1.C9p-12), 0x1.56p-6); | 587 | try std.testing.expectEqual(sqrt_f16(0x1.C9p-12), 0x1.56p-6); |
| 575 | try std.testing.expectEqual(__sqrth(0x1.CE8p-7), 0x1.E68p-4); | 588 | try std.testing.expectEqual(sqrt_f16(0x1.CE8p-7), 0x1.E68p-4); |
| 576 | try std.testing.expectEqual(__sqrth(0x1.134p-7), 0x1.778p-4); | 589 | try std.testing.expectEqual(sqrt_f16(0x1.134p-7), 0x1.778p-4); |
| 577 | try std.testing.expectEqual(__sqrth(0x1.E9Cp-10), 0x1.62p-5); | 590 | try std.testing.expectEqual(sqrt_f16(0x1.E9Cp-10), 0x1.62p-5); |
| 578 | try std.testing.expectEqual(__sqrth(0x1.3Dp9), 0x1.92Cp4); | 591 | try std.testing.expectEqual(sqrt_f16(0x1.3Dp9), 0x1.92Cp4); |
| 579 | try std.testing.expectEqual(__sqrth(0x1.AA4p8), 0x1.4A4p4); | 592 | try std.testing.expectEqual(sqrt_f16(0x1.AA4p8), 0x1.4A4p4); |
| 580 | try std.testing.expectEqual(__sqrth(0x1.8A8p4), 0x1.3DCp2); | 593 | try std.testing.expectEqual(sqrt_f16(0x1.8A8p4), 0x1.3DCp2); |
| 581 | try std.testing.expectEqual(__sqrth(0x1.8Fp-7), 0x1.C4p-4); | 594 | try std.testing.expectEqual(sqrt_f16(0x1.8Fp-7), 0x1.C4p-4); |
| 582 | try std.testing.expectEqual(__sqrth(0x1.584p-11), 0x1.A3Cp-6); | 595 | try std.testing.expectEqual(sqrt_f16(0x1.584p-11), 0x1.A3Cp-6); |
| 583 | } | 596 | } |
| 584 | 597 | ||
| 585 | test "sqrtf" { | 598 | test "sqrt_f32" { |
| 586 | // sqrt(±0) is ±0 | 599 | // sqrt(±0) is ±0 |
| 587 | try std.testing.expectEqual(sqrtf(0x0.0p0), 0x0.0p0); | 600 | try std.testing.expectEqual(sqrt_f32(0x0.0p0), 0x0.0p0); |
| 588 | try std.testing.expectEqual(sqrtf(-0x0.0p0), -0x0.0p0); | 601 | try std.testing.expectEqual(sqrt_f32(-0x0.0p0), -0x0.0p0); |
| 589 | // sqrt(+max) is finite | 602 | // sqrt(+max) is finite |
| 590 | try std.testing.expectEqual(sqrtf(0x1.FFFFFEp127), 0x1.FFFFFEp63); | 603 | try std.testing.expectEqual(sqrt_f32(0x1.FFFFFEp127), 0x1.FFFFFEp63); |
| 591 | // sqrt(4)=2 | 604 | // sqrt(4)=2 |
| 592 | try std.testing.expectEqual(sqrtf(0x1p2), 0x1p1); | 605 | try std.testing.expectEqual(sqrt_f32(0x1p2), 0x1p1); |
| 593 | // sqrt(x) for x=1, 1±ulp | 606 | // sqrt(x) for x=1, 1±ulp |
| 594 | try std.testing.expectEqual(sqrtf(0x1p0), 0x1p0); | 607 | try std.testing.expectEqual(sqrt_f32(0x1p0), 0x1p0); |
| 595 | try std.testing.expectEqual(sqrtf(0x1.000002p0), 0x1p0); | 608 | try std.testing.expectEqual(sqrt_f32(0x1.000002p0), 0x1p0); |
| 596 | try std.testing.expectEqual(sqrtf(0x1.FFFFFEp-1), 0x1.FFFFFEp-1); | 609 | try std.testing.expectEqual(sqrt_f32(0x1.FFFFFEp-1), 0x1.FFFFFEp-1); |
| 597 | // sqrt(+min) is non-zero | 610 | // sqrt(+min) is non-zero |
| 598 | try std.testing.expectEqual(sqrtf(0x1p-126), 0x1p-63); | 611 | try std.testing.expectEqual(sqrt_f32(0x1p-126), 0x1p-63); |
| 599 | // sqrt(min subnormal) is non-zero | 612 | // sqrt(min subnormal) is non-zero |
| 600 | try std.testing.expectEqual(sqrtf(0x0.000002p-126), 0x1.6a09e6p-75); | 613 | try std.testing.expectEqual(sqrt_f32(0x0.000002p-126), 0x1.6a09e6p-75); |
| 601 | // sqrt(inf) is inf | 614 | // sqrt(inf) is inf |
| 602 | try std.testing.expect(math.isInf(sqrtf(math.inf(f32)))); | 615 | try std.testing.expect(math.isInf(sqrt_f32(math.inf(f32)))); |
| 603 | // sqrt(nan) is nan | 616 | // sqrt(nan) is nan |
| 604 | try std.testing.expect(math.isNan(sqrtf(math.nan(f32)))); | 617 | try std.testing.expect(math.isNan(sqrt_f32(math.nan(f32)))); |
| 605 | // sqrt(-ve) is nan | 618 | // sqrt(-ve) is nan |
| 606 | try std.testing.expect(math.isNan(sqrtf(-0x1p-149))); | 619 | try std.testing.expect(math.isNan(sqrt_f32(-0x1p-149))); |
| 607 | try std.testing.expect(math.isNan(sqrtf(-0x1p0))); | 620 | try std.testing.expect(math.isNan(sqrt_f32(-0x1p0))); |
| 608 | try std.testing.expect(math.isNan(sqrtf(-math.inf(f32)))); | 621 | try std.testing.expect(math.isNan(sqrt_f32(-math.inf(f32)))); |
| 609 | // random arguments | 622 | // random arguments |
| 610 | try std.testing.expectEqual(sqrtf(0x1.4DD57Ep77), 0x1.9D6DA8p38); | 623 | try std.testing.expectEqual(sqrt_f32(0x1.4DD57Ep77), 0x1.9D6DA8p38); |
| 611 | try std.testing.expectEqual(sqrtf(0x1.871848p102), 0x1.3C6AFAp51); | 624 | try std.testing.expectEqual(sqrt_f32(0x1.871848p102), 0x1.3C6AFAp51); |
| 612 | try std.testing.expectEqual(sqrtf(0x1.A1D748p-112), 0x1.470EFCp-56); | 625 | try std.testing.expectEqual(sqrt_f32(0x1.A1D748p-112), 0x1.470EFCp-56); |
| 613 | try std.testing.expectEqual(sqrtf(0x1.E626C2p18), 0x1.60C80Ep9); | 626 | try std.testing.expectEqual(sqrt_f32(0x1.E626C2p18), 0x1.60C80Ep9); |
| 614 | try std.testing.expectEqual(sqrtf(0x1.E80E66p-29), 0x1.F3E282p-15); | 627 | try std.testing.expectEqual(sqrt_f32(0x1.E80E66p-29), 0x1.F3E282p-15); |
| 615 | try std.testing.expectEqual(sqrtf(0x1.B47204p89), 0x1.D8B732p44); | 628 | try std.testing.expectEqual(sqrt_f32(0x1.B47204p89), 0x1.D8B732p44); |
| 616 | try std.testing.expectEqual(sqrtf(0x1.77F45p15), 0x1.B6BC3Ap7); | 629 | try std.testing.expectEqual(sqrt_f32(0x1.77F45p15), 0x1.B6BC3Ap7); |
| 617 | try std.testing.expectEqual(sqrtf(0x1.AD5F5p-48), 0x1.4B8A72p-24); | 630 | try std.testing.expectEqual(sqrt_f32(0x1.AD5F5p-48), 0x1.4B8A72p-24); |
| 618 | try std.testing.expectEqual(sqrtf(0x1.91A39p-76), 0x1.40A7A8p-38); | 631 | try std.testing.expectEqual(sqrt_f32(0x1.91A39p-76), 0x1.40A7A8p-38); |
| 619 | try std.testing.expectEqual(sqrtf(0x1.DAE088p79), 0x1.ED16DCp39); | 632 | try std.testing.expectEqual(sqrt_f32(0x1.DAE088p79), 0x1.ED16DCp39); |
| 620 | } | 633 | } |
| 621 | 634 | ||
| 622 | test "sqrt" { | 635 | test "sqrt_f64" { |
| 623 | // sqrt(±0) is ±0 | 636 | // sqrt(±0) is ±0 |
| 624 | try std.testing.expectEqual(sqrt(0x0.0p0), 0x0.0p0); | 637 | try std.testing.expectEqual(sqrt_f64(0x0.0p0), 0x0.0p0); |
| 625 | try std.testing.expectEqual(sqrt(-0x0.0p0), -0x0.0p0); | 638 | try std.testing.expectEqual(sqrt_f64(-0x0.0p0), -0x0.0p0); |
| 626 | // sqrt(+max) is finite | 639 | // sqrt(+max) is finite |
| 627 | try std.testing.expectEqual(sqrt(math.floatMax(f64)), 0x1.FFFFFFFFFFFFFp511); | 640 | try std.testing.expectEqual(sqrt_f64(math.floatMax(f64)), 0x1.FFFFFFFFFFFFFp511); |
| 628 | // sqrt(4)=2 | 641 | // sqrt(4)=2 |
| 629 | try std.testing.expectEqual(sqrt(0x1p2), 0x1p1); | 642 | try std.testing.expectEqual(sqrt_f64(0x1p2), 0x1p1); |
| 630 | // sqrt(x) for x=1, 1±ulp | 643 | // sqrt(x) for x=1, 1±ulp |
| 631 | try std.testing.expectEqual(sqrt(0x1p0), 0x1p0); | 644 | try std.testing.expectEqual(sqrt_f64(0x1p0), 0x1p0); |
| 632 | try std.testing.expectEqual(sqrt(0x1p0 + math.floatEps(f64)), 0x1p0); | 645 | try std.testing.expectEqual(sqrt_f64(0x1p0 + math.floatEps(f64)), 0x1p0); |
| 633 | try std.testing.expectEqual(sqrt(0x1p0 - math.floatEps(f64)), 0x1.FFFFFFFFFFFFFp-1); | 646 | try std.testing.expectEqual(sqrt_f64(0x1p0 - math.floatEps(f64)), 0x1.FFFFFFFFFFFFFp-1); |
| 634 | // sqrt(+min) is non-zero | 647 | // sqrt(+min) is non-zero |
| 635 | try std.testing.expectEqual(sqrt(math.floatMin(f64)), 0x1p-511); | 648 | try std.testing.expectEqual(sqrt_f64(math.floatMin(f64)), 0x1p-511); |
| 636 | // sqrt(min subnormal) is non-zero | 649 | // sqrt(min subnormal) is non-zero |
| 637 | try std.testing.expectEqual(sqrt(math.floatTrueMin(f64)), 0x1p-537); | 650 | try std.testing.expectEqual(sqrt_f64(math.floatTrueMin(f64)), 0x1p-537); |
| 638 | // sqrt(inf) is inf | 651 | // sqrt(inf) is inf |
| 639 | try std.testing.expect(math.isInf(sqrt(math.inf(f64)))); | 652 | try std.testing.expect(math.isInf(sqrt_f64(math.inf(f64)))); |
| 640 | // sqrt(nan) is nan | 653 | // sqrt(nan) is nan |
| 641 | try std.testing.expect(math.isNan(sqrt(math.nan(f64)))); | 654 | try std.testing.expect(math.isNan(sqrt_f64(math.nan(f64)))); |
| 642 | // sqrt(-ve) is nan | 655 | // sqrt(-ve) is nan |
| 643 | try std.testing.expect(math.isNan(sqrt(-0x1p-1074))); | 656 | try std.testing.expect(math.isNan(sqrt_f64(-0x1p-1074))); |
| 644 | try std.testing.expect(math.isNan(sqrt(-0x1p0))); | 657 | try std.testing.expect(math.isNan(sqrt_f64(-0x1p0))); |
| 645 | try std.testing.expect(math.isNan(sqrt(-math.inf(f64)))); | 658 | try std.testing.expect(math.isNan(sqrt_f64(-math.inf(f64)))); |
| 646 | // random arguments | 659 | // random arguments |
| 647 | try std.testing.expectEqual(sqrt(0x1.27D3510D4789Bp471), 0x1.852E97E58CFB7p235); | 660 | try std.testing.expectEqual(sqrt_f64(0x1.27D3510D4789Bp471), 0x1.852E97E58CFB7p235); |
| 648 | try std.testing.expectEqual(sqrt(0x1.8C4FCD5A07846p791), 0x1.C27504E56D938p395); | 661 | try std.testing.expectEqual(sqrt_f64(0x1.8C4FCD5A07846p791), 0x1.C27504E56D938p395); |
| 649 | try std.testing.expectEqual(sqrt(0x1.B1B69324F96E7p-137), 0x1.D73BD0414D8BFp-69); | 662 | try std.testing.expectEqual(sqrt_f64(0x1.B1B69324F96E7p-137), 0x1.D73BD0414D8BFp-69); |
| 650 | try std.testing.expectEqual(sqrt(0x1.1CBD179A811FEp278), 0x1.0DFCB9A114A61p139); | 663 | try std.testing.expectEqual(sqrt_f64(0x1.1CBD179A811FEp278), 0x1.0DFCB9A114A61p139); |
| 651 | try std.testing.expectEqual(sqrt(0x1.1D0C7EFB04A56p917), 0x1.7E0708A25DDCDp458); | 664 | try std.testing.expectEqual(sqrt_f64(0x1.1D0C7EFB04A56p917), 0x1.7E0708A25DDCDp458); |
| 652 | try std.testing.expectEqual(sqrt(0x1.21B355DA8C94Bp-249), 0x1.8121CBE2608E3p-125); | 665 | try std.testing.expectEqual(sqrt_f64(0x1.21B355DA8C94Bp-249), 0x1.8121CBE2608E3p-125); |
| 653 | try std.testing.expectEqual(sqrt(0x1.63024D4C5E987p487), 0x1.AA56AEA589DCDp243); | 666 | try std.testing.expectEqual(sqrt_f64(0x1.63024D4C5E987p487), 0x1.AA56AEA589DCDp243); |
| 654 | try std.testing.expectEqual(sqrt(0x1.45AC3BE941F6Ep339), 0x1.9857F3F453E2Dp169); | 667 | try std.testing.expectEqual(sqrt_f64(0x1.45AC3BE941F6Ep339), 0x1.9857F3F453E2Dp169); |
| 655 | try std.testing.expectEqual(sqrt(0x1.3B719C733AA24p267), 0x1.91E12E3AC8F71p133); | 668 | try std.testing.expectEqual(sqrt_f64(0x1.3B719C733AA24p267), 0x1.91E12E3AC8F71p133); |
| 656 | try std.testing.expectEqual(sqrt(0x1.0B150433A2275p357), 0x1.71CAB87F8277Cp178); | 669 | try std.testing.expectEqual(sqrt_f64(0x1.0B150433A2275p357), 0x1.71CAB87F8277Cp178); |
| 657 | } | 670 | } |
| 658 | 671 | ||
| 659 | test "__sqrtx" { | 672 | test "__sqrtx" { |
| 660 | // sqrt(±0) is ±0 | 673 | // sqrt(±0) is ±0 |
| 661 | try std.testing.expectEqual(__sqrtx(0x0.0p0), 0x0.0p0); | 674 | try std.testing.expectEqual(sqrt_f80(0x0.0p0), 0x0.0p0); |
| 662 | try std.testing.expectEqual(__sqrtx(-0x0.0p0), -0x0.0p0); | 675 | try std.testing.expectEqual(sqrt_f80(-0x0.0p0), -0x0.0p0); |
| 663 | // sqrt(+max) is finite | 676 | // sqrt(+max) is finite |
| 664 | try std.testing.expectEqual(__sqrtx(math.floatMax(f80)), 0x1.FFFFFFFFFFFFFFFEp8191); | 677 | try std.testing.expectEqual(sqrt_f80(math.floatMax(f80)), 0x1.FFFFFFFFFFFFFFFEp8191); |
| 665 | // sqrt(4)=2 | 678 | // sqrt(4)=2 |
| 666 | try std.testing.expectEqual(__sqrtx(0x1p2), 0x1p1); | 679 | try std.testing.expectEqual(sqrt_f80(0x1p2), 0x1p1); |
| 667 | // sqrt(x) for x=1, 1±ulp | 680 | // sqrt(x) for x=1, 1±ulp |
| 668 | try std.testing.expectEqual(__sqrtx(0x1p0), 0x1p0); | 681 | try std.testing.expectEqual(sqrt_f80(0x1p0), 0x1p0); |
| 669 | try std.testing.expectEqual(__sqrtx(0x1p0 + math.floatEps(f80)), 0x1p0); | 682 | try std.testing.expectEqual(sqrt_f80(0x1p0 + math.floatEps(f80)), 0x1p0); |
| 670 | try std.testing.expectEqual(__sqrtx(0x1p0 - math.floatEps(f80)), 0x1.FFFFFFFFFFFFFFFEp-1); | 683 | try std.testing.expectEqual(sqrt_f80(0x1p0 - math.floatEps(f80)), 0x1.FFFFFFFFFFFFFFFEp-1); |
| 671 | // sqrt(+min) is non-zero | 684 | // sqrt(+min) is non-zero |
| 672 | try std.testing.expectEqual(__sqrtx(math.floatMin(f80)), 0x1p-8191); | 685 | try std.testing.expectEqual(sqrt_f80(math.floatMin(f80)), 0x1p-8191); |
| 673 | // sqrt(min subnormal) is non-zero | 686 | // sqrt(min subnormal) is non-zero |
| 674 | try std.testing.expectEqual(__sqrtx(math.floatTrueMin(f80)), 0x1.6A09E667F3BCC908p-8223); | 687 | try std.testing.expectEqual(sqrt_f80(math.floatTrueMin(f80)), 0x1.6A09E667F3BCC908p-8223); |
| 675 | // sqrt(inf) is inf | 688 | // sqrt(inf) is inf |
| 676 | try std.testing.expect(math.isInf(__sqrtx(math.inf(f80)))); | 689 | try std.testing.expect(math.isInf(sqrt_f80(math.inf(f80)))); |
| 677 | // sqrt(nan) is nan | 690 | // sqrt(nan) is nan |
| 678 | try std.testing.expect(math.isNan(__sqrtx(math.nan(f80)))); | 691 | try std.testing.expect(math.isNan(sqrt_f80(math.nan(f80)))); |
| 679 | // sqrt(-ve) is nan | 692 | // sqrt(-ve) is nan |
| 680 | try std.testing.expect(math.isNan(__sqrtx(-0x1p-16442))); | 693 | try std.testing.expect(math.isNan(sqrt_f80(-0x1p-16442))); |
| 681 | try std.testing.expect(math.isNan(__sqrtx(-0x1p0))); | 694 | try std.testing.expect(math.isNan(sqrt_f80(-0x1p0))); |
| 682 | try std.testing.expect(math.isNan(__sqrtx(-math.inf(f80)))); | 695 | try std.testing.expect(math.isNan(sqrt_f80(-math.inf(f80)))); |
| 683 | // random arguments | 696 | // random arguments |
| 684 | try std.testing.expectEqual(__sqrtx(0x1.087F3953486918A4p15482), 0x1.0436BBE03D02F32p7741); | 697 | try std.testing.expectEqual(sqrt_f80(0x1.087F3953486918A4p15482), 0x1.0436BBE03D02F32p7741); |
| 685 | try std.testing.expectEqual(__sqrtx(0x1.530CF9E2AE84D8Fp-6330), 0x1.269CFEF51933BE58p-3165); | 698 | try std.testing.expectEqual(sqrt_f80(0x1.530CF9E2AE84D8Fp-6330), 0x1.269CFEF51933BE58p-3165); |
| 686 | try std.testing.expectEqual(__sqrtx(0x1.3F971515EADD574Ap5713), 0x1.9483232AB780B006p2856); | 699 | try std.testing.expectEqual(sqrt_f80(0x1.3F971515EADD574Ap5713), 0x1.9483232AB780B006p2856); |
| 687 | try std.testing.expectEqual(__sqrtx(0x1.4CC0DC7379222954p864), 0x1.23DD4D0A4758C2Cp432); | 700 | try std.testing.expectEqual(sqrt_f80(0x1.4CC0DC7379222954p864), 0x1.23DD4D0A4758C2Cp432); |
| 688 | try std.testing.expectEqual(__sqrtx(0x1.920E5649559A839Ep-3181), 0x1.C5B5BC0F98DD83D2p-1591); | 701 | try std.testing.expectEqual(sqrt_f80(0x1.920E5649559A839Ep-3181), 0x1.C5B5BC0F98DD83D2p-1591); |
| 689 | try std.testing.expectEqual(__sqrtx(0x1.2E59726F87CD1746p-629), 0x1.8973327E95CB350Cp-315); | 702 | try std.testing.expectEqual(sqrt_f80(0x1.2E59726F87CD1746p-629), 0x1.8973327E95CB350Cp-315); |
| 690 | try std.testing.expectEqual(__sqrtx(0x1.D3A16391F57B4D64p-9034), 0x1.59FF08B7DEEF5DB2p-4517); | 703 | try std.testing.expectEqual(sqrt_f80(0x1.D3A16391F57B4D64p-9034), 0x1.59FF08B7DEEF5DB2p-4517); |
| 691 | try std.testing.expectEqual(__sqrtx(0x1.E7053D8DAA49BCEEp-11411), 0x1.F35AA3EA5E18E344p-5706); | 704 | try std.testing.expectEqual(sqrt_f80(0x1.E7053D8DAA49BCEEp-11411), 0x1.F35AA3EA5E18E344p-5706); |
| 692 | try std.testing.expectEqual(__sqrtx(0x1.797ED0B05DD4A984p7521), 0x1.B7A22E40C6A7867Ap3760); | 705 | try std.testing.expectEqual(sqrt_f80(0x1.797ED0B05DD4A984p7521), 0x1.B7A22E40C6A7867Ap3760); |
| 693 | try std.testing.expectEqual(__sqrtx(0x1.FC50806445C7226Ap15371), 0x1.FE2766142653F5BEp7685); | 706 | try std.testing.expectEqual(sqrt_f80(0x1.FC50806445C7226Ap15371), 0x1.FE2766142653F5BEp7685); |
| 694 | } | 707 | } |
| 695 | 708 | ||
| 696 | test "sqrtq" { | 709 | test "sqrt_f128" { |
| 697 | // sqrt(±0) is ±0 | 710 | // sqrt(±0) is ±0 |
| 698 | try std.testing.expectEqual(sqrtq(0x0.0p0), 0x0.0p0); | 711 | try std.testing.expectEqual(sqrt_f128(0x0.0p0), 0x0.0p0); |
| 699 | try std.testing.expectEqual(sqrtq(-0x0.0p0), -0x0.0p0); | 712 | try std.testing.expectEqual(sqrt_f128(-0x0.0p0), -0x0.0p0); |
| 700 | // sqrt(+max) is finite | 713 | // sqrt(+max) is finite |
| 701 | try std.testing.expectEqual(sqrtq(math.floatMax(f128)), 0x1.FFFFFFFFFFFFFFFFFFFFFFFFFFFFp8191); | 714 | try std.testing.expectEqual(sqrt_f128(math.floatMax(f128)), 0x1.FFFFFFFFFFFFFFFFFFFFFFFFFFFFp8191); |
| 702 | // sqrt(4)=2 | 715 | // sqrt(4)=2 |
| 703 | try std.testing.expectEqual(sqrtq(0x1p2), 0x1p1); | 716 | try std.testing.expectEqual(sqrt_f128(0x1p2), 0x1p1); |
| 704 | // sqrt(x) for x=1, 1±ulp | 717 | // sqrt(x) for x=1, 1±ulp |
| 705 | try std.testing.expectEqual(sqrtq(0x1p0), 0x1p0); | 718 | try std.testing.expectEqual(sqrt_f128(0x1p0), 0x1p0); |
| 706 | try std.testing.expectEqual(sqrtq(0x1p0 + math.floatEps(f128)), 0x1p0); | 719 | try std.testing.expectEqual(sqrt_f128(0x1p0 + math.floatEps(f128)), 0x1p0); |
| 707 | try std.testing.expectEqual(sqrtq(0x1p0 - math.floatEps(f128)), 0x1.FFFFFFFFFFFFFFFFFFFFFFFFFFFFp-1); | 720 | try std.testing.expectEqual(sqrt_f128(0x1p0 - math.floatEps(f128)), 0x1.FFFFFFFFFFFFFFFFFFFFFFFFFFFFp-1); |
| 708 | // sqrt(+min) is non-zero | 721 | // sqrt(+min) is non-zero |
| 709 | try std.testing.expectEqual(sqrtq(math.floatMin(f128)), 0x1p-8191); | 722 | try std.testing.expectEqual(sqrt_f128(math.floatMin(f128)), 0x1p-8191); |
| 710 | // sqrt(min subnormal) is non-zero | 723 | // sqrt(min subnormal) is non-zero |
| 711 | try std.testing.expectEqual(sqrtq(math.floatTrueMin(f128)), 0x1p-8247); | 724 | try std.testing.expectEqual(sqrt_f128(math.floatTrueMin(f128)), 0x1p-8247); |
| 712 | // sqrt(inf) is inf | 725 | // sqrt(inf) is inf |
| 713 | try std.testing.expect(math.isInf(sqrtq(math.inf(f128)))); | 726 | try std.testing.expect(math.isInf(sqrt_f128(math.inf(f128)))); |
| 714 | // sqrt(nan) is nan | 727 | // sqrt(nan) is nan |
| 715 | try std.testing.expect(math.isNan(sqrtq(math.nan(f128)))); | 728 | try std.testing.expect(math.isNan(sqrt_f128(math.nan(f128)))); |
| 716 | // sqrt(-ve) is nan | 729 | // sqrt(-ve) is nan |
| 717 | try std.testing.expect(math.isNan(sqrtq(-0x1p-16442))); | 730 | try std.testing.expect(math.isNan(sqrt_f128(-0x1p-16442))); |
| 718 | try std.testing.expect(math.isNan(sqrtq(-0x1p0))); | 731 | try std.testing.expect(math.isNan(sqrt_f128(-0x1p0))); |
| 719 | try std.testing.expect(math.isNan(sqrtq(-math.inf(f128)))); | 732 | try std.testing.expect(math.isNan(sqrt_f128(-math.inf(f128)))); |
| 720 | // random arguments | 733 | // random arguments |
| 721 | try std.testing.expectEqual(sqrtq(0x1.B6942D29A331751600C9F3AF7E5Fp3363), 0x1.D9DE9AFEF0F2D25586A50CA39D4Dp1681); | 734 | try std.testing.expectEqual(sqrt_f128(0x1.B6942D29A331751600C9F3AF7E5Fp3363), 0x1.D9DE9AFEF0F2D25586A50CA39D4Dp1681); |
| 722 | try std.testing.expectEqual(sqrtq(0x1.5E65C405F84D471A8070ADD7A42Dp11765), 0x1.A78F7F9452B4D9EC2403C81D9D42p5882); | 735 | try std.testing.expectEqual(sqrt_f128(0x1.5E65C405F84D471A8070ADD7A42Dp11765), 0x1.A78F7F9452B4D9EC2403C81D9D42p5882); |
| 723 | try std.testing.expectEqual(sqrtq(0x1.B42334D68F8016D8AE6F5E22B044p-5624), 0x1.4E247A7F2FF2A325E9377BB09C8p-2812); | 736 | try std.testing.expectEqual(sqrt_f128(0x1.B42334D68F8016D8AE6F5E22B044p-5624), 0x1.4E247A7F2FF2A325E9377BB09C8p-2812); |
| 724 | try std.testing.expectEqual(sqrtq(0x1.E61715047F80F2E0B9382B38E06Bp10062), 0x1.60C25D9DFDC0116B78EF5AFDE0E9p5031); | 737 | try std.testing.expectEqual(sqrt_f128(0x1.E61715047F80F2E0B9382B38E06Bp10062), 0x1.60C25D9DFDC0116B78EF5AFDE0E9p5031); |
| 725 | try std.testing.expectEqual(sqrtq(0x1.2ED0B53B494CB55A7B04E653D40Ep-1026), 0x1.166CE78D658D2453D700B04C5748p-513); | 738 | try std.testing.expectEqual(sqrt_f128(0x1.2ED0B53B494CB55A7B04E653D40Ep-1026), 0x1.166CE78D658D2453D700B04C5748p-513); |
| 726 | try std.testing.expectEqual(sqrtq(0x1.1BA756B9790E78A4E6F0B083AA89p1835), 0x1.7D1767EA3303DB7A46940033988p917); | 739 | try std.testing.expectEqual(sqrt_f128(0x1.1BA756B9790E78A4E6F0B083AA89p1835), 0x1.7D1767EA3303DB7A46940033988p917); |
| 727 | try std.testing.expectEqual(sqrtq(0x1.5B6C574319C1120335C8E1609704p4512), 0x1.2A3A8A415BB1648C548FBA2A4182p2256); | 740 | try std.testing.expectEqual(sqrt_f128(0x1.5B6C574319C1120335C8E1609704p4512), 0x1.2A3A8A415BB1648C548FBA2A4182p2256); |
| 728 | try std.testing.expectEqual(sqrtq(0x1.FF91E8CDEE1552A2B74E77B602Ep14953), 0x1.FFC8F171267D4FE75CBE7AB4D851p7476); | 741 | try std.testing.expectEqual(sqrt_f128(0x1.FF91E8CDEE1552A2B74E77B602Ep14953), 0x1.FFC8F171267D4FE75CBE7AB4D851p7476); |
| 729 | try std.testing.expectEqual(sqrtq(0x1.9B1837CFC629A1B6B1BB97099E7Dp2892), 0x1.4468511B909EAF8641BD59105A6Bp1446); | 742 | try std.testing.expectEqual(sqrt_f128(0x1.9B1837CFC629A1B6B1BB97099E7Dp2892), 0x1.4468511B909EAF8641BD59105A6Bp1446); |
| 730 | try std.testing.expectEqual(sqrtq(0x1.0E2115475E64A92340914E7F7B37p-13951), 0x1.73E536F82F414134012F55BA5368p-6976); | 743 | try std.testing.expectEqual(sqrt_f128(0x1.0E2115475E64A92340914E7F7B37p-13951), 0x1.73E536F82F414134012F55BA5368p-6976); |
| 731 | } | 744 | } |
lib/compiler_rt/ssp.zig+2-2| ... | @@ -17,7 +17,7 @@ const compiler_rt = @import("../compiler_rt.zig"); | ... | @@ -17,7 +17,7 @@ const compiler_rt = @import("../compiler_rt.zig"); |
| 17 | const symbol = compiler_rt.symbol; | 17 | const symbol = compiler_rt.symbol; |
| 18 | const builtin = @import("builtin"); | 18 | const builtin = @import("builtin"); |
| 19 | 19 | ||
| 20 | extern fn memset(dest: ?[*]u8, c: u8, n: usize) callconv(.c) ?[*]u8; | 20 | extern fn memset(dest: ?[*]u8, c: c_int, n: usize) callconv(.c) ?[*]u8; |
| 21 | extern fn memcpy(noalias dest: ?[*]u8, noalias src: ?[*]const u8, n: usize) callconv(.c) ?[*]u8; | 21 | extern fn memcpy(noalias dest: ?[*]u8, noalias src: ?[*]const u8, n: usize) callconv(.c) ?[*]u8; |
| 22 | extern fn memmove(dest: ?[*]u8, src: ?[*]const u8, n: usize) callconv(.c) ?[*]u8; | 22 | extern fn memmove(dest: ?[*]u8, src: ?[*]const u8, n: usize) callconv(.c) ?[*]u8; |
| 23 | 23 | ||
| ... | @@ -138,7 +138,7 @@ fn __memmove_chk(dest: ?[*]u8, src: ?[*]const u8, n: usize, dest_n: usize) callc | ... | @@ -138,7 +138,7 @@ fn __memmove_chk(dest: ?[*]u8, src: ?[*]const u8, n: usize, dest_n: usize) callc |
| 138 | return memmove(dest, src, n); | 138 | return memmove(dest, src, n); |
| 139 | } | 139 | } |
| 140 | 140 | ||
| 141 | fn __memset_chk(dest: ?[*]u8, c: u8, n: usize, dest_n: usize) callconv(.c) ?[*]u8 { | 141 | fn __memset_chk(dest: ?[*]u8, c: c_int, n: usize, dest_n: usize) callconv(.c) ?[*]u8 { |
| 142 | if (dest_n < n) __chk_fail(); | 142 | if (dest_n < n) __chk_fail(); |
| 143 | return memset(dest, c, n); | 143 | return memset(dest, c, n); |
| 144 | } | 144 | } |
lib/compiler_rt/subdf3.zig deleted-24| ... | @@ -1,24 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const addf3 = @import("./addf3.zig").addf3; | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_aeabi) { | ||
| 7 | symbol(&__aeabi_dsub, "__aeabi_dsub"); | ||
| 8 | } else { | ||
| 9 | symbol(&__subdf3, "__subdf3"); | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | fn __subdf3(a: f64, b: f64) callconv(.c) f64 { | ||
| 14 | return sub(a, b); | ||
| 15 | } | ||
| 16 | |||
| 17 | fn __aeabi_dsub(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 { | ||
| 18 | return sub(a, b); | ||
| 19 | } | ||
| 20 | |||
| 21 | inline fn sub(a: f64, b: f64) f64 { | ||
| 22 | const neg_b = @as(f64, @bitCast(@as(u64, @bitCast(b)) ^ (@as(u64, 1) << 63))); | ||
| 23 | return addf3(f64, a, neg_b); | ||
| 24 | } | ||
lib/compiler_rt/subhf3.zig deleted-12| ... | @@ -1,12 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const addf3 = @import("./addf3.zig").addf3; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__subhf3, "__subhf3"); | ||
| 7 | } | ||
| 8 | |||
| 9 | fn __subhf3(a: f16, b: f16) callconv(.c) f16 { | ||
| 10 | const neg_b = @as(f16, @bitCast(@as(u16, @bitCast(b)) ^ (@as(u16, 1) << 15))); | ||
| 11 | return addf3(f16, a, neg_b); | ||
| 12 | } | ||
lib/compiler_rt/subsf3.zig deleted-24| ... | @@ -1,24 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const addf3 = @import("./addf3.zig").addf3; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_aeabi) { | ||
| 7 | symbol(&__aeabi_fsub, "__aeabi_fsub"); | ||
| 8 | } else { | ||
| 9 | symbol(&__subsf3, "__subsf3"); | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | fn __subsf3(a: f32, b: f32) callconv(.c) f32 { | ||
| 14 | return sub(a, b); | ||
| 15 | } | ||
| 16 | |||
| 17 | fn __aeabi_fsub(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 { | ||
| 18 | return sub(a, b); | ||
| 19 | } | ||
| 20 | |||
| 21 | inline fn sub(a: f32, b: f32) f32 { | ||
| 22 | const neg_b = @as(f32, @bitCast(@as(u32, @bitCast(b)) ^ (@as(u32, 1) << 31))); | ||
| 23 | return addf3(f32, a, neg_b); | ||
| 24 | } | ||
lib/compiler_rt/subtf3.zig deleted-27| ... | @@ -1,27 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const addf3 = @import("./addf3.zig").addf3; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_ppc_abi) { | ||
| 7 | symbol(&__subtf3, "__subkf3"); | ||
| 8 | } else if (compiler_rt.want_sparc64_abi) { | ||
| 9 | symbol(&_Qp_sub, "_Qp_sub"); | ||
| 10 | } else if (compiler_rt.want_sparc32_abi) { | ||
| 11 | symbol(&__subtf3, "_Q_sub"); | ||
| 12 | } | ||
| 13 | symbol(&__subtf3, "__subtf3"); | ||
| 14 | } | ||
| 15 | |||
| 16 | pub fn __subtf3(a: f128, b: f128) callconv(.c) f128 { | ||
| 17 | return sub(a, b); | ||
| 18 | } | ||
| 19 | |||
| 20 | fn _Qp_sub(c: *f128, a: *const f128, b: *const f128) callconv(.c) void { | ||
| 21 | c.* = sub(a.*, b.*); | ||
| 22 | } | ||
| 23 | |||
| 24 | inline fn sub(a: f128, b: f128) f128 { | ||
| 25 | const neg_b = @as(f128, @bitCast(@as(u128, @bitCast(b)) ^ (@as(u128, 1) << 127))); | ||
| 26 | return addf3(f128, a, neg_b); | ||
| 27 | } | ||
lib/compiler_rt/subvdi3.zig+3-2| ... | @@ -1,5 +1,6 @@ | ... | @@ -1,5 +1,6 @@ |
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 2 | const testing = @import("std").testing; | 1 | const testing = @import("std").testing; |
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 3 | const symbol = compiler_rt.symbol; | ||
| 3 | 4 | ||
| 4 | comptime { | 5 | comptime { |
| 5 | symbol(&__subvdi3, "__subvdi3"); | 6 | symbol(&__subvdi3, "__subvdi3"); |
| ... | @@ -9,7 +10,7 @@ pub fn __subvdi3(a: i64, b: i64) callconv(.c) i64 { | ... | @@ -9,7 +10,7 @@ pub fn __subvdi3(a: i64, b: i64) callconv(.c) i64 { |
| 9 | const sum = a -% b; | 10 | const sum = a -% b; |
| 10 | // Overflow occurred iff the operands have opposite signs, and the sign of the | 11 | // Overflow occurred iff the operands have opposite signs, and the sign of the |
| 11 | // sum is the opposite of the lhs sign. | 12 | // sum is the opposite of the lhs sign. |
| 12 | if (((a ^ b) & (sum ^ a)) < 0) @panic("compiler-rt: integer overflow"); | 13 | if (((a ^ b) & (sum ^ a)) < 0) @panic("integer overflow"); |
| 13 | return sum; | 14 | return sum; |
| 14 | } | 15 | } |
| 15 | 16 |
lib/compiler_rt/subvsi3.zig+1-1| ... | @@ -10,7 +10,7 @@ pub fn __subvsi3(a: i32, b: i32) callconv(.c) i32 { | ... | @@ -10,7 +10,7 @@ pub fn __subvsi3(a: i32, b: i32) callconv(.c) i32 { |
| 10 | const sum = a -% b; | 10 | const sum = a -% b; |
| 11 | // Overflow occurred iff the operands have opposite signs, and the sign of the | 11 | // Overflow occurred iff the operands have opposite signs, and the sign of the |
| 12 | // sum is the opposite of the lhs sign. | 12 | // sum is the opposite of the lhs sign. |
| 13 | if (((a ^ b) & (sum ^ a)) < 0) @panic("compiler-rt: integer overflow"); | 13 | if (((a ^ b) & (sum ^ a)) < 0) @panic("integer overflow"); |
| 14 | return sum; | 14 | return sum; |
| 15 | } | 15 | } |
| 16 | 16 |
lib/compiler_rt/subxf3.zig deleted-13| ... | @@ -1,13 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 3 | |||
| 4 | comptime { | ||
| 5 | symbol(&__subxf3, "__subxf3"); | ||
| 6 | } | ||
| 7 | |||
| 8 | fn __subxf3(a: f80, b: f80) callconv(.c) f80 { | ||
| 9 | var b_rep = std.math.F80.fromFloat(b); | ||
| 10 | b_rep.exp ^= 0x8000; | ||
| 11 | const neg_b = b_rep.toFloat(); | ||
| 12 | return a + neg_b; | ||
| 13 | } | ||
lib/compiler_rt/tan.zig+53-37| ... | @@ -21,26 +21,29 @@ const rem_pio2l = @import("rem_pio2l.zig").rem_pio2l; | ... | @@ -21,26 +21,29 @@ const rem_pio2l = @import("rem_pio2l.zig").rem_pio2l; |
| 21 | 21 | ||
| 22 | const arch = builtin.cpu.arch; | 22 | const arch = builtin.cpu.arch; |
| 23 | const compiler_rt = @import("../compiler_rt.zig"); | 23 | const compiler_rt = @import("../compiler_rt.zig"); |
| 24 | const symbol = @import("../compiler_rt.zig").symbol; | 24 | const symbol = compiler_rt.symbol; |
| 25 | 25 | ||
| 26 | comptime { | 26 | comptime { |
| 27 | symbol(&tanh, "__tanh"); | 27 | symbol(&__tanh, "__tanh"); |
| 28 | symbol(&tanf, "tanf"); | 28 | symbol(&tanf, "tanf"); |
| 29 | symbol(&tan, "tan"); | 29 | symbol(&tan, "tan"); |
| 30 | symbol(&tanx, "__tanx"); | 30 | symbol(&__tanx, "__tanx"); |
| 31 | if (compiler_rt.want_ppc_abi) { | 31 | symbol(&tanq, "tanf128"); |
| 32 | symbol(&tanq, "tanf128"); | ||
| 33 | } | ||
| 34 | symbol(&tanq, "tanq"); | ||
| 35 | symbol(&tanl, "tanl"); | 32 | symbol(&tanl, "tanl"); |
| 36 | } | 33 | } |
| 37 | 34 | ||
| 38 | pub fn tanh(x: f16) callconv(.c) f16 { | 35 | fn __tanh(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { |
| 36 | return compiler_rt.f16.toAbi(tan_f16(compiler_rt.f16.fromAbi(x))); | ||
| 37 | } | ||
| 38 | pub fn tan_f16(x: f16) f16 { | ||
| 39 | // TODO: more efficient implementation | 39 | // TODO: more efficient implementation |
| 40 | return @floatCast(tanf(x)); | 40 | return @floatCast(tan_f32(x)); |
| 41 | } | 41 | } |
| 42 | 42 | ||
| 43 | pub fn tanf(x: f32) callconv(.c) f32 { | 43 | fn tanf(x: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { |
| 44 | return compiler_rt.f32.toAbi(tan_f32(compiler_rt.f32.fromAbi(x))); | ||
| 45 | } | ||
| 46 | pub fn tan_f32(x: f32) f32 { | ||
| 44 | // Small multiples of pi/2 rounded to double precision. | 47 | // Small multiples of pi/2 rounded to double precision. |
| 45 | const t1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D18 | 48 | const t1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D18 |
| 46 | const t2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D18 | 49 | const t2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D18 |
| ... | @@ -90,7 +93,10 @@ pub fn tanf(x: f32) callconv(.c) f32 { | ... | @@ -90,7 +93,10 @@ pub fn tanf(x: f32) callconv(.c) f32 { |
| 90 | return kernel.tandf(y, n & 1 != 0); | 93 | return kernel.tandf(y, n & 1 != 0); |
| 91 | } | 94 | } |
| 92 | 95 | ||
| 93 | pub fn tan(x: f64) callconv(.c) f64 { | 96 | fn tan(x: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { |
| 97 | return compiler_rt.f64.toAbi(tan_f64(compiler_rt.f64.fromAbi(x))); | ||
| 98 | } | ||
| 99 | pub fn tan_f64(x: f64) f64 { | ||
| 94 | var ix = @as(u64, @bitCast(x)) >> 32; | 100 | var ix = @as(u64, @bitCast(x)) >> 32; |
| 95 | ix &= 0x7fffffff; | 101 | ix &= 0x7fffffff; |
| 96 | 102 | ||
| ... | @@ -120,7 +126,10 @@ pub fn tan(x: f64) callconv(.c) f64 { | ... | @@ -120,7 +126,10 @@ pub fn tan(x: f64) callconv(.c) f64 { |
| 120 | return kernel.tan(y[0], y[1], n & 1 != 0); | 126 | return kernel.tan(y[0], y[1], n & 1 != 0); |
| 121 | } | 127 | } |
| 122 | 128 | ||
| 123 | pub fn tanx(x: f80) callconv(.c) f80 { | 129 | fn __tanx(x: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { |
| 130 | return compiler_rt.f80.toAbi(tan_f80(compiler_rt.f80.fromAbi(x))); | ||
| 131 | } | ||
| 132 | pub fn tan_f80(x: f80) f80 { | ||
| 124 | const se = ld.signExponent(x) & 0x7fff; | 133 | const se = ld.signExponent(x) & 0x7fff; |
| 125 | if (se == 0x7fff) { | 134 | if (se == 0x7fff) { |
| 126 | return x - x; | 135 | return x - x; |
| ... | @@ -141,7 +150,10 @@ pub fn tanx(x: f80) callconv(.c) f80 { | ... | @@ -141,7 +150,10 @@ pub fn tanx(x: f80) callconv(.c) f80 { |
| 141 | return kernel.tanx(y[0], y[1], n & 1); | 150 | return kernel.tanx(y[0], y[1], n & 1); |
| 142 | } | 151 | } |
| 143 | 152 | ||
| 144 | pub fn tanq(x: f128) callconv(.c) f128 { | 153 | fn tanq(x: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { |
| 154 | return compiler_rt.f128.toAbi(tan_f128(compiler_rt.f128.fromAbi(x))); | ||
| 155 | } | ||
| 156 | pub fn tan_f128(x: f128) f128 { | ||
| 145 | const se = ld.signExponent(x) & 0x7fff; | 157 | const se = ld.signExponent(x) & 0x7fff; |
| 146 | if (se == 0x7fff) { | 158 | if (se == 0x7fff) { |
| 147 | return x - x; | 159 | return x - x; |
| ... | @@ -164,18 +176,21 @@ pub fn tanq(x: f128) callconv(.c) f128 { | ... | @@ -164,18 +176,21 @@ pub fn tanq(x: f128) callconv(.c) f128 { |
| 164 | 176 | ||
| 165 | pub fn tanl(x: c_longdouble) callconv(.c) c_longdouble { | 177 | pub fn tanl(x: c_longdouble) callconv(.c) c_longdouble { |
| 166 | switch (@typeInfo(c_longdouble).float.bits) { | 178 | switch (@typeInfo(c_longdouble).float.bits) { |
| 167 | 64 => return tan(x), | 179 | 64 => return tan_f64(x), |
| 168 | 80 => return tanx(x), | 180 | 80 => return tan_f80(x), |
| 169 | 128 => return tanq(x), | 181 | 128 => return tan_f128(x), |
| 170 | else => @compileError("unreachable"), | 182 | else => comptime unreachable, |
| 171 | } | 183 | } |
| 172 | } | 184 | } |
| 173 | 185 | ||
| 174 | fn testTanNormal(comptime T: type) !void { | 186 | fn testTanNormal(comptime T: type) !void { |
| 175 | const f = switch (T) { | 187 | const f = switch (T) { |
| 176 | f32 => tanf, | 188 | f16 => tan_f16, |
| 177 | f64 => tan, | 189 | f32 => tan_f32, |
| 178 | else => @compileError("unimplemented"), | 190 | f64 => tan_f64, |
| 191 | f80 => tan_f80, | ||
| 192 | f128 => tan_f128, | ||
| 193 | else => comptime unreachable, | ||
| 179 | }; | 194 | }; |
| 180 | const epsilon = 0.00001; | 195 | const epsilon = 0.00001; |
| 181 | 196 | ||
| ... | @@ -189,11 +204,12 @@ fn testTanNormal(comptime T: type) !void { | ... | @@ -189,11 +204,12 @@ fn testTanNormal(comptime T: type) !void { |
| 189 | 204 | ||
| 190 | fn testTanSpecial(comptime T: type) !void { | 205 | fn testTanSpecial(comptime T: type) !void { |
| 191 | const f = switch (T) { | 206 | const f = switch (T) { |
| 192 | f32 => tanf, | 207 | f16 => tan_f16, |
| 193 | f64 => tan, | 208 | f32 => tan_f32, |
| 194 | f80 => tanx, | 209 | f64 => tan_f64, |
| 195 | f128 => tanq, | 210 | f80 => tan_f80, |
| 196 | else => @compileError("unimplemented"), | 211 | f128 => tan_f128, |
| 212 | else => comptime unreachable, | ||
| 197 | }; | 213 | }; |
| 198 | 214 | ||
| 199 | try expect(math.isPositiveZero(f(0.0))); | 215 | try expect(math.isPositiveZero(f(0.0))); |
| ... | @@ -214,23 +230,23 @@ test "tan64.normal" { | ... | @@ -214,23 +230,23 @@ test "tan64.normal" { |
| 214 | test "tan80.normal" { | 230 | test "tan80.normal" { |
| 215 | const epsilon = math.floatEps(f80); | 231 | const epsilon = math.floatEps(f80); |
| 216 | 232 | ||
| 217 | try expectApproxEqAbs(@as(f80, 0.0), tanx(0.0), epsilon); | 233 | try expectApproxEqAbs(@as(f80, 0.0), tan_f80(0.0), epsilon); |
| 218 | try expectApproxEqAbs(@as(f80, 0.2027100355086724833213582716475345), tanx(0.2), epsilon); | 234 | try expectApproxEqAbs(@as(f80, 0.2027100355086724833213582716475345), tan_f80(0.2), epsilon); |
| 219 | try expectApproxEqAbs(@as(f80, 1.2404217445497097995561220131857544), tanx(0.8923), epsilon); | 235 | try expectApproxEqAbs(@as(f80, 1.2404217445497097995561220131857544), tan_f80(0.8923), epsilon); |
| 220 | try expectApproxEqAbs(@as(f80, 14.10141994717171938764), tanx(1.5), epsilon); | 236 | try expectApproxEqAbs(@as(f80, 14.10141994717171938764), tan_f80(1.5), epsilon); |
| 221 | try expectApproxEqAbs(@as(f80, -0.25439607116885656232), tanx(37.45), epsilon); | 237 | try expectApproxEqAbs(@as(f80, -0.25439607116885656232), tan_f80(37.45), epsilon); |
| 222 | try expectApproxEqAbs(@as(f80, 2.2858376251355320963), tanx(89.123), epsilon); | 238 | try expectApproxEqAbs(@as(f80, 2.2858376251355320963), tan_f80(89.123), epsilon); |
| 223 | } | 239 | } |
| 224 | 240 | ||
| 225 | test "tan128.normal" { | 241 | test "tan128.normal" { |
| 226 | const epsilon = math.floatEps(f128); | 242 | const epsilon = math.floatEps(f128); |
| 227 | 243 | ||
| 228 | try expectApproxEqAbs(@as(f128, 0.0), tanq(0.0), epsilon); | 244 | try expectApproxEqAbs(@as(f128, 0.0), tan_f128(0.0), epsilon); |
| 229 | try expectApproxEqAbs(@as(f128, 0.2027100355086724833213582716475345), tanq(0.2), epsilon); | 245 | try expectApproxEqAbs(@as(f128, 0.2027100355086724833213582716475345), tan_f128(0.2), epsilon); |
| 230 | try expectApproxEqAbs(@as(f128, 1.2404217445497097995561220131857544), tanq(0.8923), epsilon); | 246 | try expectApproxEqAbs(@as(f128, 1.2404217445497097995561220131857544), tan_f128(0.8923), epsilon); |
| 231 | try expectApproxEqAbs(@as(f128, 14.101419947171719387646083651987755), tanq(1.5), epsilon); | 247 | try expectApproxEqAbs(@as(f128, 14.101419947171719387646083651987755), tan_f128(1.5), epsilon); |
| 232 | try expectApproxEqAbs(@as(f128, -0.2543960711688565630469573224504774), tanq(37.45), epsilon); | 248 | try expectApproxEqAbs(@as(f128, -0.2543960711688565630469573224504774), tan_f128(37.45), epsilon); |
| 233 | try expectApproxEqAbs(@as(f128, 2.2858376251355321074066028114094292), tanq(89.123), epsilon); | 249 | try expectApproxEqAbs(@as(f128, 2.2858376251355321074066028114094292), tan_f128(89.123), epsilon); |
| 234 | } | 250 | } |
| 235 | 251 | ||
| 236 | test "tan32.special" { | 252 | test "tan32.special" { |
lib/compiler_rt/trunc.zig+77-47| ... | @@ -17,19 +17,22 @@ comptime { | ... | @@ -17,19 +17,22 @@ comptime { |
| 17 | symbol(&truncf, "truncf"); | 17 | symbol(&truncf, "truncf"); |
| 18 | symbol(&trunc, "trunc"); | 18 | symbol(&trunc, "trunc"); |
| 19 | symbol(&__truncx, "__truncx"); | 19 | symbol(&__truncx, "__truncx"); |
| 20 | if (compiler_rt.want_ppc_abi) { | 20 | symbol(&truncq, "truncf128"); |
| 21 | symbol(&truncq, "truncf128"); | ||
| 22 | } | ||
| 23 | symbol(&truncq, "truncq"); | ||
| 24 | symbol(&truncl, "truncl"); | 21 | symbol(&truncl, "truncl"); |
| 25 | } | 22 | } |
| 26 | 23 | ||
| 27 | pub fn __trunch(x: f16) callconv(.c) f16 { | 24 | fn __trunch(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { |
| 25 | return compiler_rt.f16.toAbi(trunc_f16(compiler_rt.f16.fromAbi(x))); | ||
| 26 | } | ||
| 27 | pub fn trunc_f16(x: f16) f16 { | ||
| 28 | // TODO: more efficient implementation | 28 | // TODO: more efficient implementation |
| 29 | return @floatCast(truncf(x)); | 29 | return @floatCast(trunc_f32(x)); |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | pub fn truncf(x: f32) callconv(.c) f32 { | 32 | fn truncf(x: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { |
| 33 | return compiler_rt.f32.toAbi(trunc_f32(compiler_rt.f32.fromAbi(x))); | ||
| 34 | } | ||
| 35 | pub fn trunc_f32(x: f32) f32 { | ||
| 33 | const u: u32 = @bitCast(x); | 36 | const u: u32 = @bitCast(x); |
| 34 | var e = @as(i32, @intCast(((u >> 23) & 0xFF))) - 0x7F + 9; | 37 | var e = @as(i32, @intCast(((u >> 23) & 0xFF))) - 0x7F + 9; |
| 35 | var m: u32 = undefined; | 38 | var m: u32 = undefined; |
| ... | @@ -50,7 +53,10 @@ pub fn truncf(x: f32) callconv(.c) f32 { | ... | @@ -50,7 +53,10 @@ pub fn truncf(x: f32) callconv(.c) f32 { |
| 50 | } | 53 | } |
| 51 | } | 54 | } |
| 52 | 55 | ||
| 53 | pub fn trunc(x: f64) callconv(.c) f64 { | 56 | fn trunc(x: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { |
| 57 | return compiler_rt.f64.toAbi(trunc_f64(compiler_rt.f64.fromAbi(x))); | ||
| 58 | } | ||
| 59 | pub fn trunc_f64(x: f64) f64 { | ||
| 54 | const u: u64 = @bitCast(x); | 60 | const u: u64 = @bitCast(x); |
| 55 | var e = @as(i32, @intCast(((u >> 52) & 0x7FF))) - 0x3FF + 12; | 61 | var e = @as(i32, @intCast(((u >> 52) & 0x7FF))) - 0x3FF + 12; |
| 56 | var m: u64 = undefined; | 62 | var m: u64 = undefined; |
| ... | @@ -71,12 +77,18 @@ pub fn trunc(x: f64) callconv(.c) f64 { | ... | @@ -71,12 +77,18 @@ pub fn trunc(x: f64) callconv(.c) f64 { |
| 71 | } | 77 | } |
| 72 | } | 78 | } |
| 73 | 79 | ||
| 74 | pub fn __truncx(x: f80) callconv(.c) f80 { | 80 | fn __truncx(x: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { |
| 81 | return compiler_rt.f80.toAbi(trunc_f80(compiler_rt.f80.fromAbi(x))); | ||
| 82 | } | ||
| 83 | pub fn trunc_f80(x: f80) f80 { | ||
| 75 | // TODO: more efficient implementation | 84 | // TODO: more efficient implementation |
| 76 | return @floatCast(truncq(x)); | 85 | return @floatCast(trunc_f128(x)); |
| 77 | } | 86 | } |
| 78 | 87 | ||
| 79 | pub fn truncq(x: f128) callconv(.c) f128 { | 88 | fn truncq(x: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { |
| 89 | return compiler_rt.f128.toAbi(trunc_f128(compiler_rt.f128.fromAbi(x))); | ||
| 90 | } | ||
| 91 | pub fn trunc_f128(x: f128) f128 { | ||
| 80 | const u: u128 = @bitCast(x); | 92 | const u: u128 = @bitCast(x); |
| 81 | var e = @as(i32, @intCast(((u >> 112) & 0x7FFF))) - 0x3FFF + 16; | 93 | var e = @as(i32, @intCast(((u >> 112) & 0x7FFF))) - 0x3FFF + 16; |
| 82 | var m: u128 = undefined; | 94 | var m: u128 = undefined; |
| ... | @@ -99,51 +111,69 @@ pub fn truncq(x: f128) callconv(.c) f128 { | ... | @@ -99,51 +111,69 @@ pub fn truncq(x: f128) callconv(.c) f128 { |
| 99 | 111 | ||
| 100 | pub fn truncl(x: c_longdouble) callconv(.c) c_longdouble { | 112 | pub fn truncl(x: c_longdouble) callconv(.c) c_longdouble { |
| 101 | switch (@typeInfo(c_longdouble).float.bits) { | 113 | switch (@typeInfo(c_longdouble).float.bits) { |
| 102 | 64 => return trunc(x), | 114 | 64 => return trunc_f64(x), |
| 103 | 80 => return __truncx(x), | 115 | 80 => return trunc_f80(x), |
| 104 | 128 => return truncq(x), | 116 | 128 => return trunc_f128(x), |
| 105 | else => @compileError("unreachable"), | 117 | else => comptime unreachable, |
| 106 | } | 118 | } |
| 107 | } | 119 | } |
| 108 | 120 | ||
| 109 | test "trunc32" { | 121 | test trunc_f16 { |
| 110 | try expect(truncf(1.3) == 1.0); | 122 | try expect(trunc_f16(1.3) == 1.0); |
| 111 | try expect(truncf(-1.3) == -1.0); | 123 | try expect(trunc_f16(-1.3) == -1.0); |
| 112 | try expect(truncf(0.2) == 0.0); | 124 | try expect(math.isPositiveZero(trunc_f16(0.2))); |
| 113 | } | 125 | try expect(math.isNegativeZero(trunc_f16(-0.2))); |
| 114 | 126 | try expect(math.isPositiveZero(trunc_f16(0.0))); | |
| 115 | test "trunc64" { | 127 | try expect(math.isNegativeZero(trunc_f16(-0.0))); |
| 116 | try expect(trunc(1.3) == 1.0); | 128 | try expect(math.isPositiveInf(trunc_f16(math.inf(f32)))); |
| 117 | try expect(trunc(-1.3) == -1.0); | 129 | try expect(math.isNegativeInf(trunc_f16(-math.inf(f32)))); |
| 118 | try expect(trunc(0.2) == 0.0); | 130 | try expect(math.isNan(trunc_f16(math.nan(f32)))); |
| 119 | } | 131 | } |
| 120 | 132 | ||
| 121 | test "trunc128" { | 133 | test trunc_f32 { |
| 122 | try expect(truncq(1.3) == 1.0); | 134 | try expect(trunc_f32(1.3) == 1.0); |
| 123 | try expect(truncq(-1.3) == -1.0); | 135 | try expect(trunc_f32(-1.3) == -1.0); |
| 124 | try expect(truncq(0.2) == 0.0); | 136 | try expect(math.isPositiveZero(trunc_f32(0.2))); |
| 137 | try expect(math.isNegativeZero(trunc_f32(-0.2))); | ||
| 138 | try expect(math.isPositiveZero(trunc_f32(0.0))); | ||
| 139 | try expect(math.isNegativeZero(trunc_f32(-0.0))); | ||
| 140 | try expect(math.isPositiveInf(trunc_f32(math.inf(f32)))); | ||
| 141 | try expect(math.isNegativeInf(trunc_f32(-math.inf(f32)))); | ||
| 142 | try expect(math.isNan(trunc_f32(math.nan(f32)))); | ||
| 125 | } | 143 | } |
| 126 | 144 | ||
| 127 | test "trunc32.special" { | 145 | test trunc_f64 { |
| 128 | try expect(truncf(0.0) == 0.0); // 0x3F800000 | 146 | try expect(trunc_f64(1.3) == 1.0); |
| 129 | try expect(truncf(-0.0) == -0.0); | 147 | try expect(trunc_f64(-1.3) == -1.0); |
| 130 | try expect(math.isPositiveInf(truncf(math.inf(f32)))); | 148 | try expect(math.isPositiveZero(trunc_f64(0.2))); |
| 131 | try expect(math.isNegativeInf(truncf(-math.inf(f32)))); | 149 | try expect(math.isNegativeZero(trunc_f64(-0.2))); |
| 132 | try expect(math.isNan(truncf(math.nan(f32)))); | 150 | try expect(math.isPositiveZero(trunc_f64(0.0))); |
| 151 | try expect(math.isNegativeZero(trunc_f64(-0.0))); | ||
| 152 | try expect(math.isPositiveInf(trunc_f64(math.inf(f64)))); | ||
| 153 | try expect(math.isNegativeInf(trunc_f64(-math.inf(f64)))); | ||
| 154 | try expect(math.isNan(trunc_f64(math.nan(f64)))); | ||
| 133 | } | 155 | } |
| 134 | 156 | ||
| 135 | test "trunc64.special" { | 157 | test trunc_f80 { |
| 136 | try expect(trunc(0.0) == 0.0); | 158 | try expect(trunc_f80(1.3) == 1.0); |
| 137 | try expect(trunc(-0.0) == -0.0); | 159 | try expect(trunc_f80(-1.3) == -1.0); |
| 138 | try expect(math.isPositiveInf(trunc(math.inf(f64)))); | 160 | try expect(math.isPositiveZero(trunc_f80(0.2))); |
| 139 | try expect(math.isNegativeInf(trunc(-math.inf(f64)))); | 161 | try expect(math.isNegativeZero(trunc_f80(-0.2))); |
| 140 | try expect(math.isNan(trunc(math.nan(f64)))); | 162 | try expect(math.isPositiveZero(trunc_f80(0.0))); |
| 163 | try expect(math.isNegativeZero(trunc_f80(-0.0))); | ||
| 164 | try expect(math.isPositiveInf(trunc_f80(math.inf(f64)))); | ||
| 165 | try expect(math.isNegativeInf(trunc_f80(-math.inf(f64)))); | ||
| 166 | try expect(math.isNan(trunc_f80(math.nan(f64)))); | ||
| 141 | } | 167 | } |
| 142 | 168 | ||
| 143 | test "trunc128.special" { | 169 | test trunc_f128 { |
| 144 | try expect(truncq(0.0) == 0.0); | 170 | try expect(trunc_f128(1.3) == 1.0); |
| 145 | try expect(truncq(-0.0) == -0.0); | 171 | try expect(trunc_f128(-1.3) == -1.0); |
| 146 | try expect(math.isPositiveInf(truncq(math.inf(f128)))); | 172 | try expect(math.isPositiveZero(trunc_f128(0.2))); |
| 147 | try expect(math.isNegativeInf(truncq(-math.inf(f128)))); | 173 | try expect(math.isNegativeZero(trunc_f128(-0.2))); |
| 148 | try expect(math.isNan(truncq(math.nan(f128)))); | 174 | try expect(math.isPositiveZero(trunc_f128(0.0))); |
| 175 | try expect(math.isNegativeZero(trunc_f128(-0.0))); | ||
| 176 | try expect(math.isPositiveInf(trunc_f128(math.inf(f128)))); | ||
| 177 | try expect(math.isNegativeInf(trunc_f128(-math.inf(f128)))); | ||
| 178 | try expect(math.isNan(trunc_f128(math.nan(f128)))); | ||
| 149 | } | 179 | } |
lib/compiler_rt/truncdfhf2.zig deleted-18| ... | @@ -1,18 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const truncf = @import("./truncf.zig").truncf; | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_aeabi) { | ||
| 7 | symbol(&__aeabi_d2h, "__aeabi_d2h"); | ||
| 8 | } | ||
| 9 | symbol(&__truncdfhf2, "__truncdfhf2"); | ||
| 10 | } | ||
| 11 | |||
| 12 | pub fn __truncdfhf2(a: f64) callconv(.c) compiler_rt.F16T(f64) { | ||
| 13 | return @bitCast(truncf(f16, f64, a)); | ||
| 14 | } | ||
| 15 | |||
| 16 | fn __aeabi_d2h(a: f64) callconv(.{ .arm_aapcs = .{} }) u16 { | ||
| 17 | return @bitCast(truncf(f16, f64, a)); | ||
| 18 | } | ||
lib/compiler_rt/truncdfsf2.zig deleted-19| ... | @@ -1,19 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const truncf = @import("./truncf.zig").truncf; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_aeabi) { | ||
| 7 | symbol(&__aeabi_d2f, "__aeabi_d2f"); | ||
| 8 | } else { | ||
| 9 | symbol(&__truncdfsf2, "__truncdfsf2"); | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | pub fn __truncdfsf2(a: f64) callconv(.c) f32 { | ||
| 14 | return truncf(f32, f64, a); | ||
| 15 | } | ||
| 16 | |||
| 17 | fn __aeabi_d2f(a: f64) callconv(.{ .arm_aapcs = .{} }) f32 { | ||
| 18 | return truncf(f32, f64, a); | ||
| 19 | } | ||
lib/compiler_rt/truncf.zig+200-2| ... | @@ -1,6 +1,204 @@ | ... | @@ -1,6 +1,204 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | 2 | ||
| 3 | pub inline fn truncf(comptime dst_t: type, comptime src_t: type, a: src_t) dst_t { | 3 | const compiler_rt = @import("../compiler_rt.zig"); |
| 4 | const symbol = compiler_rt.symbol; | ||
| 5 | |||
| 6 | comptime { | ||
| 7 | if (compiler_rt.want_aeabi) { | ||
| 8 | if (compiler_rt.gnu_f16_abi) { | ||
| 9 | symbol(&__aeabi_f2h, "__gnu_f2h_ieee"); | ||
| 10 | } else { | ||
| 11 | symbol(&__aeabi_f2h, "__aeabi_f2h"); | ||
| 12 | } | ||
| 13 | symbol(&__aeabi_d2h, "__aeabi_d2h"); | ||
| 14 | } else if (compiler_rt.gnu_f16_abi) { | ||
| 15 | symbol(&__truncsfhf2, "__gnu_f2h_ieee"); | ||
| 16 | } | ||
| 17 | symbol(&__truncsfhf2, "__truncsfhf2"); | ||
| 18 | symbol(&__truncdfhf2, "__truncdfhf2"); | ||
| 19 | symbol(&__truncxfhf2, "__truncxfhf2"); | ||
| 20 | if (compiler_rt.want_ppc_abi) { | ||
| 21 | symbol(&__trunctfhf2, "__trunckfhf2"); | ||
| 22 | } else { | ||
| 23 | symbol(&__trunctfhf2, "__trunctfhf2"); | ||
| 24 | } | ||
| 25 | |||
| 26 | if (compiler_rt.want_aeabi) { | ||
| 27 | symbol(&__aeabi_d2f, "__aeabi_d2f"); | ||
| 28 | } else { | ||
| 29 | symbol(&__truncdfsf2, "__truncdfsf2"); | ||
| 30 | } | ||
| 31 | symbol(&__truncxfsf2, "__truncxfsf2"); | ||
| 32 | if (compiler_rt.want_ppc_abi) { | ||
| 33 | symbol(&__trunctfsf2, "__trunckfsf2"); | ||
| 34 | } else if (compiler_rt.want_sparc64_abi) { | ||
| 35 | symbol(&_Qp_qtos, "_Qp_qtos"); | ||
| 36 | } else if (compiler_rt.want_sparc32_abi) { | ||
| 37 | symbol(&__trunctfsf2, "_Q_qtos"); | ||
| 38 | } else { | ||
| 39 | symbol(&__trunctfsf2, "__trunctfsf2"); | ||
| 40 | } | ||
| 41 | |||
| 42 | symbol(&__truncxfdf2, "__truncxfdf2"); | ||
| 43 | |||
| 44 | if (compiler_rt.want_ppc_abi) { | ||
| 45 | symbol(&__trunctfdf2, "__trunckfdf2"); | ||
| 46 | } else if (compiler_rt.want_sparc64_abi) { | ||
| 47 | symbol(&_Qp_qtod, "_Qp_qtod"); | ||
| 48 | } else if (compiler_rt.want_sparc32_abi) { | ||
| 49 | symbol(&__trunctfdf2, "_Q_qtod"); | ||
| 50 | } else { | ||
| 51 | symbol(&__trunctfdf2, "__trunctfdf2"); | ||
| 52 | } | ||
| 53 | |||
| 54 | if (compiler_rt.want_ppc_abi) { | ||
| 55 | symbol(&__trunctfxf2, "__trunckfxf2"); | ||
| 56 | } else { | ||
| 57 | symbol(&__trunctfxf2, "__trunctfxf2"); | ||
| 58 | } | ||
| 59 | } | ||
| 60 | |||
| 61 | fn __truncsfhf2(a: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f16Conv(f32).Abi { | ||
| 62 | return compiler_rt.f16Conv(f32).toAbi(f16_floatCast_f32(compiler_rt.f32.fromAbi(a))); | ||
| 63 | } | ||
| 64 | fn __aeabi_f2h(a: u32) callconv(.{ .arm_aapcs = .{} }) u16 { | ||
| 65 | return @bitCast(f16_floatCast_f32(@bitCast(a))); | ||
| 66 | } | ||
| 67 | pub fn f16_floatCast_f32(a: f32) f16 { | ||
| 68 | return truncf(f16, f32, a); | ||
| 69 | } | ||
| 70 | |||
| 71 | fn __truncdfhf2(a: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f16Conv(f64).Abi { | ||
| 72 | return compiler_rt.f16Conv(f64).toAbi(f16_floatCast_f64(compiler_rt.f64.fromAbi(a))); | ||
| 73 | } | ||
| 74 | fn __aeabi_d2h(a: u64) callconv(.{ .arm_aapcs = .{} }) u16 { | ||
| 75 | return @bitCast(f16_floatCast_f64(@bitCast(a))); | ||
| 76 | } | ||
| 77 | pub fn f16_floatCast_f64(a: f64) f16 { | ||
| 78 | return truncf(f16, f64, a); | ||
| 79 | } | ||
| 80 | |||
| 81 | fn __truncxfhf2(a: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f16Conv(f80).Abi { | ||
| 82 | return compiler_rt.f16Conv(f80).toAbi(f16_floatCast_f80(compiler_rt.f80.fromAbi(a))); | ||
| 83 | } | ||
| 84 | pub fn f16_floatCast_f80(a: f80) f16 { | ||
| 85 | return trunc_f80(f16, a); | ||
| 86 | } | ||
| 87 | |||
| 88 | fn __trunctfhf2(a: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f16Conv(f128).Abi { | ||
| 89 | return compiler_rt.f16Conv(f128).toAbi(f16_floatCast_f128(compiler_rt.f128.fromAbi(a))); | ||
| 90 | } | ||
| 91 | pub fn f16_floatCast_f128(a: f128) f16 { | ||
| 92 | return truncf(f16, f128, a); | ||
| 93 | } | ||
| 94 | |||
| 95 | fn __truncdfsf2(a: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f32.Abi { | ||
| 96 | return compiler_rt.f32.toAbi(f32_floatCast_f64(compiler_rt.f64.fromAbi(a))); | ||
| 97 | } | ||
| 98 | fn __aeabi_d2f(a: f64) callconv(.{ .arm_aapcs = .{} }) f32 { | ||
| 99 | return f32_floatCast_f64(a); | ||
| 100 | } | ||
| 101 | pub fn f32_floatCast_f64(a: f64) f32 { | ||
| 102 | return truncf(f32, f64, a); | ||
| 103 | } | ||
| 104 | |||
| 105 | fn __truncxfsf2(a: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f32.Abi { | ||
| 106 | return compiler_rt.f32.toAbi(f32_floatCast_f80(compiler_rt.f80.fromAbi(a))); | ||
| 107 | } | ||
| 108 | pub fn f32_floatCast_f80(a: f80) f32 { | ||
| 109 | return trunc_f80(f32, a); | ||
| 110 | } | ||
| 111 | |||
| 112 | fn __trunctfsf2(a: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f32.Abi { | ||
| 113 | return compiler_rt.f32.toAbi(f32_floatCast_f128(compiler_rt.f128.fromAbi(a))); | ||
| 114 | } | ||
| 115 | fn _Qp_qtos(a: *const f128) callconv(.c) f32 { | ||
| 116 | return f32_floatCast_f128(a.*); | ||
| 117 | } | ||
| 118 | pub fn f32_floatCast_f128(a: f128) f32 { | ||
| 119 | return truncf(f32, f128, a); | ||
| 120 | } | ||
| 121 | |||
| 122 | fn __truncxfdf2(a: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f64.Abi { | ||
| 123 | return compiler_rt.f64.toAbi(f64_floatCast_f80(compiler_rt.f80.fromAbi(a))); | ||
| 124 | } | ||
| 125 | pub fn f64_floatCast_f80(a: f80) f64 { | ||
| 126 | return trunc_f80(f64, a); | ||
| 127 | } | ||
| 128 | |||
| 129 | fn __trunctfdf2(a: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f64.Abi { | ||
| 130 | return compiler_rt.f64.toAbi(f64_floatCast_f128(compiler_rt.f128.fromAbi(a))); | ||
| 131 | } | ||
| 132 | fn _Qp_qtod(a: *const f128) callconv(.c) f64 { | ||
| 133 | return f64_floatCast_f128(a.*); | ||
| 134 | } | ||
| 135 | pub fn f64_floatCast_f128(a: f128) f64 { | ||
| 136 | return truncf(f64, f128, a); | ||
| 137 | } | ||
| 138 | |||
| 139 | fn __trunctfxf2(a: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f80.Abi { | ||
| 140 | return compiler_rt.f80.toAbi(f80_floatCast_f128(compiler_rt.f128.fromAbi(a))); | ||
| 141 | } | ||
| 142 | pub fn f80_floatCast_f128(a: f128) f80 { | ||
| 143 | const src_sig_bits = std.math.floatMantissaBits(f128); | ||
| 144 | const dst_sig_bits = std.math.floatMantissaBits(f80) - 1; // -1 for the integer bit | ||
| 145 | |||
| 146 | // Various constants whose values follow from the type parameters. | ||
| 147 | // Any reasonable optimizer will fold and propagate all of these. | ||
| 148 | const src_bits = @typeInfo(f128).float.bits; | ||
| 149 | const src_exp_bits = src_bits - src_sig_bits - 1; | ||
| 150 | const src_inf_exp = 0x7FFF; | ||
| 151 | |||
| 152 | const src_inf = src_inf_exp << src_sig_bits; | ||
| 153 | const src_sign_mask = 1 << (src_sig_bits + src_exp_bits); | ||
| 154 | const src_abs_mask = src_sign_mask - 1; | ||
| 155 | const round_mask = (1 << (src_sig_bits - dst_sig_bits)) - 1; | ||
| 156 | const halfway = 1 << (src_sig_bits - dst_sig_bits - 1); | ||
| 157 | |||
| 158 | // Break a into a sign and representation of the absolute value | ||
| 159 | const a_rep: u128 = @bitCast(a); | ||
| 160 | const a_abs = a_rep & src_abs_mask; | ||
| 161 | const sign: u16 = if (a_rep & src_sign_mask != 0) 0x8000 else 0; | ||
| 162 | const integer_bit = 1 << 63; | ||
| 163 | |||
| 164 | var res: std.math.F80 = undefined; | ||
| 165 | |||
| 166 | if (a_abs > src_inf) { | ||
| 167 | // a is NaN. | ||
| 168 | // Conjure the result by beginning with infinity, setting the qNaN | ||
| 169 | // bit and inserting the (truncated) trailing NaN field. | ||
| 170 | res.exp = 0x7fff; | ||
| 171 | res.fraction = 0x8000000000000000; | ||
| 172 | res.fraction |= @as(u64, @truncate(a_abs >> (src_sig_bits - dst_sig_bits))); | ||
| 173 | } else { | ||
| 174 | // The exponent of a is within the range of normal numbers in the | ||
| 175 | // destination format. We can convert by simply right-shifting with | ||
| 176 | // rounding, adding the explicit integer bit, and adjusting the exponent | ||
| 177 | res.fraction = @as(u64, @truncate(a_abs >> (src_sig_bits - dst_sig_bits))) | integer_bit; | ||
| 178 | res.exp = @truncate(a_abs >> src_sig_bits); | ||
| 179 | |||
| 180 | const round_bits = a_abs & round_mask; | ||
| 181 | if (round_bits > halfway) { | ||
| 182 | // Round to nearest | ||
| 183 | const ov = @addWithOverflow(res.fraction, 1); | ||
| 184 | res.fraction = ov[0]; | ||
| 185 | res.exp += ov[1]; | ||
| 186 | res.fraction |= @as(u64, ov[1]) << 63; // Restore integer bit after carry | ||
| 187 | } else if (round_bits == halfway) { | ||
| 188 | // Ties to even | ||
| 189 | const ov = @addWithOverflow(res.fraction, res.fraction & 1); | ||
| 190 | res.fraction = ov[0]; | ||
| 191 | res.exp += ov[1]; | ||
| 192 | res.fraction |= @as(u64, ov[1]) << 63; // Restore integer bit after carry | ||
| 193 | } | ||
| 194 | if (res.exp == 0) res.fraction &= ~@as(u64, integer_bit); // Remove integer bit for de-normals | ||
| 195 | } | ||
| 196 | |||
| 197 | res.exp |= sign; | ||
| 198 | return res.toFloat(); | ||
| 199 | } | ||
| 200 | |||
| 201 | inline fn truncf(comptime dst_t: type, comptime src_t: type, a: src_t) dst_t { | ||
| 4 | const src_rep_t = @Int(.unsigned, @typeInfo(src_t).float.bits); | 202 | const src_rep_t = @Int(.unsigned, @typeInfo(src_t).float.bits); |
| 5 | const dst_rep_t = @Int(.unsigned, @typeInfo(dst_t).float.bits); | 203 | const dst_rep_t = @Int(.unsigned, @typeInfo(dst_t).float.bits); |
| 6 | const srcSigBits = std.math.floatMantissaBits(src_t); | 204 | const srcSigBits = std.math.floatMantissaBits(src_t); |
| ... | @@ -99,7 +297,7 @@ pub inline fn truncf(comptime dst_t: type, comptime src_t: type, a: src_t) dst_t | ... | @@ -99,7 +297,7 @@ pub inline fn truncf(comptime dst_t: type, comptime src_t: type, a: src_t) dst_t |
| 99 | return @bitCast(result); | 297 | return @bitCast(result); |
| 100 | } | 298 | } |
| 101 | 299 | ||
| 102 | pub inline fn trunc_f80(comptime dst_t: type, a: f80) dst_t { | 300 | inline fn trunc_f80(comptime dst_t: type, a: f80) dst_t { |
| 103 | const dst_rep_t = @Int(.unsigned, @typeInfo(dst_t).float.bits); | 301 | const dst_rep_t = @Int(.unsigned, @typeInfo(dst_t).float.bits); |
| 104 | const src_sig_bits = std.math.floatMantissaBits(f80) - 1; // -1 for the integer bit | 302 | const src_sig_bits = std.math.floatMantissaBits(f80) - 1; // -1 for the integer bit |
| 105 | const dst_sig_bits = std.math.floatMantissaBits(dst_t); | 303 | const dst_sig_bits = std.math.floatMantissaBits(dst_t); |
lib/compiler_rt/truncf_test.zig+160-174| ... | @@ -1,79 +1,82 @@ | ... | @@ -1,79 +1,82 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const testing = std.testing; | 2 | const testing = std.testing; |
| 3 | 3 | ||
| 4 | const __truncsfhf2 = @import("truncsfhf2.zig").__truncsfhf2; | 4 | const impl = @import("truncf.zig"); |
| 5 | const __truncdfhf2 = @import("truncdfhf2.zig").__truncdfhf2; | ||
| 6 | const __truncdfsf2 = @import("truncdfsf2.zig").__truncdfsf2; | ||
| 7 | const __trunctfhf2 = @import("trunctfhf2.zig").__trunctfhf2; | ||
| 8 | const __trunctfsf2 = @import("trunctfsf2.zig").__trunctfsf2; | ||
| 9 | const __trunctfdf2 = @import("trunctfdf2.zig").__trunctfdf2; | ||
| 10 | const __trunctfxf2 = @import("trunctfxf2.zig").__trunctfxf2; | ||
| 11 | |||
| 12 | fn test__truncsfhf2(a: u32, expected: u16) !void { | ||
| 13 | const actual: u16 = @bitCast(__truncsfhf2(@bitCast(a))); | ||
| 14 | |||
| 15 | if (actual == expected) { | ||
| 16 | return; | ||
| 17 | } | ||
| 18 | 5 | ||
| 19 | return error.TestFailure; | 6 | const f16_floatCast_f32 = impl.f16_floatCast_f32; |
| 7 | const f16_floatCast_f64 = impl.f16_floatCast_f64; | ||
| 8 | const f16_floatCast_f80 = impl.f16_floatCast_f80; | ||
| 9 | const f16_floatCast_f128 = impl.f16_floatCast_f128; | ||
| 10 | |||
| 11 | const f32_floatCast_f64 = impl.f32_floatCast_f64; | ||
| 12 | const f32_floatCast_f80 = impl.f32_floatCast_f80; | ||
| 13 | const f32_floatCast_f128 = impl.f32_floatCast_f128; | ||
| 14 | |||
| 15 | const f64_floatCast_f80 = impl.f64_floatCast_f80; | ||
| 16 | const f64_floatCast_f128 = impl.f64_floatCast_f128; | ||
| 17 | |||
| 18 | const f80_floatCast_f128 = impl.f80_floatCast_f128; | ||
| 19 | |||
| 20 | fn test_f16_floatCast_f32(a: u32, expected: u16) !void { | ||
| 21 | const actual: u16 = @bitCast(f16_floatCast_f32(@bitCast(a))); | ||
| 22 | try testing.expect(actual == expected); | ||
| 20 | } | 23 | } |
| 21 | 24 | ||
| 22 | test "truncsfhf2" { | 25 | test f16_floatCast_f32 { |
| 23 | try test__truncsfhf2(0x7fc00000, 0x7e00); // qNaN | 26 | try test_f16_floatCast_f32(0x7fc00000, 0x7e00); // qNaN |
| 24 | try test__truncsfhf2(0x7fe00000, 0x7f00); // sNaN | 27 | try test_f16_floatCast_f32(0x7fe00000, 0x7f00); // sNaN |
| 25 | 28 | ||
| 26 | try test__truncsfhf2(0, 0); // 0 | 29 | try test_f16_floatCast_f32(0, 0); // 0 |
| 27 | try test__truncsfhf2(0x80000000, 0x8000); // -0 | 30 | try test_f16_floatCast_f32(0x80000000, 0x8000); // -0 |
| 28 | 31 | ||
| 29 | try test__truncsfhf2(0x7f800000, 0x7c00); // inf | 32 | try test_f16_floatCast_f32(0x7f800000, 0x7c00); // inf |
| 30 | try test__truncsfhf2(0xff800000, 0xfc00); // -inf | 33 | try test_f16_floatCast_f32(0xff800000, 0xfc00); // -inf |
| 31 | 34 | ||
| 32 | try test__truncsfhf2(0x477ff000, 0x7c00); // 65520 -> inf | 35 | try test_f16_floatCast_f32(0x477ff000, 0x7c00); // 65520 -> inf |
| 33 | try test__truncsfhf2(0xc77ff000, 0xfc00); // -65520 -> -inf | 36 | try test_f16_floatCast_f32(0xc77ff000, 0xfc00); // -65520 -> -inf |
| 34 | 37 | ||
| 35 | try test__truncsfhf2(0x71cc3892, 0x7c00); // 0x1.987124876876324p+100 -> inf | 38 | try test_f16_floatCast_f32(0x71cc3892, 0x7c00); // 0x1.987124876876324p+100 -> inf |
| 36 | try test__truncsfhf2(0xf1cc3892, 0xfc00); // -0x1.987124876876324p+100 -> -inf | 39 | try test_f16_floatCast_f32(0xf1cc3892, 0xfc00); // -0x1.987124876876324p+100 -> -inf |
| 37 | 40 | ||
| 38 | try test__truncsfhf2(0x38800000, 0x0400); // normal (min), 2**-14 | 41 | try test_f16_floatCast_f32(0x38800000, 0x0400); // normal (min), 2**-14 |
| 39 | try test__truncsfhf2(0xb8800000, 0x8400); // normal (min), -2**-14 | 42 | try test_f16_floatCast_f32(0xb8800000, 0x8400); // normal (min), -2**-14 |
| 40 | 43 | ||
| 41 | try test__truncsfhf2(0x477fe000, 0x7bff); // normal (max), 65504 | 44 | try test_f16_floatCast_f32(0x477fe000, 0x7bff); // normal (max), 65504 |
| 42 | try test__truncsfhf2(0xc77fe000, 0xfbff); // normal (max), -65504 | 45 | try test_f16_floatCast_f32(0xc77fe000, 0xfbff); // normal (max), -65504 |
| 43 | 46 | ||
| 44 | try test__truncsfhf2(0x477fe100, 0x7bff); // normal, 65505 -> 65504 | 47 | try test_f16_floatCast_f32(0x477fe100, 0x7bff); // normal, 65505 -> 65504 |
| 45 | try test__truncsfhf2(0xc77fe100, 0xfbff); // normal, -65505 -> -65504 | 48 | try test_f16_floatCast_f32(0xc77fe100, 0xfbff); // normal, -65505 -> -65504 |
| 46 | 49 | ||
| 47 | try test__truncsfhf2(0x477fef00, 0x7bff); // normal, 65519 -> 65504 | 50 | try test_f16_floatCast_f32(0x477fef00, 0x7bff); // normal, 65519 -> 65504 |
| 48 | try test__truncsfhf2(0xc77fef00, 0xfbff); // normal, -65519 -> -65504 | 51 | try test_f16_floatCast_f32(0xc77fef00, 0xfbff); // normal, -65519 -> -65504 |
| 49 | 52 | ||
| 50 | try test__truncsfhf2(0x3f802000, 0x3c01); // normal, 1 + 2**-10 | 53 | try test_f16_floatCast_f32(0x3f802000, 0x3c01); // normal, 1 + 2**-10 |
| 51 | try test__truncsfhf2(0xbf802000, 0xbc01); // normal, -1 - 2**-10 | 54 | try test_f16_floatCast_f32(0xbf802000, 0xbc01); // normal, -1 - 2**-10 |
| 52 | 55 | ||
| 53 | try test__truncsfhf2(0x3eaaa000, 0x3555); // normal, approx. 1/3 | 56 | try test_f16_floatCast_f32(0x3eaaa000, 0x3555); // normal, approx. 1/3 |
| 54 | try test__truncsfhf2(0xbeaaa000, 0xb555); // normal, approx. -1/3 | 57 | try test_f16_floatCast_f32(0xbeaaa000, 0xb555); // normal, approx. -1/3 |
| 55 | 58 | ||
| 56 | try test__truncsfhf2(0x40490fdb, 0x4248); // normal, 3.1415926535 | 59 | try test_f16_floatCast_f32(0x40490fdb, 0x4248); // normal, 3.1415926535 |
| 57 | try test__truncsfhf2(0xc0490fdb, 0xc248); // normal, -3.1415926535 | 60 | try test_f16_floatCast_f32(0xc0490fdb, 0xc248); // normal, -3.1415926535 |
| 58 | 61 | ||
| 59 | try test__truncsfhf2(0x45cc3892, 0x6e62); // normal, 0x1.987124876876324p+12 | 62 | try test_f16_floatCast_f32(0x45cc3892, 0x6e62); // normal, 0x1.987124876876324p+12 |
| 60 | 63 | ||
| 61 | try test__truncsfhf2(0x3f800000, 0x3c00); // normal, 1 | 64 | try test_f16_floatCast_f32(0x3f800000, 0x3c00); // normal, 1 |
| 62 | try test__truncsfhf2(0x38800000, 0x0400); // normal, 0x1.0p-14 | 65 | try test_f16_floatCast_f32(0x38800000, 0x0400); // normal, 0x1.0p-14 |
| 63 | 66 | ||
| 64 | try test__truncsfhf2(0x33800000, 0x0001); // denormal (min), 2**-24 | 67 | try test_f16_floatCast_f32(0x33800000, 0x0001); // denormal (min), 2**-24 |
| 65 | try test__truncsfhf2(0xb3800000, 0x8001); // denormal (min), -2**-24 | 68 | try test_f16_floatCast_f32(0xb3800000, 0x8001); // denormal (min), -2**-24 |
| 66 | 69 | ||
| 67 | try test__truncsfhf2(0x387fc000, 0x03ff); // denormal (max), 2**-14 - 2**-24 | 70 | try test_f16_floatCast_f32(0x387fc000, 0x03ff); // denormal (max), 2**-14 - 2**-24 |
| 68 | try test__truncsfhf2(0xb87fc000, 0x83ff); // denormal (max), -2**-14 + 2**-24 | 71 | try test_f16_floatCast_f32(0xb87fc000, 0x83ff); // denormal (max), -2**-14 + 2**-24 |
| 69 | 72 | ||
| 70 | try test__truncsfhf2(0x35800000, 0x0010); // denormal, 0x1.0p-20 | 73 | try test_f16_floatCast_f32(0x35800000, 0x0010); // denormal, 0x1.0p-20 |
| 71 | try test__truncsfhf2(0x33280000, 0x0001); // denormal, 0x1.5p-25 -> 0x1.0p-24 | 74 | try test_f16_floatCast_f32(0x33280000, 0x0001); // denormal, 0x1.5p-25 -> 0x1.0p-24 |
| 72 | try test__truncsfhf2(0x33000000, 0x0000); // 0x1.0p-25 -> zero | 75 | try test_f16_floatCast_f32(0x33000000, 0x0000); // 0x1.0p-25 -> zero |
| 73 | } | 76 | } |
| 74 | 77 | ||
| 75 | fn test__truncdfhf2(a: f64, expected: u16) void { | 78 | fn test_f16_floatCast_f64(a: f64, expected: u16) !void { |
| 76 | const rep: u16 = @bitCast(__truncdfhf2(a)); | 79 | const rep: u16 = @bitCast(f16_floatCast_f64(a)); |
| 77 | 80 | ||
| 78 | if (rep == expected) { | 81 | if (rep == expected) { |
| 79 | return; | 82 | return; |
| ... | @@ -84,62 +87,56 @@ fn test__truncdfhf2(a: f64, expected: u16) void { | ... | @@ -84,62 +87,56 @@ fn test__truncdfhf2(a: f64, expected: u16) void { |
| 84 | return; | 87 | return; |
| 85 | } | 88 | } |
| 86 | } | 89 | } |
| 87 | 90 | return error.TestFailure; | |
| 88 | @panic("__truncdfhf2 test failure"); | ||
| 89 | } | 91 | } |
| 90 | 92 | ||
| 91 | fn test__truncdfhf2_raw(a: u64, expected: u16) void { | 93 | fn test_f16_floatCast_f64_raw(a: u64, expected: u16) !void { |
| 92 | const actual: u16 = @bitCast(__truncdfhf2(@bitCast(a))); | 94 | const actual: u16 = @bitCast(f16_floatCast_f64(@bitCast(a))); |
| 93 | 95 | try testing.expect(actual == expected); | |
| 94 | if (actual == expected) { | ||
| 95 | return; | ||
| 96 | } | ||
| 97 | |||
| 98 | @panic("__truncdfhf2 test failure"); | ||
| 99 | } | 96 | } |
| 100 | 97 | ||
| 101 | test "truncdfhf2" { | 98 | test f16_floatCast_f64 { |
| 102 | test__truncdfhf2_raw(0x7ff8000000000000, 0x7e00); // qNaN | 99 | try test_f16_floatCast_f64_raw(0x7ff8000000000000, 0x7e00); // qNaN |
| 103 | test__truncdfhf2_raw(0x7ff0000000008000, 0x7e00); // NaN | 100 | try test_f16_floatCast_f64_raw(0x7ff0000000008000, 0x7e00); // NaN |
| 104 | 101 | ||
| 105 | test__truncdfhf2_raw(0x7ff0000000000000, 0x7c00); //inf | 102 | try test_f16_floatCast_f64_raw(0x7ff0000000000000, 0x7c00); //inf |
| 106 | test__truncdfhf2_raw(0xfff0000000000000, 0xfc00); // -inf | 103 | try test_f16_floatCast_f64_raw(0xfff0000000000000, 0xfc00); // -inf |
| 107 | 104 | ||
| 108 | test__truncdfhf2(0.0, 0x0); // zero | 105 | try test_f16_floatCast_f64(0.0, 0x0); // zero |
| 109 | test__truncdfhf2_raw(0x80000000 << 32, 0x8000); // -zero | 106 | try test_f16_floatCast_f64_raw(0x80000000 << 32, 0x8000); // -zero |
| 110 | 107 | ||
| 111 | test__truncdfhf2(3.1415926535, 0x4248); | 108 | try test_f16_floatCast_f64(3.1415926535, 0x4248); |
| 112 | test__truncdfhf2(-3.1415926535, 0xc248); | 109 | try test_f16_floatCast_f64(-3.1415926535, 0xc248); |
| 113 | 110 | ||
| 114 | test__truncdfhf2(0x1.987124876876324p+1000, 0x7c00); | 111 | try test_f16_floatCast_f64(0x1.987124876876324p+1000, 0x7c00); |
| 115 | test__truncdfhf2(0x1.987124876876324p+12, 0x6e62); | 112 | try test_f16_floatCast_f64(0x1.987124876876324p+12, 0x6e62); |
| 116 | test__truncdfhf2(0x1.0p+0, 0x3c00); | 113 | try test_f16_floatCast_f64(0x1.0p+0, 0x3c00); |
| 117 | test__truncdfhf2(0x1.0p-14, 0x0400); | 114 | try test_f16_floatCast_f64(0x1.0p-14, 0x0400); |
| 118 | 115 | ||
| 119 | // denormal | 116 | // denormal |
| 120 | test__truncdfhf2(0x1.0p-20, 0x0010); | 117 | try test_f16_floatCast_f64(0x1.0p-20, 0x0010); |
| 121 | test__truncdfhf2(0x1.0p-24, 0x0001); | 118 | try test_f16_floatCast_f64(0x1.0p-24, 0x0001); |
| 122 | test__truncdfhf2(-0x1.0p-24, 0x8001); | 119 | try test_f16_floatCast_f64(-0x1.0p-24, 0x8001); |
| 123 | test__truncdfhf2(0x1.5p-25, 0x0001); | 120 | try test_f16_floatCast_f64(0x1.5p-25, 0x0001); |
| 124 | 121 | ||
| 125 | // and back to zero | 122 | // and back to zero |
| 126 | test__truncdfhf2(0x1.0p-25, 0x0000); | 123 | try test_f16_floatCast_f64(0x1.0p-25, 0x0000); |
| 127 | test__truncdfhf2(-0x1.0p-25, 0x8000); | 124 | try test_f16_floatCast_f64(-0x1.0p-25, 0x8000); |
| 128 | 125 | ||
| 129 | // max (precise) | 126 | // max (precise) |
| 130 | test__truncdfhf2(65504.0, 0x7bff); | 127 | try test_f16_floatCast_f64(65504.0, 0x7bff); |
| 131 | 128 | ||
| 132 | // max (rounded) | 129 | // max (rounded) |
| 133 | test__truncdfhf2(65519.0, 0x7bff); | 130 | try test_f16_floatCast_f64(65519.0, 0x7bff); |
| 134 | 131 | ||
| 135 | // max (to +inf) | 132 | // max (to +inf) |
| 136 | test__truncdfhf2(65520.0, 0x7c00); | 133 | try test_f16_floatCast_f64(65520.0, 0x7c00); |
| 137 | test__truncdfhf2(-65520.0, 0xfc00); | 134 | try test_f16_floatCast_f64(-65520.0, 0xfc00); |
| 138 | test__truncdfhf2(65536.0, 0x7c00); | 135 | try test_f16_floatCast_f64(65536.0, 0x7c00); |
| 139 | } | 136 | } |
| 140 | 137 | ||
| 141 | fn test__trunctfsf2(a: f128, expected: u32) void { | 138 | fn test_f32_floatCast_f128(a: f128, expected: u32) !void { |
| 142 | const x = __trunctfsf2(a); | 139 | const x = f32_floatCast_f128(a); |
| 143 | 140 | ||
| 144 | const rep: u32 = @bitCast(x); | 141 | const rep: u32 = @bitCast(x); |
| 145 | if (rep == expected) { | 142 | if (rep == expected) { |
| ... | @@ -151,28 +148,27 @@ fn test__trunctfsf2(a: f128, expected: u32) void { | ... | @@ -151,28 +148,27 @@ fn test__trunctfsf2(a: f128, expected: u32) void { |
| 151 | return; | 148 | return; |
| 152 | } | 149 | } |
| 153 | } | 150 | } |
| 154 | 151 | return error.TestFailure; | |
| 155 | @panic("__trunctfsf2 test failure"); | ||
| 156 | } | 152 | } |
| 157 | 153 | ||
| 158 | test "trunctfsf2" { | 154 | test f32_floatCast_f128 { |
| 159 | // qnan | 155 | // qnan |
| 160 | test__trunctfsf2(@bitCast(@as(u128, 0x7fff800000000000 << 64)), 0x7fc00000); | 156 | try test_f32_floatCast_f128(@bitCast(@as(u128, 0x7fff800000000000 << 64)), 0x7fc00000); |
| 161 | // nan | 157 | // nan |
| 162 | test__trunctfsf2(@bitCast(@as(u128, (0x7fff000000000000 | (0x810000000000 & 0xffffffffffff)) << 64)), 0x7fc08000); | 158 | try test_f32_floatCast_f128(@bitCast(@as(u128, (0x7fff000000000000 | (0x810000000000 & 0xffffffffffff)) << 64)), 0x7fc08000); |
| 163 | // inf | 159 | // inf |
| 164 | test__trunctfsf2(@bitCast(@as(u128, 0x7fff000000000000 << 64)), 0x7f800000); | 160 | try test_f32_floatCast_f128(@bitCast(@as(u128, 0x7fff000000000000 << 64)), 0x7f800000); |
| 165 | // zero | 161 | // zero |
| 166 | test__trunctfsf2(0.0, 0x0); | 162 | try test_f32_floatCast_f128(0.0, 0x0); |
| 167 | 163 | ||
| 168 | test__trunctfsf2(0x1.23a2abb4a2ddee355f36789abcdep+5, 0x4211d156); | 164 | try test_f32_floatCast_f128(0x1.23a2abb4a2ddee355f36789abcdep+5, 0x4211d156); |
| 169 | test__trunctfsf2(0x1.e3d3c45bd3abfd98b76a54cc321fp-9, 0x3b71e9e2); | 165 | try test_f32_floatCast_f128(0x1.e3d3c45bd3abfd98b76a54cc321fp-9, 0x3b71e9e2); |
| 170 | test__trunctfsf2(0x1.234eebb5faa678f4488693abcdefp+4534, 0x7f800000); | 166 | try test_f32_floatCast_f128(0x1.234eebb5faa678f4488693abcdefp+4534, 0x7f800000); |
| 171 | test__trunctfsf2(0x1.edcba9bb8c76a5a43dd21f334634p-435, 0x0); | 167 | try test_f32_floatCast_f128(0x1.edcba9bb8c76a5a43dd21f334634p-435, 0x0); |
| 172 | } | 168 | } |
| 173 | 169 | ||
| 174 | fn test__trunctfdf2(a: f128, expected: u64) void { | 170 | fn test_f64_floatCast_f128(a: f128, expected: u64) !void { |
| 175 | const x = __trunctfdf2(a); | 171 | const x = f64_floatCast_f128(a); |
| 176 | 172 | ||
| 177 | const rep: u64 = @bitCast(x); | 173 | const rep: u64 = @bitCast(x); |
| 178 | if (rep == expected) { | 174 | if (rep == expected) { |
| ... | @@ -184,28 +180,27 @@ fn test__trunctfdf2(a: f128, expected: u64) void { | ... | @@ -184,28 +180,27 @@ fn test__trunctfdf2(a: f128, expected: u64) void { |
| 184 | return; | 180 | return; |
| 185 | } | 181 | } |
| 186 | } | 182 | } |
| 187 | 183 | return error.TestFailure; | |
| 188 | @panic("__trunctfsf2 test failure"); | ||
| 189 | } | 184 | } |
| 190 | 185 | ||
| 191 | test "trunctfdf2" { | 186 | test f64_floatCast_f128 { |
| 192 | // qnan | 187 | // qnan |
| 193 | test__trunctfdf2(@bitCast(@as(u128, 0x7fff800000000000 << 64)), 0x7ff8000000000000); | 188 | try test_f64_floatCast_f128(@bitCast(@as(u128, 0x7fff800000000000 << 64)), 0x7ff8000000000000); |
| 194 | // nan | 189 | // nan |
| 195 | test__trunctfdf2(@bitCast(@as(u128, (0x7fff000000000000 | (0x810000000000 & 0xffffffffffff)) << 64)), 0x7ff8100000000000); | 190 | try test_f64_floatCast_f128(@bitCast(@as(u128, (0x7fff000000000000 | (0x810000000000 & 0xffffffffffff)) << 64)), 0x7ff8100000000000); |
| 196 | // inf | 191 | // inf |
| 197 | test__trunctfdf2(@bitCast(@as(u128, 0x7fff000000000000 << 64)), 0x7ff0000000000000); | 192 | try test_f64_floatCast_f128(@bitCast(@as(u128, 0x7fff000000000000 << 64)), 0x7ff0000000000000); |
| 198 | // zero | 193 | // zero |
| 199 | test__trunctfdf2(0.0, 0x0); | 194 | try test_f64_floatCast_f128(0.0, 0x0); |
| 200 | 195 | ||
| 201 | test__trunctfdf2(0x1.af23456789bbaaab347645365cdep+5, 0x404af23456789bbb); | 196 | try test_f64_floatCast_f128(0x1.af23456789bbaaab347645365cdep+5, 0x404af23456789bbb); |
| 202 | test__trunctfdf2(0x1.dedafcff354b6ae9758763545432p-9, 0x3f6dedafcff354b7); | 197 | try test_f64_floatCast_f128(0x1.dedafcff354b6ae9758763545432p-9, 0x3f6dedafcff354b7); |
| 203 | test__trunctfdf2(0x1.2f34dd5f437e849b4baab754cdefp+4534, 0x7ff0000000000000); | 198 | try test_f64_floatCast_f128(0x1.2f34dd5f437e849b4baab754cdefp+4534, 0x7ff0000000000000); |
| 204 | test__trunctfdf2(0x1.edcbff8ad76ab5bf46463233214fp-435, 0x24cedcbff8ad76ab); | 199 | try test_f64_floatCast_f128(0x1.edcbff8ad76ab5bf46463233214fp-435, 0x24cedcbff8ad76ab); |
| 205 | } | 200 | } |
| 206 | 201 | ||
| 207 | fn test__truncdfsf2(a: f64, expected: u32) void { | 202 | fn test_f32_floatCast_f64(a: f64, expected: u32) !void { |
| 208 | const x = __truncdfsf2(a); | 203 | const x = f32_floatCast_f64(a); |
| 209 | 204 | ||
| 210 | const rep: u32 = @bitCast(x); | 205 | const rep: u32 = @bitCast(x); |
| 211 | if (rep == expected) { | 206 | if (rep == expected) { |
| ... | @@ -217,90 +212,81 @@ fn test__truncdfsf2(a: f64, expected: u32) void { | ... | @@ -217,90 +212,81 @@ fn test__truncdfsf2(a: f64, expected: u32) void { |
| 217 | return; | 212 | return; |
| 218 | } | 213 | } |
| 219 | } | 214 | } |
| 220 | 215 | return error.TestFailure; | |
| 221 | std.debug.print("got 0x{x} wanted 0x{x}\n", .{ rep, expected }); | ||
| 222 | |||
| 223 | @panic("__trunctfsf2 test failure"); | ||
| 224 | } | 216 | } |
| 225 | 217 | ||
| 226 | test "truncdfsf2" { | 218 | test f32_floatCast_f64 { |
| 227 | // nan & qnan | 219 | // nan & qnan |
| 228 | test__truncdfsf2(@bitCast(@as(u64, 0x7ff8000000000000)), 0x7fc00000); | 220 | try test_f32_floatCast_f64(@bitCast(@as(u64, 0x7ff8000000000000)), 0x7fc00000); |
| 229 | test__truncdfsf2(@bitCast(@as(u64, 0x7ff0000000000001)), 0x7fc00000); | 221 | try test_f32_floatCast_f64(@bitCast(@as(u64, 0x7ff0000000000001)), 0x7fc00000); |
| 230 | // inf | 222 | // inf |
| 231 | test__truncdfsf2(@bitCast(@as(u64, 0x7ff0000000000000)), 0x7f800000); | 223 | try test_f32_floatCast_f64(@bitCast(@as(u64, 0x7ff0000000000000)), 0x7f800000); |
| 232 | test__truncdfsf2(@bitCast(@as(u64, 0xfff0000000000000)), 0xff800000); | 224 | try test_f32_floatCast_f64(@bitCast(@as(u64, 0xfff0000000000000)), 0xff800000); |
| 233 | 225 | ||
| 234 | test__truncdfsf2(0.0, 0x0); | 226 | try test_f32_floatCast_f64(0.0, 0x0); |
| 235 | test__truncdfsf2(1.0, 0x3f800000); | 227 | try test_f32_floatCast_f64(1.0, 0x3f800000); |
| 236 | test__truncdfsf2(-1.0, 0xbf800000); | 228 | try test_f32_floatCast_f64(-1.0, 0xbf800000); |
| 237 | 229 | ||
| 238 | // huge number becomes inf | 230 | // huge number becomes inf |
| 239 | test__truncdfsf2(340282366920938463463374607431768211456.0, 0x7f800000); | 231 | try test_f32_floatCast_f64(340282366920938463463374607431768211456.0, 0x7f800000); |
| 240 | } | 232 | } |
| 241 | 233 | ||
| 242 | fn test__trunctfhf2(a: f128, expected: u16) void { | 234 | fn test_f16_floatCast_f128(a: f128, expected: u16) !void { |
| 243 | const x = __trunctfhf2(a); | 235 | const x = f16_floatCast_f128(a); |
| 244 | 236 | ||
| 245 | const rep: u16 = @bitCast(x); | 237 | const rep: u16 = @bitCast(x); |
| 246 | if (rep == expected) { | 238 | try testing.expect(rep == expected); |
| 247 | return; | ||
| 248 | } | ||
| 249 | |||
| 250 | std.debug.print("got 0x{x} wanted 0x{x}\n", .{ rep, expected }); | ||
| 251 | |||
| 252 | @panic("__trunctfhf2 test failure"); | ||
| 253 | } | 239 | } |
| 254 | 240 | ||
| 255 | test "trunctfhf2" { | 241 | test f16_floatCast_f128 { |
| 256 | // qNaN | 242 | // qNaN |
| 257 | test__trunctfhf2(@bitCast(@as(u128, 0x7fff8000000000000000000000000000)), 0x7e00); | 243 | try test_f16_floatCast_f128(@bitCast(@as(u128, 0x7fff8000000000000000000000000000)), 0x7e00); |
| 258 | // NaN | 244 | // NaN |
| 259 | test__trunctfhf2(@bitCast(@as(u128, 0x7fff0000000000000000000000000001)), 0x7e00); | 245 | try test_f16_floatCast_f128(@bitCast(@as(u128, 0x7fff0000000000000000000000000001)), 0x7e00); |
| 260 | // inf | 246 | // inf |
| 261 | test__trunctfhf2(@bitCast(@as(u128, 0x7fff0000000000000000000000000000)), 0x7c00); | 247 | try test_f16_floatCast_f128(@bitCast(@as(u128, 0x7fff0000000000000000000000000000)), 0x7c00); |
| 262 | test__trunctfhf2(-@as(f128, @bitCast(@as(u128, 0x7fff0000000000000000000000000000))), 0xfc00); | 248 | try test_f16_floatCast_f128(-@as(f128, @bitCast(@as(u128, 0x7fff0000000000000000000000000000))), 0xfc00); |
| 263 | // zero | 249 | // zero |
| 264 | test__trunctfhf2(0.0, 0x0); | 250 | try test_f16_floatCast_f128(0.0, 0x0); |
| 265 | test__trunctfhf2(-0.0, 0x8000); | 251 | try test_f16_floatCast_f128(-0.0, 0x8000); |
| 266 | 252 | ||
| 267 | test__trunctfhf2(3.1415926535, 0x4248); | 253 | try test_f16_floatCast_f128(3.1415926535, 0x4248); |
| 268 | test__trunctfhf2(-3.1415926535, 0xc248); | 254 | try test_f16_floatCast_f128(-3.1415926535, 0xc248); |
| 269 | test__trunctfhf2(0x1.987124876876324p+100, 0x7c00); | 255 | try test_f16_floatCast_f128(0x1.987124876876324p+100, 0x7c00); |
| 270 | test__trunctfhf2(0x1.987124876876324p+12, 0x6e62); | 256 | try test_f16_floatCast_f128(0x1.987124876876324p+12, 0x6e62); |
| 271 | test__trunctfhf2(0x1.0p+0, 0x3c00); | 257 | try test_f16_floatCast_f128(0x1.0p+0, 0x3c00); |
| 272 | test__trunctfhf2(0x1.0p-14, 0x0400); | 258 | try test_f16_floatCast_f128(0x1.0p-14, 0x0400); |
| 273 | // denormal | 259 | // denormal |
| 274 | test__trunctfhf2(0x1.0p-20, 0x0010); | 260 | try test_f16_floatCast_f128(0x1.0p-20, 0x0010); |
| 275 | test__trunctfhf2(0x1.0p-24, 0x0001); | 261 | try test_f16_floatCast_f128(0x1.0p-24, 0x0001); |
| 276 | test__trunctfhf2(-0x1.0p-24, 0x8001); | 262 | try test_f16_floatCast_f128(-0x1.0p-24, 0x8001); |
| 277 | test__trunctfhf2(0x1.5p-25, 0x0001); | 263 | try test_f16_floatCast_f128(0x1.5p-25, 0x0001); |
| 278 | // and back to zero | 264 | // and back to zero |
| 279 | test__trunctfhf2(0x1.0p-25, 0x0000); | 265 | try test_f16_floatCast_f128(0x1.0p-25, 0x0000); |
| 280 | test__trunctfhf2(-0x1.0p-25, 0x8000); | 266 | try test_f16_floatCast_f128(-0x1.0p-25, 0x8000); |
| 281 | // max (precise) | 267 | // max (precise) |
| 282 | test__trunctfhf2(65504.0, 0x7bff); | 268 | try test_f16_floatCast_f128(65504.0, 0x7bff); |
| 283 | // max (rounded) | 269 | // max (rounded) |
| 284 | test__trunctfhf2(65519.0, 0x7bff); | 270 | try test_f16_floatCast_f128(65519.0, 0x7bff); |
| 285 | // max (to +inf) | 271 | // max (to +inf) |
| 286 | test__trunctfhf2(65520.0, 0x7c00); | 272 | try test_f16_floatCast_f128(65520.0, 0x7c00); |
| 287 | test__trunctfhf2(65536.0, 0x7c00); | 273 | try test_f16_floatCast_f128(65536.0, 0x7c00); |
| 288 | test__trunctfhf2(-65520.0, 0xfc00); | 274 | try test_f16_floatCast_f128(-65520.0, 0xfc00); |
| 289 | 275 | ||
| 290 | test__trunctfhf2(0x1.23a2abb4a2ddee355f36789abcdep+5, 0x508f); | 276 | try test_f16_floatCast_f128(0x1.23a2abb4a2ddee355f36789abcdep+5, 0x508f); |
| 291 | test__trunctfhf2(0x1.e3d3c45bd3abfd98b76a54cc321fp-9, 0x1b8f); | 277 | try test_f16_floatCast_f128(0x1.e3d3c45bd3abfd98b76a54cc321fp-9, 0x1b8f); |
| 292 | test__trunctfhf2(0x1.234eebb5faa678f4488693abcdefp+453, 0x7c00); | 278 | try test_f16_floatCast_f128(0x1.234eebb5faa678f4488693abcdefp+453, 0x7c00); |
| 293 | test__trunctfhf2(0x1.edcba9bb8c76a5a43dd21f334634p-43, 0x0); | 279 | try test_f16_floatCast_f128(0x1.edcba9bb8c76a5a43dd21f334634p-43, 0x0); |
| 294 | } | 280 | } |
| 295 | 281 | ||
| 296 | test "trunctfxf2" { | 282 | fn test_f80_floatCast_f128(a: f128, expected: f80) !void { |
| 297 | try test__trunctfxf2(1.5, 1.5); | 283 | const x = f80_floatCast_f128(a); |
| 298 | try test__trunctfxf2(2.5, 2.5); | 284 | try testing.expect(x == expected); |
| 299 | try test__trunctfxf2(-2.5, -2.5); | ||
| 300 | try test__trunctfxf2(0.0, 0.0); | ||
| 301 | } | 285 | } |
| 302 | 286 | ||
| 303 | fn test__trunctfxf2(a: f128, expected: f80) !void { | 287 | test f80_floatCast_f128 { |
| 304 | const x = __trunctfxf2(a); | 288 | try test_f80_floatCast_f128(1.5, 1.5); |
| 305 | try testing.expect(x == expected); | 289 | try test_f80_floatCast_f128(2.5, 2.5); |
| 290 | try test_f80_floatCast_f128(-2.5, -2.5); | ||
| 291 | try test_f80_floatCast_f128(0.0, 0.0); | ||
| 306 | } | 292 | } |
lib/compiler_rt/truncsfhf2.zig deleted-24| ... | @@ -1,24 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const truncf = @import("./truncf.zig").truncf; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.gnu_f16_abi) { | ||
| 7 | symbol(&__gnu_f2h_ieee, "__gnu_f2h_ieee"); | ||
| 8 | } else if (compiler_rt.want_aeabi) { | ||
| 9 | symbol(&__aeabi_f2h, "__aeabi_f2h"); | ||
| 10 | } | ||
| 11 | symbol(&__truncsfhf2, "__truncsfhf2"); | ||
| 12 | } | ||
| 13 | |||
| 14 | pub fn __truncsfhf2(a: f32) callconv(.c) compiler_rt.F16T(f32) { | ||
| 15 | return @bitCast(truncf(f16, f32, a)); | ||
| 16 | } | ||
| 17 | |||
| 18 | fn __gnu_f2h_ieee(a: f32) callconv(.c) compiler_rt.F16T(f32) { | ||
| 19 | return @bitCast(truncf(f16, f32, a)); | ||
| 20 | } | ||
| 21 | |||
| 22 | fn __aeabi_f2h(a: f32) callconv(.{ .arm_aapcs = .{} }) u16 { | ||
| 23 | return @bitCast(truncf(f16, f32, a)); | ||
| 24 | } | ||
lib/compiler_rt/trunctfdf2.zig deleted-22| ... | @@ -1,22 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = compiler_rt.symbol; | ||
| 3 | const truncf = @import("./truncf.zig").truncf; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_ppc_abi) { | ||
| 7 | symbol(&__trunctfdf2, "__trunckfdf2"); | ||
| 8 | } else if (compiler_rt.want_sparc64_abi) { | ||
| 9 | symbol(&_Qp_qtod, "_Qp_qtod"); | ||
| 10 | } else if (compiler_rt.want_sparc32_abi) { | ||
| 11 | symbol(&__trunctfdf2, "_Q_qtod"); | ||
| 12 | } | ||
| 13 | symbol(&__trunctfdf2, "__trunctfdf2"); | ||
| 14 | } | ||
| 15 | |||
| 16 | pub fn __trunctfdf2(a: f128) callconv(.c) f64 { | ||
| 17 | return truncf(f64, f128, a); | ||
| 18 | } | ||
| 19 | |||
| 20 | fn _Qp_qtod(a: *const f128) callconv(.c) f64 { | ||
| 21 | return truncf(f64, f128, a.*); | ||
| 22 | } | ||
lib/compiler_rt/trunctfhf2.zig deleted-14| ... | @@ -1,14 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 3 | const truncf = @import("./truncf.zig").truncf; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__trunctfhf2, "__trunctfhf2"); | ||
| 7 | if (compiler_rt.want_ppc_abi) { | ||
| 8 | symbol(&__trunctfhf2, "__trunckfhf2"); | ||
| 9 | } | ||
| 10 | } | ||
| 11 | |||
| 12 | pub fn __trunctfhf2(a: f128) callconv(.c) compiler_rt.F16T(f128) { | ||
| 13 | return @bitCast(truncf(f16, f128, a)); | ||
| 14 | } | ||
lib/compiler_rt/trunctfsf2.zig deleted-22| ... | @@ -1,22 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const truncf = @import("./truncf.zig").truncf; | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_ppc_abi) { | ||
| 7 | symbol(&__trunctfsf2, "__trunckfsf2"); | ||
| 8 | } else if (compiler_rt.want_sparc64_abi) { | ||
| 9 | symbol(&_Qp_qtos, "_Qp_qtos"); | ||
| 10 | } else if (compiler_rt.want_sparc32_abi) { | ||
| 11 | symbol(&__trunctfsf2, "_Q_qtos"); | ||
| 12 | } | ||
| 13 | symbol(&__trunctfsf2, "__trunctfsf2"); | ||
| 14 | } | ||
| 15 | |||
| 16 | pub fn __trunctfsf2(a: f128) callconv(.c) f32 { | ||
| 17 | return truncf(f32, f128, a); | ||
| 18 | } | ||
| 19 | |||
| 20 | fn _Qp_qtos(a: *const f128) callconv(.c) f32 { | ||
| 21 | return truncf(f32, f128, a.*); | ||
| 22 | } | ||
lib/compiler_rt/trunctfxf2.zig deleted-67| ... | @@ -1,67 +0,0 @@ | ||
| 1 | const math = @import("std").math; | ||
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 3 | const symbol = compiler_rt.symbol; | ||
| 4 | const trunc_f80 = @import("./truncf.zig").trunc_f80; | ||
| 5 | |||
| 6 | comptime { | ||
| 7 | symbol(&__trunctfxf2, "__trunctfxf2"); | ||
| 8 | } | ||
| 9 | |||
| 10 | pub fn __trunctfxf2(a: f128) callconv(.c) f80 { | ||
| 11 | const src_sig_bits = math.floatMantissaBits(f128); | ||
| 12 | const dst_sig_bits = math.floatMantissaBits(f80) - 1; // -1 for the integer bit | ||
| 13 | |||
| 14 | // Various constants whose values follow from the type parameters. | ||
| 15 | // Any reasonable optimizer will fold and propagate all of these. | ||
| 16 | const src_bits = @typeInfo(f128).float.bits; | ||
| 17 | const src_exp_bits = src_bits - src_sig_bits - 1; | ||
| 18 | const src_inf_exp = 0x7FFF; | ||
| 19 | |||
| 20 | const src_inf = src_inf_exp << src_sig_bits; | ||
| 21 | const src_sign_mask = 1 << (src_sig_bits + src_exp_bits); | ||
| 22 | const src_abs_mask = src_sign_mask - 1; | ||
| 23 | const round_mask = (1 << (src_sig_bits - dst_sig_bits)) - 1; | ||
| 24 | const halfway = 1 << (src_sig_bits - dst_sig_bits - 1); | ||
| 25 | |||
| 26 | // Break a into a sign and representation of the absolute value | ||
| 27 | const a_rep = @as(u128, @bitCast(a)); | ||
| 28 | const a_abs = a_rep & src_abs_mask; | ||
| 29 | const sign: u16 = if (a_rep & src_sign_mask != 0) 0x8000 else 0; | ||
| 30 | const integer_bit = 1 << 63; | ||
| 31 | |||
| 32 | var res: math.F80 = undefined; | ||
| 33 | |||
| 34 | if (a_abs > src_inf) { | ||
| 35 | // a is NaN. | ||
| 36 | // Conjure the result by beginning with infinity, setting the qNaN | ||
| 37 | // bit and inserting the (truncated) trailing NaN field. | ||
| 38 | res.exp = 0x7fff; | ||
| 39 | res.fraction = 0x8000000000000000; | ||
| 40 | res.fraction |= @as(u64, @truncate(a_abs >> (src_sig_bits - dst_sig_bits))); | ||
| 41 | } else { | ||
| 42 | // The exponent of a is within the range of normal numbers in the | ||
| 43 | // destination format. We can convert by simply right-shifting with | ||
| 44 | // rounding, adding the explicit integer bit, and adjusting the exponent | ||
| 45 | res.fraction = @as(u64, @truncate(a_abs >> (src_sig_bits - dst_sig_bits))) | integer_bit; | ||
| 46 | res.exp = @truncate(a_abs >> src_sig_bits); | ||
| 47 | |||
| 48 | const round_bits = a_abs & round_mask; | ||
| 49 | if (round_bits > halfway) { | ||
| 50 | // Round to nearest | ||
| 51 | const ov = @addWithOverflow(res.fraction, 1); | ||
| 52 | res.fraction = ov[0]; | ||
| 53 | res.exp += ov[1]; | ||
| 54 | res.fraction |= @as(u64, ov[1]) << 63; // Restore integer bit after carry | ||
| 55 | } else if (round_bits == halfway) { | ||
| 56 | // Ties to even | ||
| 57 | const ov = @addWithOverflow(res.fraction, res.fraction & 1); | ||
| 58 | res.fraction = ov[0]; | ||
| 59 | res.exp += ov[1]; | ||
| 60 | res.fraction |= @as(u64, ov[1]) << 63; // Restore integer bit after carry | ||
| 61 | } | ||
| 62 | if (res.exp == 0) res.fraction &= ~@as(u64, integer_bit); // Remove integer bit for de-normals | ||
| 63 | } | ||
| 64 | |||
| 65 | res.exp |= sign; | ||
| 66 | return res.toFloat(); | ||
| 67 | } | ||
lib/compiler_rt/truncxfdf2.zig deleted-10| ... | @@ -1,10 +0,0 @@ | ||
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 2 | const trunc_f80 = @import("./truncf.zig").trunc_f80; | ||
| 3 | |||
| 4 | comptime { | ||
| 5 | symbol(&__truncxfdf2, "__truncxfdf2"); | ||
| 6 | } | ||
| 7 | |||
| 8 | fn __truncxfdf2(a: f80) callconv(.c) f64 { | ||
| 9 | return trunc_f80(f64, a); | ||
| 10 | } | ||
lib/compiler_rt/truncxfhf2.zig deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 3 | const trunc_f80 = @import("./truncf.zig").trunc_f80; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | symbol(&__truncxfhf2, "__truncxfhf2"); | ||
| 7 | } | ||
| 8 | |||
| 9 | fn __truncxfhf2(a: f80) callconv(.c) compiler_rt.F16T(f80) { | ||
| 10 | return @bitCast(trunc_f80(f16, a)); | ||
| 11 | } | ||
lib/compiler_rt/truncxfsf2.zig deleted-10| ... | @@ -1,10 +0,0 @@ | ||
| 1 | const trunc_f80 = @import("./truncf.zig").trunc_f80; | ||
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 3 | |||
| 4 | comptime { | ||
| 5 | symbol(&__truncxfsf2, "__truncxfsf2"); | ||
| 6 | } | ||
| 7 | |||
| 8 | fn __truncxfsf2(a: f80) callconv(.c) f32 { | ||
| 9 | return trunc_f80(f32, a); | ||
| 10 | } | ||
lib/compiler_rt/udivmodei4.zig+1-1| ... | @@ -6,7 +6,7 @@ const shr = std.math.shr; | ... | @@ -6,7 +6,7 @@ const shr = std.math.shr; |
| 6 | const shl = std.math.shl; | 6 | const shl = std.math.shl; |
| 7 | 7 | ||
| 8 | const compiler_rt = @import("../compiler_rt.zig"); | 8 | const compiler_rt = @import("../compiler_rt.zig"); |
| 9 | const symbol = @import("../compiler_rt.zig").symbol; | 9 | const symbol = compiler_rt.symbol; |
| 10 | 10 | ||
| 11 | const max_limbs = @divCeil(65535, 32); // max supported type is u65535 | 11 | const max_limbs = @divCeil(65535, 32); // max supported type is u65535 |
| 12 | 12 |
lib/compiler_rt/unorddf2.zig deleted-19| ... | @@ -1,19 +0,0 @@ | ||
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 2 | const comparef = @import("./comparef.zig"); | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | ||
| 4 | |||
| 5 | comptime { | ||
| 6 | if (compiler_rt.want_aeabi) { | ||
| 7 | symbol(&__aeabi_dcmpun, "__aeabi_dcmpun"); | ||
| 8 | } else { | ||
| 9 | symbol(&__unorddf2, "__unorddf2"); | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | pub fn __unorddf2(a: f64, b: f64) callconv(.c) i32 { | ||
| 14 | return comparef.unordcmp(f64, a, b); | ||
| 15 | } | ||
| 16 | |||
| 17 | fn __aeabi_dcmpun(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { | ||
| 18 | return comparef.unordcmp(f64, a, b); | ||
| 19 | } | ||
lib/docs/wasm/html_render.zig+1-1| ... | @@ -62,7 +62,7 @@ pub fn fileSourceHtml( | ... | @@ -62,7 +62,7 @@ pub fn fileSourceHtml( |
| 62 | var cursor: usize = ast.tokenStart(start_token); | 62 | var cursor: usize = ast.tokenStart(start_token); |
| 63 | 63 | ||
| 64 | var indent: usize = 0; | 64 | var indent: usize = 0; |
| 65 | if (std.mem.lastIndexOf(u8, ast.source[0..cursor], "\n")) |newline_index| { | 65 | if (std.mem.findLast(u8, ast.source[0..cursor], "\n")) |newline_index| { |
| 66 | for (ast.source[newline_index + 1 .. cursor]) |c| { | 66 | for (ast.source[newline_index + 1 .. cursor]) |c| { |
| 67 | if (c == ' ') { | 67 | if (c == ' ') { |
| 68 | indent += 1; | 68 | indent += 1; |
lib/docs/wasm/main.zig+3-3| ... | @@ -153,11 +153,11 @@ fn query_exec_fallible(query: []const u8, ignore_case: bool) !void { | ... | @@ -153,11 +153,11 @@ fn query_exec_fallible(query: []const u8, ignore_case: bool) !void { |
| 153 | continue; | 153 | continue; |
| 154 | } | 154 | } |
| 155 | // substring, case insensitive match of full decl path | 155 | // substring, case insensitive match of full decl path |
| 156 | if (std.mem.indexOf(u8, g.full_path_search_text_lower.items, term) != null) { | 156 | if (std.mem.find(u8, g.full_path_search_text_lower.items, term) != null) { |
| 157 | points += 2; | 157 | points += 2; |
| 158 | continue; | 158 | continue; |
| 159 | } | 159 | } |
| 160 | if (std.mem.indexOf(u8, g.doc_search_text.items, term) != null) { | 160 | if (std.mem.find(u8, g.doc_search_text.items, term) != null) { |
| 161 | points += 1; | 161 | points += 1; |
| 162 | continue; | 162 | continue; |
| 163 | } | 163 | } |
| ... | @@ -803,7 +803,7 @@ fn unpackInner(tar_bytes: []u8) !void { | ... | @@ -803,7 +803,7 @@ fn unpackInner(tar_bytes: []u8) !void { |
| 803 | if (std.mem.endsWith(u8, tar_file.name, ".zig")) { | 803 | if (std.mem.endsWith(u8, tar_file.name, ".zig")) { |
| 804 | log.debug("found file: '{s}'", .{tar_file.name}); | 804 | log.debug("found file: '{s}'", .{tar_file.name}); |
| 805 | const file_name = try gpa.dupe(u8, tar_file.name); | 805 | const file_name = try gpa.dupe(u8, tar_file.name); |
| 806 | if (std.mem.indexOfScalar(u8, file_name, '/')) |pkg_name_end| { | 806 | if (std.mem.findScalar(u8, file_name, '/')) |pkg_name_end| { |
| 807 | const pkg_name = file_name[0..pkg_name_end]; | 807 | const pkg_name = file_name[0..pkg_name_end]; |
| 808 | const gop = try Walk.modules.getOrPut(gpa, pkg_name); | 808 | const gop = try Walk.modules.getOrPut(gpa, pkg_name); |
| 809 | const file: Walk.File.Index = @fromBackingInt(@intCast(Walk.files.entries.len)); | 809 | const file: Walk.File.Index = @fromBackingInt(@intCast(Walk.files.entries.len)); |
lib/docs/wasm/markdown/Document.zig+1-1| ... | @@ -108,7 +108,7 @@ pub const Node = struct { | ... | @@ -108,7 +108,7 @@ pub const Node = struct { |
| 108 | // In Debug and ReleaseSafe builds, there may be hidden extra fields | 108 | // In Debug and ReleaseSafe builds, there may be hidden extra fields |
| 109 | // included for safety checks. Without such safety checks enabled, | 109 | // included for safety checks. Without such safety checks enabled, |
| 110 | // we always want this union to be 8 bytes. | 110 | // we always want this union to be 8 bytes. |
| 111 | if (builtin.mode != .Debug and builtin.mode != .ReleaseSafe) { | 111 | if (builtin.mode != .debug and builtin.mode != .safe) { |
| 112 | assert(@sizeOf(Data) == 8); | 112 | assert(@sizeOf(Data) == 8); |
| 113 | } | 113 | } |
| 114 | } | 114 | } |
lib/docs/wasm/markdown/Parser.zig+21-21| ... | @@ -159,7 +159,7 @@ const Block = struct { | ... | @@ -159,7 +159,7 @@ const Block = struct { |
| 159 | .heading => null, | 159 | .heading => null, |
| 160 | .code_block => code_block: { | 160 | .code_block => code_block: { |
| 161 | const trimmed = mem.trimEnd(u8, unindented, " \t"); | 161 | const trimmed = mem.trimEnd(u8, unindented, " \t"); |
| 162 | if (mem.indexOfNone(u8, trimmed, "`") != null or trimmed.len != b.data.code_block.fence_len) { | 162 | if (mem.findNone(u8, trimmed, "`") != null or trimmed.len != b.data.code_block.fence_len) { |
| 163 | const effective_indent = @min(indent, b.data.code_block.indent); | 163 | const effective_indent = @min(indent, b.data.code_block.indent); |
| 164 | break :code_block line[effective_indent..]; | 164 | break :code_block line[effective_indent..]; |
| 165 | } else { | 165 | } else { |
| ... | @@ -209,7 +209,7 @@ pub fn feedLine(p: *Parser, line: []const u8) Allocator.Error!void { | ... | @@ -209,7 +209,7 @@ pub fn feedLine(p: *Parser, line: []const u8) Allocator.Error!void { |
| 209 | } else p.pending_blocks.items.len; | 209 | } else p.pending_blocks.items.len; |
| 210 | 210 | ||
| 211 | const in_code_block = p.pending_blocks.items.len > 0 and | 211 | const in_code_block = p.pending_blocks.items.len > 0 and |
| 212 | p.pending_blocks.getLast().?.tag == .code_block; | 212 | p.pending_blocks.last().?.tag == .code_block; |
| 213 | const code_block_end = in_code_block and | 213 | const code_block_end = in_code_block and |
| 214 | first_unmatched + 1 == p.pending_blocks.items.len; | 214 | first_unmatched + 1 == p.pending_blocks.items.len; |
| 215 | // New blocks cannot be started if we are actively inside a code block or | 215 | // New blocks cannot be started if we are actively inside a code block or |
| ... | @@ -225,7 +225,7 @@ pub fn feedLine(p: *Parser, line: []const u8) Allocator.Error!void { | ... | @@ -225,7 +225,7 @@ pub fn feedLine(p: *Parser, line: []const u8) Allocator.Error!void { |
| 225 | if (maybe_block_start == null and | 225 | if (maybe_block_start == null and |
| 226 | !isBlank(rest_line) and | 226 | !isBlank(rest_line) and |
| 227 | p.pending_blocks.items.len > 0 and | 227 | p.pending_blocks.items.len > 0 and |
| 228 | p.pending_blocks.getLast().?.tag == .paragraph) | 228 | p.pending_blocks.last().?.tag == .paragraph) |
| 229 | { | 229 | { |
| 230 | try p.addScratchStringLine(mem.trimStart(u8, rest_line, " \t")); | 230 | try p.addScratchStringLine(mem.trimStart(u8, rest_line, " \t")); |
| 231 | return; | 231 | return; |
| ... | @@ -236,7 +236,7 @@ pub fn feedLine(p: *Parser, line: []const u8) Allocator.Error!void { | ... | @@ -236,7 +236,7 @@ pub fn feedLine(p: *Parser, line: []const u8) Allocator.Error!void { |
| 236 | // paragraphs. | 236 | // paragraphs. |
| 237 | if (maybe_block_start != null and | 237 | if (maybe_block_start != null and |
| 238 | p.pending_blocks.items.len > 0 and | 238 | p.pending_blocks.items.len > 0 and |
| 239 | p.pending_blocks.getLast().?.tag == .paragraph) | 239 | p.pending_blocks.last().?.tag == .paragraph) |
| 240 | { | 240 | { |
| 241 | try p.closeLastBlock(); | 241 | try p.closeLastBlock(); |
| 242 | } | 242 | } |
| ... | @@ -259,7 +259,7 @@ pub fn feedLine(p: *Parser, line: []const u8) Allocator.Error!void { | ... | @@ -259,7 +259,7 @@ pub fn feedLine(p: *Parser, line: []const u8) Allocator.Error!void { |
| 259 | // Do not append the end of a code block (```) as textual content. | 259 | // Do not append the end of a code block (```) as textual content. |
| 260 | if (code_block_end) return; | 260 | if (code_block_end) return; |
| 261 | 261 | ||
| 262 | const can_accept = if (p.pending_blocks.getLast()) |last_pending_block| | 262 | const can_accept = if (p.pending_blocks.last()) |last_pending_block| |
| 263 | last_pending_block.canAccept() | 263 | last_pending_block.canAccept() |
| 264 | else | 264 | else |
| 265 | .blocks; | 265 | .blocks; |
| ... | @@ -273,7 +273,7 @@ pub fn feedLine(p: *Parser, line: []const u8) Allocator.Error!void { | ... | @@ -273,7 +273,7 @@ pub fn feedLine(p: *Parser, line: []const u8) Allocator.Error!void { |
| 273 | // loose, since we might just be looking at a blank line after the | 273 | // loose, since we might just be looking at a blank line after the |
| 274 | // end of the last item in the list. The final determination will be | 274 | // end of the last item in the list. The final determination will be |
| 275 | // made when appending the next child of the list or list item. | 275 | // made when appending the next child of the list or list item. |
| 276 | const maybe_containing_list_index = if (p.pending_blocks.items.len > 0 and p.pending_blocks.getLast().?.tag == .list_item) | 276 | const maybe_containing_list_index = if (p.pending_blocks.items.len > 0 and p.pending_blocks.last().?.tag == .list_item) |
| 277 | p.pending_blocks.items.len - 2 | 277 | p.pending_blocks.items.len - 2 |
| 278 | else | 278 | else |
| 279 | null; | 279 | null; |
| ... | @@ -368,7 +368,7 @@ const BlockStart = struct { | ... | @@ -368,7 +368,7 @@ const BlockStart = struct { |
| 368 | }; | 368 | }; |
| 369 | 369 | ||
| 370 | fn appendBlockStart(p: *Parser, block_start: BlockStart) !void { | 370 | fn appendBlockStart(p: *Parser, block_start: BlockStart) !void { |
| 371 | if (p.pending_blocks.getLast()) |last_pending_block| { | 371 | if (p.pending_blocks.last()) |last_pending_block| { |
| 372 | // Close the last block if it is a list and the new block is not a list item | 372 | // Close the last block if it is a list and the new block is not a list item |
| 373 | // or not of the same marker type. | 373 | // or not of the same marker type. |
| 374 | const should_close_list = last_pending_block.tag == .list and | 374 | const should_close_list = last_pending_block.tag == .list and |
| ... | @@ -383,7 +383,7 @@ fn appendBlockStart(p: *Parser, block_start: BlockStart) !void { | ... | @@ -383,7 +383,7 @@ fn appendBlockStart(p: *Parser, block_start: BlockStart) !void { |
| 383 | } | 383 | } |
| 384 | } | 384 | } |
| 385 | 385 | ||
| 386 | if (p.pending_blocks.getLast()) |last_pending_block| { | 386 | if (p.pending_blocks.last()) |last_pending_block| { |
| 387 | // If the last block is a list or list item, check for tightness based | 387 | // If the last block is a list or list item, check for tightness based |
| 388 | // on the last line. | 388 | // on the last line. |
| 389 | const maybe_containing_list = switch (last_pending_block.tag) { | 389 | const maybe_containing_list = switch (last_pending_block.tag) { |
| ... | @@ -401,7 +401,7 @@ fn appendBlockStart(p: *Parser, block_start: BlockStart) !void { | ... | @@ -401,7 +401,7 @@ fn appendBlockStart(p: *Parser, block_start: BlockStart) !void { |
| 401 | // Start a new list if the new block is a list item and there is no | 401 | // Start a new list if the new block is a list item and there is no |
| 402 | // containing list yet. | 402 | // containing list yet. |
| 403 | if (block_start.tag == .list_item and | 403 | if (block_start.tag == .list_item and |
| 404 | (p.pending_blocks.items.len == 0 or p.pending_blocks.getLast().?.tag != .list)) | 404 | (p.pending_blocks.items.len == 0 or p.pending_blocks.last().?.tag != .list)) |
| 405 | { | 405 | { |
| 406 | try p.pending_blocks.append(p.allocator, .{ | 406 | try p.pending_blocks.append(p.allocator, .{ |
| 407 | .tag = .list, | 407 | .tag = .list, |
| ... | @@ -417,7 +417,7 @@ fn appendBlockStart(p: *Parser, block_start: BlockStart) !void { | ... | @@ -417,7 +417,7 @@ fn appendBlockStart(p: *Parser, block_start: BlockStart) !void { |
| 417 | 417 | ||
| 418 | if (block_start.tag == .table_row) { | 418 | if (block_start.tag == .table_row) { |
| 419 | // Likewise, table rows start a table implicitly. | 419 | // Likewise, table rows start a table implicitly. |
| 420 | if (p.pending_blocks.items.len == 0 or p.pending_blocks.getLast().?.tag != .table) { | 420 | if (p.pending_blocks.items.len == 0 or p.pending_blocks.last().?.tag != .table) { |
| 421 | try p.pending_blocks.append(p.allocator, .{ | 421 | try p.pending_blocks.append(p.allocator, .{ |
| 422 | .tag = .table, | 422 | .tag = .table, |
| 423 | .data = .{ .table = .{ | 423 | .data = .{ .table = .{ |
| ... | @@ -429,7 +429,7 @@ fn appendBlockStart(p: *Parser, block_start: BlockStart) !void { | ... | @@ -429,7 +429,7 @@ fn appendBlockStart(p: *Parser, block_start: BlockStart) !void { |
| 429 | }); | 429 | }); |
| 430 | } | 430 | } |
| 431 | 431 | ||
| 432 | const current_row = p.scratch_extra.items.len - p.pending_blocks.getLast().?.extra_start; | 432 | const current_row = p.scratch_extra.items.len - p.pending_blocks.last().?.extra_start; |
| 433 | if (current_row <= 1) { | 433 | if (current_row <= 1) { |
| 434 | var buffer: [max_table_columns]Node.TableCellAlignment = undefined; | 434 | var buffer: [max_table_columns]Node.TableCellAlignment = undefined; |
| 435 | const table_row = &block_start.data.table_row; | 435 | const table_row = &block_start.data.table_row; |
| ... | @@ -441,7 +441,7 @@ fn appendBlockStart(p: *Parser, block_start: BlockStart) !void { | ... | @@ -441,7 +441,7 @@ fn appendBlockStart(p: *Parser, block_start: BlockStart) !void { |
| 441 | // We need to go back and mark the header row and its column | 441 | // We need to go back and mark the header row and its column |
| 442 | // alignments. | 442 | // alignments. |
| 443 | const datas = p.nodes.items(.data); | 443 | const datas = p.nodes.items(.data); |
| 444 | const header_data = datas[p.scratch_extra.getLast().?]; | 444 | const header_data = datas[p.scratch_extra.last().?]; |
| 445 | for (p.extraChildren(header_data.container.children), 0..) |header_cell, i| { | 445 | for (p.extraChildren(header_data.container.children), 0..) |header_cell, i| { |
| 446 | const alignment = if (i < alignments.len) alignments[i] else .unset; | 446 | const alignment = if (i < alignments.len) alignments[i] else .unset; |
| 447 | const cell_data = &datas[@backingInt(header_cell)].table_cell; | 447 | const cell_data = &datas[@backingInt(header_cell)].table_cell; |
| ... | @@ -594,7 +594,7 @@ fn startListItem(unindented_line: []const u8) ?ListItemStart { | ... | @@ -594,7 +594,7 @@ fn startListItem(unindented_line: []const u8) ?ListItemStart { |
| 594 | }; | 594 | }; |
| 595 | } | 595 | } |
| 596 | 596 | ||
| 597 | const number_end = mem.indexOfNone(u8, unindented_line, "0123456789") orelse return null; | 597 | const number_end = mem.findNone(u8, unindented_line, "0123456789") orelse return null; |
| 598 | const after_number = unindented_line[number_end..]; | 598 | const after_number = unindented_line[number_end..]; |
| 599 | const marker: Block.Data.ListMarker = if (mem.startsWith(u8, after_number, ". ")) | 599 | const marker: Block.Data.ListMarker = if (mem.startsWith(u8, after_number, ". ")) |
| 600 | .number_dot | 600 | .number_dot |
| ... | @@ -639,10 +639,10 @@ fn startTableRow(unindented_line: []const u8) ?TableRowStart { | ... | @@ -639,10 +639,10 @@ fn startTableRow(unindented_line: []const u8) ?TableRowStart { |
| 639 | // Ignoring pipes in code spans allows table cells to contain | 639 | // Ignoring pipes in code spans allows table cells to contain |
| 640 | // code using ||, for example. | 640 | // code using ||, for example. |
| 641 | const open_start = i; | 641 | const open_start = i; |
| 642 | i = mem.indexOfNonePos(u8, table_row_content, i, "`") orelse return null; | 642 | i = mem.findNonePos(u8, table_row_content, i, "`") orelse return null; |
| 643 | const open_len = i - open_start; | 643 | const open_len = i - open_start; |
| 644 | while (mem.indexOfScalarPos(u8, table_row_content, i, '`')) |close_start| { | 644 | while (mem.findScalarPos(u8, table_row_content, i, '`')) |close_start| { |
| 645 | i = mem.indexOfNonePos(u8, table_row_content, close_start, "`") orelse return null; | 645 | i = mem.findNonePos(u8, table_row_content, close_start, "`") orelse return null; |
| 646 | const close_len = i - close_start; | 646 | const close_len = i - close_start; |
| 647 | if (close_len == open_len) break; | 647 | if (close_len == open_len) break; |
| 648 | } else return null; | 648 | } else return null; |
| ... | @@ -794,7 +794,7 @@ fn startCodeBlock(p: *Parser, unindented_line: []const u8) !?CodeBlockStart { | ... | @@ -794,7 +794,7 @@ fn startCodeBlock(p: *Parser, unindented_line: []const u8) !?CodeBlockStart { |
| 794 | } else ""; | 794 | } else ""; |
| 795 | // Code block tags may not contain backticks, since that would create | 795 | // Code block tags may not contain backticks, since that would create |
| 796 | // potential confusion with inline code spans. | 796 | // potential confusion with inline code spans. |
| 797 | if (fence_len < 3 or mem.indexOfScalar(u8, tag_bytes, '`') != null) return null; | 797 | if (fence_len < 3 or mem.findScalar(u8, tag_bytes, '`') != null) return null; |
| 798 | return .{ | 798 | return .{ |
| 799 | .tag = try p.addString(mem.trim(u8, tag_bytes, " ")), | 799 | .tag = try p.addString(mem.trim(u8, tag_bytes, " ")), |
| 800 | .fence_len = fence_len, | 800 | .fence_len = fence_len, |
| ... | @@ -1382,12 +1382,12 @@ const InlineParser = struct { | ... | @@ -1382,12 +1382,12 @@ const InlineParser = struct { |
| 1382 | /// parsing. | 1382 | /// parsing. |
| 1383 | fn parseCodeSpan(ip: *InlineParser) !void { | 1383 | fn parseCodeSpan(ip: *InlineParser) !void { |
| 1384 | const opener_start = ip.pos; | 1384 | const opener_start = ip.pos; |
| 1385 | ip.pos = mem.indexOfNonePos(u8, ip.content, ip.pos, "`") orelse ip.content.len; | 1385 | ip.pos = mem.findNonePos(u8, ip.content, ip.pos, "`") orelse ip.content.len; |
| 1386 | const opener_len = ip.pos - opener_start; | 1386 | const opener_len = ip.pos - opener_start; |
| 1387 | 1387 | ||
| 1388 | const start = ip.pos; | 1388 | const start = ip.pos; |
| 1389 | const end = while (mem.indexOfScalarPos(u8, ip.content, ip.pos, '`')) |closer_start| { | 1389 | const end = while (mem.findScalarPos(u8, ip.content, ip.pos, '`')) |closer_start| { |
| 1390 | ip.pos = mem.indexOfNonePos(u8, ip.content, closer_start, "`") orelse ip.content.len; | 1390 | ip.pos = mem.findNonePos(u8, ip.content, closer_start, "`") orelse ip.content.len; |
| 1391 | const closer_len = ip.pos - closer_start; | 1391 | const closer_len = ip.pos - closer_start; |
| 1392 | 1392 | ||
| 1393 | if (closer_len == opener_len) break closer_start; | 1393 | if (closer_len == opener_len) break closer_start; |
| ... | @@ -1627,7 +1627,7 @@ fn addScratchStringLine(p: *Parser, line: []const u8) !void { | ... | @@ -1627,7 +1627,7 @@ fn addScratchStringLine(p: *Parser, line: []const u8) !void { |
| 1627 | } | 1627 | } |
| 1628 | 1628 | ||
| 1629 | fn isBlank(line: []const u8) bool { | 1629 | fn isBlank(line: []const u8) bool { |
| 1630 | return mem.indexOfNone(u8, line, " \t") == null; | 1630 | return mem.findNone(u8, line, " \t") == null; |
| 1631 | } | 1631 | } |
| 1632 | 1632 | ||
| 1633 | fn isPunctuation(c: u8) bool { | 1633 | fn isPunctuation(c: u8) bool { |
lib/fuzzer.zig+4-4| ... | @@ -41,8 +41,8 @@ fn logOverride( | ... | @@ -41,8 +41,8 @@ fn logOverride( |
| 41 | 41 | ||
| 42 | var safe_allocator: std.heap.SafeAllocator = .init(std.heap.page_allocator, .{}); | 42 | var safe_allocator: std.heap.SafeAllocator = .init(std.heap.page_allocator, .{}); |
| 43 | const gpa = switch (builtin.mode) { | 43 | const gpa = switch (builtin.mode) { |
| 44 | .Debug, .ReleaseSafe => safe_allocator.allocator(), | 44 | .debug, .safe => safe_allocator.allocator(), |
| 45 | .ReleaseFast, .ReleaseSmall => std.heap.smp_allocator, | 45 | .fast, .small => std.heap.smp_allocator, |
| 46 | }; | 46 | }; |
| 47 | 47 | ||
| 48 | // Seperate from `exec` to allow initialization before `exec` is. | 48 | // Seperate from `exec` to allow initialization before `exec` is. |
| ... | @@ -1085,7 +1085,7 @@ const Fuzzer = struct { | ... | @@ -1085,7 +1085,7 @@ const Fuzzer = struct { |
| 1085 | fn removeBest(f: *Fuzzer, i: Input.Index, best_i: u32) void { | 1085 | fn removeBest(f: *Fuzzer, i: Input.Index, best_i: u32) void { |
| 1086 | const t = &f.tests[f.test_i]; | 1086 | const t = &f.tests[f.test_i]; |
| 1087 | const ref = &t.corpus.items(.ref)[@backingInt(i)]; | 1087 | const ref = &t.corpus.items(.ref)[@backingInt(i)]; |
| 1088 | const list_i = mem.indexOfScalar(u32, ref.best_i_buf[0..ref.best_i_len], best_i).?; | 1088 | const list_i = mem.findScalar(u32, ref.best_i_buf[0..ref.best_i_len], best_i).?; |
| 1089 | ref.best_i_len -= 1; | 1089 | ref.best_i_len -= 1; |
| 1090 | ref.best_i_buf[list_i] = ref.best_i_buf[ref.best_i_len]; | 1090 | ref.best_i_buf[list_i] = ref.best_i_buf[ref.best_i_len]; |
| 1091 | 1091 | ||
| ... | @@ -1209,7 +1209,7 @@ const Fuzzer = struct { | ... | @@ -1209,7 +1209,7 @@ const Fuzzer = struct { |
| 1209 | f.req_bytes = @intCast(f.input_builder.bytes_table.items.len); | 1209 | f.req_bytes = @intCast(f.input_builder.bytes_table.items.len); |
| 1210 | const quality: Input.Best.Quality = .{ | 1210 | const quality: Input.Best.Quality = .{ |
| 1211 | .n_pcs = n_pcs: { | 1211 | .n_pcs = n_pcs: { |
| 1212 | @setRuntimeSafety(builtin.mode == .Debug); // Necessary for vectorization | 1212 | @setRuntimeSafety(builtin.mode == .debug); // Necessary for vectorization |
| 1213 | var n: u32 = 0; | 1213 | var n: u32 = 0; |
| 1214 | for (exec.pc_counters) |c| { | 1214 | for (exec.pc_counters) |c| { |
| 1215 | n += @intFromBool(c != 0); | 1215 | n += @intFromBool(c != 0); |
lib/libc/glibc/abilists| Binary files a/lib/libc/glibc/abilists and b/lib/libc/glibc/abilists differ | |||
lib/libc/glibc/elf/elf.h+6-2| ... | @@ -798,7 +798,8 @@ typedef struct | ... | @@ -798,7 +798,8 @@ typedef struct |
| 798 | #define NT_X86_XSTATE	0x202		/* x86 extended state using xsave */ | 798 | #define NT_X86_XSTATE	0x202		/* x86 extended state using xsave */ |
| 799 | #define NT_X86_SHSTK	0x204		/* x86 SHSTK state */ | 799 | #define NT_X86_SHSTK	0x204		/* x86 SHSTK state */ |
| 800 | #define NT_X86_XSAVE_LAYOUT	0x205		/* XSAVE layout description. */ | 800 | #define NT_X86_XSAVE_LAYOUT	0x205		/* XSAVE layout description. */ |
| 801 | #define NT_S390_HIGH_GPRS	0x300	/* s390 upper register halves */ | 801 | #define NT_S390_HIGH_GPRS	0x300	/* s390 upper register halves. This was |
| 802 | 					 used in now removed s390-32 arch. */ | ||
| 802 | #define NT_S390_TIMER	0x301		/* s390 timer register */ | 803 | #define NT_S390_TIMER	0x301		/* s390 timer register */ |
| 803 | #define NT_S390_TODCMP	0x302		/* s390 TOD clock comparator register */ | 804 | #define NT_S390_TODCMP	0x302		/* s390 TOD clock comparator register */ |
| 804 | #define NT_S390_TODPREG	0x303		/* s390 TOD programmable register */ | 805 | #define NT_S390_TODPREG	0x303		/* s390 TOD programmable register */ |
| ... | @@ -846,6 +847,7 @@ typedef struct | ... | @@ -846,6 +847,7 @@ typedef struct |
| 846 | #define NT_RISCV_VECTOR	0x901		/* RISC-V vector registers */ | 847 | #define NT_RISCV_VECTOR	0x901		/* RISC-V vector registers */ |
| 847 | #define NT_RISCV_TAGGED_ADDR_CTRL	0x902	/* RISC-V tagged | 848 | #define NT_RISCV_TAGGED_ADDR_CTRL	0x902	/* RISC-V tagged |
| 848 | 						 address control */ | 849 | 						 address control */ |
| 850 | #define NT_RISCV_USER_CFI	0x903		/* RISC-V shadow stack state */ | ||
| 849 | #define NT_LOONGARCH_CPUCFG	0xa00	/* LoongArch CPU config registers. */ | 851 | #define NT_LOONGARCH_CPUCFG	0xa00	/* LoongArch CPU config registers. */ |
| 850 | #define NT_LOONGARCH_CSR	0xa01	/* LoongArch control and | 852 | #define NT_LOONGARCH_CSR	0xa01	/* LoongArch control and |
| 851 | 					 status registers. */ | 853 | 					 status registers. */ |
| ... | @@ -3470,7 +3472,9 @@ enum | ... | @@ -3470,7 +3472,9 @@ enum |
| 3470 | 3472 | ||
| 3471 | /* Valid values for the e_flags field. */ | 3473 | /* Valid values for the e_flags field. */ |
| 3472 | 3474 | ||
| 3473 | #define EF_S390_HIGH_GPRS 0x00000001 /* High GPRs kernel facility needed. */ | 3475 | #define EF_S390_HIGH_GPRS 0x00000001 /* High GPRs kernel facility needed. |
| 3476 | 					 This was used in now removed s390-32 | ||
| 3477 | 					 arch. */ | ||
| 3474 | 3478 | ||
| 3475 | /* Additional s390 relocs */ | 3479 | /* Additional s390 relocs */ |
| 3476 | 3480 |
lib/libc/glibc/include/libc-symbols.h+2-1| ... | @@ -113,6 +113,7 @@ | ... | @@ -113,6 +113,7 @@ |
| 113 | #define HAVE_LIBINTL_H	1 | 113 | #define HAVE_LIBINTL_H	1 |
| 114 | #define HAVE_WCTYPE_H	1 | 114 | #define HAVE_WCTYPE_H	1 |
| 115 | #define HAVE_ISWCTYPE	1 | 115 | #define HAVE_ISWCTYPE	1 |
| 116 | #define HAVE_MEMPCPY	1 | ||
| 116 | #define ENABLE_NLS	1 | 117 | #define ENABLE_NLS	1 |
| 117 | 118 | ||
| 118 | /* The symbols in all the user (non-_) macros are C symbols. */ | 119 | /* The symbols in all the user (non-_) macros are C symbols. */ |
| ... | @@ -682,7 +683,7 @@ for linking") | ... | @@ -682,7 +683,7 @@ for linking") |
| 682 | 683 | ||
| 683 | /* Helper / base macros for indirect function symbols. */ | 684 | /* Helper / base macros for indirect function symbols. */ |
| 684 | #define __ifunc_resolver(type_name, name, expr, init, classifier, ...)	\ | 685 | #define __ifunc_resolver(type_name, name, expr, init, classifier, ...)	\ |
| 685 | classifier inhibit_stack_protector					\ | 686 | classifier								\ |
| 686 | __typeof (type_name) *name##_ifunc (__VA_ARGS__)			\ | 687 | __typeof (type_name) *name##_ifunc (__VA_ARGS__)			\ |
| 687 | {									\ | 688 | {									\ |
| 688 | init ();								\ | 689 | init ();								\ |
lib/libc/glibc/sysdeps/aarch64/sysdep.h+28-4| ... | @@ -43,7 +43,6 @@ | ... | @@ -43,7 +43,6 @@ |
| 43 | #define FEATURE_1_PAC 2 | 43 | #define FEATURE_1_PAC 2 |
| 44 | #define FEATURE_1_GCS 4 | 44 | #define FEATURE_1_GCS 4 |
| 45 | 45 | ||
| 46 | /* Add a NT_GNU_PROPERTY_TYPE_0 note. */ | ||
| 47 | #define GNU_PROPERTY(type, value)	\ | 46 | #define GNU_PROPERTY(type, value)	\ |
| 48 | .section .note.gnu.property, "a";	\ | 47 | .section .note.gnu.property, "a";	\ |
| 49 | .p2align 3;				\ | 48 | .p2align 3;				\ |
| ... | @@ -57,9 +56,34 @@ | ... | @@ -57,9 +56,34 @@ |
| 57 | .word 0;				\ | 56 | .word 0;				\ |
| 58 | .text | 57 | .text |
| 59 | 58 | ||
| 60 | /* Add GNU property note with the supported features to all asm code | 59 | #ifdef __ARM_BUILDATTR64_FV |
| 61 | where sysdep.h is included. */ | 60 | /* Add AArch64 feature bits build attributes. */ |
| 62 | GNU_PROPERTY (FEATURE_1_AND, FEATURE_1_BTI|FEATURE_1_PAC|FEATURE_1_GCS) | 61 | # define FEATURE_1_AND_MARK(value)					\ |
| 62 | .aeabi_subsection aeabi_feature_and_bits, optional, ULEB128;	\ | ||
| 63 | .if ((value) & FEATURE_1_BTI);					\ | ||
| 64 | .aeabi_attribute Tag_Feature_BTI, 1;				\ | ||
| 65 | .else;								\ | ||
| 66 | .aeabi_attribute Tag_Feature_BTI, 0;				\ | ||
| 67 | .endif;								\ | ||
| 68 | .if ((value) & FEATURE_1_GCS);					\ | ||
| 69 | .aeabi_attribute Tag_Feature_GCS, 1;				\ | ||
| 70 | .else;								\ | ||
| 71 | .aeabi_attribute Tag_Feature_GCS, 0;				\ | ||
| 72 | .endif;								\ | ||
| 73 | .if ((value) & FEATURE_1_PAC);					\ | ||
| 74 | .aeabi_attribute Tag_Feature_PAC, 1;				\ | ||
| 75 | .else;								\ | ||
| 76 | .aeabi_attribute Tag_Feature_PAC, 0;				\ | ||
| 77 | .endif;								\ | ||
| 78 | .text | ||
| 79 | #else | ||
| 80 | /* Add a NT_GNU_PROPERTY_TYPE_0 note. */ | ||
| 81 | # define FEATURE_1_AND_MARK(value) GNU_PROPERTY (FEATURE_1_AND, value) | ||
| 82 | #endif /* __ARM_BUILDATTR64_FV */ | ||
| 83 | |||
| 84 | /* Add marking with the supported features to all asm code where sysdep.h | ||
| 85 | is included. */ | ||
| 86 | FEATURE_1_AND_MARK (FEATURE_1_BTI | FEATURE_1_PAC | FEATURE_1_GCS) | ||
| 63 | 87 | ||
| 64 | /* Define an entry point visible from C. */ | 88 | /* Define an entry point visible from C. */ |
| 65 | #define ENTRY(name)						\ | 89 | #define ENTRY(name)						\ |
lib/libc/glibc/sysdeps/arm/start.S+27| ... | @@ -90,6 +90,7 @@ _start: | ... | @@ -90,6 +90,7 @@ _start: |
| 90 | 	push { a1 } | 90 | 	push { a1 } |
| 91 | 91 | ||
| 92 | #ifdef PIC | 92 | #ifdef PIC |
| 93 | # ifdef SHARED | ||
| 93 | 	ldr sl, .L_GOT | 94 | 	ldr sl, .L_GOT |
| 94 | 	adr a4, .L_GOT | 95 | 	adr a4, .L_GOT |
| 95 | 	add sl, sl, a4 | 96 | 	add sl, sl, a4 |
| ... | @@ -103,6 +104,16 @@ _start: | ... | @@ -103,6 +104,16 @@ _start: |
| 103 | 	/* __libc_start_main (main, argc, argv, init, fini, rtld_fini, stack_end) */ | 104 | 	/* __libc_start_main (main, argc, argv, init, fini, rtld_fini, stack_end) */ |
| 104 | 	/* Let the libc call main and exit with its return code. */ | 105 | 	/* Let the libc call main and exit with its return code. */ |
| 105 | 	bl __libc_start_main(PLT) | 106 | 	bl __libc_start_main(PLT) |
| 107 | # else | ||
| 108 | 	ldr a1, .L_main_rel	/* Load the relative offset of __wrap_main. */ | ||
| 109 | 	adr a4, .L_main_rel	/* Load the actual runtime address of the label. */ | ||
| 110 | 	add a1, a4, a1		/* Add them together to get the absolute address. */ | ||
| 111 | |||
| 112 | 	mov a4, #0		/* Used to be init. */ | ||
| 113 | 	push { a4 }		/* Used to be fini. */ | ||
| 114 | |||
| 115 | 	bl __libc_start_main | ||
| 116 | # endif /* ifdef SHARED */ | ||
| 106 | #else | 117 | #else |
| 107 | 118 | ||
| 108 | 	mov a4, #0		/* Used to init. */ | 119 | 	mov a4, #0		/* Used to init. */ |
| ... | @@ -119,14 +130,30 @@ _start: | ... | @@ -119,14 +130,30 @@ _start: |
| 119 | 130 | ||
| 120 | #ifdef PIC | 131 | #ifdef PIC |
| 121 | 	.align 2 | 132 | 	.align 2 |
| 133 | # ifdef SHARED | ||
| 122 | .L_GOT: | 134 | .L_GOT: |
| 123 | 	.word _GLOBAL_OFFSET_TABLE_ - .L_GOT | 135 | 	.word _GLOBAL_OFFSET_TABLE_ - .L_GOT |
| 124 | 	.word main(GOT) | 136 | 	.word main(GOT) |
| 137 | # else | ||
| 138 | .L_main_rel: | ||
| 139 | 	.word __wrap_main - .L_main_rel | ||
| 140 | # endif | ||
| 125 | #endif | 141 | #endif |
| 126 | 142 | ||
| 127 | .cantunwind | 143 | .cantunwind |
| 128 | .fnend | 144 | .fnend |
| 129 | 145 | ||
| 146 | #if defined PIC && !defined SHARED | ||
| 147 | /* When main is not defined in the executable but in a shared library then | ||
| 148 | a wrapper is needed, because crt1.o and rcrt1.o share this code and the | ||
| 149 | latter (static PIE) must avoid GOT relocations before __libc_start_main | ||
| 150 | is called. The branch to main is turned into a PLT entry by every linker, | ||
| 151 | unlike a REL32 data relocation against main. */ | ||
| 152 | 	.type __wrap_main, %function | ||
| 153 | __wrap_main: | ||
| 154 | 	b main | ||
| 155 | #endif | ||
| 156 | |||
| 130 | /* Define a symbol for the first piece of initialized data. */ | 157 | /* Define a symbol for the first piece of initialized data. */ |
| 131 | 	.data | 158 | 	.data |
| 132 | 	.globl __data_start | 159 | 	.globl __data_start |
lib/libc/glibc/sysdeps/htl/libc-lockP.h+14| ... | @@ -21,6 +21,20 @@ | ... | @@ -21,6 +21,20 @@ |
| 21 | 21 | ||
| 22 | #include <pthread.h> | 22 | #include <pthread.h> |
| 23 | 23 | ||
| 24 | typedef pthread_rwlock_t __libc_rwlock_t; | ||
| 25 | |||
| 26 | #define __libc_rwlock_define(CLASS,NAME) \ | ||
| 27 | CLASS __libc_rwlock_t NAME; | ||
| 28 | #define __libc_rwlock_define_initialized(CLASS,NAME) \ | ||
| 29 | CLASS __libc_rwlock_t NAME = PTHREAD_RWLOCK_INITIALIZER; | ||
| 30 | #define __libc_rwlock_init(NAME) __pthread_rwlock_init (&(NAME), NULL) | ||
| 31 | #define __libc_rwlock_fini(NAME) ((void) 0) | ||
| 32 | #define __libc_rwlock_rdlock(NAME) __pthread_rwlock_rdlock (&(NAME)) | ||
| 33 | #define __libc_rwlock_wrlock(NAME) __pthread_rwlock_wrlock (&(NAME)) | ||
| 34 | #define __libc_rwlock_tryrdlock(NAME) __pthread_rwlock_tryrdlock (&(NAME)) | ||
| 35 | #define __libc_rwlock_trywrlock(NAME) __pthread_rwlock_trywrlock (&(NAME)) | ||
| 36 | #define __libc_rwlock_unlock(NAME) __pthread_rwlock_unlock (&(NAME)) | ||
| 37 | |||
| 24 | /* If we check for a weakly referenced symbol and then perform a | 38 | /* If we check for a weakly referenced symbol and then perform a |
| 25 | normal jump to it te code generated for some platforms in case of | 39 | normal jump to it te code generated for some platforms in case of |
| 26 | PIC is unnecessarily slow. What would happen is that the function | 40 | PIC is unnecessarily slow. What would happen is that the function |
lib/libc/glibc/sysdeps/loongarch/start.S+18-8| ... | @@ -36,6 +36,7 @@ | ... | @@ -36,6 +36,7 @@ |
| 36 | #define __ASSEMBLY__ 1 | 36 | #define __ASSEMBLY__ 1 |
| 37 | #include <entry.h> | 37 | #include <entry.h> |
| 38 | #include <sys/asm.h> | 38 | #include <sys/asm.h> |
| 39 | #include <sysdep.h> | ||
| 39 | 40 | ||
| 40 | /* The entry point's job is to call __libc_start_main. Per the ABI, | 41 | /* The entry point's job is to call __libc_start_main. Per the ABI, |
| 41 | a0 contains the address of a function to be passed to atexit. | 42 | a0 contains the address of a function to be passed to atexit. |
| ... | @@ -57,23 +58,32 @@ ENTRY (ENTRY_POINT) | ... | @@ -57,23 +58,32 @@ ENTRY (ENTRY_POINT) |
| 57 | /* Terminate call stack by noting ra is undefined. Use a dummy | 58 | /* Terminate call stack by noting ra is undefined. Use a dummy |
| 58 | .cfi_label to force starting the FDE. */ | 59 | .cfi_label to force starting the FDE. */ |
| 59 | 	.cfi_label .Ldummy | 60 | 	.cfi_label .Ldummy |
| 60 | 	cfi_undefined (1) | 61 | 	cfi_undefined	(1) |
| 61 | 	or		a5, a0, zero /* rtld_fini */ | 62 | 	or		a5, a0, zero /* rtld_fini */ |
| 62 | 63 | ||
| 63 | 	la.pcrel	a0, t0, main | 64 | #if defined PIC && !defined SHARED |
| 65 | 	/* Avoid relocation in static PIE since _start is called before it | ||
| 66 | 	 is relocated. */ | ||
| 67 | 	la.pcrel	a0, __wrap_main | ||
| 68 | #else | ||
| 69 | 	LA_GOT		(a0, main) | ||
| 70 | #endif | ||
| 71 | |||
| 64 | 	REG_L		a1, sp, 0 | 72 | 	REG_L		a1, sp, 0 |
| 65 | 	ADDI		a2, sp, SZREG | 73 | 	ADDI		a2, sp, SZREG |
| 66 | 74 | ||
| 67 | 	/* Adjust $sp for 16-aligned */ | 75 | 	/* Adjust $sp for 16-bytes aligned */ |
| 68 | 	BSTRINS		sp, zero, 3, 0 | 76 | 	REG_ALIGN_ASM	(sp, 4) |
| 69 | 77 | ||
| 70 | 	move		a3, zero /* used to be init */ | 78 | 	move		a3, zero /* used to be init */ |
| 71 | 	move		a4, zero /* used to be fini */ | 79 | 	move		a4, zero /* used to be fini */ |
| 72 | 	or		a6, sp, zero /* stack_end */ | 80 | 	or		a6, sp, zero /* stack_end */ |
| 73 | 81 | ||
| 74 | 	la.pcrel	ra, t0, __libc_start_main | 82 | 	CALL		(__libc_start_main) |
| 75 | 	jirl		ra, ra, 0 | 83 | 	CALL		(abort) |
| 76 | 84 | ||
| 77 | 	la.pcrel	ra, t0, abort | 85 | #if defined PIC && !defined SHARED |
| 78 | 	jirl		ra, ra, 0 | 86 | __wrap_main: |
| 87 | 	TAIL		(main) | ||
| 88 | #endif | ||
| 79 | END (ENTRY_POINT) | 89 | END (ENTRY_POINT) |
lib/libc/glibc/sysdeps/loongarch/sys/asm.h created+104| ... | @@ -0,0 +1,104 @@ | ||
| 1 | /* Miscellaneous macros. | ||
| 2 | Copyright (C) 2022-2026 Free Software Foundation, Inc. | ||
| 3 | This file is part of the GNU C Library. | ||
| 4 | |||
| 5 | The GNU C Library is free software; you can redistribute it and/or | ||
| 6 | modify it under the terms of the GNU Lesser General Public | ||
| 7 | License as published by the Free Software Foundation; either | ||
| 8 | version 2.1 of the License, or (at your option) any later version. | ||
| 9 | |||
| 10 | The GNU C Library is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 13 | Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public | ||
| 16 | License along with the GNU C Library. If not, see | ||
| 17 | <https://www.gnu.org/licenses/>. */ | ||
| 18 | |||
| 19 | #ifndef _SYS_ASM_H | ||
| 20 | #define _SYS_ASM_H | ||
| 21 | |||
| 22 | #include <sys/regdef.h> | ||
| 23 | #include <sysdeps/generic/sysdep.h> | ||
| 24 | |||
| 25 | /* Macros to handle different pointer/register sizes for 32/64-bit code. */ | ||
| 26 | #if __loongarch_grlen == 64 | ||
| 27 | #define SZREG 8 | ||
| 28 | #define REG_L ld.d | ||
| 29 | #define REG_S st.d | ||
| 30 | #define SRLI srli.d | ||
| 31 | #define SLLI slli.d | ||
| 32 | #define ADDI addi.d | ||
| 33 | #define ADD add.d | ||
| 34 | #define SUB sub.d | ||
| 35 | #define LI li.d | ||
| 36 | #define BSTRINS bstrins.d | ||
| 37 | |||
| 38 | #elif __loongarch_grlen == 32 | ||
| 39 | |||
| 40 | #define SZREG 4 | ||
| 41 | #define REG_L ld.w | ||
| 42 | #define REG_S st.w | ||
| 43 | #define SRLI srli.w | ||
| 44 | #define SLLI slli.w | ||
| 45 | #define ADDI addi.w | ||
| 46 | #define ADD add.w | ||
| 47 | #define SUB sub.w | ||
| 48 | #define LI li.w | ||
| 49 | #define BSTRINS bstrins.w | ||
| 50 | |||
| 51 | #else | ||
| 52 | #error __loongarch_grlen must equal 32 or 64 | ||
| 53 | #endif | ||
| 54 | |||
| 55 | #if __loongarch_frlen == 64 | ||
| 56 | #define SZFREG 8 | ||
| 57 | #define FREG_L fld.d | ||
| 58 | #define FREG_S fst.d | ||
| 59 | #elif __loongarch_frlen == 32 | ||
| 60 | #define SZFREG 4 | ||
| 61 | #define FREG_L fld.s | ||
| 62 | #define FREG_S fst.s | ||
| 63 | #endif | ||
| 64 | |||
| 65 | #define SZVREG 16 | ||
| 66 | #define SZXREG 32 | ||
| 67 | |||
| 68 | /* Declare leaf routine. | ||
| 69 | The usage of macro LEAF/ENTRY is as follows: | ||
| 70 | 1. LEAF(fcn) -- the align value of fcn is .align 3 (default value) | ||
| 71 | 2. LEAF(fcn, 6) -- the align value of fcn is .align 6 | ||
| 72 | */ | ||
| 73 | #define LEAF_IMPL(symbol, aln, ...)	\ | ||
| 74 | 	.text;				\ | ||
| 75 | 	.globl symbol;			\ | ||
| 76 | 	.align aln;			\ | ||
| 77 | 	.type symbol, @function;	\ | ||
| 78 | symbol: \ | ||
| 79 | 	cfi_startproc; | ||
| 80 | |||
| 81 | |||
| 82 | #define LEAF(...) LEAF_IMPL(__VA_ARGS__, 3) | ||
| 83 | #define ENTRY(...) LEAF(__VA_ARGS__) | ||
| 84 | |||
| 85 | #define	LEAF_NO_ALIGN(symbol)		\ | ||
| 86 | 	.text;				\ | ||
| 87 | 	.globl	symbol;			\ | ||
| 88 | 	.type	symbol, @function;	\ | ||
| 89 | symbol: \ | ||
| 90 | 	cfi_startproc; | ||
| 91 | |||
| 92 | #define ENTRY_NO_ALIGN(symbol) LEAF_NO_ALIGN(symbol) | ||
| 93 | |||
| 94 | |||
| 95 | /* Mark end of function. */ | ||
| 96 | #undef END | ||
| 97 | #define END(function) \ | ||
| 98 | cfi_endproc; \ | ||
| 99 | .size function, .- function; | ||
| 100 | |||
| 101 | /* Stack alignment. */ | ||
| 102 | #define ALMASK ~15 | ||
| 103 | |||
| 104 | #endif /* sys/asm.h */ | ||
lib/libc/glibc/sysdeps/loongarch/sysdep.h created+94| ... | @@ -0,0 +1,94 @@ | ||
| 1 | /* Macros for LoongArch. | ||
| 2 | Copyright (C) 2026 Free Software Foundation, Inc. | ||
| 3 | This file is part of the GNU C Library. | ||
| 4 | |||
| 5 | The GNU C Library is free software; you can redistribute it and/or | ||
| 6 | modify it under the terms of the GNU Lesser General Public | ||
| 7 | License as published by the Free Software Foundation; either | ||
| 8 | version 2.1 of the License, or (at your option) any later version. | ||
| 9 | |||
| 10 | The GNU C Library is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 13 | Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public | ||
| 16 | License along with the GNU C Library. If not, see | ||
| 17 | <https://www.gnu.org/licenses/>. */ | ||
| 18 | |||
| 19 | #ifndef _LOONGARCH_SYSDEP_H | ||
| 20 | #define _LOONGARCH_SYSDEP_H | ||
| 21 | |||
| 22 | #if __loongarch_grlen == 64 | ||
| 23 | |||
| 24 | #define PTRLOG 3 | ||
| 25 | /* Align reg to 2^n. Used in C. */ | ||
| 26 | #define REG_ALIGN_C(reg, n) \ | ||
| 27 | "bstrins.d\t" __STRING(reg) ", $zero, (" __STRING(n) "-1), 0" | ||
| 28 | |||
| 29 | #elif __loongarch_grlen == 32 | ||
| 30 | |||
| 31 | #define PTRLOG 2 | ||
| 32 | #define REG_ALIGN_C(reg, n) \ | ||
| 33 | "srli.w\t" __STRING(reg)", " __STRING(reg)", " __STRING(n) "\n\t" \ | ||
| 34 | "slli.w\t" __STRING(reg)", " __STRING(reg)", " __STRING(n) | ||
| 35 | |||
| 36 | #else | ||
| 37 | #error __loongarch_grlen must equal 32 or 64 | ||
| 38 | #endif | ||
| 39 | |||
| 40 | #ifdef	__ASSEMBLER__ | ||
| 41 | |||
| 42 | /* Stack alignment bytes. */ | ||
| 43 | #define STACK_ALIGN 16 | ||
| 44 | |||
| 45 | /* Macros to handle different pointer/register sizes for 32/64-bit code. */ | ||
| 46 | #if __loongarch_grlen == 64 | ||
| 47 | #define SRAI srai.d | ||
| 48 | |||
| 49 | /* Align reg to 2^n. Used in assembly. */ | ||
| 50 | #define REG_ALIGN_ASM(reg, n) bstrins.d reg, zero, (n-1), 0 | ||
| 51 | |||
| 52 | #define LOAD_LOCAL(reg, sym) \ | ||
| 53 | pcalau12i reg, %pc_hi20(sym); \ | ||
| 54 | ld.d	 reg, reg, %pc_lo12(sym); | ||
| 55 | |||
| 56 | #define LOAD_GLOBAL(reg, sym) \ | ||
| 57 | la.got reg, sym; \ | ||
| 58 | ld.d	 reg, reg, 0; | ||
| 59 | |||
| 60 | #define LA_GOT(reg, sym) la.got reg, t0, sym | ||
| 61 | |||
| 62 | #define CALL(sym) call36 sym | ||
| 63 | #define TAIL(sym) tail36 t0, sym | ||
| 64 | |||
| 65 | #elif __loongarch_grlen == 32 /* __loongarch_grlen == 64 */ | ||
| 66 | |||
| 67 | #define SRAI srai.w | ||
| 68 | |||
| 69 | /* LA32R not have bstrins.w, use srli.w and slli.w on both LA32S and LA32R. */ | ||
| 70 | #define REG_ALIGN_ASM(reg, n) \ | ||
| 71 | srli.w reg, reg, n; \ | ||
| 72 | slli.w reg, reg, n; | ||
| 73 | |||
| 74 | #define LOAD_LOCAL(reg, sym) \ | ||
| 75 | 1: pcaddu12i	reg, %pcadd_hi20(sym); \ | ||
| 76 | ld.w	reg, reg, %pcadd_lo12(1b); | ||
| 77 | |||
| 78 | #define LOAD_GLOBAL(reg, sym) \ | ||
| 79 | 1: pcaddu12i	reg, %got_pcadd_hi20(sym); \ | ||
| 80 | ld.w	reg, reg, %pcadd_lo12(1b); \ | ||
| 81 | ld.w	reg, reg, 0; | ||
| 82 | |||
| 83 | #define LA_GOT(reg, sym) la.got reg, sym | ||
| 84 | |||
| 85 | #define CALL(sym) call30 sym | ||
| 86 | #define TAIL(sym) tail30 t0, sym | ||
| 87 | |||
| 88 | #else /* __loongarch_grlen == 64 */ | ||
| 89 | #error __loongarch_grlen must equal 32 or 64 | ||
| 90 | #endif /* __loongarch_grlen == 64 */ | ||
| 91 | |||
| 92 | #endif	/* __ASSEMBLER__ */ | ||
| 93 | |||
| 94 | #endif /* _LOONGARCH_SYSDEP_H */ | ||
lib/libc/glibc/sysdeps/mach/libc-lock.h+10-10| ... | @@ -145,16 +145,16 @@ typedef struct __libc_lock_recursive_opaque__ __libc_lock_recursive_t; | ... | @@ -145,16 +145,16 @@ typedef struct __libc_lock_recursive_opaque__ __libc_lock_recursive_t; |
| 145 | #define __rtld_lock_unlock_recursive(NAME) \ | 145 | #define __rtld_lock_unlock_recursive(NAME) \ |
| 146 | __libc_lock_unlock_recursive (NAME) | 146 | __libc_lock_unlock_recursive (NAME) |
| 147 | 147 | ||
| 148 | /* XXX for now */ | 148 | /* XXX for now, waiting for a futex-based pthread_rwlock implementation */ |
| 149 | #define __libc_rwlock_define		__libc_lock_define | 149 | #define __mach_rwlock_define		__libc_lock_define |
| 150 | #define __libc_rwlock_define_initialized __libc_lock_define_initialized | 150 | #define __mach_rwlock_define_initialized __libc_lock_define_initialized |
| 151 | #define __libc_rwlock_init		__libc_lock_init | 151 | #define __mach_rwlock_init		__libc_lock_init |
| 152 | #define __libc_rwlock_fini		__libc_lock_fini | 152 | #define __mach_rwlock_fini		__libc_lock_fini |
| 153 | #define __libc_rwlock_rdlock		__libc_lock_lock | 153 | #define __mach_rwlock_rdlock		__libc_lock_lock |
| 154 | #define __libc_rwlock_wrlock		__libc_lock_lock | 154 | #define __mach_rwlock_wrlock		__libc_lock_lock |
| 155 | #define __libc_rwlock_tryrdlock		__libc_lock_trylock | 155 | #define __mach_rwlock_tryrdlock		__libc_lock_trylock |
| 156 | #define __libc_rwlock_trywrlock		__libc_lock_trylock | 156 | #define __mach_rwlock_trywrlock		__libc_lock_trylock |
| 157 | #define __libc_rwlock_unlock		__libc_lock_unlock | 157 | #define __mach_rwlock_unlock		__libc_lock_unlock |
| 158 | 158 | ||
| 159 | struct __libc_cleanup_frame | 159 | struct __libc_cleanup_frame |
| 160 | { | 160 | { |
lib/libc/glibc/sysdeps/s390/s390-64/start-2.33.S deleted-107| ... | @@ -1,107 +0,0 @@ | ||
| 1 | /* Startup code compliant to the 64 bit S/390 ELF ABI. | ||
| 2 | Copyright (C) 2001-2020 Free Software Foundation, Inc. | ||
| 3 | Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). | ||
| 4 | This file is part of the GNU C Library. | ||
| 5 | |||
| 6 | The GNU C Library is free software; you can redistribute it and/or | ||
| 7 | modify it under the terms of the GNU Lesser General Public | ||
| 8 | License as published by the Free Software Foundation; either | ||
| 9 | version 2.1 of the License, or (at your option) any later version. | ||
| 10 | |||
| 11 | In addition to the permissions in the GNU Lesser General Public | ||
| 12 | License, the Free Software Foundation gives you unlimited | ||
| 13 | permission to link the compiled version of this file with other | ||
| 14 | programs, and to distribute those programs without any restriction | ||
| 15 | coming from the use of this file. (The GNU Lesser General Public | ||
| 16 | License restrictions do apply in other respects; for example, they | ||
| 17 | cover modification of the file, and distribution when not linked | ||
| 18 | into another program.) | ||
| 19 | |||
| 20 | Note that people who make modified versions of this file are not | ||
| 21 | obligated to grant this special exception for their modified | ||
| 22 | versions; it is their choice whether to do so. The GNU Lesser | ||
| 23 | General Public License gives permission to release a modified | ||
| 24 | version without this exception; this exception also makes it | ||
| 25 | possible to release a modified version which carries forward this | ||
| 26 | exception. | ||
| 27 | |||
| 28 | The GNU C Library is distributed in the hope that it will be useful, | ||
| 29 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 30 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 31 | Lesser General Public License for more details. | ||
| 32 | |||
| 33 | You should have received a copy of the GNU Lesser General Public | ||
| 34 | License along with the GNU C Library; if not, see | ||
| 35 | <https://www.gnu.org/licenses/>. */ | ||
| 36 | |||
| 37 | #include <sysdep.h> | ||
| 38 | |||
| 39 | /* | ||
| 40 | This is the canonical entry point, usually the first thing in the text | ||
| 41 | segment. Most registers' values are unspecified, except for: | ||
| 42 | |||
| 43 | %r14		Contains a function pointer to be registered with `atexit'. | ||
| 44 | 		This is how the dynamic linker arranges to have DT_FINI | ||
| 45 | 		functions called for shared libraries that have been loaded | ||
| 46 | 		before this code runs. | ||
| 47 | |||
| 48 | %r15		The stack contains the arguments and environment: | ||
| 49 | 		0(%r15)			argc | ||
| 50 | 		8(%r15)			argv[0] | ||
| 51 | 		... | ||
| 52 | 		(8*argc)(%r15)		NULL | ||
| 53 | 		(8*(argc+1))(%r15)	envp[0] | ||
| 54 | 		... | ||
| 55 | 					NULL | ||
| 56 | */ | ||
| 57 | |||
| 58 | 	.text | ||
| 59 | 	.globl _start | ||
| 60 | 	.type _start,@function | ||
| 61 | _start: | ||
| 62 | 	cfi_startproc | ||
| 63 | 	/* Mark r14 as undefined in order to stop unwinding here! */ | ||
| 64 | 	cfi_undefined (r14) | ||
| 65 | 	/* Load argc and argv from stack. */ | ||
| 66 | 	la	%r4,8(%r15)		# get argv | ||
| 67 | 	lg	%r3,0(%r15)		# get argc | ||
| 68 | |||
| 69 | 	/* Align the stack to a double word boundary. */ | ||
| 70 | 	lghi	%r0,-16 | ||
| 71 | 	ngr	%r15,%r0 | ||
| 72 | |||
| 73 | 	/* Setup a stack frame and a parameter area. */ | ||
| 74 | 	aghi	%r15,-176		# make room on stack | ||
| 75 | 	xc	0(8,%r15),0(%r15)	# clear back-chain | ||
| 76 | |||
| 77 | 	/* Set up arguments for __libc_start_main: | ||
| 78 | 	 main, argc, argv, envp, _init, _fini, rtld_fini, stack_end | ||
| 79 | 	 Note that envp will be determined later in __libc_start_main. | ||
| 80 | 	 */ | ||
| 81 | 	stmg	%r14,%r15,160(%r15)	# store rtld_fini/stack_end to parameter area | ||
| 82 | 	la	%r7,160(%r15) | ||
| 83 | 	larl	%r6,__libc_csu_fini	# load pointer to __libc_csu_fini | ||
| 84 | 	larl	%r5,__libc_csu_init	# load pointer to __libc_csu_init | ||
| 85 | |||
| 86 | 	/* Ok, now branch to the libc main routine. */ | ||
| 87 | #ifdef PIC | ||
| 88 | 	larl	%r2,main@GOTENT		# load pointer to main | ||
| 89 | 	lg	%r2,0(%r2) | ||
| 90 | 	brasl	%r14,__libc_start_main@plt | ||
| 91 | #else | ||
| 92 | 	larl	%r2,main		# load pointer to main | ||
| 93 | 	brasl	%r14,__libc_start_main | ||
| 94 | #endif | ||
| 95 | |||
| 96 | 	/* Crash if __libc_start_main returns.	*/ | ||
| 97 | 	.word	0 | ||
| 98 | |||
| 99 | 	cfi_endproc | ||
| 100 | |||
| 101 | 	/* Define a symbol for the first piece of initialized data. */ | ||
| 102 | 	.data | ||
| 103 | 	.globl __data_start | ||
| 104 | __data_start: | ||
| 105 | 	.long 0 | ||
| 106 | 	.weak data_start | ||
| 107 | 	data_start = __data_start | ||
lib/libc/glibc/sysdeps/s390/s390-64/start.S deleted-134| ... | @@ -1,134 +0,0 @@ | ||
| 1 | /* Startup code compliant to the 64 bit S/390 ELF ABI. | ||
| 2 | Copyright (C) 2001-2026 Free Software Foundation, Inc. | ||
| 3 | This file is part of the GNU C Library. | ||
| 4 | |||
| 5 | The GNU C Library is free software; you can redistribute it and/or | ||
| 6 | modify it under the terms of the GNU Lesser General Public | ||
| 7 | License as published by the Free Software Foundation; either | ||
| 8 | version 2.1 of the License, or (at your option) any later version. | ||
| 9 | |||
| 10 | In addition to the permissions in the GNU Lesser General Public | ||
| 11 | License, the Free Software Foundation gives you unlimited | ||
| 12 | permission to link the compiled version of this file with other | ||
| 13 | programs, and to distribute those programs without any restriction | ||
| 14 | coming from the use of this file. (The GNU Lesser General Public | ||
| 15 | License restrictions do apply in other respects; for example, they | ||
| 16 | cover modification of the file, and distribution when not linked | ||
| 17 | into another program.) | ||
| 18 | |||
| 19 | Note that people who make modified versions of this file are not | ||
| 20 | obligated to grant this special exception for their modified | ||
| 21 | versions; it is their choice whether to do so. The GNU Lesser | ||
| 22 | General Public License gives permission to release a modified | ||
| 23 | version without this exception; this exception also makes it | ||
| 24 | possible to release a modified version which carries forward this | ||
| 25 | exception. | ||
| 26 | |||
| 27 | The GNU C Library is distributed in the hope that it will be useful, | ||
| 28 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 29 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 30 | Lesser General Public License for more details. | ||
| 31 | |||
| 32 | You should have received a copy of the GNU Lesser General Public | ||
| 33 | License along with the GNU C Library; if not, see | ||
| 34 | <https://www.gnu.org/licenses/>. */ | ||
| 35 | |||
| 36 | #include <sysdep.h> | ||
| 37 | |||
| 38 | /* | ||
| 39 | This is the canonical entry point, usually the first thing in the text | ||
| 40 | segment. Most registers' values are unspecified, except for: | ||
| 41 | |||
| 42 | %r14		Contains a function pointer to be registered with `atexit'. | ||
| 43 | 		This is how the dynamic linker arranges to have DT_FINI | ||
| 44 | 		functions called for shared libraries that have been loaded | ||
| 45 | 		before this code runs. | ||
| 46 | |||
| 47 | %r15		The stack contains the arguments and environment: | ||
| 48 | 		0(%r15)			argc | ||
| 49 | 		8(%r15)			argv[0] | ||
| 50 | 		... | ||
| 51 | 		(8*argc)(%r15)		NULL | ||
| 52 | 		(8*(argc+1))(%r15)	envp[0] | ||
| 53 | 		... | ||
| 54 | 					NULL | ||
| 55 | */ | ||
| 56 | |||
| 57 | 	.text | ||
| 58 | 	.globl _start | ||
| 59 | 	.type _start,@function | ||
| 60 | _start: | ||
| 61 | 	cfi_startproc | ||
| 62 | 	/* Mark r14 as undefined in order to stop unwinding here! */ | ||
| 63 | 	cfi_undefined (r14) | ||
| 64 | 	/* Load argc and argv from stack. */ | ||
| 65 | 	la	%r4,8(%r15)		# get argv | ||
| 66 | 	lg	%r3,0(%r15)		# get argc | ||
| 67 | |||
| 68 | 	/* Align the stack to a double word boundary. */ | ||
| 69 | 	lghi	%r0,-16 | ||
| 70 | 	ngr	%r15,%r0 | ||
| 71 | |||
| 72 | 	/* Setup a stack frame and a parameter area. */ | ||
| 73 | 	aghi	%r15,-176		# make room on stack | ||
| 74 | 	xc	0(8,%r15),0(%r15)	# clear back-chain | ||
| 75 | |||
| 76 | 	/* Set up arguments for __libc_start_main: | ||
| 77 | 	 main, argc, argv, envp, _init, _fini, rtld_fini, stack_end | ||
| 78 | 	 Note that envp will be determined later in __libc_start_main. | ||
| 79 | 	 */ | ||
| 80 | 	stmg	%r14,%r15,160(%r15)	# store rtld_fini/stack_end to parameter area | ||
| 81 | 	la	%r7,160(%r15) | ||
| 82 | 	lghi	%r6,0			# Used to be fini. | ||
| 83 | 	lghi	%r5,0			# Used to be init. | ||
| 84 | |||
| 85 | 	/* Ok, now branch to the libc main routine. */ | ||
| 86 | #ifdef PIC | ||
| 87 | # ifdef SHARED | ||
| 88 | 	/* Used for dynamic linked position independent executable. | ||
| 89 | 	 => Scrt1.o */ | ||
| 90 | 	larl	%r2,main@GOTENT		# load pointer to main | ||
| 91 | 	lg	%r2,0(%r2) | ||
| 92 | # else | ||
| 93 | 	/* Used for dynamic linked position dependent executable. | ||
| 94 | 	 => crt1.o (glibc configured without --disable-default-pie: | ||
| 95 | 	 PIC is defined) | ||
| 96 | 	 Or for static linked position independent executable. | ||
| 97 | 	 => rcrt1.o (only available if glibc configured without | ||
| 98 | 	 --disable-default-pie: PIC is defined) */ | ||
| 99 | 	larl	%r2,__wrap_main | ||
| 100 | # endif | ||
| 101 | 	brasl	%r14,__libc_start_main@plt | ||
| 102 | #else | ||
| 103 | 	/* Used for dynamic/static linked position dependent executable. | ||
| 104 | 	 => crt1.o (glibc configured with --disable-default-pie: | ||
| 105 | 	 PIC and SHARED are not defined) */ | ||
| 106 | 	larl	%r2,main		# load pointer to main | ||
| 107 | 	brasl	%r14,__libc_start_main | ||
| 108 | #endif | ||
| 109 | |||
| 110 | 	/* Crash if __libc_start_main returns.	*/ | ||
| 111 | 	.word	0 | ||
| 112 | |||
| 113 | 	cfi_endproc | ||
| 114 | |||
| 115 | #if defined PIC && !defined SHARED | ||
| 116 | 	/* When main is not defined in the executable but in a shared library | ||
| 117 | 	 then a wrapper is needed in crt1.o of the static-pie enabled libc, | ||
| 118 | 	 because crt1.o and rcrt1.o share code and the later must avoid the | ||
| 119 | 	 use of GOT relocations before __libc_start_main is called. */ | ||
| 120 | __wrap_main: | ||
| 121 | 	cfi_startproc | ||
| 122 | 	larl	%r1,main@GOTENT		# load pointer to main | ||
| 123 | 	lg	%r1,0(%r1) | ||
| 124 | 	br	%r1 | ||
| 125 | 	cfi_endproc | ||
| 126 | #endif | ||
| 127 | |||
| 128 | 	/* Define a symbol for the first piece of initialized data. */ | ||
| 129 | 	.data | ||
| 130 | 	.globl __data_start | ||
| 131 | __data_start: | ||
| 132 | 	.long 0 | ||
| 133 | 	.weak data_start | ||
| 134 | 	data_start = __data_start | ||
lib/libc/glibc/sysdeps/s390/s390-64/sysdep.h deleted-93| ... | @@ -1,93 +0,0 @@ | ||
| 1 | /* Assembler macros for 64 bit S/390. | ||
| 2 | Copyright (C) 2001-2026 Free Software Foundation, Inc. | ||
| 3 | This file is part of the GNU C Library. | ||
| 4 | |||
| 5 | The GNU C Library is free software; you can redistribute it and/or | ||
| 6 | modify it under the terms of the GNU Lesser General Public | ||
| 7 | License as published by the Free Software Foundation; either | ||
| 8 | version 2.1 of the License, or (at your option) any later version. | ||
| 9 | |||
| 10 | The GNU C Library is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 13 | Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public | ||
| 16 | License along with the GNU C Library; if not, see | ||
| 17 | <https://www.gnu.org/licenses/>. */ | ||
| 18 | |||
| 19 | #include <sysdeps/generic/sysdep.h> | ||
| 20 | |||
| 21 | #ifdef	__ASSEMBLER__ | ||
| 22 | |||
| 23 | /* Syntactic details of assembler. */ | ||
| 24 | |||
| 25 | /* ELF uses byte-counts for .align, most others use log2 of count of bytes. */ | ||
| 26 | #define ALIGNARG(log2) 1<<log2 | ||
| 27 | #define ASM_SIZE_DIRECTIVE(name) .size name,.-name; | ||
| 28 | |||
| 29 | |||
| 30 | /* Define an entry point visible from C. */ | ||
| 31 | #define	ENTRY(name)							 \ | ||
| 32 | .globl C_SYMBOL_NAME(name);						 \ | ||
| 33 | .type C_SYMBOL_NAME(name),@function;					 \ | ||
| 34 | .align ALIGNARG(4);							 \ | ||
| 35 | C_LABEL(name)								 \ | ||
| 36 | cfi_startproc;							 \ | ||
| 37 | CALL_MCOUNT | ||
| 38 | |||
| 39 | #undef	END | ||
| 40 | #define END(name)							 \ | ||
| 41 | cfi_endproc;								 \ | ||
| 42 | ASM_SIZE_DIRECTIVE(name)						 \ | ||
| 43 | |||
| 44 | /* If compiled for profiling, call `mcount' at the start of each function. */ | ||
| 45 | #ifdef	PROF | ||
| 46 | #ifdef PIC | ||
| 47 | #define CALL_MCOUNT \ | ||
| 48 | lgr 0,14 ; larl 1,0f ; brasl 14,_mcount@PLT ; lgr 14,0 ; \ | ||
| 49 | .data ; .align 4 ; 0: .long 0 ; .text ; | ||
| 50 | #else | ||
| 51 | #define CALL_MCOUNT \ | ||
| 52 | lgr 0,14 ; larl 1,0f ; brasl 14,_mcount ; lgr 14,0 ; \ | ||
| 53 | .data ; .align 4 ; 0: .long 0 ; .text ; | ||
| 54 | #endif | ||
| 55 | #else | ||
| 56 | #define CALL_MCOUNT		/* Do nothing. */ | ||
| 57 | #endif | ||
| 58 | |||
| 59 | /* Since C identifiers are not normally prefixed with an underscore | ||
| 60 | on this system, the asm identifier `syscall_error' intrudes on the | ||
| 61 | C name space. Make sure we use an innocuous name. */ | ||
| 62 | #define	syscall_error	__syscall_error | ||
| 63 | #define mcount		_mcount | ||
| 64 | |||
| 65 | #undef PSEUDO | ||
| 66 | #define	PSEUDO(name, syscall_name, args) \ | ||
| 67 | lose: SYSCALL_PIC_SETUP			\ | ||
| 68 | jg JUMPTARGET(syscall_error);		\ | ||
| 69 | .globl syscall_error;			\ | ||
| 70 | ENTRY (name)				\ | ||
| 71 | DO_CALL (syscall_name, args);		\ | ||
| 72 | jm lose | ||
| 73 | |||
| 74 | #undef	PSEUDO_END | ||
| 75 | #define	PSEUDO_END(name)						 \ | ||
| 76 | END (name) | ||
| 77 | |||
| 78 | #undef JUMPTARGET | ||
| 79 | #ifdef SHARED | ||
| 80 | #define JUMPTARGET(name)	name##@PLT | ||
| 81 | #define SYSCALL_PIC_SETUP \ | ||
| 82 | larl %r12,_GLOBAL_OFFSET_TABLE_ | ||
| 83 | #else | ||
| 84 | #define JUMPTARGET(name)	name | ||
| 85 | #define SYSCALL_PIC_SETUP	/* Nothing. */ | ||
| 86 | #endif | ||
| 87 | |||
| 88 | /* Local label name for asm code. */ | ||
| 89 | #ifndef L | ||
| 90 | #define L(name)		.L##name | ||
| 91 | #endif | ||
| 92 | |||
| 93 | #endif	/* __ASSEMBLER__ */ | ||
lib/libc/glibc/sysdeps/s390/start-2.33.S created+107| ... | @@ -0,0 +1,107 @@ | ||
| 1 | /* Startup code compliant to the 64 bit S/390 ELF ABI. | ||
| 2 | Copyright (C) 2001-2020 Free Software Foundation, Inc. | ||
| 3 | Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). | ||
| 4 | This file is part of the GNU C Library. | ||
| 5 | |||
| 6 | The GNU C Library is free software; you can redistribute it and/or | ||
| 7 | modify it under the terms of the GNU Lesser General Public | ||
| 8 | License as published by the Free Software Foundation; either | ||
| 9 | version 2.1 of the License, or (at your option) any later version. | ||
| 10 | |||
| 11 | In addition to the permissions in the GNU Lesser General Public | ||
| 12 | License, the Free Software Foundation gives you unlimited | ||
| 13 | permission to link the compiled version of this file with other | ||
| 14 | programs, and to distribute those programs without any restriction | ||
| 15 | coming from the use of this file. (The GNU Lesser General Public | ||
| 16 | License restrictions do apply in other respects; for example, they | ||
| 17 | cover modification of the file, and distribution when not linked | ||
| 18 | into another program.) | ||
| 19 | |||
| 20 | Note that people who make modified versions of this file are not | ||
| 21 | obligated to grant this special exception for their modified | ||
| 22 | versions; it is their choice whether to do so. The GNU Lesser | ||
| 23 | General Public License gives permission to release a modified | ||
| 24 | version without this exception; this exception also makes it | ||
| 25 | possible to release a modified version which carries forward this | ||
| 26 | exception. | ||
| 27 | |||
| 28 | The GNU C Library is distributed in the hope that it will be useful, | ||
| 29 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 30 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 31 | Lesser General Public License for more details. | ||
| 32 | |||
| 33 | You should have received a copy of the GNU Lesser General Public | ||
| 34 | License along with the GNU C Library; if not, see | ||
| 35 | <https://www.gnu.org/licenses/>. */ | ||
| 36 | |||
| 37 | #include <sysdep.h> | ||
| 38 | |||
| 39 | /* | ||
| 40 | This is the canonical entry point, usually the first thing in the text | ||
| 41 | segment. Most registers' values are unspecified, except for: | ||
| 42 | |||
| 43 | %r14		Contains a function pointer to be registered with `atexit'. | ||
| 44 | 		This is how the dynamic linker arranges to have DT_FINI | ||
| 45 | 		functions called for shared libraries that have been loaded | ||
| 46 | 		before this code runs. | ||
| 47 | |||
| 48 | %r15		The stack contains the arguments and environment: | ||
| 49 | 		0(%r15)			argc | ||
| 50 | 		8(%r15)			argv[0] | ||
| 51 | 		... | ||
| 52 | 		(8*argc)(%r15)		NULL | ||
| 53 | 		(8*(argc+1))(%r15)	envp[0] | ||
| 54 | 		... | ||
| 55 | 					NULL | ||
| 56 | */ | ||
| 57 | |||
| 58 | 	.text | ||
| 59 | 	.globl _start | ||
| 60 | 	.type _start,@function | ||
| 61 | _start: | ||
| 62 | 	cfi_startproc | ||
| 63 | 	/* Mark r14 as undefined in order to stop unwinding here! */ | ||
| 64 | 	cfi_undefined (r14) | ||
| 65 | 	/* Load argc and argv from stack. */ | ||
| 66 | 	la	%r4,8(%r15)		# get argv | ||
| 67 | 	lg	%r3,0(%r15)		# get argc | ||
| 68 | |||
| 69 | 	/* Align the stack to a double word boundary. */ | ||
| 70 | 	lghi	%r0,-16 | ||
| 71 | 	ngr	%r15,%r0 | ||
| 72 | |||
| 73 | 	/* Setup a stack frame and a parameter area. */ | ||
| 74 | 	aghi	%r15,-176		# make room on stack | ||
| 75 | 	xc	0(8,%r15),0(%r15)	# clear back-chain | ||
| 76 | |||
| 77 | 	/* Set up arguments for __libc_start_main: | ||
| 78 | 	 main, argc, argv, envp, _init, _fini, rtld_fini, stack_end | ||
| 79 | 	 Note that envp will be determined later in __libc_start_main. | ||
| 80 | 	 */ | ||
| 81 | 	stmg	%r14,%r15,160(%r15)	# store rtld_fini/stack_end to parameter area | ||
| 82 | 	la	%r7,160(%r15) | ||
| 83 | 	larl	%r6,__libc_csu_fini	# load pointer to __libc_csu_fini | ||
| 84 | 	larl	%r5,__libc_csu_init	# load pointer to __libc_csu_init | ||
| 85 | |||
| 86 | 	/* Ok, now branch to the libc main routine. */ | ||
| 87 | #ifdef PIC | ||
| 88 | 	larl	%r2,main@GOTENT		# load pointer to main | ||
| 89 | 	lg	%r2,0(%r2) | ||
| 90 | 	brasl	%r14,__libc_start_main@plt | ||
| 91 | #else | ||
| 92 | 	larl	%r2,main		# load pointer to main | ||
| 93 | 	brasl	%r14,__libc_start_main | ||
| 94 | #endif | ||
| 95 | |||
| 96 | 	/* Crash if __libc_start_main returns.	*/ | ||
| 97 | 	.word	0 | ||
| 98 | |||
| 99 | 	cfi_endproc | ||
| 100 | |||
| 101 | 	/* Define a symbol for the first piece of initialized data. */ | ||
| 102 | 	.data | ||
| 103 | 	.globl __data_start | ||
| 104 | __data_start: | ||
| 105 | 	.long 0 | ||
| 106 | 	.weak data_start | ||
| 107 | 	data_start = __data_start | ||
lib/libc/glibc/sysdeps/s390/start.S created+134| ... | @@ -0,0 +1,134 @@ | ||
| 1 | /* Startup code compliant to the 64 bit S/390 ELF ABI. | ||
| 2 | Copyright (C) 2001-2026 Free Software Foundation, Inc. | ||
| 3 | This file is part of the GNU C Library. | ||
| 4 | |||
| 5 | The GNU C Library is free software; you can redistribute it and/or | ||
| 6 | modify it under the terms of the GNU Lesser General Public | ||
| 7 | License as published by the Free Software Foundation; either | ||
| 8 | version 2.1 of the License, or (at your option) any later version. | ||
| 9 | |||
| 10 | In addition to the permissions in the GNU Lesser General Public | ||
| 11 | License, the Free Software Foundation gives you unlimited | ||
| 12 | permission to link the compiled version of this file with other | ||
| 13 | programs, and to distribute those programs without any restriction | ||
| 14 | coming from the use of this file. (The GNU Lesser General Public | ||
| 15 | License restrictions do apply in other respects; for example, they | ||
| 16 | cover modification of the file, and distribution when not linked | ||
| 17 | into another program.) | ||
| 18 | |||
| 19 | Note that people who make modified versions of this file are not | ||
| 20 | obligated to grant this special exception for their modified | ||
| 21 | versions; it is their choice whether to do so. The GNU Lesser | ||
| 22 | General Public License gives permission to release a modified | ||
| 23 | version without this exception; this exception also makes it | ||
| 24 | possible to release a modified version which carries forward this | ||
| 25 | exception. | ||
| 26 | |||
| 27 | The GNU C Library is distributed in the hope that it will be useful, | ||
| 28 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 29 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 30 | Lesser General Public License for more details. | ||
| 31 | |||
| 32 | You should have received a copy of the GNU Lesser General Public | ||
| 33 | License along with the GNU C Library; if not, see | ||
| 34 | <https://www.gnu.org/licenses/>. */ | ||
| 35 | |||
| 36 | #include <sysdep.h> | ||
| 37 | |||
| 38 | /* | ||
| 39 | This is the canonical entry point, usually the first thing in the text | ||
| 40 | segment. Most registers' values are unspecified, except for: | ||
| 41 | |||
| 42 | %r14		Contains a function pointer to be registered with `atexit'. | ||
| 43 | 		This is how the dynamic linker arranges to have DT_FINI | ||
| 44 | 		functions called for shared libraries that have been loaded | ||
| 45 | 		before this code runs. | ||
| 46 | |||
| 47 | %r15		The stack contains the arguments and environment: | ||
| 48 | 		0(%r15)			argc | ||
| 49 | 		8(%r15)			argv[0] | ||
| 50 | 		... | ||
| 51 | 		(8*argc)(%r15)		NULL | ||
| 52 | 		(8*(argc+1))(%r15)	envp[0] | ||
| 53 | 		... | ||
| 54 | 					NULL | ||
| 55 | */ | ||
| 56 | |||
| 57 | 	.text | ||
| 58 | 	.globl _start | ||
| 59 | 	.type _start,@function | ||
| 60 | _start: | ||
| 61 | 	cfi_startproc | ||
| 62 | 	/* Mark r14 as undefined in order to stop unwinding here! */ | ||
| 63 | 	cfi_undefined (r14) | ||
| 64 | 	/* Load argc and argv from stack. */ | ||
| 65 | 	la	%r4,8(%r15)		# get argv | ||
| 66 | 	lg	%r3,0(%r15)		# get argc | ||
| 67 | |||
| 68 | 	/* Align the stack to a double word boundary. */ | ||
| 69 | 	lghi	%r0,-16 | ||
| 70 | 	ngr	%r15,%r0 | ||
| 71 | |||
| 72 | 	/* Setup a stack frame and a parameter area. */ | ||
| 73 | 	aghi	%r15,-176		# make room on stack | ||
| 74 | 	xc	0(8,%r15),0(%r15)	# clear back-chain | ||
| 75 | |||
| 76 | 	/* Set up arguments for __libc_start_main: | ||
| 77 | 	 main, argc, argv, envp, _init, _fini, rtld_fini, stack_end | ||
| 78 | 	 Note that envp will be determined later in __libc_start_main. | ||
| 79 | 	 */ | ||
| 80 | 	stmg	%r14,%r15,160(%r15)	# store rtld_fini/stack_end to parameter area | ||
| 81 | 	la	%r7,160(%r15) | ||
| 82 | 	lghi	%r6,0			# Used to be fini. | ||
| 83 | 	lghi	%r5,0			# Used to be init. | ||
| 84 | |||
| 85 | 	/* Ok, now branch to the libc main routine. */ | ||
| 86 | #ifdef PIC | ||
| 87 | # ifdef SHARED | ||
| 88 | 	/* Used for dynamic linked position independent executable. | ||
| 89 | 	 => Scrt1.o */ | ||
| 90 | 	larl	%r2,main@GOTENT		# load pointer to main | ||
| 91 | 	lg	%r2,0(%r2) | ||
| 92 | # else | ||
| 93 | 	/* Used for dynamic linked position dependent executable. | ||
| 94 | 	 => crt1.o (glibc configured without --disable-default-pie: | ||
| 95 | 	 PIC is defined) | ||
| 96 | 	 Or for static linked position independent executable. | ||
| 97 | 	 => rcrt1.o (only available if glibc configured without | ||
| 98 | 	 --disable-default-pie: PIC is defined) */ | ||
| 99 | 	larl	%r2,__wrap_main | ||
| 100 | # endif | ||
| 101 | 	brasl	%r14,__libc_start_main@plt | ||
| 102 | #else | ||
| 103 | 	/* Used for dynamic/static linked position dependent executable. | ||
| 104 | 	 => crt1.o (glibc configured with --disable-default-pie: | ||
| 105 | 	 PIC and SHARED are not defined) */ | ||
| 106 | 	larl	%r2,main		# load pointer to main | ||
| 107 | 	brasl	%r14,__libc_start_main | ||
| 108 | #endif | ||
| 109 | |||
| 110 | 	/* Crash if __libc_start_main returns.	*/ | ||
| 111 | 	.word	0 | ||
| 112 | |||
| 113 | 	cfi_endproc | ||
| 114 | |||
| 115 | #if defined PIC && !defined SHARED | ||
| 116 | 	/* When main is not defined in the executable but in a shared library | ||
| 117 | 	 then a wrapper is needed in crt1.o of the static-pie enabled libc, | ||
| 118 | 	 because crt1.o and rcrt1.o share code and the later must avoid the | ||
| 119 | 	 use of GOT relocations before __libc_start_main is called. */ | ||
| 120 | __wrap_main: | ||
| 121 | 	cfi_startproc | ||
| 122 | 	larl	%r1,main@GOTENT		# load pointer to main | ||
| 123 | 	lg	%r1,0(%r1) | ||
| 124 | 	br	%r1 | ||
| 125 | 	cfi_endproc | ||
| 126 | #endif | ||
| 127 | |||
| 128 | 	/* Define a symbol for the first piece of initialized data. */ | ||
| 129 | 	.data | ||
| 130 | 	.globl __data_start | ||
| 131 | __data_start: | ||
| 132 | 	.long 0 | ||
| 133 | 	.weak data_start | ||
| 134 | 	data_start = __data_start | ||
lib/libc/glibc/sysdeps/s390/sysdep.h created+93| ... | @@ -0,0 +1,93 @@ | ||
| 1 | /* Assembler macros for 64 bit S/390. | ||
| 2 | Copyright (C) 2001-2026 Free Software Foundation, Inc. | ||
| 3 | This file is part of the GNU C Library. | ||
| 4 | |||
| 5 | The GNU C Library is free software; you can redistribute it and/or | ||
| 6 | modify it under the terms of the GNU Lesser General Public | ||
| 7 | License as published by the Free Software Foundation; either | ||
| 8 | version 2.1 of the License, or (at your option) any later version. | ||
| 9 | |||
| 10 | The GNU C Library is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 13 | Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public | ||
| 16 | License along with the GNU C Library; if not, see | ||
| 17 | <https://www.gnu.org/licenses/>. */ | ||
| 18 | |||
| 19 | #include <sysdeps/generic/sysdep.h> | ||
| 20 | |||
| 21 | #ifdef	__ASSEMBLER__ | ||
| 22 | |||
| 23 | /* Syntactic details of assembler. */ | ||
| 24 | |||
| 25 | /* ELF uses byte-counts for .align, most others use log2 of count of bytes. */ | ||
| 26 | #define ALIGNARG(log2) 1<<log2 | ||
| 27 | #define ASM_SIZE_DIRECTIVE(name) .size name,.-name; | ||
| 28 | |||
| 29 | |||
| 30 | /* Define an entry point visible from C. */ | ||
| 31 | #define	ENTRY(name)							 \ | ||
| 32 | .globl C_SYMBOL_NAME(name);						 \ | ||
| 33 | .type C_SYMBOL_NAME(name),@function;					 \ | ||
| 34 | .align ALIGNARG(4);							 \ | ||
| 35 | C_LABEL(name)								 \ | ||
| 36 | cfi_startproc;							 \ | ||
| 37 | CALL_MCOUNT | ||
| 38 | |||
| 39 | #undef	END | ||
| 40 | #define END(name)							 \ | ||
| 41 | cfi_endproc;								 \ | ||
| 42 | ASM_SIZE_DIRECTIVE(name)						 \ | ||
| 43 | |||
| 44 | /* If compiled for profiling, call `mcount' at the start of each function. */ | ||
| 45 | #ifdef	PROF | ||
| 46 | #ifdef PIC | ||
| 47 | #define CALL_MCOUNT \ | ||
| 48 | lgr 0,14 ; larl 1,0f ; brasl 14,_mcount@PLT ; lgr 14,0 ; \ | ||
| 49 | .data ; .align 4 ; 0: .long 0 ; .text ; | ||
| 50 | #else | ||
| 51 | #define CALL_MCOUNT \ | ||
| 52 | lgr 0,14 ; larl 1,0f ; brasl 14,_mcount ; lgr 14,0 ; \ | ||
| 53 | .data ; .align 4 ; 0: .long 0 ; .text ; | ||
| 54 | #endif | ||
| 55 | #else | ||
| 56 | #define CALL_MCOUNT		/* Do nothing. */ | ||
| 57 | #endif | ||
| 58 | |||
| 59 | /* Since C identifiers are not normally prefixed with an underscore | ||
| 60 | on this system, the asm identifier `syscall_error' intrudes on the | ||
| 61 | C name space. Make sure we use an innocuous name. */ | ||
| 62 | #define	syscall_error	__syscall_error | ||
| 63 | #define mcount		_mcount | ||
| 64 | |||
| 65 | #undef PSEUDO | ||
| 66 | #define	PSEUDO(name, syscall_name, args) \ | ||
| 67 | lose: SYSCALL_PIC_SETUP			\ | ||
| 68 | jg JUMPTARGET(syscall_error);		\ | ||
| 69 | .globl syscall_error;			\ | ||
| 70 | ENTRY (name)				\ | ||
| 71 | DO_CALL (syscall_name, args);		\ | ||
| 72 | jm lose | ||
| 73 | |||
| 74 | #undef	PSEUDO_END | ||
| 75 | #define	PSEUDO_END(name)						 \ | ||
| 76 | END (name) | ||
| 77 | |||
| 78 | #undef JUMPTARGET | ||
| 79 | #ifdef SHARED | ||
| 80 | #define JUMPTARGET(name)	name##@PLT | ||
| 81 | #define SYSCALL_PIC_SETUP \ | ||
| 82 | larl %r12,_GLOBAL_OFFSET_TABLE_ | ||
| 83 | #else | ||
| 84 | #define JUMPTARGET(name)	name | ||
| 85 | #define SYSCALL_PIC_SETUP	/* Nothing. */ | ||
| 86 | #endif | ||
| 87 | |||
| 88 | /* Local label name for asm code. */ | ||
| 89 | #ifndef L | ||
| 90 | #define L(name)		.L##name | ||
| 91 | #endif | ||
| 92 | |||
| 93 | #endif	/* __ASSEMBLER__ */ | ||
lib/libc/glibc/sysdeps/unix/sysv/linux/kernel-features.h+6-1| ... | @@ -155,7 +155,7 @@ | ... | @@ -155,7 +155,7 @@ |
| 155 | similar to kernel: | 155 | similar to kernel: |
| 156 | 156 | ||
| 157 | - __ASSUME_CLONE_BACKWARDS: for variant 1. | 157 | - __ASSUME_CLONE_BACKWARDS: for variant 1. |
| 158 | - __ASSUME_CLONE_BACKWARDS2: for variant 2 (s390). | 158 | - __ASSUME_CLONE_BACKWARDS2: for variant 2 (s390x). |
| 159 | - __ASSUME_CLONE_BACKWARDS3: for variant 3 (microblaze). | 159 | - __ASSUME_CLONE_BACKWARDS3: for variant 3 (microblaze). |
| 160 | - __ASSUME_CLONE_DEFAULT: for variant 4. | 160 | - __ASSUME_CLONE_DEFAULT: for variant 4. |
| 161 | */ | 161 | */ |
| ... | @@ -266,4 +266,9 @@ | ... | @@ -266,4 +266,9 @@ |
| 266 | /* zig patch: don't assume kernel version */ | 266 | /* zig patch: don't assume kernel version */ |
| 267 | #define __ASSUME_MSEAL 0 | 267 | #define __ASSUME_MSEAL 0 |
| 268 | 268 | ||
| 269 | /* The PIDFD_GET_INFO ioctl was introduced across all architectures in Linux | ||
| 270 | 6.13. */ | ||
| 271 | /* zig patch: don't assume kernel version */ | ||
| 272 | #define __ASSUME_PIDFD_GET_INFO 0 | ||
| 273 | |||
| 269 | #endif /* kernel-features.h */ | 274 | #endif /* kernel-features.h */ |
lib/libc/glibc/sysdeps/unix/sysv/linux/loongarch/sysdep.h+25-6| ... | @@ -19,6 +19,7 @@ | ... | @@ -19,6 +19,7 @@ |
| 19 | #ifndef _LINUX_LOONGARCH_SYSDEP_H | 19 | #ifndef _LINUX_LOONGARCH_SYSDEP_H |
| 20 | #define _LINUX_LOONGARCH_SYSDEP_H 1 | 20 | #define _LINUX_LOONGARCH_SYSDEP_H 1 |
| 21 | 21 | ||
| 22 | #include <sysdeps/loongarch/sysdep.h> | ||
| 22 | #include <sysdeps/unix/sysv/linux/sysdep.h> | 23 | #include <sysdeps/unix/sysv/linux/sysdep.h> |
| 23 | #include <sysdeps/unix/sysdep.h> | 24 | #include <sysdeps/unix/sysdep.h> |
| 24 | #include <tls.h> | 25 | #include <tls.h> |
| ... | @@ -34,9 +35,9 @@ | ... | @@ -34,9 +35,9 @@ |
| 34 | #undef PSEUDO | 35 | #undef PSEUDO |
| 35 | #define PSEUDO(name, syscall_name, args) \ | 36 | #define PSEUDO(name, syscall_name, args) \ |
| 36 | ENTRY (name); \ | 37 | ENTRY (name); \ |
| 37 | li.d a7, SYS_ify (syscall_name); \ | 38 | LI a7, SYS_ify (syscall_name); \ |
| 38 | syscall 0; \ | 39 | syscall 0; \ |
| 39 | li.d a7, -4096; \ | 40 | LI a7, -4096; \ |
| 40 | bltu a7, a0, .Lsyscall_error##name; | 41 | bltu a7, a0, .Lsyscall_error##name; |
| 41 | 42 | ||
| 42 | #undef PSEUDO_END | 43 | #undef PSEUDO_END |
| ... | @@ -52,16 +53,16 @@ | ... | @@ -52,16 +53,16 @@ |
| 52 | .Lsyscall_error##name : la t0, rtld_errno; \ | 53 | .Lsyscall_error##name : la t0, rtld_errno; \ |
| 53 | sub.w a0, zero, a0; \ | 54 | sub.w a0, zero, a0; \ |
| 54 | st.w a0, t0, 0; \ | 55 | st.w a0, t0, 0; \ |
| 55 | li.d a0, -1; | 56 | LI a0, -1; |
| 56 | 57 | ||
| 57 | #else | 58 | #else |
| 58 | 59 | ||
| 59 | #define SYSCALL_ERROR_HANDLER(name) \ | 60 | #define SYSCALL_ERROR_HANDLER(name) \ |
| 60 | .Lsyscall_error##name : la.tls.ie t0, errno; \ | 61 | .Lsyscall_error##name : la.tls.ie t0, errno; \ |
| 61 | add.d t0, tp, t0; \ | 62 | ADD t0, tp, t0; \ |
| 62 | sub.w a0, zero, a0; \ | 63 | sub.w a0, zero, a0; \ |
| 63 | st.w a0, t0, 0; \ | 64 | st.w a0, t0, 0; \ |
| 64 | li.d a0, -1; | 65 | LI a0, -1; |
| 65 | 66 | ||
| 66 | #endif | 67 | #endif |
| 67 | #else | 68 | #else |
| ... | @@ -74,7 +75,7 @@ | ... | @@ -74,7 +75,7 @@ |
| 74 | #undef PSEUDO_NEORRNO | 75 | #undef PSEUDO_NEORRNO |
| 75 | #define PSEUDO_NOERRNO(name, syscall_name, args) \ | 76 | #define PSEUDO_NOERRNO(name, syscall_name, args) \ |
| 76 | ENTRY (name); \ | 77 | ENTRY (name); \ |
| 77 | li.d a7, SYS_ify (syscall_name); \ | 78 | LI a7, SYS_ify (syscall_name); \ |
| 78 | syscall 0; | 79 | syscall 0; |
| 79 | 80 | ||
| 80 | #undef PSEUDO_END_NOERRNO | 81 | #undef PSEUDO_END_NOERRNO |
| ... | @@ -85,11 +86,17 @@ | ... | @@ -85,11 +86,17 @@ |
| 85 | 86 | ||
| 86 | /* Performs a system call, returning the error code. */ | 87 | /* Performs a system call, returning the error code. */ |
| 87 | #undef PSEUDO_ERRVAL | 88 | #undef PSEUDO_ERRVAL |
| 89 | #if __loongarch_grlen == 64 | ||
| 88 | #define PSEUDO_ERRVAL(name, syscall_name, args) \ | 90 | #define PSEUDO_ERRVAL(name, syscall_name, args) \ |
| 89 | PSEUDO_NOERRNO (name, syscall_name, args); \ | 91 | PSEUDO_NOERRNO (name, syscall_name, args); \ |
| 90 | slli.d a0, a0, 32; \ | 92 | slli.d a0, a0, 32; \ |
| 91 | srai.d a0, a0, 32; /* sign_ext */ \ | 93 | srai.d a0, a0, 32; /* sign_ext */ \ |
| 92 | sub.d a0, zero, a0; | 94 | sub.d a0, zero, a0; |
| 95 | #else | ||
| 96 | #define PSEUDO_ERRVAL(name, syscall_name, args) \ | ||
| 97 | PSEUDO_NOERRNO (name, syscall_name, args); \ | ||
| 98 | sub.w a0, zero, a0; | ||
| 99 | #endif | ||
| 93 | 100 | ||
| 94 | #undef PSEUDO_END_ERRVAL | 101 | #undef PSEUDO_END_ERRVAL |
| 95 | #define PSEUDO_END_ERRVAL(name) END (name); | 102 | #define PSEUDO_END_ERRVAL(name) END (name); |
| ... | @@ -109,6 +116,18 @@ | ... | @@ -109,6 +116,18 @@ |
| 109 | #undef SYS_ify | 116 | #undef SYS_ify |
| 110 | #define SYS_ify(syscall_name) __NR_##syscall_name | 117 | #define SYS_ify(syscall_name) __NR_##syscall_name |
| 111 | 118 | ||
| 119 | #if __WORDSIZE == 32 | ||
| 120 | /* Workarounds for generic code needing to handle 64-bit time_t. */ | ||
| 121 | #define __NR_clock_getres	__NR_clock_getres_time64 | ||
| 122 | #define __NR_futex		__NR_futex_time64 | ||
| 123 | #define __NR_ppoll		__NR_ppoll_time64 | ||
| 124 | #define __NR_pselect6		__NR_pselect6_time64 | ||
| 125 | #define __NR_recvmmsg		__NR_recvmmsg_time64 | ||
| 126 | #define __NR_rt_sigtimedwait	__NR_rt_sigtimedwait_time64 | ||
| 127 | #define __NR_semtimedop		__NR_semtimedop_time64 | ||
| 128 | #define __NR_utimensat		__NR_utimensat_time64 | ||
| 129 | #endif /* __WORDSIZE == 32 */ | ||
| 130 | |||
| 112 | #ifndef __ASSEMBLER__ | 131 | #ifndef __ASSEMBLER__ |
| 113 | 132 | ||
| 114 | #define VDSO_NAME "LINUX_5.10" | 133 | #define VDSO_NAME "LINUX_5.10" |
lib/libc/glibc/sysdeps/unix/sysv/linux/s390/bits/typesizes.h+14-22| ... | @@ -57,42 +57,34 @@ | ... | @@ -57,42 +57,34 @@ |
| 57 | #define __TIMER_T_TYPE		void * | 57 | #define __TIMER_T_TYPE		void * |
| 58 | #define __BLKSIZE_T_TYPE	__SLONGWORD_TYPE | 58 | #define __BLKSIZE_T_TYPE	__SLONGWORD_TYPE |
| 59 | #define __FSID_T_TYPE		struct { int __val[2]; } | 59 | #define __FSID_T_TYPE		struct { int __val[2]; } |
| 60 | #if defined __GNUC__ && __GNUC__ <= 2 | 60 | |
| 61 | /* Compatibility with g++ 2.95.x. */ | 61 | /* With s390-32, __SSIZE_T_TYPE was __SWORD_TYPE for compatibility with |
| 62 | #define __SSIZE_T_TYPE		__SWORD_TYPE | 62 | g++ 2.95.x. Afterwards __SLONGWORD_TYPE was needed as size_t was |
| 63 | #else | 63 | unsigned long int on s390-32. |
| 64 | /* size_t is unsigned long int on s390 -m31. */ | 64 | Now as only s390-64 exists, __SWORD_TYPE can be used as also used in the |
| 65 | #define __SSIZE_T_TYPE		__SLONGWORD_TYPE | 65 | generic version as both types result in long int. */ |
| 66 | #endif | 66 | #define __SSIZE_T_TYPE __SWORD_TYPE |
| 67 | |||
| 67 | #define __SYSCALL_SLONG_TYPE	__SLONGWORD_TYPE | 68 | #define __SYSCALL_SLONG_TYPE	__SLONGWORD_TYPE |
| 68 | #define __SYSCALL_ULONG_TYPE	__ULONGWORD_TYPE | 69 | #define __SYSCALL_ULONG_TYPE	__ULONGWORD_TYPE |
| 69 | #define __CPU_MASK_TYPE 	__ULONGWORD_TYPE | 70 | #define __CPU_MASK_TYPE		__ULONGWORD_TYPE |
| 70 | 71 | ||
| 71 | #ifdef __s390x__ | ||
| 72 | /* Tell the libc code that off_t and off64_t are actually the same type | 72 | /* Tell the libc code that off_t and off64_t are actually the same type |
| 73 | for all ABI purposes, even if possibly expressed as different base types | 73 | for all ABI purposes, even if possibly expressed as different base types |
| 74 | for C type-checking purposes. */ | 74 | for C type-checking purposes. */ |
| 75 | # define __OFF_T_MATCHES_OFF64_T	1 | 75 | #define __OFF_T_MATCHES_OFF64_T	1 |
| 76 | 76 | ||
| 77 | /* Same for ino_t and ino64_t. */ | 77 | /* Same for ino_t and ino64_t. */ |
| 78 | # define __INO_T_MATCHES_INO64_T	1 | 78 | #define __INO_T_MATCHES_INO64_T	1 |
| 79 | 79 | ||
| 80 | /* And for __rlim_t and __rlim64_t. */ | 80 | /* And for __rlim_t and __rlim64_t. */ |
| 81 | # define __RLIM_T_MATCHES_RLIM64_T	1 | 81 | #define __RLIM_T_MATCHES_RLIM64_T	1 |
| 82 | 82 | ||
| 83 | /* And for fsblkcnt_t, fsblkcnt64_t, fsfilcnt_t and fsfilcnt64_t. */ | 83 | /* And for fsblkcnt_t, fsblkcnt64_t, fsfilcnt_t and fsfilcnt64_t. */ |
| 84 | # define __STATFS_MATCHES_STATFS64 1 | 84 | #define __STATFS_MATCHES_STATFS64 1 |
| 85 | 85 | ||
| 86 | /* And for getitimer, setitimer and rusage */ | 86 | /* And for getitimer, setitimer and rusage */ |
| 87 | # define __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 1 | 87 | #define __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 1 |
| 88 | #else | ||
| 89 | # define __RLIM_T_MATCHES_RLIM64_T	0 | ||
| 90 | |||
| 91 | # define __STATFS_MATCHES_STATFS64 0 | ||
| 92 | |||
| 93 | /* And for getitimer, setitimer and rusage */ | ||
| 94 | # define __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 0 | ||
| 95 | #endif | ||
| 96 | 88 | ||
| 97 | /* Number of descriptors that can fit in an `fd_set'. */ | 89 | /* Number of descriptors that can fit in an `fd_set'. */ |
| 98 | #define	__FD_SETSIZE		1024 | 90 | #define	__FD_SETSIZE		1024 |
lib/libc/glibc/sysdeps/unix/sysv/linux/s390/kernel-features.h-3| ... | @@ -47,9 +47,6 @@ | ... | @@ -47,9 +47,6 @@ |
| 47 | # undef __ASSUME_DIRECT_SYSVIPC_SYSCALLS | 47 | # undef __ASSUME_DIRECT_SYSVIPC_SYSCALLS |
| 48 | # undef __ASSUME_SYSVIPC_DEFAULT_IPC_64 | 48 | # undef __ASSUME_SYSVIPC_DEFAULT_IPC_64 |
| 49 | #endif | 49 | #endif |
| 50 | #ifndef __s390x__ | ||
| 51 | # define __ASSUME_SYSVIPC_BROKEN_MODE_T | ||
| 52 | #endif | ||
| 53 | 50 | ||
| 54 | #undef __ASSUME_CLONE_DEFAULT | 51 | #undef __ASSUME_CLONE_DEFAULT |
| 55 | #define __ASSUME_CLONE_BACKWARDS2 | 52 | #define __ASSUME_CLONE_BACKWARDS2 |
lib/libc/glibc/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h deleted-178| ... | @@ -1,178 +0,0 @@ | ||
| 1 | /* Assembler macros for 64 bit S/390. | ||
| 2 | Copyright (C) 2001-2026 Free Software Foundation, Inc. | ||
| 3 | This file is part of the GNU C Library. | ||
| 4 | |||
| 5 | The GNU C Library is free software; you can redistribute it and/or | ||
| 6 | modify it under the terms of the GNU Lesser General Public | ||
| 7 | License as published by the Free Software Foundation; either | ||
| 8 | version 2.1 of the License, or (at your option) any later version. | ||
| 9 | |||
| 10 | The GNU C Library is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 13 | Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public | ||
| 16 | License along with the GNU C Library; if not, see | ||
| 17 | <https://www.gnu.org/licenses/>. */ | ||
| 18 | |||
| 19 | #ifndef _LINUX_S390_SYSDEP_H | ||
| 20 | #define _LINUX_S390_SYSDEP_H | ||
| 21 | |||
| 22 | #include <sysdeps/s390/s390-64/sysdep.h> | ||
| 23 | #include <sysdeps/unix/sysdep.h> | ||
| 24 | #include <sysdeps/unix/sysv/linux/s390/sysdep.h> | ||
| 25 | #include <sysdeps/unix/sysv/linux/sysdep.h> | ||
| 26 | #include <dl-sysdep.h>	/* For RTLD_PRIVATE_ERRNO. */ | ||
| 27 | #include <tls.h> | ||
| 28 | |||
| 29 | /* For Linux we can use the system call table in the header file | ||
| 30 | 	/usr/include/asm/unistd.h | ||
| 31 | of the kernel. But these symbols do not follow the SYS_* syntax | ||
| 32 | so we have to redefine the `SYS_ify' macro here. */ | ||
| 33 | /* In newer 2.1 kernels __NR_syscall is missing so we define it here. */ | ||
| 34 | #define __NR_syscall 0 | ||
| 35 | |||
| 36 | #undef SYS_ify | ||
| 37 | #define SYS_ify(syscall_name)	__NR_##syscall_name | ||
| 38 | |||
| 39 | #ifdef __ASSEMBLER__ | ||
| 40 | |||
| 41 | /* Linux uses a negative return value to indicate syscall errors, unlike | ||
| 42 | most Unices, which use the condition codes' carry flag. | ||
| 43 | |||
| 44 | Since version 2.1 the return value of a system call might be negative | ||
| 45 | even if the call succeeded.	E.g., the `lseek' system call might return | ||
| 46 | a large offset. Therefore we must not anymore test for < 0, but test | ||
| 47 | for a real error by making sure the value in gpr2 is a real error | ||
| 48 | number. Linus said he will make sure that no syscall returns a value | ||
| 49 | in -1 .. -4095 as a valid result so we can safely test with -4095. */ | ||
| 50 | |||
| 51 | #undef PSEUDO | ||
| 52 | #define	PSEUDO(name, syscall_name, args)				 \ | ||
| 53 | .text;								 \ | ||
| 54 | ENTRY (name)								 \ | ||
| 55 | DO_CALL (syscall_name, args);					 \ | ||
| 56 | lghi %r4,-4095 ;							 \ | ||
| 57 | clgr %r2,%r4 ;							 \ | ||
| 58 | jgnl SYSCALL_ERROR_LABEL | ||
| 59 | |||
| 60 | #undef PSEUDO_END | ||
| 61 | #define PSEUDO_END(name)						 \ | ||
| 62 | SYSCALL_ERROR_HANDLER;						 \ | ||
| 63 | END (name) | ||
| 64 | |||
| 65 | #undef PSEUDO_NOERRNO | ||
| 66 | #define	PSEUDO_NOERRNO(name, syscall_name, args)			 \ | ||
| 67 | .text;								 \ | ||
| 68 | ENTRY (name)								 \ | ||
| 69 | DO_CALL (syscall_name, args) | ||
| 70 | |||
| 71 | #undef PSEUDO_END_NOERRNO | ||
| 72 | #define PSEUDO_END_NOERRNO(name)					 \ | ||
| 73 | SYSCALL_ERROR_HANDLER;						 \ | ||
| 74 | END (name) | ||
| 75 | |||
| 76 | #undef PSEUDO_ERRVAL | ||
| 77 | #define	PSEUDO_ERRVAL(name, syscall_name, args)				 \ | ||
| 78 | .text;								 \ | ||
| 79 | ENTRY (name)								 \ | ||
| 80 | DO_CALL (syscall_name, args);					 \ | ||
| 81 | lcgr %r2,%r2 | ||
| 82 | |||
| 83 | #undef PSEUDO_END_ERRVAL | ||
| 84 | #define PSEUDO_END_ERRVAL(name)						 \ | ||
| 85 | SYSCALL_ERROR_HANDLER;						 \ | ||
| 86 | END (name) | ||
| 87 | |||
| 88 | #undef SYSCALL_ERROR_LABEL | ||
| 89 | #ifndef PIC | ||
| 90 | # undef SYSCALL_ERROR_LABEL | ||
| 91 | # define SYSCALL_ERROR_LABEL syscall_error | ||
| 92 | # define SYSCALL_ERROR_HANDLER | ||
| 93 | #else | ||
| 94 | # if RTLD_PRIVATE_ERRNO | ||
| 95 | # undef SYSCALL_ERROR_LABEL | ||
| 96 | # define SYSCALL_ERROR_LABEL 0f | ||
| 97 | # define SYSCALL_ERROR_HANDLER \ | ||
| 98 | 0: larl %r1,rtld_errno;						 \ | ||
| 99 | lcr %r2,%r2;							 \ | ||
| 100 | st %r2,0(%r1);							 \ | ||
| 101 | lghi %r2,-1;							 \ | ||
| 102 | br %r14 | ||
| 103 | # elif defined _LIBC_REENTRANT | ||
| 104 | # if IS_IN (libc) | ||
| 105 | # define SYSCALL_ERROR_ERRNO __libc_errno | ||
| 106 | # else | ||
| 107 | # define SYSCALL_ERROR_ERRNO errno | ||
| 108 | # endif | ||
| 109 | # undef SYSCALL_ERROR_LABEL | ||
| 110 | # define SYSCALL_ERROR_LABEL 0f | ||
| 111 | # define SYSCALL_ERROR_HANDLER \ | ||
| 112 | 0: lcr %r0,%r2;							 \ | ||
| 113 | larl %r1,SYSCALL_ERROR_ERRNO@indntpoff;				 \ | ||
| 114 | lg %r1,0(%r1);							 \ | ||
| 115 | ear %r2,%a0;							 \ | ||
| 116 | sllg %r2,%r2,32;							 \ | ||
| 117 | ear %r2,%a1;							 \ | ||
| 118 | st %r0,0(%r1,%r2);						 \ | ||
| 119 | lghi %r2,-1;							 \ | ||
| 120 | br %r14 | ||
| 121 | # else | ||
| 122 | # undef SYSCALL_ERROR_LABEL | ||
| 123 | # define SYSCALL_ERROR_LABEL 0f | ||
| 124 | # define SYSCALL_ERROR_HANDLER \ | ||
| 125 | 0: larl %r1,_GLOBAL_OFFSET_TABLE_;					 \ | ||
| 126 | lg %r1,errno@GOT(%r1);						 \ | ||
| 127 | lcr %r2,%r2;							 \ | ||
| 128 | st %r2,0(%r1);							 \ | ||
| 129 | lghi %r2,-1;							 \ | ||
| 130 | br %r14 | ||
| 131 | # endif /* _LIBC_REENTRANT */ | ||
| 132 | #endif /* PIC */ | ||
| 133 | |||
| 134 | /* Linux takes system call arguments in registers: | ||
| 135 | |||
| 136 | 	syscall number	1	 call-clobbered | ||
| 137 | 	arg 1		2	 call-clobbered | ||
| 138 | 	arg 2		3	 call-clobbered | ||
| 139 | 	arg 3		4	 call-clobbered | ||
| 140 | 	arg 4		5	 call-clobbered | ||
| 141 | 	arg 5		6	 call-saved | ||
| 142 | 	arg 6		7	 call-saved | ||
| 143 | |||
| 144 | (Of course a function with say 3 arguments does not have entries for | ||
| 145 | arguments 4 and 5.) | ||
| 146 | For system calls with 6 parameters a stack operation is required | ||
| 147 | to load the 6th parameter to register 7. Call saved register 7 is | ||
| 148 | moved to register 0 and back to avoid an additional stack frame. | ||
| 149 | */ | ||
| 150 | |||
| 151 | #define DO_CALL(syscall, args)						 \ | ||
| 152 | .if args > 5;								 \ | ||
| 153 | lgr %r0,%r7;							 \ | ||
| 154 | lg %r7,160(%r15);							 \ | ||
| 155 | .endif;								 \ | ||
| 156 | lghi %r1,SYS_ify (syscall);						 \ | ||
| 157 | svc 0;								 \ | ||
| 158 | .if args > 5;								 \ | ||
| 159 | lgr %r7,%r0;							 \ | ||
| 160 | .endif | ||
| 161 | |||
| 162 | #define ret								 \ | ||
| 163 | br	 14 | ||
| 164 | |||
| 165 | #define ret_NOERRNO							 \ | ||
| 166 | br	 14 | ||
| 167 | |||
| 168 | #define ret_ERRVAL							 \ | ||
| 169 | br	 14 | ||
| 170 | |||
| 171 | #else | ||
| 172 | |||
| 173 | # undef HAVE_INTERNAL_BRK_ADDR_SYMBOL | ||
| 174 | # define HAVE_INTERNAL_BRK_ADDR_SYMBOL 1 | ||
| 175 | |||
| 176 | #endif /* __ASSEMBLER__ */ | ||
| 177 | |||
| 178 | #endif /* _LINUX_S390_SYSDEP_H */ | ||
lib/libc/glibc/sysdeps/unix/sysv/linux/s390/sysdep.h+186-37| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | /* Syscall definitions, Linux s390 version. | 1 | /* Assembler macros for 64 bit S/390. |
| 2 | Copyright (C) 2019-2026 Free Software Foundation, Inc. | 2 | Copyright (C) 2001-2026 Free Software Foundation, Inc. |
| 3 | This file is part of the GNU C Library. | 3 | This file is part of the GNU C Library. |
| 4 | 4 | ||
| 5 | The GNU C Library is free software; you can redistribute it and/or | 5 | The GNU C Library is free software; you can redistribute it and/or |
| ... | @@ -14,15 +14,163 @@ | ... | @@ -14,15 +14,163 @@ |
| 14 | 14 | ||
| 15 | You should have received a copy of the GNU Lesser General Public | 15 | You should have received a copy of the GNU Lesser General Public |
| 16 | License along with the GNU C Library; if not, see | 16 | License along with the GNU C Library; if not, see |
| 17 | <http://www.gnu.org/licenses/>. */ | 17 | <https://www.gnu.org/licenses/>. */ |
| 18 | 18 | ||
| 19 | #ifndef __ASSEMBLY__ | 19 | #ifndef _LINUX_S390_SYSDEP_H |
| 20 | #define _LINUX_S390_SYSDEP_H | ||
| 21 | |||
| 22 | #include <sysdeps/s390/sysdep.h> | ||
| 23 | #include <sysdeps/unix/sysdep.h> | ||
| 24 | #include <sysdeps/unix/sysv/linux/sysdep.h> | ||
| 25 | #include <dl-sysdep.h>	/* For RTLD_PRIVATE_ERRNO. */ | ||
| 26 | #include <tls.h> | ||
| 27 | |||
| 28 | /* For Linux we can use the system call table in the header file | ||
| 29 | 	/usr/include/asm/unistd.h | ||
| 30 | of the kernel. But these symbols do not follow the SYS_* syntax | ||
| 31 | so we have to redefine the `SYS_ify' macro here. */ | ||
| 32 | /* In newer 2.1 kernels __NR_syscall is missing so we define it here. */ | ||
| 33 | #define __NR_syscall 0 | ||
| 20 | 34 | ||
| 21 | #undef SYS_ify | 35 | #undef SYS_ify |
| 22 | #define SYS_ify(syscall_name)	__NR_##syscall_name | 36 | #define SYS_ify(syscall_name)	__NR_##syscall_name |
| 23 | 37 | ||
| 24 | #undef INTERNAL_SYSCALL_NCS | 38 | #ifdef __ASSEMBLER__ |
| 25 | #define INTERNAL_SYSCALL_NCS(no, nr, args...)				 \ | 39 | |
| 40 | /* Linux uses a negative return value to indicate syscall errors, unlike | ||
| 41 | most Unices, which use the condition codes' carry flag. | ||
| 42 | |||
| 43 | Since version 2.1 the return value of a system call might be negative | ||
| 44 | even if the call succeeded.	E.g., the `lseek' system call might return | ||
| 45 | a large offset. Therefore we must not anymore test for < 0, but test | ||
| 46 | for a real error by making sure the value in gpr2 is a real error | ||
| 47 | number. Linus said he will make sure that no syscall returns a value | ||
| 48 | in -1 .. -4095 as a valid result so we can safely test with -4095. */ | ||
| 49 | |||
| 50 | # undef PSEUDO | ||
| 51 | # define PSEUDO(name, syscall_name, args)				 \ | ||
| 52 | .text;								 \ | ||
| 53 | ENTRY (name)								 \ | ||
| 54 | DO_CALL (syscall_name, args);					 \ | ||
| 55 | lghi %r4,-4095 ;							 \ | ||
| 56 | clgr %r2,%r4 ;							 \ | ||
| 57 | jgnl SYSCALL_ERROR_LABEL | ||
| 58 | |||
| 59 | # undef PSEUDO_END | ||
| 60 | # define PSEUDO_END(name)						 \ | ||
| 61 | SYSCALL_ERROR_HANDLER;						 \ | ||
| 62 | END (name) | ||
| 63 | |||
| 64 | # undef PSEUDO_NOERRNO | ||
| 65 | # define PSEUDO_NOERRNO(name, syscall_name, args)			 \ | ||
| 66 | .text;								 \ | ||
| 67 | ENTRY (name)								 \ | ||
| 68 | DO_CALL (syscall_name, args) | ||
| 69 | |||
| 70 | # undef PSEUDO_END_NOERRNO | ||
| 71 | # define PSEUDO_END_NOERRNO(name)					 \ | ||
| 72 | SYSCALL_ERROR_HANDLER;						 \ | ||
| 73 | END (name) | ||
| 74 | |||
| 75 | # undef PSEUDO_ERRVAL | ||
| 76 | # define PSEUDO_ERRVAL(name, syscall_name, args)				 \ | ||
| 77 | .text;								 \ | ||
| 78 | ENTRY (name)								 \ | ||
| 79 | DO_CALL (syscall_name, args);					 \ | ||
| 80 | lcgr %r2,%r2 | ||
| 81 | |||
| 82 | # undef PSEUDO_END_ERRVAL | ||
| 83 | # define PSEUDO_END_ERRVAL(name)						 \ | ||
| 84 | SYSCALL_ERROR_HANDLER;						 \ | ||
| 85 | END (name) | ||
| 86 | |||
| 87 | # undef SYSCALL_ERROR_LABEL | ||
| 88 | # ifndef PIC | ||
| 89 | # undef SYSCALL_ERROR_LABEL | ||
| 90 | # define SYSCALL_ERROR_LABEL syscall_error | ||
| 91 | # define SYSCALL_ERROR_HANDLER | ||
| 92 | # else | ||
| 93 | # if RTLD_PRIVATE_ERRNO | ||
| 94 | # undef SYSCALL_ERROR_LABEL | ||
| 95 | # define SYSCALL_ERROR_LABEL 0f | ||
| 96 | # define SYSCALL_ERROR_HANDLER \ | ||
| 97 | 0: larl %r1,rtld_errno;						 \ | ||
| 98 | lcr %r2,%r2;							 \ | ||
| 99 | st %r2,0(%r1);							 \ | ||
| 100 | lghi %r2,-1;							 \ | ||
| 101 | br %r14 | ||
| 102 | # elif defined _LIBC_REENTRANT | ||
| 103 | # if IS_IN (libc) | ||
| 104 | # define SYSCALL_ERROR_ERRNO __libc_errno | ||
| 105 | # else | ||
| 106 | # define SYSCALL_ERROR_ERRNO errno | ||
| 107 | # endif | ||
| 108 | # undef SYSCALL_ERROR_LABEL | ||
| 109 | # define SYSCALL_ERROR_LABEL 0f | ||
| 110 | # define SYSCALL_ERROR_HANDLER \ | ||
| 111 | 0: lcr %r0,%r2;							 \ | ||
| 112 | larl %r1,SYSCALL_ERROR_ERRNO@indntpoff;				 \ | ||
| 113 | lg %r1,0(%r1);							 \ | ||
| 114 | ear %r2,%a0;							 \ | ||
| 115 | sllg %r2,%r2,32;							 \ | ||
| 116 | ear %r2,%a1;							 \ | ||
| 117 | st %r0,0(%r1,%r2);						 \ | ||
| 118 | lghi %r2,-1;							 \ | ||
| 119 | br %r14 | ||
| 120 | # else | ||
| 121 | # undef SYSCALL_ERROR_LABEL | ||
| 122 | # define SYSCALL_ERROR_LABEL 0f | ||
| 123 | # define SYSCALL_ERROR_HANDLER \ | ||
| 124 | 0: larl %r1,_GLOBAL_OFFSET_TABLE_;					 \ | ||
| 125 | lg %r1,errno@GOT(%r1);						 \ | ||
| 126 | lcr %r2,%r2;							 \ | ||
| 127 | st %r2,0(%r1);							 \ | ||
| 128 | lghi %r2,-1;							 \ | ||
| 129 | br %r14 | ||
| 130 | # endif /* _LIBC_REENTRANT */ | ||
| 131 | # endif /* PIC */ | ||
| 132 | |||
| 133 | /* Linux takes system call arguments in registers: | ||
| 134 | |||
| 135 | 	syscall number	1	 call-clobbered | ||
| 136 | 	arg 1		2	 call-clobbered | ||
| 137 | 	arg 2		3	 call-clobbered | ||
| 138 | 	arg 3		4	 call-clobbered | ||
| 139 | 	arg 4		5	 call-clobbered | ||
| 140 | 	arg 5		6	 call-saved | ||
| 141 | 	arg 6		7	 call-saved | ||
| 142 | |||
| 143 | (Of course a function with say 3 arguments does not have entries for | ||
| 144 | arguments 4 and 5.) | ||
| 145 | For system calls with 6 parameters a stack operation is required | ||
| 146 | to load the 6th parameter to register 7. Call saved register 7 is | ||
| 147 | moved to register 0 and back to avoid an additional stack frame. | ||
| 148 | */ | ||
| 149 | |||
| 150 | # define DO_CALL(syscall, args)						 \ | ||
| 151 | .if args > 5;								 \ | ||
| 152 | lgr %r0,%r7;							 \ | ||
| 153 | lg %r7,160(%r15);							 \ | ||
| 154 | .endif;								 \ | ||
| 155 | lghi %r1,SYS_ify (syscall);						 \ | ||
| 156 | svc 0;								 \ | ||
| 157 | .if args > 5;								 \ | ||
| 158 | lgr %r7,%r0;							 \ | ||
| 159 | .endif | ||
| 160 | |||
| 161 | # define ret								 \ | ||
| 162 | br	 14 | ||
| 163 | |||
| 164 | # define ret_NOERRNO							 \ | ||
| 165 | br	 14 | ||
| 166 | |||
| 167 | # define ret_ERRVAL							 \ | ||
| 168 | br	 14 | ||
| 169 | |||
| 170 | #else /* not __ASSEMBLER__ */ | ||
| 171 | |||
| 172 | # undef INTERNAL_SYSCALL_NCS | ||
| 173 | # define INTERNAL_SYSCALL_NCS(no, nr, args...)				 \ | ||
| 26 | ({									 \ | 174 | ({									 \ |
| 27 | DECLARGS_##nr(args)							 \ | 175 | DECLARGS_##nr(args)							 \ |
| 28 | register unsigned long int _nr __asm__("1") = (unsigned long int)(no); \ | 176 | register unsigned long int _nr __asm__("1") = (unsigned long int)(no); \ |
| ... | @@ -34,51 +182,52 @@ | ... | @@ -34,51 +182,52 @@ |
| 34 | 			 : "memory" );					 \ | 182 | 			 : "memory" );					 \ |
| 35 | _ret; }) | 183 | _ret; }) |
| 36 | 184 | ||
| 37 | #undef INTERNAL_SYSCALL | 185 | # undef INTERNAL_SYSCALL |
| 38 | #define INTERNAL_SYSCALL(name, nr, args...)				\ | 186 | # define INTERNAL_SYSCALL(name, nr, args...)				\ |
| 39 | INTERNAL_SYSCALL_NCS(__NR_##name, nr, args) | 187 | INTERNAL_SYSCALL_NCS(__NR_##name, nr, args) |
| 40 | 188 | ||
| 41 | #define DECLARGS_0() | 189 | # define DECLARGS_0() |
| 42 | #define DECLARGS_1(arg1) \ | 190 | # define DECLARGS_1(arg1) \ |
| 43 | register unsigned long int gpr2 __asm__ ("2") = (unsigned long int)(arg1); | 191 | register unsigned long int gpr2 __asm__ ("2") = (unsigned long int)(arg1); |
| 44 | #define DECLARGS_2(arg1, arg2) \ | 192 | # define DECLARGS_2(arg1, arg2) \ |
| 45 | DECLARGS_1(arg1) \ | 193 | DECLARGS_1(arg1) \ |
| 46 | register unsigned long int gpr3 __asm__ ("3") = (unsigned long int)(arg2); | 194 | register unsigned long int gpr3 __asm__ ("3") = (unsigned long int)(arg2); |
| 47 | #define DECLARGS_3(arg1, arg2, arg3) \ | 195 | # define DECLARGS_3(arg1, arg2, arg3) \ |
| 48 | DECLARGS_2(arg1, arg2) \ | 196 | DECLARGS_2(arg1, arg2) \ |
| 49 | register unsigned long int gpr4 __asm__ ("4") = (unsigned long int)(arg3); | 197 | register unsigned long int gpr4 __asm__ ("4") = (unsigned long int)(arg3); |
| 50 | #define DECLARGS_4(arg1, arg2, arg3, arg4) \ | 198 | # define DECLARGS_4(arg1, arg2, arg3, arg4) \ |
| 51 | DECLARGS_3(arg1, arg2, arg3) \ | 199 | DECLARGS_3(arg1, arg2, arg3) \ |
| 52 | register unsigned long int gpr5 __asm__ ("5") = (unsigned long int)(arg4); | 200 | register unsigned long int gpr5 __asm__ ("5") = (unsigned long int)(arg4); |
| 53 | #define DECLARGS_5(arg1, arg2, arg3, arg4, arg5) \ | 201 | # define DECLARGS_5(arg1, arg2, arg3, arg4, arg5) \ |
| 54 | DECLARGS_4(arg1, arg2, arg3, arg4) \ | 202 | DECLARGS_4(arg1, arg2, arg3, arg4) \ |
| 55 | register unsigned long int gpr6 __asm__ ("6") = (unsigned long int)(arg5); | 203 | register unsigned long int gpr6 __asm__ ("6") = (unsigned long int)(arg5); |
| 56 | #define DECLARGS_6(arg1, arg2, arg3, arg4, arg5, arg6) \ | 204 | # define DECLARGS_6(arg1, arg2, arg3, arg4, arg5, arg6) \ |
| 57 | DECLARGS_5(arg1, arg2, arg3, arg4, arg5) \ | 205 | DECLARGS_5(arg1, arg2, arg3, arg4, arg5) \ |
| 58 | register unsigned long int gpr7 __asm__ ("7") = (unsigned long int)(arg6); | 206 | register unsigned long int gpr7 __asm__ ("7") = (unsigned long int)(arg6); |
| 59 | 207 | ||
| 60 | #define ASMFMT_0 | 208 | # define ASMFMT_0 |
| 61 | #define ASMFMT_1 , "0" (gpr2) | 209 | # define ASMFMT_1 , "0" (gpr2) |
| 62 | #define ASMFMT_2 , "0" (gpr2), "d" (gpr3) | 210 | # define ASMFMT_2 , "0" (gpr2), "d" (gpr3) |
| 63 | #define ASMFMT_3 , "0" (gpr2), "d" (gpr3), "d" (gpr4) | 211 | # define ASMFMT_3 , "0" (gpr2), "d" (gpr3), "d" (gpr4) |
| 64 | #define ASMFMT_4 , "0" (gpr2), "d" (gpr3), "d" (gpr4), "d" (gpr5) | 212 | # define ASMFMT_4 , "0" (gpr2), "d" (gpr3), "d" (gpr4), "d" (gpr5) |
| 65 | #define ASMFMT_5 , "0" (gpr2), "d" (gpr3), "d" (gpr4), "d" (gpr5), "d" (gpr6) | 213 | # define ASMFMT_5 , "0" (gpr2), "d" (gpr3), "d" (gpr4), "d" (gpr5), "d" (gpr6) |
| 66 | #define ASMFMT_6 , "0" (gpr2), "d" (gpr3), "d" (gpr4), "d" (gpr5), "d" (gpr6), "d" (gpr7) | 214 | # define ASMFMT_6 , "0" (gpr2), "d" (gpr3), "d" (gpr4), "d" (gpr5), "d" (gpr6), "d" (gpr7) |
| 67 | 215 | ||
| 68 | #define VDSO_NAME "LINUX_2.6.29" | 216 | # define VDSO_NAME "LINUX_2.6.29" |
| 69 | #define VDSO_HASH 123718585 | 217 | # define VDSO_HASH 123718585 |
| 70 | 218 | ||
| 71 | /* List of system calls which are supported as vsyscalls. */ | 219 | /* List of system calls which are supported as vsyscalls. */ |
| 72 | #ifdef __s390x__ | 220 | # define HAVE_CLOCK_GETRES64_VSYSCALL	"__kernel_clock_getres" |
| 73 | #define HAVE_CLOCK_GETRES64_VSYSCALL	"__kernel_clock_getres" | 221 | # define HAVE_CLOCK_GETTIME64_VSYSCALL	"__kernel_clock_gettime" |
| 74 | #define HAVE_CLOCK_GETTIME64_VSYSCALL	"__kernel_clock_gettime" | 222 | # define HAVE_GETRANDOM_VSYSCALL		"__kernel_getrandom" |
| 75 | #define HAVE_GETRANDOM_VSYSCALL		"__kernel_getrandom" | 223 | # define HAVE_GETTIMEOFDAY_VSYSCALL	"__kernel_gettimeofday" |
| 76 | #else | 224 | # define HAVE_GETCPU_VSYSCALL		"__kernel_getcpu" |
| 77 | #define HAVE_CLOCK_GETRES_VSYSCALL	"__kernel_clock_getres" | 225 | |
| 78 | #define HAVE_CLOCK_GETTIME_VSYSCALL	"__kernel_clock_gettime" | 226 | # define HAVE_CLONE3_WRAPPER		1 |
| 79 | #endif | 227 | |
| 80 | #define HAVE_GETTIMEOFDAY_VSYSCALL	"__kernel_gettimeofday" | 228 | # undef HAVE_INTERNAL_BRK_ADDR_SYMBOL |
| 81 | #define HAVE_GETCPU_VSYSCALL		"__kernel_getcpu" | 229 | # define HAVE_INTERNAL_BRK_ADDR_SYMBOL 1 |
| 82 | 230 | ||
| 83 | #define HAVE_CLONE3_WRAPPER		1 | 231 | #endif /* __ASSEMBLER__ */ |
| 84 | #endif | 232 | |
| 233 | #endif /* _LINUX_S390_SYSDEP_H */ |
lib/libc/glibc/sysdeps/unix/sysv/linux/s390/xstatver.h+6-15| ... | @@ -1,19 +1,10 @@ | ... | @@ -1,19 +1,10 @@ |
| 1 | /* Versions of the 'struct stat' data structure used in compatibility xstat | 1 | /* Versions of the 'struct stat' data structure used in compatibility xstat |
| 2 | functions. */ | 2 | functions. */ |
| 3 | 3 | #define _STAT_VER_KERNEL	0 | |
| 4 | #include <bits/wordsize.h> | 4 | #define _STAT_VER_LINUX		1 |
| 5 | |||
| 6 | #if __WORDSIZE == 64 | ||
| 7 | # define _STAT_VER_KERNEL	0 | ||
| 8 | # define _STAT_VER_LINUX	1 | ||
| 9 | # define _MKNOD_VER_LINUX	0 | ||
| 10 | #else | ||
| 11 | # define _STAT_VER_LINUX_OLD	1 | ||
| 12 | # define _STAT_VER_KERNEL	1 | ||
| 13 | # define _STAT_VER_SVR4		2 | ||
| 14 | # define _STAT_VER_LINUX	3 | ||
| 15 | # define _MKNOD_VER_LINUX	1 | ||
| 16 | # define _MKNOD_VER_SVR4	2 | ||
| 17 | #endif | ||
| 18 | #define _STAT_VER		_STAT_VER_LINUX | 5 | #define _STAT_VER		_STAT_VER_LINUX |
| 6 | |||
| 7 | /* Versions of the 'xmknod' interface used in compatibility xmknod | ||
| 8 | functions. */ | ||
| 9 | #define _MKNOD_VER_LINUX	0 | ||
| 19 | #define _MKNOD_VER		_MKNOD_VER_LINUX | 10 | #define _MKNOD_VER		_MKNOD_VER_LINUX |
lib/libc/include/aarch64-linux-gnu/bits/hwcap.h+18-1| ... | @@ -55,6 +55,21 @@ | ... | @@ -55,6 +55,21 @@ |
| 55 | #define HWCAP_PACA		(1 << 30) | 55 | #define HWCAP_PACA		(1 << 30) |
| 56 | #define HWCAP_PACG		(1UL << 31) | 56 | #define HWCAP_PACG		(1UL << 31) |
| 57 | #define HWCAP_GCS		(1UL << 32) | 57 | #define HWCAP_GCS		(1UL << 32) |
| 58 | #define HWCAP_CMPBR		(1UL << 33) | ||
| 59 | #define HWCAP_FPRCVT		(1UL << 34) | ||
| 60 | #define HWCAP_F8MM8		(1UL << 35) | ||
| 61 | #define HWCAP_F8MM4		(1UL << 36) | ||
| 62 | #define HWCAP_SVE_F16MM		(1UL << 37) | ||
| 63 | #define HWCAP_SVE_ELTPERM	(1UL << 38) | ||
| 64 | #define HWCAP_SVE_AES2		(1UL << 39) | ||
| 65 | #define HWCAP_SVE_BFSCALE	(1UL << 40) | ||
| 66 | #define HWCAP_SVE2P2		(1UL << 41) | ||
| 67 | #define HWCAP_SME2P2		(1UL << 42) | ||
| 68 | #define HWCAP_SME_SBITPERM	(1UL << 43) | ||
| 69 | #define HWCAP_SME_AES		(1UL << 44) | ||
| 70 | #define HWCAP_SME_SFEXPA	(1UL << 45) | ||
| 71 | #define HWCAP_SME_STMOP		(1UL << 46) | ||
| 72 | #define HWCAP_SME_SMOP4		(1UL << 47) | ||
| 58 | 73 | ||
| 59 | #define HWCAP2_DCPODP		(1 << 0) | 74 | #define HWCAP2_DCPODP		(1 << 0) |
| 60 | #define HWCAP2_SVE2		(1 << 1) | 75 | #define HWCAP2_SVE2		(1 << 1) |
| ... | @@ -122,4 +137,6 @@ | ... | @@ -122,4 +137,6 @@ |
| 122 | #define HWCAP2_POE		(1UL << 63) | 137 | #define HWCAP2_POE		(1UL << 63) |
| 123 | 138 | ||
| 124 | #define HWCAP3_MTE_FAR		(1UL << 0) | 139 | #define HWCAP3_MTE_FAR		(1UL << 0) |
| 125 | #define HWCAP3_MTE_STORE_ONLY	(1UL << 1) | ||
| \ No newline at end of file | |||
| 140 | #define HWCAP3_MTE_STORE_ONLY	(1UL << 1) | ||
| 141 | #define HWCAP3_LSFE		(1UL << 2) | ||
| 142 | #define HWCAP3_LS64		(1UL << 3) | ||
| \ No newline at end of file | |||
lib/libc/include/aarch64-linux-gnu/bits/long-double.h deleted-21| ... | @@ -1,21 +0,0 @@ | ||
| 1 | /* Properties of long double type. ldbl-128 version. | ||
| 2 | Copyright (C) 2016-2026 Free Software Foundation, Inc. | ||
| 3 | This file is part of the GNU C Library. | ||
| 4 | |||
| 5 | The GNU C Library is free software; you can redistribute it and/or | ||
| 6 | modify it under the terms of the GNU Lesser General Public | ||
| 7 | License published by the Free Software Foundation; either | ||
| 8 | version 2.1 of the License, or (at your option) any later version. | ||
| 9 | |||
| 10 | The GNU C Library is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 13 | Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public | ||
| 16 | License along with the GNU C Library; if not, see | ||
| 17 | <https://www.gnu.org/licenses/>. */ | ||
| 18 | |||
| 19 | /* long double is distinct from double, so there is nothing to | ||
| 20 | define here. */ | ||
| 21 | #define __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI 0 | ||
| \ No newline at end of file | |||
lib/libc/include/aarch64-linux-gnu/bits/math-vector.h+8| ... | @@ -157,6 +157,10 @@ | ... | @@ -157,6 +157,10 @@ |
| 157 | # define __DECL_SIMD_pow __DECL_SIMD_aarch64 | 157 | # define __DECL_SIMD_pow __DECL_SIMD_aarch64 |
| 158 | # undef __DECL_SIMD_powf | 158 | # undef __DECL_SIMD_powf |
| 159 | # define __DECL_SIMD_powf __DECL_SIMD_aarch64 | 159 | # define __DECL_SIMD_powf __DECL_SIMD_aarch64 |
| 160 | # undef __DECL_SIMD_powr | ||
| 161 | # define __DECL_SIMD_powr __DECL_SIMD_aarch64 | ||
| 162 | # undef __DECL_SIMD_powrf | ||
| 163 | # define __DECL_SIMD_powrf __DECL_SIMD_aarch64 | ||
| 160 | # undef __DECL_SIMD_rsqrt | 164 | # undef __DECL_SIMD_rsqrt |
| 161 | # define __DECL_SIMD_rsqrt __DECL_SIMD_aarch64 | 165 | # define __DECL_SIMD_rsqrt __DECL_SIMD_aarch64 |
| 162 | # undef __DECL_SIMD_rsqrtf | 166 | # undef __DECL_SIMD_rsqrtf |
| ... | @@ -243,6 +247,7 @@ __vpcs __f32x4_t _ZGVnN4v_log2f (__f32x4_t); | ... | @@ -243,6 +247,7 @@ __vpcs __f32x4_t _ZGVnN4v_log2f (__f32x4_t); |
| 243 | __vpcs __f32x4_t _ZGVnN4v_log2p1f (__f32x4_t); | 247 | __vpcs __f32x4_t _ZGVnN4v_log2p1f (__f32x4_t); |
| 244 | __vpcs __f32x4_t _ZGVnN4v_logp1f (__f32x4_t); | 248 | __vpcs __f32x4_t _ZGVnN4v_logp1f (__f32x4_t); |
| 245 | __vpcs __f32x4_t _ZGVnN4vv_powf (__f32x4_t, __f32x4_t); | 249 | __vpcs __f32x4_t _ZGVnN4vv_powf (__f32x4_t, __f32x4_t); |
| 250 | __vpcs __f32x4_t _ZGVnN4vv_powrf (__f32x4_t, __f32x4_t); | ||
| 246 | __vpcs __f32x4_t _ZGVnN4v_rsqrtf (__f32x4_t); | 251 | __vpcs __f32x4_t _ZGVnN4v_rsqrtf (__f32x4_t); |
| 247 | __vpcs __f32x4_t _ZGVnN4v_sinf (__f32x4_t); | 252 | __vpcs __f32x4_t _ZGVnN4v_sinf (__f32x4_t); |
| 248 | __vpcs __f32x4_t _ZGVnN4v_sinhf (__f32x4_t); | 253 | __vpcs __f32x4_t _ZGVnN4v_sinhf (__f32x4_t); |
| ... | @@ -283,6 +288,7 @@ __vpcs __f64x2_t _ZGVnN2v_log2 (__f64x2_t); | ... | @@ -283,6 +288,7 @@ __vpcs __f64x2_t _ZGVnN2v_log2 (__f64x2_t); |
| 283 | __vpcs __f64x2_t _ZGVnN2v_log2p1 (__f64x2_t); | 288 | __vpcs __f64x2_t _ZGVnN2v_log2p1 (__f64x2_t); |
| 284 | __vpcs __f64x2_t _ZGVnN2v_logp1 (__f64x2_t); | 289 | __vpcs __f64x2_t _ZGVnN2v_logp1 (__f64x2_t); |
| 285 | __vpcs __f64x2_t _ZGVnN2vv_pow (__f64x2_t, __f64x2_t); | 290 | __vpcs __f64x2_t _ZGVnN2vv_pow (__f64x2_t, __f64x2_t); |
| 291 | __vpcs __f64x2_t _ZGVnN2vv_powr (__f64x2_t, __f64x2_t); | ||
| 286 | __vpcs __f64x2_t _ZGVnN2v_rsqrt (__f64x2_t); | 292 | __vpcs __f64x2_t _ZGVnN2v_rsqrt (__f64x2_t); |
| 287 | __vpcs __f64x2_t _ZGVnN2v_sin (__f64x2_t); | 293 | __vpcs __f64x2_t _ZGVnN2v_sin (__f64x2_t); |
| 288 | __vpcs __f64x2_t _ZGVnN2v_sinh (__f64x2_t); | 294 | __vpcs __f64x2_t _ZGVnN2v_sinh (__f64x2_t); |
| ... | @@ -328,6 +334,7 @@ __sv_f32_t _ZGVsMxv_log2f (__sv_f32_t, __sv_bool_t); | ... | @@ -328,6 +334,7 @@ __sv_f32_t _ZGVsMxv_log2f (__sv_f32_t, __sv_bool_t); |
| 328 | __sv_f32_t _ZGVsMxv_log2p1f (__sv_f32_t, __sv_bool_t); | 334 | __sv_f32_t _ZGVsMxv_log2p1f (__sv_f32_t, __sv_bool_t); |
| 329 | __sv_f32_t _ZGVsMxv_logp1f (__sv_f32_t, __sv_bool_t); | 335 | __sv_f32_t _ZGVsMxv_logp1f (__sv_f32_t, __sv_bool_t); |
| 330 | __sv_f32_t _ZGVsMxvv_powf (__sv_f32_t, __sv_f32_t, __sv_bool_t); | 336 | __sv_f32_t _ZGVsMxvv_powf (__sv_f32_t, __sv_f32_t, __sv_bool_t); |
| 337 | __sv_f32_t _ZGVsMxvv_powrf (__sv_f32_t, __sv_f32_t, __sv_bool_t); | ||
| 331 | __sv_f32_t _ZGVsMxv_rsqrtf (__sv_f32_t, __sv_bool_t); | 338 | __sv_f32_t _ZGVsMxv_rsqrtf (__sv_f32_t, __sv_bool_t); |
| 332 | __sv_f32_t _ZGVsMxv_sinf (__sv_f32_t, __sv_bool_t); | 339 | __sv_f32_t _ZGVsMxv_sinf (__sv_f32_t, __sv_bool_t); |
| 333 | __sv_f32_t _ZGVsMxv_sinhf (__sv_f32_t, __sv_bool_t); | 340 | __sv_f32_t _ZGVsMxv_sinhf (__sv_f32_t, __sv_bool_t); |
| ... | @@ -368,6 +375,7 @@ __sv_f64_t _ZGVsMxv_log2 (__sv_f64_t, __sv_bool_t); | ... | @@ -368,6 +375,7 @@ __sv_f64_t _ZGVsMxv_log2 (__sv_f64_t, __sv_bool_t); |
| 368 | __sv_f64_t _ZGVsMxv_log2p1 (__sv_f64_t, __sv_bool_t); | 375 | __sv_f64_t _ZGVsMxv_log2p1 (__sv_f64_t, __sv_bool_t); |
| 369 | __sv_f64_t _ZGVsMxv_logp1 (__sv_f64_t, __sv_bool_t); | 376 | __sv_f64_t _ZGVsMxv_logp1 (__sv_f64_t, __sv_bool_t); |
| 370 | __sv_f64_t _ZGVsMxvv_pow (__sv_f64_t, __sv_f64_t, __sv_bool_t); | 377 | __sv_f64_t _ZGVsMxvv_pow (__sv_f64_t, __sv_f64_t, __sv_bool_t); |
| 378 | __sv_f64_t _ZGVsMxvv_powr (__sv_f64_t, __sv_f64_t, __sv_bool_t); | ||
| 371 | __sv_f64_t _ZGVsMxv_rsqrt (__sv_f64_t, __sv_bool_t); | 379 | __sv_f64_t _ZGVsMxv_rsqrt (__sv_f64_t, __sv_bool_t); |
| 372 | __sv_f64_t _ZGVsMxv_sin (__sv_f64_t, __sv_bool_t); | 380 | __sv_f64_t _ZGVsMxv_sin (__sv_f64_t, __sv_bool_t); |
| 373 | __sv_f64_t _ZGVsMxv_sinh (__sv_f64_t, __sv_bool_t); | 381 | __sv_f64_t _ZGVsMxv_sinh (__sv_f64_t, __sv_bool_t); |
lib/libc/include/aarch64-linux-gnu/bits/struct_stat.h deleted-127| ... | @@ -1,127 +0,0 @@ | ||
| 1 | /* Definition for struct stat. | ||
| 2 | Copyright (C) 2020-2026 Free Software Foundation, Inc. | ||
| 3 | This file is part of the GNU C Library. | ||
| 4 | |||
| 5 | The GNU C Library is free software; you can redistribute it and/or | ||
| 6 | modify it under the terms of the GNU Lesser General Public | ||
| 7 | License as published by the Free Software Foundation; either | ||
| 8 | version 2.1 of the License, or (at your option) any later version. | ||
| 9 | |||
| 10 | The GNU C Library is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 13 | Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public | ||
| 16 | License along with the GNU C Library. If not, see | ||
| 17 | <https://www.gnu.org/licenses/>. */ | ||
| 18 | |||
| 19 | #if !defined _SYS_STAT_H && !defined _FCNTL_H | ||
| 20 | # error "Never include <bits/struct_stat.h> directly; use <sys/stat.h> instead." | ||
| 21 | #endif | ||
| 22 | |||
| 23 | #ifndef _BITS_STRUCT_STAT_H | ||
| 24 | #define _BITS_STRUCT_STAT_H	1 | ||
| 25 | |||
| 26 | #include <bits/endian.h> | ||
| 27 | #include <bits/wordsize.h> | ||
| 28 | |||
| 29 | #if defined __USE_FILE_OFFSET64 | ||
| 30 | # define __field64(type, type64, name) type64 name | ||
| 31 | #elif __WORDSIZE == 64 || defined __INO_T_MATCHES_INO64_T | ||
| 32 | # if defined __INO_T_MATCHES_INO64_T && !defined __OFF_T_MATCHES_OFF64_T | ||
| 33 | # error "ino_t and off_t must both be the same type" | ||
| 34 | # endif | ||
| 35 | # define __field64(type, type64, name) type name | ||
| 36 | #elif __BYTE_ORDER == __LITTLE_ENDIAN | ||
| 37 | # define __field64(type, type64, name) \ | ||
| 38 | type name __attribute__((__aligned__ (__alignof__ (type64)))); int __##name##_pad | ||
| 39 | #else | ||
| 40 | # define __field64(type, type64, name) \ | ||
| 41 | int __##name##_pad __attribute__((__aligned__ (__alignof__ (type64)))); type name | ||
| 42 | #endif | ||
| 43 | |||
| 44 | struct stat | ||
| 45 | { | ||
| 46 | __dev_t st_dev;		/* Device. */ | ||
| 47 | __field64(__ino_t, __ino64_t, st_ino); /* File serial number. */ | ||
| 48 | __mode_t st_mode;		/* File mode. */ | ||
| 49 | __nlink_t st_nlink;		/* Link count. */ | ||
| 50 | __uid_t st_uid;		/* User ID of the file's owner.	*/ | ||
| 51 | __gid_t st_gid;		/* Group ID of the file's group.*/ | ||
| 52 | __dev_t st_rdev;		/* Device number, if device. */ | ||
| 53 | __dev_t __pad1; | ||
| 54 | __field64(__off_t, __off64_t, st_size); /* Size of file, in bytes. */ | ||
| 55 | __blksize_t st_blksize;	/* Optimal block size for I/O. */ | ||
| 56 | int __pad2; | ||
| 57 | __field64(__blkcnt_t, __blkcnt64_t, st_blocks); /* 512-byte blocks */ | ||
| 58 | #ifdef __USE_XOPEN2K8 | ||
| 59 | /* Nanosecond resolution timestamps are stored in a format | ||
| 60 | equivalent to 'struct timespec'. This is the type used | ||
| 61 | whenever possible but the Unix namespace rules do not allow the | ||
| 62 | identifier 'timespec' to appear in the <sys/stat.h> header. | ||
| 63 | Therefore we have to handle the use of this header in strictly | ||
| 64 | standard-compliant sources special. */ | ||
| 65 | struct timespec st_atim;		/* Time of last access. */ | ||
| 66 | struct timespec st_mtim;		/* Time of last modification. */ | ||
| 67 | struct timespec st_ctim;		/* Time of last status change. */ | ||
| 68 | # define st_atime st_atim.tv_sec	/* Backward compatibility. */ | ||
| 69 | # define st_mtime st_mtim.tv_sec | ||
| 70 | # define st_ctime st_ctim.tv_sec | ||
| 71 | #else | ||
| 72 | __time_t st_atime;			/* Time of last access. */ | ||
| 73 | unsigned long int st_atimensec;	/* Nscecs of last access. */ | ||
| 74 | __time_t st_mtime;			/* Time of last modification. */ | ||
| 75 | unsigned long int st_mtimensec;	/* Nsecs of last modification. */ | ||
| 76 | __time_t st_ctime;			/* Time of last status change. */ | ||
| 77 | unsigned long int st_ctimensec;	/* Nsecs of last status change. */ | ||
| 78 | #endif | ||
| 79 | int __glibc_reserved[2]; | ||
| 80 | }; | ||
| 81 | |||
| 82 | #undef __field64 | ||
| 83 | |||
| 84 | #ifdef __USE_LARGEFILE64 | ||
| 85 | struct stat64 | ||
| 86 | { | ||
| 87 | __dev_t st_dev;		/* Device. */ | ||
| 88 | __ino64_t st_ino;		/* File serial number.	*/ | ||
| 89 | __mode_t st_mode;		/* File mode. */ | ||
| 90 | __nlink_t st_nlink;		/* Link count. */ | ||
| 91 | __uid_t st_uid;		/* User ID of the file's owner.	*/ | ||
| 92 | __gid_t st_gid;		/* Group ID of the file's group.*/ | ||
| 93 | __dev_t st_rdev;		/* Device number, if device. */ | ||
| 94 | __dev_t __pad1; | ||
| 95 | __off64_t st_size;		/* Size of file, in bytes. */ | ||
| 96 | __blksize_t st_blksize;	/* Optimal block size for I/O. */ | ||
| 97 | int __pad2; | ||
| 98 | __blkcnt64_t st_blocks;	/* Nr. 512-byte blocks allocated. */ | ||
| 99 | #ifdef __USE_XOPEN2K8 | ||
| 100 | /* Nanosecond resolution timestamps are stored in a format | ||
| 101 | equivalent to 'struct timespec'. This is the type used | ||
| 102 | whenever possible but the Unix namespace rules do not allow the | ||
| 103 | identifier 'timespec' to appear in the <sys/stat.h> header. | ||
| 104 | Therefore we have to handle the use of this header in strictly | ||
| 105 | standard-compliant sources special. */ | ||
| 106 | struct timespec st_atim;		/* Time of last access. */ | ||
| 107 | struct timespec st_mtim;		/* Time of last modification. */ | ||
| 108 | struct timespec st_ctim;		/* Time of last status change. */ | ||
| 109 | #else | ||
| 110 | __time_t st_atime;			/* Time of last access. */ | ||
| 111 | unsigned long int st_atimensec;	/* Nscecs of last access. */ | ||
| 112 | __time_t st_mtime;			/* Time of last modification. */ | ||
| 113 | unsigned long int st_mtimensec;	/* Nsecs of last modification. */ | ||
| 114 | __time_t st_ctime;			/* Time of last status change. */ | ||
| 115 | unsigned long int st_ctimensec;	/* Nsecs of last status change. */ | ||
| 116 | #endif | ||
| 117 | int __glibc_reserved[2]; | ||
| 118 | }; | ||
| 119 | #endif | ||
| 120 | |||
| 121 | /* Tell code we have these members. */ | ||
| 122 | #define	_STATBUF_ST_BLKSIZE | ||
| 123 | #define _STATBUF_ST_RDEV | ||
| 124 | /* Nanosecond resolution time values are supported. */ | ||
| 125 | #define _STATBUF_ST_NSEC | ||
| 126 | |||
| 127 | #endif /* _BITS_STRUCT_STAT_H */ | ||
| \ No newline at end of file | |||
lib/libc/include/aarch64-linux-gnu/bits/timesize.h deleted-20| ... | @@ -1,20 +0,0 @@ | ||
| 1 | /* Bit size of the time_t type at glibc build time, general case. | ||
| 2 | Copyright (C) 2018-2026 Free Software Foundation, Inc. | ||
| 3 | This file is part of the GNU C Library. | ||
| 4 | |||
| 5 | The GNU C Library is free software; you can redistribute it and/or | ||
| 6 | modify it under the terms of the GNU Lesser General Public | ||
| 7 | License as published by the Free Software Foundation; either | ||
| 8 | version 2.1 of the License, or (at your option) any later version. | ||
| 9 | |||
| 10 | The GNU C Library is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 13 | Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public | ||
| 16 | License along with the GNU C Library; if not, see | ||
| 17 | <https://www.gnu.org/licenses/>. */ | ||
| 18 | |||
| 19 | /* Size in bits of the 'time_t' type of the default ABI. */ | ||
| 20 | #define __TIMESIZE	64 | ||
| \ No newline at end of file | |||
lib/libc/include/aarch64-linux-gnu/finclude/math-vector-fortran.h+80-78| ... | @@ -16,81 +16,83 @@ | ... | @@ -16,81 +16,83 @@ |
| 16 | ! License along with the GNU C Library; if not, see | 16 | ! License along with the GNU C Library; if not, see |
| 17 | ! <https://www.gnu.org/licenses/>. | 17 | ! <https://www.gnu.org/licenses/>. |
| 18 | 18 | ||
| 19 | !GCC$ builtin (acos) attributes simd (notinbranch) | ||
| 20 | !GCC$ builtin (acosf) attributes simd (notinbranch) | ||
| 21 | !GCC$ builtin (acosh) attributes simd (notinbranch) | ||
| 22 | !GCC$ builtin (acoshf) attributes simd (notinbranch) | ||
| 23 | !GCC$ builtin (acospi) attributes simd (notinbranch) | ||
| 24 | !GCC$ builtin (acospif) attributes simd (notinbranch) | ||
| 25 | !GCC$ builtin (asin) attributes simd (notinbranch) | ||
| 26 | !GCC$ builtin (asinf) attributes simd (notinbranch) | ||
| 27 | !GCC$ builtin (asinh) attributes simd (notinbranch) | ||
| 28 | !GCC$ builtin (asinhf) attributes simd (notinbranch) | ||
| 29 | !GCC$ builtin (asinpi) attributes simd (notinbranch) | ||
| 30 | !GCC$ builtin (asinpif) attributes simd (notinbranch) | ||
| 31 | !GCC$ builtin (atan) attributes simd (notinbranch) | ||
| 32 | !GCC$ builtin (atan2) attributes simd (notinbranch) | ||
| 33 | !GCC$ builtin (atan2f) attributes simd (notinbranch) | ||
| 34 | !GCC$ builtin (atan2pi) attributes simd (notinbranch) | ||
| 35 | !GCC$ builtin (atan2pif) attributes simd (notinbranch) | ||
| 36 | !GCC$ builtin (atanf) attributes simd (notinbranch) | ||
| 37 | !GCC$ builtin (atanh) attributes simd (notinbranch) | ||
| 38 | !GCC$ builtin (atanhf) attributes simd (notinbranch) | ||
| 39 | !GCC$ builtin (atanpi) attributes simd (notinbranch) | ||
| 40 | !GCC$ builtin (atanpif) attributes simd (notinbranch) | ||
| 41 | !GCC$ builtin (cbrt) attributes simd (notinbranch) | ||
| 42 | !GCC$ builtin (cbrtf) attributes simd (notinbranch) | ||
| 43 | !GCC$ builtin (cos) attributes simd (notinbranch) | ||
| 44 | !GCC$ builtin (cosf) attributes simd (notinbranch) | ||
| 45 | !GCC$ builtin (cosh) attributes simd (notinbranch) | ||
| 46 | !GCC$ builtin (coshf) attributes simd (notinbranch) | ||
| 47 | !GCC$ builtin (cospi) attributes simd (notinbranch) | ||
| 48 | !GCC$ builtin (cospif) attributes simd (notinbranch) | ||
| 49 | !GCC$ builtin (erf) attributes simd (notinbranch) | ||
| 50 | !GCC$ builtin (erfc) attributes simd (notinbranch) | ||
| 51 | !GCC$ builtin (erfcf) attributes simd (notinbranch) | ||
| 52 | !GCC$ builtin (erff) attributes simd (notinbranch) | ||
| 53 | !GCC$ builtin (exp) attributes simd (notinbranch) | ||
| 54 | !GCC$ builtin (exp10) attributes simd (notinbranch) | ||
| 55 | !GCC$ builtin (exp10f) attributes simd (notinbranch) | ||
| 56 | !GCC$ builtin (exp10m1) attributes simd (notinbranch) | ||
| 57 | !GCC$ builtin (exp10m1f) attributes simd (notinbranch) | ||
| 58 | !GCC$ builtin (exp2) attributes simd (notinbranch) | ||
| 59 | !GCC$ builtin (exp2f) attributes simd (notinbranch) | ||
| 60 | !GCC$ builtin (exp2m1) attributes simd (notinbranch) | ||
| 61 | !GCC$ builtin (exp2m1f) attributes simd (notinbranch) | ||
| 62 | !GCC$ builtin (expf) attributes simd (notinbranch) | ||
| 63 | !GCC$ builtin (expm1) attributes simd (notinbranch) | ||
| 64 | !GCC$ builtin (expm1f) attributes simd (notinbranch) | ||
| 65 | !GCC$ builtin (hypot) attributes simd (notinbranch) | ||
| 66 | !GCC$ builtin (hypotf) attributes simd (notinbranch) | ||
| 67 | !GCC$ builtin (log) attributes simd (notinbranch) | ||
| 68 | !GCC$ builtin (log10) attributes simd (notinbranch) | ||
| 69 | !GCC$ builtin (log10f) attributes simd (notinbranch) | ||
| 70 | !GCC$ builtin (log10p1) attributes simd (notinbranch) | ||
| 71 | !GCC$ builtin (log10p1f) attributes simd (notinbranch) | ||
| 72 | !GCC$ builtin (log1p) attributes simd (notinbranch) | ||
| 73 | !GCC$ builtin (log1pf) attributes simd (notinbranch) | ||
| 74 | !GCC$ builtin (log2) attributes simd (notinbranch) | ||
| 75 | !GCC$ builtin (log2f) attributes simd (notinbranch) | ||
| 76 | !GCC$ builtin (log2p1) attributes simd (notinbranch) | ||
| 77 | !GCC$ builtin (log2p1f) attributes simd (notinbranch) | ||
| 78 | !GCC$ builtin (logf) attributes simd (notinbranch) | ||
| 79 | !GCC$ builtin (logp1) attributes simd (notinbranch) | ||
| 80 | !GCC$ builtin (logp1f) attributes simd (notinbranch) | ||
| 81 | !GCC$ builtin (pow) attributes simd (notinbranch) | ||
| 82 | !GCC$ builtin (powf) attributes simd (notinbranch) | ||
| 83 | !GCC$ builtin (rsqrt) attributes simd (notinbranch) | ||
| 84 | !GCC$ builtin (rsqrtf) attributes simd (notinbranch) | ||
| 85 | !GCC$ builtin (sin) attributes simd (notinbranch) | ||
| 86 | !GCC$ builtin (sinf) attributes simd (notinbranch) | ||
| 87 | !GCC$ builtin (sinh) attributes simd (notinbranch) | ||
| 88 | !GCC$ builtin (sinhf) attributes simd (notinbranch) | ||
| 89 | !GCC$ builtin (sinpi) attributes simd (notinbranch) | ||
| 90 | !GCC$ builtin (sinpif) attributes simd (notinbranch) | ||
| 91 | !GCC$ builtin (tan) attributes simd (notinbranch) | ||
| 92 | !GCC$ builtin (tanf) attributes simd (notinbranch) | ||
| 93 | !GCC$ builtin (tanh) attributes simd (notinbranch) | ||
| 94 | !GCC$ builtin (tanhf) attributes simd (notinbranch) | ||
| 95 | !GCC$ builtin (tanpi) attributes simd (notinbranch) | ||
| 96 | !GCC$ builtin (tanpif) attributes simd (notinbranch) | ||
| \ No newline at end of file | |||
| 19 | !GCC$ builtin (acos) attributes simd (notinbranch) if('fastmath') | ||
| 20 | !GCC$ builtin (acosf) attributes simd (notinbranch) if('fastmath') | ||
| 21 | !GCC$ builtin (acosh) attributes simd (notinbranch) if('fastmath') | ||
| 22 | !GCC$ builtin (acoshf) attributes simd (notinbranch) if('fastmath') | ||
| 23 | !GCC$ builtin (acospi) attributes simd (notinbranch) if('fastmath') | ||
| 24 | !GCC$ builtin (acospif) attributes simd (notinbranch) if('fastmath') | ||
| 25 | !GCC$ builtin (asin) attributes simd (notinbranch) if('fastmath') | ||
| 26 | !GCC$ builtin (asinf) attributes simd (notinbranch) if('fastmath') | ||
| 27 | !GCC$ builtin (asinh) attributes simd (notinbranch) if('fastmath') | ||
| 28 | !GCC$ builtin (asinhf) attributes simd (notinbranch) if('fastmath') | ||
| 29 | !GCC$ builtin (asinpi) attributes simd (notinbranch) if('fastmath') | ||
| 30 | !GCC$ builtin (asinpif) attributes simd (notinbranch) if('fastmath') | ||
| 31 | !GCC$ builtin (atan) attributes simd (notinbranch) if('fastmath') | ||
| 32 | !GCC$ builtin (atan2) attributes simd (notinbranch) if('fastmath') | ||
| 33 | !GCC$ builtin (atan2f) attributes simd (notinbranch) if('fastmath') | ||
| 34 | !GCC$ builtin (atan2pi) attributes simd (notinbranch) if('fastmath') | ||
| 35 | !GCC$ builtin (atan2pif) attributes simd (notinbranch) if('fastmath') | ||
| 36 | !GCC$ builtin (atanf) attributes simd (notinbranch) if('fastmath') | ||
| 37 | !GCC$ builtin (atanh) attributes simd (notinbranch) if('fastmath') | ||
| 38 | !GCC$ builtin (atanhf) attributes simd (notinbranch) if('fastmath') | ||
| 39 | !GCC$ builtin (atanpi) attributes simd (notinbranch) if('fastmath') | ||
| 40 | !GCC$ builtin (atanpif) attributes simd (notinbranch) if('fastmath') | ||
| 41 | !GCC$ builtin (cbrt) attributes simd (notinbranch) if('fastmath') | ||
| 42 | !GCC$ builtin (cbrtf) attributes simd (notinbranch) if('fastmath') | ||
| 43 | !GCC$ builtin (cos) attributes simd (notinbranch) if('fastmath') | ||
| 44 | !GCC$ builtin (cosf) attributes simd (notinbranch) if('fastmath') | ||
| 45 | !GCC$ builtin (cosh) attributes simd (notinbranch) if('fastmath') | ||
| 46 | !GCC$ builtin (coshf) attributes simd (notinbranch) if('fastmath') | ||
| 47 | !GCC$ builtin (cospi) attributes simd (notinbranch) if('fastmath') | ||
| 48 | !GCC$ builtin (cospif) attributes simd (notinbranch) if('fastmath') | ||
| 49 | !GCC$ builtin (erf) attributes simd (notinbranch) if('fastmath') | ||
| 50 | !GCC$ builtin (erfc) attributes simd (notinbranch) if('fastmath') | ||
| 51 | !GCC$ builtin (erfcf) attributes simd (notinbranch) if('fastmath') | ||
| 52 | !GCC$ builtin (erff) attributes simd (notinbranch) if('fastmath') | ||
| 53 | !GCC$ builtin (exp) attributes simd (notinbranch) if('fastmath') | ||
| 54 | !GCC$ builtin (exp10) attributes simd (notinbranch) if('fastmath') | ||
| 55 | !GCC$ builtin (exp10f) attributes simd (notinbranch) if('fastmath') | ||
| 56 | !GCC$ builtin (exp10m1) attributes simd (notinbranch) if('fastmath') | ||
| 57 | !GCC$ builtin (exp10m1f) attributes simd (notinbranch) if('fastmath') | ||
| 58 | !GCC$ builtin (exp2) attributes simd (notinbranch) if('fastmath') | ||
| 59 | !GCC$ builtin (exp2f) attributes simd (notinbranch) if('fastmath') | ||
| 60 | !GCC$ builtin (exp2m1) attributes simd (notinbranch) if('fastmath') | ||
| 61 | !GCC$ builtin (exp2m1f) attributes simd (notinbranch) if('fastmath') | ||
| 62 | !GCC$ builtin (expf) attributes simd (notinbranch) if('fastmath') | ||
| 63 | !GCC$ builtin (expm1) attributes simd (notinbranch) if('fastmath') | ||
| 64 | !GCC$ builtin (expm1f) attributes simd (notinbranch) if('fastmath') | ||
| 65 | !GCC$ builtin (hypot) attributes simd (notinbranch) if('fastmath') | ||
| 66 | !GCC$ builtin (hypotf) attributes simd (notinbranch) if('fastmath') | ||
| 67 | !GCC$ builtin (log) attributes simd (notinbranch) if('fastmath') | ||
| 68 | !GCC$ builtin (log10) attributes simd (notinbranch) if('fastmath') | ||
| 69 | !GCC$ builtin (log10f) attributes simd (notinbranch) if('fastmath') | ||
| 70 | !GCC$ builtin (log10p1) attributes simd (notinbranch) if('fastmath') | ||
| 71 | !GCC$ builtin (log10p1f) attributes simd (notinbranch) if('fastmath') | ||
| 72 | !GCC$ builtin (log1p) attributes simd (notinbranch) if('fastmath') | ||
| 73 | !GCC$ builtin (log1pf) attributes simd (notinbranch) if('fastmath') | ||
| 74 | !GCC$ builtin (log2) attributes simd (notinbranch) if('fastmath') | ||
| 75 | !GCC$ builtin (log2f) attributes simd (notinbranch) if('fastmath') | ||
| 76 | !GCC$ builtin (log2p1) attributes simd (notinbranch) if('fastmath') | ||
| 77 | !GCC$ builtin (log2p1f) attributes simd (notinbranch) if('fastmath') | ||
| 78 | !GCC$ builtin (logf) attributes simd (notinbranch) if('fastmath') | ||
| 79 | !GCC$ builtin (logp1) attributes simd (notinbranch) if('fastmath') | ||
| 80 | !GCC$ builtin (logp1f) attributes simd (notinbranch) if('fastmath') | ||
| 81 | !GCC$ builtin (pow) attributes simd (notinbranch) if('fastmath') | ||
| 82 | !GCC$ builtin (powf) attributes simd (notinbranch) if('fastmath') | ||
| 83 | !GCC$ builtin (powr) attributes simd (notinbranch) if('fastmath') | ||
| 84 | !GCC$ builtin (powrf) attributes simd (notinbranch) if('fastmath') | ||
| 85 | !GCC$ builtin (rsqrt) attributes simd (notinbranch) if('fastmath') | ||
| 86 | !GCC$ builtin (rsqrtf) attributes simd (notinbranch) if('fastmath') | ||
| 87 | !GCC$ builtin (sin) attributes simd (notinbranch) if('fastmath') | ||
| 88 | !GCC$ builtin (sinf) attributes simd (notinbranch) if('fastmath') | ||
| 89 | !GCC$ builtin (sinh) attributes simd (notinbranch) if('fastmath') | ||
| 90 | !GCC$ builtin (sinhf) attributes simd (notinbranch) if('fastmath') | ||
| 91 | !GCC$ builtin (sinpi) attributes simd (notinbranch) if('fastmath') | ||
| 92 | !GCC$ builtin (sinpif) attributes simd (notinbranch) if('fastmath') | ||
| 93 | !GCC$ builtin (tan) attributes simd (notinbranch) if('fastmath') | ||
| 94 | !GCC$ builtin (tanf) attributes simd (notinbranch) if('fastmath') | ||
| 95 | !GCC$ builtin (tanh) attributes simd (notinbranch) if('fastmath') | ||
| 96 | !GCC$ builtin (tanhf) attributes simd (notinbranch) if('fastmath') | ||
| 97 | !GCC$ builtin (tanpi) attributes simd (notinbranch) if('fastmath') | ||
| 98 | !GCC$ builtin (tanpif) attributes simd (notinbranch) if('fastmath') | ||
| \ No newline at end of file | |||
lib/libc/include/aarch64-linux-gnu/gnu/lib-names-lp64.h+1| ... | @@ -24,4 +24,5 @@ | ... | @@ -24,4 +24,5 @@ |
| 24 | #define LIBRESOLV_SO "libresolv.so.2" | 24 | #define LIBRESOLV_SO "libresolv.so.2" |
| 25 | #define LIBRT_SO "librt.so.1" | 25 | #define LIBRT_SO "librt.so.1" |
| 26 | #define LIBTHREAD_DB_SO "libthread_db.so.1" | 26 | #define LIBTHREAD_DB_SO "libthread_db.so.1" |
| 27 | #define LIBUNWIND_SO "libunwind.so.1" | ||
| 27 | #define LIBUTIL_SO "libutil.so.1" | 28 | #define LIBUTIL_SO "libutil.so.1" |
| \ No newline at end of file | |||
lib/libc/include/aarch64-linux-gnu/gnu/lib-names-lp64_be.h+1| ... | @@ -24,4 +24,5 @@ | ... | @@ -24,4 +24,5 @@ |
| 24 | #define LIBRESOLV_SO "libresolv.so.2" | 24 | #define LIBRESOLV_SO "libresolv.so.2" |
| 25 | #define LIBRT_SO "librt.so.1" | 25 | #define LIBRT_SO "librt.so.1" |
| 26 | #define LIBTHREAD_DB_SO "libthread_db.so.1" | 26 | #define LIBTHREAD_DB_SO "libthread_db.so.1" |
| 27 | #define LIBUNWIND_SO "libunwind.so.1" | ||
| 27 | #define LIBUTIL_SO "libutil.so.1" | 28 | #define LIBUTIL_SO "libutil.so.1" |
| \ No newline at end of file | |||
lib/libc/include/arc-linux-gnu/bits/struct_stat.h deleted-127| ... | @@ -1,127 +0,0 @@ | ||
| 1 | /* Definition for struct stat. | ||
| 2 | Copyright (C) 2020-2026 Free Software Foundation, Inc. | ||
| 3 | This file is part of the GNU C Library. | ||
| 4 | |||
| 5 | The GNU C Library is free software; you can redistribute it and/or | ||
| 6 | modify it under the terms of the GNU Lesser General Public | ||
| 7 | License as published by the Free Software Foundation; either | ||
| 8 | version 2.1 of the License, or (at your option) any later version. | ||
| 9 | |||
| 10 | The GNU C Library is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 13 | Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public | ||
| 16 | License along with the GNU C Library. If not, see | ||
| 17 | <https://www.gnu.org/licenses/>. */ | ||
| 18 | |||
| 19 | #if !defined _SYS_STAT_H && !defined _FCNTL_H | ||
| 20 | # error "Never include <bits/struct_stat.h> directly; use <sys/stat.h> instead." | ||
| 21 | #endif | ||
| 22 | |||
| 23 | #ifndef _BITS_STRUCT_STAT_H | ||
| 24 | #define _BITS_STRUCT_STAT_H	1 | ||
| 25 | |||
| 26 | #include <bits/endian.h> | ||
| 27 | #include <bits/wordsize.h> | ||
| 28 | |||
| 29 | #if defined __USE_FILE_OFFSET64 | ||
| 30 | # define __field64(type, type64, name) type64 name | ||
| 31 | #elif __WORDSIZE == 64 || defined __INO_T_MATCHES_INO64_T | ||
| 32 | # if defined __INO_T_MATCHES_INO64_T && !defined __OFF_T_MATCHES_OFF64_T | ||
| 33 | # error "ino_t and off_t must both be the same type" | ||
| 34 | # endif | ||
| 35 | # define __field64(type, type64, name) type name | ||
| 36 | #elif __BYTE_ORDER == __LITTLE_ENDIAN | ||
| 37 | # define __field64(type, type64, name) \ | ||
| 38 | type name __attribute__((__aligned__ (__alignof__ (type64)))); int __##name##_pad | ||
| 39 | #else | ||
| 40 | # define __field64(type, type64, name) \ | ||
| 41 | int __##name##_pad __attribute__((__aligned__ (__alignof__ (type64)))); type name | ||
| 42 | #endif | ||
| 43 | |||
| 44 | struct stat | ||
| 45 | { | ||
| 46 | __dev_t st_dev;		/* Device. */ | ||
| 47 | __field64(__ino_t, __ino64_t, st_ino); /* File serial number. */ | ||
| 48 | __mode_t st_mode;		/* File mode. */ | ||
| 49 | __nlink_t st_nlink;		/* Link count. */ | ||
| 50 | __uid_t st_uid;		/* User ID of the file's owner.	*/ | ||
| 51 | __gid_t st_gid;		/* Group ID of the file's group.*/ | ||
| 52 | __dev_t st_rdev;		/* Device number, if device. */ | ||
| 53 | __dev_t __pad1; | ||
| 54 | __field64(__off_t, __off64_t, st_size); /* Size of file, in bytes. */ | ||
| 55 | __blksize_t st_blksize;	/* Optimal block size for I/O. */ | ||
| 56 | int __pad2; | ||
| 57 | __field64(__blkcnt_t, __blkcnt64_t, st_blocks); /* 512-byte blocks */ | ||
| 58 | #ifdef __USE_XOPEN2K8 | ||
| 59 | /* Nanosecond resolution timestamps are stored in a format | ||
| 60 | equivalent to 'struct timespec'. This is the type used | ||
| 61 | whenever possible but the Unix namespace rules do not allow the | ||
| 62 | identifier 'timespec' to appear in the <sys/stat.h> header. | ||
| 63 | Therefore we have to handle the use of this header in strictly | ||
| 64 | standard-compliant sources special. */ | ||
| 65 | struct timespec st_atim;		/* Time of last access. */ | ||
| 66 | struct timespec st_mtim;		/* Time of last modification. */ | ||
| 67 | struct timespec st_ctim;		/* Time of last status change. */ | ||
| 68 | # define st_atime st_atim.tv_sec	/* Backward compatibility. */ | ||
| 69 | # define st_mtime st_mtim.tv_sec | ||
| 70 | # define st_ctime st_ctim.tv_sec | ||
| 71 | #else | ||
| 72 | __time_t st_atime;			/* Time of last access. */ | ||
| 73 | unsigned long int st_atimensec;	/* Nscecs of last access. */ | ||
| 74 | __time_t st_mtime;			/* Time of last modification. */ | ||
| 75 | unsigned long int st_mtimensec;	/* Nsecs of last modification. */ | ||
| 76 | __time_t st_ctime;			/* Time of last status change. */ | ||
| 77 | unsigned long int st_ctimensec;	/* Nsecs of last status change. */ | ||
| 78 | #endif | ||
| 79 | int __glibc_reserved[2]; | ||
| 80 | }; | ||
| 81 | |||
| 82 | #undef __field64 | ||
| 83 | |||
| 84 | #ifdef __USE_LARGEFILE64 | ||
| 85 | struct stat64 | ||
| 86 | { | ||
| 87 | __dev_t st_dev;		/* Device. */ | ||
| 88 | __ino64_t st_ino;		/* File serial number.	*/ | ||
| 89 | __mode_t st_mode;		/* File mode. */ | ||
| 90 | __nlink_t st_nlink;		/* Link count. */ | ||
| 91 | __uid_t st_uid;		/* User ID of the file's owner.	*/ | ||
| 92 | __gid_t st_gid;		/* Group ID of the file's group.*/ | ||
| 93 | __dev_t st_rdev;		/* Device number, if device. */ | ||
| 94 | __dev_t __pad1; | ||
| 95 | __off64_t st_size;		/* Size of file, in bytes. */ | ||
| 96 | __blksize_t st_blksize;	/* Optimal block size for I/O. */ | ||
| 97 | int __pad2; | ||
| 98 | __blkcnt64_t st_blocks;	/* Nr. 512-byte blocks allocated. */ | ||
| 99 | #ifdef __USE_XOPEN2K8 | ||
| 100 | /* Nanosecond resolution timestamps are stored in a format | ||
| 101 | equivalent to 'struct timespec'. This is the type used | ||
| 102 | whenever possible but the Unix namespace rules do not allow the | ||
| 103 | identifier 'timespec' to appear in the <sys/stat.h> header. | ||
| 104 | Therefore we have to handle the use of this header in strictly | ||
| 105 | standard-compliant sources special. */ | ||
| 106 | struct timespec st_atim;		/* Time of last access. */ | ||
| 107 | struct timespec st_mtim;		/* Time of last modification. */ | ||
| 108 | struct timespec st_ctim;		/* Time of last status change. */ | ||
| 109 | #else | ||
| 110 | __time_t st_atime;			/* Time of last access. */ | ||
| 111 | unsigned long int st_atimensec;	/* Nscecs of last access. */ | ||
| 112 | __time_t st_mtime;			/* Time of last modification. */ | ||
| 113 | unsigned long int st_mtimensec;	/* Nsecs of last modification. */ | ||
| 114 | __time_t st_ctime;			/* Time of last status change. */ | ||
| 115 | unsigned long int st_ctimensec;	/* Nsecs of last status change. */ | ||
| 116 | #endif | ||
| 117 | int __glibc_reserved[2]; | ||
| 118 | }; | ||
| 119 | #endif | ||
| 120 | |||
| 121 | /* Tell code we have these members. */ | ||
| 122 | #define	_STATBUF_ST_BLKSIZE | ||
| 123 | #define _STATBUF_ST_RDEV | ||
| 124 | /* Nanosecond resolution time values are supported. */ | ||
| 125 | #define _STATBUF_ST_NSEC | ||
| 126 | |||
| 127 | #endif /* _BITS_STRUCT_STAT_H */ | ||
| \ No newline at end of file | |||
lib/libc/include/arc-linux-gnu/bits/timesize.h deleted-20| ... | @@ -1,20 +0,0 @@ | ||
| 1 | /* Bit size of the time_t type at glibc build time, general case. | ||
| 2 | Copyright (C) 2018-2026 Free Software Foundation, Inc. | ||
| 3 | This file is part of the GNU C Library. | ||
| 4 | |||
| 5 | The GNU C Library is free software; you can redistribute it and/or | ||
| 6 | modify it under the terms of the GNU Lesser General Public | ||
| 7 | License as published by the Free Software Foundation; either | ||
| 8 | version 2.1 of the License, or (at your option) any later version. | ||
| 9 | |||
| 10 | The GNU C Library is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 13 | Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public | ||
| 16 | License along with the GNU C Library; if not, see | ||
| 17 | <https://www.gnu.org/licenses/>. */ | ||
| 18 | |||
| 19 | /* Size in bits of the 'time_t' type of the default ABI. */ | ||
| 20 | #define __TIMESIZE	64 | ||
| \ No newline at end of file | |||
lib/libc/include/arc-linux-gnu/gnu/lib-names.h+1| ... | @@ -25,6 +25,7 @@ | ... | @@ -25,6 +25,7 @@ |
| 25 | #define LIBRESOLV_SO "libresolv.so.2" | 25 | #define LIBRESOLV_SO "libresolv.so.2" |
| 26 | #define LIBRT_SO "librt.so.1" | 26 | #define LIBRT_SO "librt.so.1" |
| 27 | #define LIBTHREAD_DB_SO "libthread_db.so.1" | 27 | #define LIBTHREAD_DB_SO "libthread_db.so.1" |
| 28 | #define LIBUNWIND_SO "libunwind.so.1" | ||
| 28 | #define LIBUTIL_SO "libutil.so.1" | 29 | #define LIBUTIL_SO "libutil.so.1" |
| 29 | 30 | ||
| 30 | #endif	/* gnu/lib-names.h */ | 31 | #endif	/* gnu/lib-names.h */ |
| \ No newline at end of file | |||
lib/libc/include/csky-linux-gnu/gnu/lib-names.h+2-1| ... | @@ -31,6 +31,7 @@ | ... | @@ -31,6 +31,7 @@ |
| 31 | #define LIBRESOLV_SO "libresolv.so.2" | 31 | #define LIBRESOLV_SO "libresolv.so.2" |
| 32 | #define LIBRT_SO "librt.so.1" | 32 | #define LIBRT_SO "librt.so.1" |
| 33 | #define LIBTHREAD_DB_SO "libthread_db.so.1" | 33 | #define LIBTHREAD_DB_SO "libthread_db.so.1" |
| 34 | #define LIBUNWIND_SO "libunwind.so.1" | ||
| 34 | #define LIBUTIL_SO "libutil.so.1" | 35 | #define LIBUTIL_SO "libutil.so.1" |
| 35 | 36 | ||
| 36 | #endif	/* gnu/lib-names.h */ | 37 | #endif	/* gnu/lib-names.h */ |
| \ No newline at end of file | |||
lib/libc/include/generic-glibc/assert.h+19-9| ... | @@ -52,13 +52,12 @@ | ... | @@ -52,13 +52,12 @@ |
| 52 | comma in the initializer list, can be passed to assert. This | 52 | comma in the initializer list, can be passed to assert. This |
| 53 | depends on support for variadic macros (added in C99 and GCC 2.95), | 53 | depends on support for variadic macros (added in C99 and GCC 2.95), |
| 54 | and on support for _Bool (added in C99 and GCC 3.0) in order to | 54 | and on support for _Bool (added in C99 and GCC 3.0) in order to |
| 55 | validate that only a single expression is passed as an argument, | 55 | validate that only a single expression is passed as an argument. */ |
| 56 | and is currently implemented only for C. */ | 56 | #if ((__GLIBC_USE (ISOC23)						\ |
| 57 | #if (__GLIBC_USE (ISOC23)						\ | 57 | && (defined __GNUC__						\ |
| 58 | && (defined __GNUC__						\ | 58 | 	 ? __GNUC_PREREQ (3, 0)					\ |
| 59 | 	 ? __GNUC_PREREQ (3, 0)						\ | 59 | 	 : defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L))	\ |
| 60 | 	 : defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)	\ | 60 | || (defined __cplusplus && __cplusplus > 202302L)) |
| 61 | && !defined __cplusplus) | ||
| 62 | # define __ASSERT_VARIADIC 1 | 61 | # define __ASSERT_VARIADIC 1 |
| 63 | #else | 62 | #else |
| 64 | # define __ASSERT_VARIADIC 0 | 63 | # define __ASSERT_VARIADIC 0 |
| ... | @@ -108,7 +107,7 @@ extern void __assert (const char *__assertion, const char *__file, int __line) | ... | @@ -108,7 +107,7 @@ extern void __assert (const char *__assertion, const char *__file, int __line) |
| 108 | __THROW __attribute__ ((__noreturn__)) __COLD; | 107 | __THROW __attribute__ ((__noreturn__)) __COLD; |
| 109 | 108 | ||
| 110 | 109 | ||
| 111 | # if __ASSERT_VARIADIC | 110 | # if __ASSERT_VARIADIC && !defined __cplusplus |
| 112 | /* This function is not defined and is not called outside of an | 111 | /* This function is not defined and is not called outside of an |
| 113 | unevaluated sizeof, but serves to verify that the argument to | 112 | unevaluated sizeof, but serves to verify that the argument to |
| 114 | assert is a single expression. */ | 113 | assert is a single expression. */ |
| ... | @@ -131,11 +130,22 @@ __END_DECLS | ... | @@ -131,11 +130,22 @@ __END_DECLS |
| 131 | # define __ASSERT_FILE __FILE__ | 130 | # define __ASSERT_FILE __FILE__ |
| 132 | # define __ASSERT_LINE __LINE__ | 131 | # define __ASSERT_LINE __LINE__ |
| 133 | # endif | 132 | # endif |
| 134 | # define assert(expr)							\ | 133 | # if __ASSERT_VARIADIC |
| 134 | /* The first test of __VA_ARGS__ evaluates it without converting scoped | ||
| 135 | enumeration values to bool, and the second test checks that it is a | ||
| 136 | single expression without evaluating it. */ | ||
| 137 | # define assert(...)							\ | ||
| 138 | ((__VA_ARGS__)							\ | ||
| 139 | ? void (1 ? 1 : bool (__VA_ARGS__))				\ | ||
| 140 | : __assert_fail (#__VA_ARGS__, __ASSERT_FILE, __ASSERT_LINE,	\ | ||
| 141 | __ASSERT_FUNCTION)) | ||
| 142 | # else | ||
| 143 | # define assert(expr)						\ | ||
| 135 | (static_cast <bool> (expr)						\ | 144 | (static_cast <bool> (expr)						\ |
| 136 | ? void (0)							\ | 145 | ? void (0)							\ |
| 137 | : __assert_fail (#expr, __ASSERT_FILE, __ASSERT_LINE, \ | 146 | : __assert_fail (#expr, __ASSERT_FILE, __ASSERT_LINE, \ |
| 138 | __ASSERT_FUNCTION)) | 147 | __ASSERT_FUNCTION)) |
| 148 | # endif | ||
| 139 | # elif !defined __GNUC__ || defined __STRICT_ANSI__ | 149 | # elif !defined __GNUC__ || defined __STRICT_ANSI__ |
| 140 | # if __ASSERT_VARIADIC | 150 | # if __ASSERT_VARIADIC |
| 141 | # define assert(...)							\ | 151 | # define assert(...)							\ |
lib/libc/include/generic-glibc/bits/cloexec.h created+1| ... | @@ -0,0 +1 @@ | ||
| 1 | #define __O_CLOEXEC 02000000 | ||
| \ No newline at end of file | |||
lib/libc/include/generic-glibc/bits/fcntl-linux.h+11-10| ... | @@ -81,9 +81,7 @@ | ... | @@ -81,9 +81,7 @@ |
| 81 | #ifndef __O_NOFOLLOW | 81 | #ifndef __O_NOFOLLOW |
| 82 | # define __O_NOFOLLOW	0400000 | 82 | # define __O_NOFOLLOW	0400000 |
| 83 | #endif | 83 | #endif |
| 84 | #ifndef __O_CLOEXEC | 84 | #include <bits/cloexec.h> |
| 85 | # define __O_CLOEXEC 02000000 | ||
| 86 | #endif | ||
| 87 | #ifndef __O_DIRECT | 85 | #ifndef __O_DIRECT |
| 88 | # define __O_DIRECT	 040000 | 86 | # define __O_DIRECT	 040000 |
| 89 | #endif | 87 | #endif |
| ... | @@ -176,8 +174,8 @@ | ... | @@ -176,8 +174,8 @@ |
| 176 | #endif | 174 | #endif |
| 177 | 175 | ||
| 178 | #if defined __USE_UNIX98 || defined __USE_XOPEN2K8 | 176 | #if defined __USE_UNIX98 || defined __USE_XOPEN2K8 |
| 179 | # define F_SETOWN	__F_SETOWN /* Get owner (process receiving SIGIO). */ | 177 | # define F_SETOWN	__F_SETOWN /* Set owner (process receiving SIGIO). */ |
| 180 | # define F_GETOWN	__F_GETOWN /* Set owner (process receiving SIGIO). */ | 178 | # define F_GETOWN	__F_GETOWN /* Get owner (process receiving SIGIO). */ |
| 181 | #endif | 179 | #endif |
| 182 | 180 | ||
| 183 | #ifndef __F_SETSIG | 181 | #ifndef __F_SETSIG |
| ... | @@ -185,15 +183,15 @@ | ... | @@ -185,15 +183,15 @@ |
| 185 | # define __F_GETSIG	11	/* Get number of signal to be sent. */ | 183 | # define __F_GETSIG	11	/* Get number of signal to be sent. */ |
| 186 | #endif | 184 | #endif |
| 187 | #ifndef __F_SETOWN_EX | 185 | #ifndef __F_SETOWN_EX |
| 188 | # define __F_SETOWN_EX	15	/* Get owner (thread receiving SIGIO). */ | 186 | # define __F_SETOWN_EX	15	/* Set owner (thread receiving SIGIO). */ |
| 189 | # define __F_GETOWN_EX	16	/* Set owner (thread receiving SIGIO). */ | 187 | # define __F_GETOWN_EX	16	/* Get owner (thread receiving SIGIO). */ |
| 190 | #endif | 188 | #endif |
| 191 | 189 | ||
| 192 | #ifdef __USE_GNU | 190 | #ifdef __USE_GNU |
| 193 | # define F_SETSIG	__F_SETSIG	/* Set number of signal to be sent. */ | 191 | # define F_SETSIG	__F_SETSIG	/* Set number of signal to be sent. */ |
| 194 | # define F_GETSIG	__F_GETSIG	/* Get number of signal to be sent. */ | 192 | # define F_GETSIG	__F_GETSIG	/* Get number of signal to be sent. */ |
| 195 | # define F_SETOWN_EX	__F_SETOWN_EX	/* Get owner (thread receiving SIGIO). */ | 193 | # define F_SETOWN_EX	__F_SETOWN_EX	/* Set owner (thread receiving SIGIO). */ |
| 196 | # define F_GETOWN_EX	__F_GETOWN_EX	/* Set owner (thread receiving SIGIO). */ | 194 | # define F_GETOWN_EX	__F_GETOWN_EX	/* Get owner (thread receiving SIGIO). */ |
| 197 | #endif | 195 | #endif |
| 198 | 196 | ||
| 199 | #ifdef __USE_GNU | 197 | #ifdef __USE_GNU |
| ... | @@ -203,7 +201,7 @@ | ... | @@ -203,7 +201,7 @@ |
| 203 | # define F_DUPFD_QUERY 1027 /* Compare two file descriptors for sameness. */ | 201 | # define F_DUPFD_QUERY 1027 /* Compare two file descriptors for sameness. */ |
| 204 | # define F_CREATED_QUERY 1028 /* Was the file just created? */ | 202 | # define F_CREATED_QUERY 1028 /* Was the file just created? */ |
| 205 | # define F_SETPIPE_SZ	1031	/* Set pipe page size array. */ | 203 | # define F_SETPIPE_SZ	1031	/* Set pipe page size array. */ |
| 206 | # define F_GETPIPE_SZ	1032	/* Set pipe page size array. */ | 204 | # define F_GETPIPE_SZ	1032	/* Get pipe page size array. */ |
| 207 | # define F_ADD_SEALS	1033	/* Add seals to file. */ | 205 | # define F_ADD_SEALS	1033	/* Add seals to file. */ |
| 208 | # define F_GET_SEALS	1034	/* Get seals for file. */ | 206 | # define F_GET_SEALS	1034	/* Get seals for file. */ |
| 209 | /* Set / get write life time hints. */ | 207 | /* Set / get write life time hints. */ |
| ... | @@ -211,6 +209,8 @@ | ... | @@ -211,6 +209,8 @@ |
| 211 | # define F_SET_RW_HINT	1036 | 209 | # define F_SET_RW_HINT	1036 |
| 212 | # define F_GET_FILE_RW_HINT	1037 | 210 | # define F_GET_FILE_RW_HINT	1037 |
| 213 | # define F_SET_FILE_RW_HINT	1038 | 211 | # define F_SET_FILE_RW_HINT	1038 |
| 212 | # define F_GETDELEG	1039	/* Get delegation. */ | ||
| 213 | # define F_SETDELEG	1040	/* Set delegation. */ | ||
| 214 | #endif | 214 | #endif |
| 215 | #ifdef __USE_XOPEN2K8 | 215 | #ifdef __USE_XOPEN2K8 |
| 216 | # define F_DUPFD_CLOEXEC 1030	/* Duplicate file descriptor with | 216 | # define F_DUPFD_CLOEXEC 1030	/* Duplicate file descriptor with |
| ... | @@ -221,6 +221,7 @@ | ... | @@ -221,6 +221,7 @@ |
| 221 | #define FD_CLOEXEC	1	/* Actually anything with low bit set goes */ | 221 | #define FD_CLOEXEC	1	/* Actually anything with low bit set goes */ |
| 222 | #ifdef __USE_GNU | 222 | #ifdef __USE_GNU |
| 223 | # define FD_PIDFS_ROOT	-10002	/* Root of the pidfs filesystem */ | 223 | # define FD_PIDFS_ROOT	-10002	/* Root of the pidfs filesystem */ |
| 224 | # define FD_NSFS_ROOT	-10003	/* Root of the nsfs filesystem */ | ||
| 224 | #endif | 225 | #endif |
| 225 | 226 | ||
| 226 | #ifndef F_RDLCK | 227 | #ifndef F_RDLCK |
lib/libc/include/generic-glibc/bits/libm-simd-decl-stubs.h+11| ... | @@ -99,6 +99,17 @@ | ... | @@ -99,6 +99,17 @@ |
| 99 | #define __DECL_SIMD_powf64x | 99 | #define __DECL_SIMD_powf64x |
| 100 | #define __DECL_SIMD_powf128x | 100 | #define __DECL_SIMD_powf128x |
| 101 | 101 | ||
| 102 | #define __DECL_SIMD_powr | ||
| 103 | #define __DECL_SIMD_powrf | ||
| 104 | #define __DECL_SIMD_powrl | ||
| 105 | #define __DECL_SIMD_powrf16 | ||
| 106 | #define __DECL_SIMD_powrf32 | ||
| 107 | #define __DECL_SIMD_powrf64 | ||
| 108 | #define __DECL_SIMD_powrf128 | ||
| 109 | #define __DECL_SIMD_powrf32x | ||
| 110 | #define __DECL_SIMD_powrf64x | ||
| 111 | #define __DECL_SIMD_powrf128x | ||
| 112 | |||
| 102 | #define __DECL_SIMD_acos | 113 | #define __DECL_SIMD_acos |
| 103 | #define __DECL_SIMD_acosf | 114 | #define __DECL_SIMD_acosf |
| 104 | #define __DECL_SIMD_acosl | 115 | #define __DECL_SIMD_acosl |
lib/libc/include/generic-glibc/bits/long-double.h+3-6| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | /* Properties of long double type. MIPS version. | 1 | /* Properties of long double type. ldbl-128 version. |
| 2 | Copyright (C) 2016-2026 Free Software Foundation, Inc. | 2 | Copyright (C) 2016-2026 Free Software Foundation, Inc. |
| 3 | This file is part of the GNU C Library. | 3 | This file is part of the GNU C Library. |
| 4 | 4 | ||
| ... | @@ -16,9 +16,6 @@ | ... | @@ -16,9 +16,6 @@ |
| 16 | License along with the GNU C Library; if not, see | 16 | License along with the GNU C Library; if not, see |
| 17 | <https://www.gnu.org/licenses/>. */ | 17 | <https://www.gnu.org/licenses/>. */ |
| 18 | 18 | ||
| 19 | #include <sgidefs.h> | 19 | /* long double is distinct from double, so there is nothing to |
| 20 | 20 | define here. */ | |
| 21 | #if !defined __NO_LONG_DOUBLE_MATH && _MIPS_SIM == _ABIO32 | ||
| 22 | # define __NO_LONG_DOUBLE_MATH	1 | ||
| 23 | #endif | ||
| 24 | #define __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI 0 | 21 | #define __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI 0 |
| \ No newline at end of file | |||
lib/libc/include/generic-glibc/bits/mathcalls.h+1| ... | @@ -197,6 +197,7 @@ __MATHCALL (compoundn,, (_Mdouble_ __x, long long int __y)); | ... | @@ -197,6 +197,7 @@ __MATHCALL (compoundn,, (_Mdouble_ __x, long long int __y)); |
| 197 | __MATHCALL (pown,, (_Mdouble_ __x, long long int __y)); | 197 | __MATHCALL (pown,, (_Mdouble_ __x, long long int __y)); |
| 198 | 198 | ||
| 199 | /* Return X to the Y power. */ | 199 | /* Return X to the Y power. */ |
| 200 | __MATHCALL_VEC (powr,, (_Mdouble_ __x, _Mdouble_ __y)); | ||
| 200 | __MATHCALL (powr,, (_Mdouble_ __x, _Mdouble_ __y)); | 201 | __MATHCALL (powr,, (_Mdouble_ __x, _Mdouble_ __y)); |
| 201 | 202 | ||
| 202 | /* Return the Yth root of X. */ | 203 | /* Return the Yth root of X. */ |
lib/libc/include/generic-glibc/bits/ppc.h deleted-33| ... | @@ -1,33 +0,0 @@ | ||
| 1 | /* Facilities specific to the PowerPC architecture on Linux | ||
| 2 | Copyright (C) 2012-2026 Free Software Foundation, Inc. | ||
| 3 | This file is part of the GNU C Library. | ||
| 4 | |||
| 5 | The GNU C Library is free software; you can redistribute it and/or | ||
| 6 | modify it under the terms of the GNU Lesser General Public | ||
| 7 | License as published by the Free Software Foundation; either | ||
| 8 | version 2.1 of the License, or (at your option) any later version. | ||
| 9 | |||
| 10 | The GNU C Library is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 13 | Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public | ||
| 16 | License along with the GNU C Library; if not, see | ||
| 17 | <https://www.gnu.org/licenses/>. */ | ||
| 18 | |||
| 19 | #ifndef _BITS_PPC_H | ||
| 20 | #define _BITS_PPC_H | ||
| 21 | |||
| 22 | #ifndef _SYS_PLATFORM_PPC_H | ||
| 23 | # error "Never include this file directly; use <sys/platform/ppc.h> instead." | ||
| 24 | #endif | ||
| 25 | |||
| 26 | __BEGIN_DECLS | ||
| 27 | |||
| 28 | /* Read the time base frequency. */ | ||
| 29 | extern uint64_t __ppc_get_timebase_freq (void); | ||
| 30 | |||
| 31 | __END_DECLS | ||
| 32 | |||
| 33 | #endif | ||
| \ No newline at end of file | |||
lib/libc/include/generic-glibc/bits/sched.h+3| ... | @@ -54,6 +54,9 @@ | ... | @@ -54,6 +54,9 @@ |
| 54 | #define SCHED_FLAG_UTIL_CLAMP \ | 54 | #define SCHED_FLAG_UTIL_CLAMP \ |
| 55 | (SCHED_FLAG_UTIL_CLAMP_MIN | SCHED_FLAG_UTIL_CLAMP_MAX) | 55 | (SCHED_FLAG_UTIL_CLAMP_MIN | SCHED_FLAG_UTIL_CLAMP_MAX) |
| 56 | 56 | ||
| 57 | /* Flags for the flags argument of sched_getattr. */ | ||
| 58 | #define SCHED_GETATTR_FLAG_DL_DYNAMIC	0x01 | ||
| 59 | |||
| 57 | /* Use "" to work around incorrect macro expansion of the | 60 | /* Use "" to work around incorrect macro expansion of the |
| 58 | __has_include argument (GCC PR 80005). */ | 61 | __has_include argument (GCC PR 80005). */ |
| 59 | # ifdef __has_include | 62 | # ifdef __has_include |
lib/libc/include/generic-glibc/bits/struct_stat.h+54-164| ... | @@ -23,215 +23,105 @@ | ... | @@ -23,215 +23,105 @@ |
| 23 | #ifndef _BITS_STRUCT_STAT_H | 23 | #ifndef _BITS_STRUCT_STAT_H |
| 24 | #define _BITS_STRUCT_STAT_H	1 | 24 | #define _BITS_STRUCT_STAT_H	1 |
| 25 | 25 | ||
| 26 | #include <sgidefs.h> | 26 | #include <bits/endian.h> |
| 27 | #include <bits/wordsize.h> | ||
| 28 | |||
| 29 | #if defined __USE_FILE_OFFSET64 | ||
| 30 | # define __field64(type, type64, name) type64 name | ||
| 31 | #elif __WORDSIZE == 64 || defined __INO_T_MATCHES_INO64_T | ||
| 32 | # if defined __INO_T_MATCHES_INO64_T && !defined __OFF_T_MATCHES_OFF64_T | ||
| 33 | # error "ino_t and off_t must both be the same type" | ||
| 34 | # endif | ||
| 35 | # define __field64(type, type64, name) type name | ||
| 36 | #elif __BYTE_ORDER == __LITTLE_ENDIAN | ||
| 37 | # define __field64(type, type64, name) \ | ||
| 38 | type name __attribute__((__aligned__ (__alignof__ (type64)))); int __##name##_pad | ||
| 39 | #else | ||
| 40 | # define __field64(type, type64, name) \ | ||
| 41 | int __##name##_pad __attribute__((__aligned__ (__alignof__ (type64)))); type name | ||
| 42 | #endif | ||
| 27 | 43 | ||
| 28 | #if _MIPS_SIM == _ABIO32 | ||
| 29 | /* Structure describing file characteristics. */ | ||
| 30 | struct stat | 44 | struct stat |
| 31 | { | 45 | { |
| 32 | # ifdef __USE_TIME64_REDIRECTS | 46 | __dev_t st_dev;		/* Device. */ |
| 33 | # include <bits/struct_stat_time64_helper.h> | 47 | __field64(__ino_t, __ino64_t, st_ino); /* File serial number. */ |
| 34 | # else | ||
| 35 | unsigned long int st_dev; | ||
| 36 | long int st_pad1[3]; | ||
| 37 | # ifndef __USE_FILE_OFFSET64 | ||
| 38 | __ino_t st_ino;		/* File serial number.		*/ | ||
| 39 | # else | ||
| 40 | __ino64_t st_ino;		/* File serial number.		*/ | ||
| 41 | # endif | ||
| 42 | __mode_t st_mode;		/* File mode. */ | 48 | __mode_t st_mode;		/* File mode. */ |
| 43 | __nlink_t st_nlink;		/* Link count. */ | 49 | __nlink_t st_nlink;		/* Link count. */ |
| 44 | __uid_t st_uid;		/* User ID of the file's owner.	*/ | 50 | __uid_t st_uid;		/* User ID of the file's owner.	*/ |
| 45 | __gid_t st_gid;		/* Group ID of the file's group.*/ | 51 | __gid_t st_gid;		/* Group ID of the file's group.*/ |
| 46 | unsigned long int st_rdev;	/* Device number, if device. */ | 52 | __dev_t st_rdev;		/* Device number, if device. */ |
| 47 | # ifndef __USE_FILE_OFFSET64 | 53 | __dev_t __pad1; |
| 48 | long int st_pad2[2]; | 54 | __field64(__off_t, __off64_t, st_size); /* Size of file, in bytes. */ |
| 49 | __off_t st_size;		/* Size of file, in bytes. */ | 55 | __blksize_t st_blksize;	/* Optimal block size for I/O. */ |
| 50 | /* SVR4 added this extra long to allow for expansion of off_t. */ | 56 | int __pad2; |
| 51 | long int st_pad3; | 57 | __field64(__blkcnt_t, __blkcnt64_t, st_blocks); /* 512-byte blocks */ |
| 52 | # else | 58 | #ifdef __USE_XOPEN2K8 |
| 53 | long int st_pad2[3]; | ||
| 54 | __off64_t st_size;		/* Size of file, in bytes. */ | ||
| 55 | # endif | ||
| 56 | # ifdef __USE_XOPEN2K8 | ||
| 57 | /* Nanosecond resolution timestamps are stored in a format | 59 | /* Nanosecond resolution timestamps are stored in a format |
| 58 | equivalent to 'struct timespec'. This is the type used | 60 | equivalent to 'struct timespec'. This is the type used |
| 59 | whenever possible but the Unix namespace rules do not allow the | 61 | whenever possible but the Unix namespace rules do not allow the |
| 60 | identifier 'timespec' to appear in the <sys/stat.h> header. | 62 | identifier 'timespec' to appear in the <sys/stat.h> header. |
| 61 | Therefore we have to handle the use of this header in strictly | 63 | Therefore we have to handle the use of this header in strictly |
| 62 | standard-compliant sources special. */ | 64 | standard-compliant sources special. */ |
| 63 | struct timespec st_atim; /* Time of last access. */ | 65 | struct timespec st_atim;		/* Time of last access. */ |
| 64 | struct timespec st_mtim; /* Time of last modification. */ | 66 | struct timespec st_mtim;		/* Time of last modification. */ |
| 65 | struct timespec st_ctim; /* Time of last status change. */ | 67 | struct timespec st_ctim;		/* Time of last status change. */ |
| 66 | # define st_atime st_atim.tv_sec /* Backward compatibility. */ | 68 | # define st_atime st_atim.tv_sec	/* Backward compatibility. */ |
| 67 | # define st_mtime st_mtim.tv_sec | 69 | # define st_mtime st_mtim.tv_sec |
| 68 | # define st_ctime st_ctim.tv_sec | 70 | # define st_ctime st_ctim.tv_sec |
| 69 | # else | 71 | #else |
| 70 | __time_t st_atime;			/* Time of last access. */ | 72 | __time_t st_atime;			/* Time of last access. */ |
| 71 | unsigned long int st_atimensec;	/* Nscecs of last access. */ | 73 | unsigned long int st_atimensec;	/* Nscecs of last access. */ |
| 72 | __time_t st_mtime;			/* Time of last modification. */ | 74 | __time_t st_mtime;			/* Time of last modification. */ |
| 73 | unsigned long int st_mtimensec;	/* Nsecs of last modification. */ | 75 | unsigned long int st_mtimensec;	/* Nsecs of last modification. */ |
| 74 | __time_t st_ctime;			/* Time of last status change. */ | 76 | __time_t st_ctime;			/* Time of last status change. */ |
| 75 | unsigned long int st_ctimensec;	/* Nsecs of last status change. */ | 77 | unsigned long int st_ctimensec;	/* Nsecs of last status change. */ |
| 76 | # endif | 78 | #endif |
| 77 | __blksize_t st_blksize;	/* Optimal block size for I/O. */ | 79 | int __glibc_reserved[2]; |
| 78 | # ifndef __USE_FILE_OFFSET64 | ||
| 79 | __blkcnt_t st_blocks;	/* Number of 512-byte blocks allocated. */ | ||
| 80 | # else | ||
| 81 | long int st_pad4; | ||
| 82 | __blkcnt64_t st_blocks;	/* Number of 512-byte blocks allocated. */ | ||
| 83 | # endif | ||
| 84 | long int st_pad5[14]; | ||
| 85 | # endif /* __USE_TIME64_REDIRECTS */ | ||
| 86 | }; | 80 | }; |
| 87 | 81 | ||
| 88 | # ifdef __USE_LARGEFILE64 | 82 | #undef __field64 |
| 83 | |||
| 84 | #ifdef __USE_LARGEFILE64 | ||
| 89 | struct stat64 | 85 | struct stat64 |
| 90 | { | 86 | { |
| 91 | # ifdef __USE_TIME64_REDIRECTS | 87 | __dev_t st_dev;		/* Device. */ |
| 92 | # include <bits/struct_stat_time64_helper.h> | 88 | __ino64_t st_ino;		/* File serial number.	*/ |
| 93 | # else | ||
| 94 | unsigned long int st_dev; | ||
| 95 | long int st_pad1[3]; | ||
| 96 | __ino64_t st_ino;		/* File serial number.		*/ | ||
| 97 | __mode_t st_mode;		/* File mode. */ | 89 | __mode_t st_mode;		/* File mode. */ |
| 98 | __nlink_t st_nlink;		/* Link count. */ | 90 | __nlink_t st_nlink;		/* Link count. */ |
| 99 | __uid_t st_uid;		/* User ID of the file's owner.	*/ | 91 | __uid_t st_uid;		/* User ID of the file's owner.	*/ |
| 100 | __gid_t st_gid;		/* Group ID of the file's group.*/ | 92 | __gid_t st_gid;		/* Group ID of the file's group.*/ |
| 101 | unsigned long int st_rdev;	/* Device number, if device. */ | 93 | __dev_t st_rdev;		/* Device number, if device. */ |
| 102 | long int st_pad2[3]; | 94 | __dev_t __pad1; |
| 103 | __off64_t st_size;		/* Size of file, in bytes. */ | 95 | __off64_t st_size;		/* Size of file, in bytes. */ |
| 104 | # ifdef __USE_XOPEN2K8 | ||
| 105 | /* Nanosecond resolution timestamps are stored in a format | ||
| 106 | equivalent to 'struct timespec'. This is the type used | ||
| 107 | whenever possible but the Unix namespace rules do not allow the | ||
| 108 | identifier 'timespec' to appear in the <sys/stat.h> header. | ||
| 109 | Therefore we have to handle the use of this header in strictly | ||
| 110 | standard-compliant sources special. */ | ||
| 111 | struct timespec st_atim; /* Time of last access. */ | ||
| 112 | struct timespec st_mtim; /* Time of last modification. */ | ||
| 113 | struct timespec st_ctim; /* Time of last status change. */ | ||
| 114 | # else | ||
| 115 | __time_t st_atime;			/* Time of last access. */ | ||
| 116 | unsigned long int st_atimensec;	/* Nscecs of last access. */ | ||
| 117 | __time_t st_mtime;			/* Time of last modification. */ | ||
| 118 | unsigned long int st_mtimensec;	/* Nsecs of last modification. */ | ||
| 119 | __time_t st_ctime;			/* Time of last status change. */ | ||
| 120 | unsigned long int st_ctimensec;	/* Nsecs of last status change. */ | ||
| 121 | # endif | ||
| 122 | __blksize_t st_blksize;	/* Optimal block size for I/O. */ | 96 | __blksize_t st_blksize;	/* Optimal block size for I/O. */ |
| 123 | long int st_pad3; | 97 | int __pad2; |
| 124 | __blkcnt64_t st_blocks;	/* Number of 512-byte blocks allocated. */ | 98 | __blkcnt64_t st_blocks;	/* Nr. 512-byte blocks allocated. */ |
| 125 | long int st_pad4[14]; | 99 | #ifdef __USE_XOPEN2K8 |
| 126 | # endif /* __USE_TIME64_REDIRECTS */ | ||
| 127 | }; | ||
| 128 | # endif /* __USE_LARGEFILE64 */ | ||
| 129 | |||
| 130 | #else /* _MIPS_SIM != _ABIO32 */ | ||
| 131 | |||
| 132 | struct stat | ||
| 133 | { | ||
| 134 | # ifdef __USE_TIME64_REDIRECTS | ||
| 135 | # include <bits/struct_stat_time64_helper.h> | ||
| 136 | # else | ||
| 137 | __dev_t st_dev; | ||
| 138 | int	st_pad1[3];		/* Reserved for st_dev expansion */ | ||
| 139 | # ifndef __USE_FILE_OFFSET64 | ||
| 140 | __ino_t st_ino; | ||
| 141 | # else | ||
| 142 | __ino64_t st_ino; | ||
| 143 | # endif | ||
| 144 | __mode_t st_mode; | ||
| 145 | __nlink_t st_nlink; | ||
| 146 | __uid_t st_uid; | ||
| 147 | __gid_t st_gid; | ||
| 148 | __dev_t st_rdev; | ||
| 149 | # if !defined __USE_FILE_OFFSET64 | ||
| 150 | unsigned int st_pad2[2];	/* Reserved for st_rdev expansion */ | ||
| 151 | __off_t st_size; | ||
| 152 | int st_pad3; | ||
| 153 | # else | ||
| 154 | unsigned int st_pad2[3];	/* Reserved for st_rdev expansion */ | ||
| 155 | __off64_t st_size; | ||
| 156 | # endif | ||
| 157 | # ifdef __USE_XOPEN2K8 | ||
| 158 | /* Nanosecond resolution timestamps are stored in a format | 100 | /* Nanosecond resolution timestamps are stored in a format |
| 159 | equivalent to 'struct timespec'. This is the type used | 101 | equivalent to 'struct timespec'. This is the type used |
| 160 | whenever possible but the Unix namespace rules do not allow the | 102 | whenever possible but the Unix namespace rules do not allow the |
| 161 | identifier 'timespec' to appear in the <sys/stat.h> header. | 103 | identifier 'timespec' to appear in the <sys/stat.h> header. |
| 162 | Therefore we have to handle the use of this header in strictly | 104 | Therefore we have to handle the use of this header in strictly |
| 163 | standard-compliant sources special. */ | 105 | standard-compliant sources special. */ |
| 164 | struct timespec st_atim; /* Time of last access. */ | 106 | struct timespec st_atim;		/* Time of last access. */ |
| 165 | struct timespec st_mtim; /* Time of last modification. */ | 107 | struct timespec st_mtim;		/* Time of last modification. */ |
| 166 | struct timespec st_ctim; /* Time of last status change. */ | 108 | struct timespec st_ctim;		/* Time of last status change. */ |
| 167 | # define st_atime st_atim.tv_sec /* Backward compatibility. */ | 109 | #else |
| 168 | # define st_mtime st_mtim.tv_sec | ||
| 169 | # define st_ctime st_ctim.tv_sec | ||
| 170 | # else | ||
| 171 | __time_t st_atime;			/* Time of last access. */ | 110 | __time_t st_atime;			/* Time of last access. */ |
| 172 | unsigned long int st_atimensec;	/* Nscecs of last access. */ | 111 | unsigned long int st_atimensec;	/* Nscecs of last access. */ |
| 173 | __time_t st_mtime;			/* Time of last modification. */ | 112 | __time_t st_mtime;			/* Time of last modification. */ |
| 174 | unsigned long int st_mtimensec;	/* Nsecs of last modification. */ | 113 | unsigned long int st_mtimensec;	/* Nsecs of last modification. */ |
| 175 | __time_t st_ctime;			/* Time of last status change. */ | 114 | __time_t st_ctime;			/* Time of last status change. */ |
| 176 | unsigned long int st_ctimensec;	/* Nsecs of last status change. */ | 115 | unsigned long int st_ctimensec;	/* Nsecs of last status change. */ |
| 177 | # endif | ||
| 178 | __blksize_t st_blksize; | ||
| 179 | unsigned int st_pad4; | ||
| 180 | # ifndef __USE_FILE_OFFSET64 | ||
| 181 | __blkcnt_t st_blocks; | ||
| 182 | # else | ||
| 183 | __blkcnt64_t st_blocks; | ||
| 184 | # endif | ||
| 185 | int st_pad5[14]; | ||
| 186 | # endif | ||
| 187 | }; | ||
| 188 | |||
| 189 | #ifdef __USE_LARGEFILE64 | ||
| 190 | struct stat64 | ||
| 191 | { | ||
| 192 | # ifdef __USE_TIME64_REDIRECTS | ||
| 193 | # include <bits/struct_stat_time64_helper.h> | ||
| 194 | # else | ||
| 195 | __dev_t st_dev; | ||
| 196 | unsigned int st_pad1[3];	/* Reserved for st_dev expansion */ | ||
| 197 | __ino64_t st_ino; | ||
| 198 | __mode_t st_mode; | ||
| 199 | __nlink_t st_nlink; | ||
| 200 | __uid_t st_uid; | ||
| 201 | __gid_t st_gid; | ||
| 202 | __dev_t st_rdev; | ||
| 203 | unsigned int st_pad2[3];	/* Reserved for st_rdev expansion */ | ||
| 204 | __off64_t st_size; | ||
| 205 | # ifdef __USE_XOPEN2K8 | ||
| 206 | /* Nanosecond resolution timestamps are stored in a format | ||
| 207 | equivalent to 'struct timespec'. This is the type used | ||
| 208 | whenever possible but the Unix namespace rules do not allow the | ||
| 209 | identifier 'timespec' to appear in the <sys/stat.h> header. | ||
| 210 | Therefore we have to handle the use of this header in strictly | ||
| 211 | standard-compliant sources special. */ | ||
| 212 | struct timespec st_atim; /* Time of last access. */ | ||
| 213 | struct timespec st_mtim; /* Time of last modification. */ | ||
| 214 | struct timespec st_ctim; /* Time of last status change. */ | ||
| 215 | # else | ||
| 216 | __time_t st_atime;			/* Time of last access. */ | ||
| 217 | unsigned long int st_atimensec;	/* Nscecs of last access. */ | ||
| 218 | __time_t st_mtime;			/* Time of last modification. */ | ||
| 219 | unsigned long int st_mtimensec;	/* Nsecs of last modification. */ | ||
| 220 | __time_t st_ctime;			/* Time of last status change. */ | ||
| 221 | unsigned long int st_ctimensec;	/* Nsecs of last status change. */ | ||
| 222 | # endif | ||
| 223 | __blksize_t st_blksize; | ||
| 224 | unsigned int st_pad3; | ||
| 225 | __blkcnt64_t st_blocks; | ||
| 226 | int st_pad4[14]; | ||
| 227 | # endif /* __USE_TIME64_REDIRECTS */ | ||
| 228 | }; | ||
| 229 | #endif | 116 | #endif |
| 230 | 117 | int __glibc_reserved[2]; | |
| 118 | }; | ||
| 231 | #endif | 119 | #endif |
| 232 | 120 | ||
| 233 | /* Tell code we have these members. */ | 121 | /* Tell code we have these members. */ |
| 234 | #define	_STATBUF_ST_BLKSIZE | 122 | #define	_STATBUF_ST_BLKSIZE |
| 235 | #define	_STATBUF_ST_RDEV | 123 | #define _STATBUF_ST_RDEV |
| 124 | /* Nanosecond resolution time values are supported. */ | ||
| 125 | #define _STATBUF_ST_NSEC | ||
| 236 | 126 | ||
| 237 | #endif /* _BITS_STRUCT_STAT_H */ | 127 | #endif /* _BITS_STRUCT_STAT_H */ |
| \ No newline at end of file | |||
lib/libc/include/generic-glibc/bits/syscall.h+14-2| ... | @@ -1,11 +1,11 @@ | ... | @@ -1,11 +1,11 @@ |
| 1 | /* Generated at libc build time from syscall list. */ | 1 | /* Generated at libc build time from syscall list. */ |
| 2 | /* The system call list corresponds to kernel 6.17. */ | 2 | /* The system call list corresponds to kernel 7.1. */ |
| 3 | 3 | ||
| 4 | #ifndef _SYSCALL_H | 4 | #ifndef _SYSCALL_H |
| 5 | # error "Never use <bits/syscall.h> directly; include <sys/syscall.h> instead." | 5 | # error "Never use <bits/syscall.h> directly; include <sys/syscall.h> instead." |
| 6 | #endif | 6 | #endif |
| 7 | 7 | ||
| 8 | #define __GLIBC_LINUX_VERSION_CODE 397568 | 8 | #define __GLIBC_LINUX_VERSION_CODE 459008 |
| 9 | 9 | ||
| 10 | #ifdef __NR_FAST_atomic_update | 10 | #ifdef __NR_FAST_atomic_update |
| 11 | # define SYS_FAST_atomic_update __NR_FAST_atomic_update | 11 | # define SYS_FAST_atomic_update __NR_FAST_atomic_update |
| ... | @@ -883,6 +883,10 @@ | ... | @@ -883,6 +883,10 @@ |
| 883 | # define SYS_listmount __NR_listmount | 883 | # define SYS_listmount __NR_listmount |
| 884 | #endif | 884 | #endif |
| 885 | 885 | ||
| 886 | #ifdef __NR_listns | ||
| 887 | # define SYS_listns __NR_listns | ||
| 888 | #endif | ||
| 889 | |||
| 886 | #ifdef __NR_listxattr | 890 | #ifdef __NR_listxattr |
| 887 | # define SYS_listxattr __NR_listxattr | 891 | # define SYS_listxattr __NR_listxattr |
| 888 | #endif | 892 | #endif |
| ... | @@ -1899,6 +1903,10 @@ | ... | @@ -1899,6 +1903,10 @@ |
| 1899 | # define SYS_rseq __NR_rseq | 1903 | # define SYS_rseq __NR_rseq |
| 1900 | #endif | 1904 | #endif |
| 1901 | 1905 | ||
| 1906 | #ifdef __NR_rseq_slice_yield | ||
| 1907 | # define SYS_rseq_slice_yield __NR_rseq_slice_yield | ||
| 1908 | #endif | ||
| 1909 | |||
| 1902 | #ifdef __NR_rt_sigaction | 1910 | #ifdef __NR_rt_sigaction |
| 1903 | # define SYS_rt_sigaction __NR_rt_sigaction | 1911 | # define SYS_rt_sigaction __NR_rt_sigaction |
| 1904 | #endif | 1912 | #endif |
| ... | @@ -2551,6 +2559,10 @@ | ... | @@ -2551,6 +2559,10 @@ |
| 2551 | # define SYS_unshare __NR_unshare | 2559 | # define SYS_unshare __NR_unshare |
| 2552 | #endif | 2560 | #endif |
| 2553 | 2561 | ||
| 2562 | #ifdef __NR_uprobe | ||
| 2563 | # define SYS_uprobe __NR_uprobe | ||
| 2564 | #endif | ||
| 2565 | |||
| 2554 | #ifdef __NR_uretprobe | 2566 | #ifdef __NR_uretprobe |
| 2555 | # define SYS_uretprobe __NR_uretprobe | 2567 | # define SYS_uretprobe __NR_uretprobe |
| 2556 | #endif | 2568 | #endif |
lib/libc/include/generic-glibc/bits/timesize.h+3-5| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | /* Bit size of the time_t type at glibc build time, Linux/MIPS. | 1 | /* Bit size of the time_t type at glibc build time, general case. |
| 2 | Copyright (C) 2021-2026 Free Software Foundation, Inc. | 2 | Copyright (C) 2018-2026 Free Software Foundation, Inc. |
| 3 | This file is part of the GNU C Library. | 3 | This file is part of the GNU C Library. |
| 4 | 4 | ||
| 5 | The GNU C Library is free software; you can redistribute it and/or | 5 | The GNU C Library is free software; you can redistribute it and/or |
| ... | @@ -16,7 +16,5 @@ | ... | @@ -16,7 +16,5 @@ |
| 16 | License along with the GNU C Library; if not, see | 16 | License along with the GNU C Library; if not, see |
| 17 | <https://www.gnu.org/licenses/>. */ | 17 | <https://www.gnu.org/licenses/>. */ |
| 18 | 18 | ||
| 19 | #include <bits/wordsize.h> | ||
| 20 | |||
| 21 | /* Size in bits of the 'time_t' type of the default ABI. */ | 19 | /* Size in bits of the 'time_t' type of the default ABI. */ |
| 22 | #define __TIMESIZE	__WORDSIZE | ||
| \ No newline at end of file | |||
| 20 | #define __TIMESIZE	64 | ||
| \ No newline at end of file | |||
lib/libc/include/generic-glibc/bits/uio-ext.h+1| ... | @@ -51,6 +51,7 @@ extern ssize_t process_vm_writev (pid_t __pid, const struct iovec *__lvec, | ... | @@ -51,6 +51,7 @@ extern ssize_t process_vm_writev (pid_t __pid, const struct iovec *__lvec, |
| 51 | #define RWF_ATOMIC	0x00000040 /* Write is to be issued with torn-write | 51 | #define RWF_ATOMIC	0x00000040 /* Write is to be issued with torn-write |
| 52 | 				 prevention. */ | 52 | 				 prevention. */ |
| 53 | #define RWF_DONTCACHE	0x00000080 /* Uncached buffered IO. */ | 53 | #define RWF_DONTCACHE	0x00000080 /* Uncached buffered IO. */ |
| 54 | #define RWF_NOSIGNAL	0x00000100 /* Do not generate SIGPIPE on error. */ | ||
| 54 | 55 | ||
| 55 | __END_DECLS | 56 | __END_DECLS |
| 56 | 57 |
lib/libc/include/generic-glibc/dlfcn.h+6-1| ... | @@ -167,7 +167,12 @@ enum | ... | @@ -167,7 +167,12 @@ enum |
| 167 | the number of program headers in the array. */ | 167 | the number of program headers in the array. */ |
| 168 | RTLD_DI_PHDR = 11, | 168 | RTLD_DI_PHDR = 11, |
| 169 | 169 | ||
| 170 | RTLD_DI_MAX = 11 | 170 | /* Treat ARG as `const char **' and at that location, store the address |
| 171 | of the directory name used to expand $ORIGIN in this shared object's | ||
| 172 | dependency file names. */ | ||
| 173 | RTLD_DI_ORIGIN_PATH = 12, | ||
| 174 | |||
| 175 | RTLD_DI_MAX = 12 | ||
| 171 | }; | 176 | }; |
| 172 | 177 | ||
| 173 | 178 |
lib/libc/include/generic-glibc/elf.h+6-2| ... | @@ -798,7 +798,8 @@ typedef struct | ... | @@ -798,7 +798,8 @@ typedef struct |
| 798 | #define NT_X86_XSTATE	0x202		/* x86 extended state using xsave */ | 798 | #define NT_X86_XSTATE	0x202		/* x86 extended state using xsave */ |
| 799 | #define NT_X86_SHSTK	0x204		/* x86 SHSTK state */ | 799 | #define NT_X86_SHSTK	0x204		/* x86 SHSTK state */ |
| 800 | #define NT_X86_XSAVE_LAYOUT	0x205		/* XSAVE layout description. */ | 800 | #define NT_X86_XSAVE_LAYOUT	0x205		/* XSAVE layout description. */ |
| 801 | #define NT_S390_HIGH_GPRS	0x300	/* s390 upper register halves */ | 801 | #define NT_S390_HIGH_GPRS	0x300	/* s390 upper register halves. This was |
| 802 | 					 used in now removed s390-32 arch. */ | ||
| 802 | #define NT_S390_TIMER	0x301		/* s390 timer register */ | 803 | #define NT_S390_TIMER	0x301		/* s390 timer register */ |
| 803 | #define NT_S390_TODCMP	0x302		/* s390 TOD clock comparator register */ | 804 | #define NT_S390_TODCMP	0x302		/* s390 TOD clock comparator register */ |
| 804 | #define NT_S390_TODPREG	0x303		/* s390 TOD programmable register */ | 805 | #define NT_S390_TODPREG	0x303		/* s390 TOD programmable register */ |
| ... | @@ -846,6 +847,7 @@ typedef struct | ... | @@ -846,6 +847,7 @@ typedef struct |
| 846 | #define NT_RISCV_VECTOR	0x901		/* RISC-V vector registers */ | 847 | #define NT_RISCV_VECTOR	0x901		/* RISC-V vector registers */ |
| 847 | #define NT_RISCV_TAGGED_ADDR_CTRL	0x902	/* RISC-V tagged | 848 | #define NT_RISCV_TAGGED_ADDR_CTRL	0x902	/* RISC-V tagged |
| 848 | 						 address control */ | 849 | 						 address control */ |
| 850 | #define NT_RISCV_USER_CFI	0x903		/* RISC-V shadow stack state */ | ||
| 849 | #define NT_LOONGARCH_CPUCFG	0xa00	/* LoongArch CPU config registers. */ | 851 | #define NT_LOONGARCH_CPUCFG	0xa00	/* LoongArch CPU config registers. */ |
| 850 | #define NT_LOONGARCH_CSR	0xa01	/* LoongArch control and | 852 | #define NT_LOONGARCH_CSR	0xa01	/* LoongArch control and |
| 851 | 					 status registers. */ | 853 | 					 status registers. */ |
| ... | @@ -3470,7 +3472,9 @@ enum | ... | @@ -3470,7 +3472,9 @@ enum |
| 3470 | 3472 | ||
| 3471 | /* Valid values for the e_flags field. */ | 3473 | /* Valid values for the e_flags field. */ |
| 3472 | 3474 | ||
| 3473 | #define EF_S390_HIGH_GPRS 0x00000001 /* High GPRs kernel facility needed. */ | 3475 | #define EF_S390_HIGH_GPRS 0x00000001 /* High GPRs kernel facility needed. |
| 3476 | 					 This was used in now removed s390-32 | ||
| 3477 | 					 arch. */ | ||
| 3474 | 3478 | ||
| 3475 | /* Additional s390 relocs */ | 3479 | /* Additional s390 relocs */ |
| 3476 | 3480 |
lib/libc/include/generic-glibc/features.h+2-2| ... | @@ -162,7 +162,7 @@ | ... | @@ -162,7 +162,7 @@ |
| 162 | #undef	__GLIBC_USE_DEPRECATED_SCANF | 162 | #undef	__GLIBC_USE_DEPRECATED_SCANF |
| 163 | #undef	__GLIBC_USE_C23_STRTOL | 163 | #undef	__GLIBC_USE_C23_STRTOL |
| 164 | 164 | ||
| 165 | /* Suppress kernel-name space pollution unless user expressedly asks | 165 | /* Suppress kernel-name space pollution unless user explicitly asks |
| 166 | for it. */ | 166 | for it. */ |
| 167 | #ifndef _LOOSE_KERNEL_NAMES | 167 | #ifndef _LOOSE_KERNEL_NAMES |
| 168 | # define __KERNEL_STRICT_NAMES | 168 | # define __KERNEL_STRICT_NAMES |
| ... | @@ -580,4 +580,4 @@ | ... | @@ -580,4 +580,4 @@ |
| 580 | #include <gnu/stubs.h> | 580 | #include <gnu/stubs.h> |
| 581 | 581 | ||
| 582 | 582 | ||
| 583 | #endif	/* features.h */ | 583 | #endif	/* features.h */ |
| \ No newline at end of file | |||
lib/libc/include/generic-glibc/fts.h+126-2| ... | @@ -52,7 +52,29 @@ | ... | @@ -52,7 +52,29 @@ |
| 52 | 52 | ||
| 53 | #include <features.h> | 53 | #include <features.h> |
| 54 | #include <sys/types.h> | 54 | #include <sys/types.h> |
| 55 | 55 | #include <sys/stat.h> | |
| 56 | #include <dirent.h> | ||
| 57 | #include <stdbool.h> | ||
| 58 | |||
| 59 | enum { __I_RING_SIZE = 4 }; | ||
| 60 | |||
| 61 | /* When ir_empty is true, the ring is empty. | ||
| 62 | Otherwise, ir_data[B..F] are defined, where B..F is the contiguous | ||
| 63 | range of indices, modulo I_RING_SIZE, from back to front, inclusive. | ||
| 64 | Undefined elements of ir_data are always set to ir_default_val. | ||
| 65 | Popping from an empty ring aborts. | ||
| 66 | Pushing onto a full ring returns the displaced value. | ||
| 67 | An empty ring has F==B and ir_empty == true. | ||
| 68 | A ring with one entry still has F==B, but now ir_empty == false. */ | ||
| 69 | struct __I_ring | ||
| 70 | { | ||
| 71 | int ir_data[__I_RING_SIZE]; | ||
| 72 | int ir_default_val; | ||
| 73 | unsigned int ir_front; | ||
| 74 | unsigned int ir_back; | ||
| 75 | bool ir_empty; | ||
| 76 | }; | ||
| 77 | typedef struct __I_ring __I_ring; | ||
| 56 | 78 | ||
| 57 | typedef struct { | 79 | typedef struct { |
| 58 | 	struct _ftsent *fts_cur;	/* current node */ | 80 | 	struct _ftsent *fts_cur;	/* current node */ |
| ... | @@ -73,11 +95,106 @@ typedef struct { | ... | @@ -73,11 +95,106 @@ typedef struct { |
| 73 | #define	FTS_SEEDOT	0x0020		/* return dot and dot-dot */ | 95 | #define	FTS_SEEDOT	0x0020		/* return dot and dot-dot */ |
| 74 | #define	FTS_XDEV	0x0040		/* don't cross devices */ | 96 | #define	FTS_XDEV	0x0040		/* don't cross devices */ |
| 75 | #define FTS_WHITEOUT	0x0080		/* return whiteout information */ | 97 | #define FTS_WHITEOUT	0x0080		/* return whiteout information */ |
| 76 | #define	FTS_OPTIONMASK	0x00ff		/* valid user option mask */ | 98 | |
| 99 | /* There are two ways to detect cycles. | ||
| 100 | The lazy way (which works only with FTS_PHYSICAL), | ||
| 101 | with which one may process a directory that is a | ||
| 102 | part of the cycle several times before detecting the cycle. | ||
| 103 | The "tight" way, whereby fts uses more memory (proportional | ||
| 104 | to number of "active" directories, aka distance from root | ||
| 105 | of current tree to current directory -- see active_dir_ht) | ||
| 106 | to detect any cycle right away. For example, du must use | ||
| 107 | this option to avoid counting disk space in a cycle multiple | ||
| 108 | times, but chown -R need not. | ||
| 109 | The default is to use the constant-memory lazy way, when possible | ||
| 110 | (see below). | ||
| 111 | |||
| 112 | However, with FTS_LOGICAL (when following symlinks, e.g., chown -L) | ||
| 113 | using lazy cycle detection is inadequate. For example, traversing | ||
| 114 | a directory containing a symbolic link to a peer directory, it is | ||
| 115 | possible to encounter the same directory twice even though there | ||
| 116 | is no cycle: | ||
| 117 | dir | ||
| 118 | ... | ||
| 119 | slink -> dir | ||
| 120 | So, when FTS_LOGICAL is selected, we have to use a different | ||
| 121 | mode of cycle detection: FTS_TIGHT_CYCLE_CHECK. */ | ||
| 122 | #define FTS_TIGHT_CYCLE_CHECK	0x0400 | ||
| 123 | |||
| 124 | /* Use this flag to enable semantics with which the parent | ||
| 125 | application may be made both more efficient and more robust. | ||
| 126 | Whereas the default is to visit each directory in a recursive | ||
| 127 | traversal (via chdir), using this flag makes it so the initial | ||
| 128 | working directory is never changed. Instead, these functions | ||
| 129 | perform the traversal via a virtual working directory, maintained | ||
| 130 | through the file descriptor member, fts_cwd_fd. */ | ||
| 131 | # define FTS_CWDFD 0x0800 | ||
| 132 | |||
| 133 | /* Historically, for each directory that fts initially encounters, it would | ||
| 134 | open it, read all entries, and stat each entry, storing the results, and | ||
| 135 | then it would process the first entry. But that behavior is bad for | ||
| 136 | locality of reference, and also causes trouble with inode-simulating | ||
| 137 | file systems like FAT, CIFS, FUSE-based ones, etc., when entries from | ||
| 138 | their name/inode cache are flushed too early. | ||
| 139 | Use this flag to make fts_open and fts_read defer the stat/lstat/fststat | ||
| 140 | of each entry until it is actually processed. However, note that if you | ||
| 141 | use this option and also specify a comparison function, that function may | ||
| 142 | not examine any data via fts_statp. However, when fts_statp->st_mode is | ||
| 143 | nonzero, the S_IFMT type bits are valid, with mapped dirent.d_type data. | ||
| 144 | Of course, that happens only on file systems that provide useful | ||
| 145 | dirent.d_type data. */ | ||
| 146 | #define FTS_DEFER_STAT	0x1000 | ||
| 147 | |||
| 148 | /* Use this flag to disable stripping of trailing slashes | ||
| 149 | from input path names during fts_open initialization. */ | ||
| 150 | #define FTS_VERBATIM	0x2000 | ||
| 151 | |||
| 152 | #define FTS_MOUNT 0x4000 /* skip other devices */ | ||
| 153 | #define FTS_OPTIONMASK 0x7fff /* valid user option mask */ | ||
| 77 | 154 | ||
| 78 | #define	FTS_NAMEONLY	0x0100		/* (private) child names only */ | 155 | #define	FTS_NAMEONLY	0x0100		/* (private) child names only */ |
| 79 | #define	FTS_STOP	0x0200		/* (private) unrecoverable error */ | 156 | #define	FTS_STOP	0x0200		/* (private) unrecoverable error */ |
| 157 | |||
| 80 | 	int fts_options;		/* fts_open options, global flags */ | 158 | 	int fts_options;		/* fts_open options, global flags */ |
| 159 | |||
| 160 | 	int fts_cwd_fd; /* the file descriptor on which the | ||
| 161 | 	 virtual cwd is open, or AT_FDCWD */ | ||
| 162 | |||
| 163 | 	/* Map a directory's device number to a boolean. The boolean is | ||
| 164 | 	 true if for that file system (type determined by a single fstatfs | ||
| 165 | 	 call per FS) st_nlink can be used to calculate the number of | ||
| 166 | 	 sub-directory entries in a directory. | ||
| 167 | 	 Using this table is an optimization that permits us to look up | ||
| 168 | 	 file system type on a per-inode basis at the minimal cost of | ||
| 169 | 	 calling fstatfs only once per traversed device. */ | ||
| 170 | 	struct hash_table *fts_leaf_optimization_works_ht; | ||
| 171 | |||
| 172 | 	union { | ||
| 173 | 	 /* This data structure is used if FTS_TIGHT_CYCLE_CHECK is | ||
| 174 | 	 specified. It records the directories between a starting | ||
| 175 | 	 point and the current directory. I.e., a directory is | ||
| 176 | 	 recorded here IFF we have visited it once, but we have not | ||
| 177 | 	 yet completed processing of all its entries. Every time we | ||
| 178 | 	 visit a new directory, we add that directory to this set. | ||
| 179 | 	 When we finish with a directory (usually by visiting it a | ||
| 180 | 	 second time), we remove it from this set. Each entry in | ||
| 181 | 	 this data structure is a device/inode pair. This data | ||
| 182 | 	 structure is used to detect directory cycles efficiently and | ||
| 183 | 	 promptly even when the depth of a hierarchy is in the tens | ||
| 184 | 	 of thousands. */ | ||
| 185 | 	 struct hash_table *ht; | ||
| 186 | |||
| 187 | 	 /* FIXME: rename these two members to have the fts_ prefix */ | ||
| 188 | 	 /* This data structure uses a lazy cycle-detection algorithm, | ||
| 189 | 	 as done by rm via cycle-check.c. It's the default, | ||
| 190 | 	 but it's not appropriate for programs like du. */ | ||
| 191 | 	 struct cycle_check_state *state; | ||
| 192 | 	} fts_cycle; | ||
| 193 | |||
| 194 | 	/* A stack of the file descriptors corresponding to the | ||
| 195 | 	 most-recently traversed parent directories. | ||
| 196 | 	 Currently used only in FTS_CWDFD mode. */ | ||
| 197 | 	__I_ring fts_fd_ring; | ||
| 81 | } FTS; | 198 | } FTS; |
| 82 | 199 | ||
| 83 | #ifdef __USE_LARGEFILE64 | 200 | #ifdef __USE_LARGEFILE64 |
| ... | @@ -92,6 +209,13 @@ typedef struct { | ... | @@ -92,6 +209,13 @@ typedef struct { |
| 92 | 	int fts_nitems;			/* elements in the sort array */ | 209 | 	int fts_nitems;			/* elements in the sort array */ |
| 93 | 	int (*fts_compar) (const void *, const void *); /* compare fn */ | 210 | 	int (*fts_compar) (const void *, const void *); /* compare fn */ |
| 94 | 	int fts_options;		/* fts_open options, global flags */ | 211 | 	int fts_options;		/* fts_open options, global flags */ |
| 212 | 	int fts_cwd_fd; | ||
| 213 | 	struct hash_table *fts_leaf_optimization_works_ht; | ||
| 214 | 	union { | ||
| 215 | 	 struct hash_table *ht; | ||
| 216 | 	 struct cycle_check_state *state; | ||
| 217 | 	} fts_cycle; | ||
| 218 | 	__I_ring fts_fd_ring; | ||
| 95 | } FTS64; | 219 | } FTS64; |
| 96 | #endif | 220 | #endif |
| 97 | 221 |
lib/libc/include/generic-glibc/gnu/lib-names-32.h+1| ... | @@ -24,4 +24,5 @@ | ... | @@ -24,4 +24,5 @@ |
| 24 | #define LIBRESOLV_SO "libresolv.so.2" | 24 | #define LIBRESOLV_SO "libresolv.so.2" |
| 25 | #define LIBRT_SO "librt.so.1" | 25 | #define LIBRT_SO "librt.so.1" |
| 26 | #define LIBTHREAD_DB_SO "libthread_db.so.1" | 26 | #define LIBTHREAD_DB_SO "libthread_db.so.1" |
| 27 | #define LIBUNWIND_SO "libunwind.so.1" | ||
| 27 | #define LIBUTIL_SO "libutil.so.1" | 28 | #define LIBUTIL_SO "libutil.so.1" |
| \ No newline at end of file | |||
lib/libc/include/generic-glibc/gnu/lib-names-hard.h+1| ... | @@ -24,4 +24,5 @@ | ... | @@ -24,4 +24,5 @@ |
| 24 | #define LIBRESOLV_SO "libresolv.so.2" | 24 | #define LIBRESOLV_SO "libresolv.so.2" |
| 25 | #define LIBRT_SO "librt.so.1" | 25 | #define LIBRT_SO "librt.so.1" |
| 26 | #define LIBTHREAD_DB_SO "libthread_db.so.1" | 26 | #define LIBTHREAD_DB_SO "libthread_db.so.1" |
| 27 | #define LIBUNWIND_SO "libunwind.so.1" | ||
| 27 | #define LIBUTIL_SO "libutil.so.1" | 28 | #define LIBUTIL_SO "libutil.so.1" |
| \ No newline at end of file | |||
lib/libc/include/generic-glibc/gnu/lib-names-n32_hard.h+1| ... | @@ -23,4 +23,5 @@ | ... | @@ -23,4 +23,5 @@ |
| 23 | #define LIBRESOLV_SO "libresolv.so.2" | 23 | #define LIBRESOLV_SO "libresolv.so.2" |
| 24 | #define LIBRT_SO "librt.so.1" | 24 | #define LIBRT_SO "librt.so.1" |
| 25 | #define LIBTHREAD_DB_SO "libthread_db.so.1" | 25 | #define LIBTHREAD_DB_SO "libthread_db.so.1" |
| 26 | #define LIBUNWIND_SO "libunwind.so.1" | ||
| 26 | #define LIBUTIL_SO "libutil.so.1" | 27 | #define LIBUTIL_SO "libutil.so.1" |
| \ No newline at end of file | |||
lib/libc/include/generic-glibc/gnu/lib-names-n64_hard.h+1| ... | @@ -23,4 +23,5 @@ | ... | @@ -23,4 +23,5 @@ |
| 23 | #define LIBRESOLV_SO "libresolv.so.2" | 23 | #define LIBRESOLV_SO "libresolv.so.2" |
| 24 | #define LIBRT_SO "librt.so.1" | 24 | #define LIBRT_SO "librt.so.1" |
| 25 | #define LIBTHREAD_DB_SO "libthread_db.so.1" | 25 | #define LIBTHREAD_DB_SO "libthread_db.so.1" |
| 26 | #define LIBUNWIND_SO "libunwind.so.1" | ||
| 26 | #define LIBUTIL_SO "libutil.so.1" | 27 | #define LIBUTIL_SO "libutil.so.1" |
| \ No newline at end of file | |||
lib/libc/include/generic-glibc/gnu/lib-names-o32_hard.h+1| ... | @@ -23,4 +23,5 @@ | ... | @@ -23,4 +23,5 @@ |
| 23 | #define LIBRESOLV_SO "libresolv.so.2" | 23 | #define LIBRESOLV_SO "libresolv.so.2" |
| 24 | #define LIBRT_SO "librt.so.1" | 24 | #define LIBRT_SO "librt.so.1" |
| 25 | #define LIBTHREAD_DB_SO "libthread_db.so.1" | 25 | #define LIBTHREAD_DB_SO "libthread_db.so.1" |
| 26 | #define LIBUNWIND_SO "libunwind.so.1" | ||
| 26 | #define LIBUTIL_SO "libutil.so.1" | 27 | #define LIBUTIL_SO "libutil.so.1" |
| \ No newline at end of file | |||
lib/libc/include/generic-glibc/gnu/lib-names-o32_soft.h+1| ... | @@ -23,4 +23,5 @@ | ... | @@ -23,4 +23,5 @@ |
| 23 | #define LIBRESOLV_SO "libresolv.so.2" | 23 | #define LIBRESOLV_SO "libresolv.so.2" |
| 24 | #define LIBRT_SO "librt.so.1" | 24 | #define LIBRT_SO "librt.so.1" |
| 25 | #define LIBTHREAD_DB_SO "libthread_db.so.1" | 25 | #define LIBTHREAD_DB_SO "libthread_db.so.1" |
| 26 | #define LIBUNWIND_SO "libunwind.so.1" | ||
| 26 | #define LIBUTIL_SO "libutil.so.1" | 27 | #define LIBUTIL_SO "libutil.so.1" |
| \ No newline at end of file | |||
lib/libc/include/generic-glibc/gnu/lib-names-soft.h+1| ... | @@ -24,4 +24,5 @@ | ... | @@ -24,4 +24,5 @@ |
| 24 | #define LIBRESOLV_SO "libresolv.so.2" | 24 | #define LIBRESOLV_SO "libresolv.so.2" |
| 25 | #define LIBRT_SO "librt.so.1" | 25 | #define LIBRT_SO "librt.so.1" |
| 26 | #define LIBTHREAD_DB_SO "libthread_db.so.1" | 26 | #define LIBTHREAD_DB_SO "libthread_db.so.1" |
| 27 | #define LIBUNWIND_SO "libunwind.so.1" | ||
| 27 | #define LIBUTIL_SO "libutil.so.1" | 28 | #define LIBUTIL_SO "libutil.so.1" |
| \ No newline at end of file | |||
lib/libc/include/generic-glibc/gnu/stubs-64.h deleted-16| ... | @@ -1,16 +0,0 @@ | ||
| 1 | /* This file is automatically generated. | ||
| 2 | It defines a symbol `__stub_FUNCTION' for each function | ||
| 3 | in the C library which is a stub, meaning it will fail | ||
| 4 | every time called, usually setting errno to ENOSYS. */ | ||
| 5 | |||
| 6 | #ifdef _LIBC | ||
| 7 | #error Applications may not define the macro _LIBC | ||
| 8 | #endif | ||
| 9 | |||
| 10 | #define __stub_chflags | ||
| 11 | #define __stub_fchflags | ||
| 12 | #define __stub_gtty | ||
| 13 | #define __stub_revoke | ||
| 14 | #define __stub_setlogin | ||
| 15 | #define __stub_sigreturn | ||
| 16 | #define __stub_stty | ||
| \ No newline at end of file | |||
lib/libc/include/generic-glibc/netinet/in.h+2| ... | @@ -91,6 +91,8 @@ enum | ... | @@ -91,6 +91,8 @@ enum |
| 91 | #define IPPROTO_MPLS		IPPROTO_MPLS | 91 | #define IPPROTO_MPLS		IPPROTO_MPLS |
| 92 | IPPROTO_ETHERNET = 143, /* Ethernet-within-IPv6 Encapsulation. */ | 92 | IPPROTO_ETHERNET = 143, /* Ethernet-within-IPv6 Encapsulation. */ |
| 93 | #define IPPROTO_ETHERNET	IPPROTO_ETHERNET | 93 | #define IPPROTO_ETHERNET	IPPROTO_ETHERNET |
| 94 | IPPROTO_AGGFRAG = 144, /* AGGFRAG in ESP (RFC 9347). */ | ||
| 95 | #define IPPROTO_AGGFRAG		IPPROTO_AGGFRAG | ||
| 94 | IPPROTO_RAW = 255,	 /* Raw IP packets. */ | 96 | IPPROTO_RAW = 255,	 /* Raw IP packets. */ |
| 95 | #define IPPROTO_RAW		IPPROTO_RAW | 97 | #define IPPROTO_RAW		IPPROTO_RAW |
| 96 | IPPROTO_SMC = 256,	 /* Shared Memory Communications. */ | 98 | IPPROTO_SMC = 256,	 /* Shared Memory Communications. */ |
lib/libc/include/generic-glibc/netinet/tcp.h+25-2| ... | @@ -80,6 +80,9 @@ | ... | @@ -80,6 +80,9 @@ |
| 80 | 				 as a cmsg on read. */ | 80 | 				 as a cmsg on read. */ |
| 81 | #define TCP_CM_INQ		 TCP_INQ | 81 | #define TCP_CM_INQ		 TCP_INQ |
| 82 | #define TCP_TX_DELAY		 37 /* Delay outgoing packets by XX usec. */ | 82 | #define TCP_TX_DELAY		 37 /* Delay outgoing packets by XX usec. */ |
| 83 | #define TCP_RTO_MAX_MS		 44 /* Max time to retransmit (msec). */ | ||
| 84 | #define TCP_RTO_MIN_US		 45 /* Min time to retransmit (usec). */ | ||
| 85 | #define TCP_DELACK_MAX_US	 46 /* Max delayed ack time (usec). */ | ||
| 83 | 86 | ||
| 84 | #define TCP_REPAIR_ON		 1 | 87 | #define TCP_REPAIR_ON		 1 |
| 85 | #define TCP_REPAIR_OFF		 0 | 88 | #define TCP_REPAIR_OFF		 0 |
| ... | @@ -226,6 +229,24 @@ enum tcp_ca_state | ... | @@ -226,6 +229,24 @@ enum tcp_ca_state |
| 226 | TCP_CA_Loss = 4 | 229 | TCP_CA_Loss = 4 |
| 227 | }; | 230 | }; |
| 228 | 231 | ||
| 232 | /* Values for tcpi_ecn_mode after negotiation. */ | ||
| 233 | #define TCPI_ECN_MODE_DISABLED	0x0 | ||
| 234 | #define TCPI_ECN_MODE_RFC3168	0x1 | ||
| 235 | #define TCPI_ECN_MODE_ACCECN	0x2 | ||
| 236 | #define TCPI_ECN_MODE_PENDING	0x3 | ||
| 237 | |||
| 238 | /* Values for tcpi_accecn_opt_seen. */ | ||
| 239 | #define TCP_ACCECN_OPT_NOT_SEEN		0x0 | ||
| 240 | #define TCP_ACCECN_OPT_EMPTY_SEEN	0x1 | ||
| 241 | #define TCP_ACCECN_OPT_COUNTER_SEEN	0x2 | ||
| 242 | #define TCP_ACCECN_OPT_FAIL_SEEN	0x3 | ||
| 243 | |||
| 244 | /* Values for tcpi_accecn_fail_mode. */ | ||
| 245 | #define TCP_ACCECN_ACE_FAIL_SEND	0x1 | ||
| 246 | #define TCP_ACCECN_ACE_FAIL_RECV	0x2 | ||
| 247 | #define TCP_ACCECN_OPT_FAIL_SEND	0x4 | ||
| 248 | #define TCP_ACCECN_OPT_FAIL_RECV	0x8 | ||
| 249 | |||
| 229 | struct tcp_info | 250 | struct tcp_info |
| 230 | { | 251 | { |
| 231 | uint8_t	tcpi_state; | 252 | uint8_t	tcpi_state; |
| ... | @@ -319,8 +340,10 @@ struct tcp_info | ... | @@ -319,8 +340,10 @@ struct tcp_info |
| 319 | uint32_t	tcpi_received_e1_bytes; | 340 | uint32_t	tcpi_received_e1_bytes; |
| 320 | uint32_t	tcpi_received_e0_bytes; | 341 | uint32_t	tcpi_received_e0_bytes; |
| 321 | uint32_t	tcpi_received_ce_bytes; | 342 | uint32_t	tcpi_received_ce_bytes; |
| 322 | uint16_t	tcpi_accecn_fail_mode; | 343 | uint32_t	tcpi_ecn_mode:2, |
| 323 | uint16_t	tcpi_accecn_opt_seen; | 344 | 		tcpi_accecn_opt_seen:2, |
| 345 | 		tcpi_accecn_fail_mode:4, | ||
| 346 | 		tcpi_options2:24; | ||
| 324 | }; | 347 | }; |
| 325 | 348 | ||
| 326 | /* Netlink attributes types for SCM_TIMESTAMPING_OPT_STATS */ | 349 | /* Netlink attributes types for SCM_TIMESTAMPING_OPT_STATS */ |
lib/libc/include/generic-glibc/regex.h+1-1| ... | @@ -74,7 +74,7 @@ typedef unsigned long int reg_syntax_t; | ... | @@ -74,7 +74,7 @@ typedef unsigned long int reg_syntax_t; |
| 74 | #ifdef __USE_GNU | 74 | #ifdef __USE_GNU |
| 75 | /* If this bit is not set, then \ inside a bracket expression is literal. | 75 | /* If this bit is not set, then \ inside a bracket expression is literal. |
| 76 | If set, then such a \ quotes the following character. */ | 76 | If set, then such a \ quotes the following character. */ |
| 77 | # define RE_BACKSLASH_ESCAPE_IN_LISTS ((unsigned long int) 1) | 77 | # define RE_BACKSLASH_ESCAPE_IN_LISTS 1ul |
| 78 | 78 | ||
| 79 | /* If this bit is not set, then + and ? are operators, and \+ and \? are | 79 | /* If this bit is not set, then + and ? are operators, and \+ and \? are |
| 80 | literals. | 80 | literals. |
lib/libc/include/generic-glibc/spawn.h+20| ... | @@ -200,6 +200,26 @@ extern int posix_spawn_file_actions_adddup2 (posix_spawn_file_actions_t * | ... | @@ -200,6 +200,26 @@ extern int posix_spawn_file_actions_adddup2 (posix_spawn_file_actions_t * |
| 200 | 					 int __fd, int __newfd) | 200 | 					 int __fd, int __newfd) |
| 201 | __THROW __nonnull ((1)); | 201 | __THROW __nonnull ((1)); |
| 202 | 202 | ||
| 203 | #ifdef __USE_XOPEN2K24XSI | ||
| 204 | |||
| 205 | /* Add an action changing the directory to PATH during spawn. This | ||
| 206 | affects the subsequent file actions. | ||
| 207 | Alias of posix_spawn_file_actions_addchdir_np. */ | ||
| 208 | extern int __REDIRECT_NTH (posix_spawn_file_actions_addchdir, | ||
| 209 | (posix_spawn_file_actions_t * __restrict __actions, | ||
| 210 | const char *__restrict __path), | ||
| 211 | posix_spawn_file_actions_addchdir_np); | ||
| 212 | |||
| 213 | /* Add an action changing the directory to FD during spawn. This | ||
| 214 | affects the subsequent file actions. FD is not duplicated and must | ||
| 215 | be open when the file action is executed. | ||
| 216 | Alias of posix_spawn_file_actions_addfchdir_np. */ | ||
| 217 | extern int __REDIRECT_NTH (posix_spawn_file_actions_addfchdir, | ||
| 218 | (posix_spawn_file_actions_t *, int __fd), | ||
| 219 | posix_spawn_file_actions_addfchdir_np); | ||
| 220 | |||
| 221 | #endif /* __USE_XOPEN2K24XSI */ | ||
| 222 | |||
| 203 | #ifdef __USE_MISC | 223 | #ifdef __USE_MISC |
| 204 | /* Add an action changing the directory to PATH during spawn. This | 224 | /* Add an action changing the directory to PATH during spawn. This |
| 205 | affects the subsequent file actions. */ | 225 | affects the subsequent file actions. */ |
lib/libc/include/generic-glibc/stdlib.h+1-1| ... | @@ -1225,4 +1225,4 @@ extern size_t memalignment (const void *__p); | ... | @@ -1225,4 +1225,4 @@ extern size_t memalignment (const void *__p); |
| 1225 | 1225 | ||
| 1226 | __END_DECLS | 1226 | __END_DECLS |
| 1227 | 1227 | ||
| 1228 | #endif /* stdlib.h */ | 1228 | #endif /* stdlib.h */ |
| \ No newline at end of file | |||
lib/libc/include/generic-glibc/sys/mount.h+18-4| ... | @@ -21,7 +21,6 @@ | ... | @@ -21,7 +21,6 @@ |
| 21 | #ifndef _SYS_MOUNT_H | 21 | #ifndef _SYS_MOUNT_H |
| 22 | #define _SYS_MOUNT_H	1 | 22 | #define _SYS_MOUNT_H	1 |
| 23 | 23 | ||
| 24 | #include <fcntl.h> | ||
| 25 | #include <features.h> | 24 | #include <features.h> |
| 26 | #include <stdint.h> | 25 | #include <stdint.h> |
| 27 | #include <stddef.h> | 26 | #include <stddef.h> |
| ... | @@ -190,6 +189,11 @@ enum | ... | @@ -190,6 +189,11 @@ enum |
| 190 | 189 | ||
| 191 | /* fsmount flags. */ | 190 | /* fsmount flags. */ |
| 192 | #define FSMOUNT_CLOEXEC 0x00000001 | 191 | #define FSMOUNT_CLOEXEC 0x00000001 |
| 192 | // zig patch: check target glibc version | ||
| 193 | #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 44) || __GLIBC__ > 2 | ||
| 194 | #define FSMOUNT_NAMESPACE 0x00000002 /* Create the mount in a new mount | ||
| 195 | 					 namespace. */ | ||
| 196 | #endif /* (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 44) || __GLIBC__ > 2 */ | ||
| 193 | 197 | ||
| 194 | /* mount attributes used on fsmount. */ | 198 | /* mount attributes used on fsmount. */ |
| 195 | #define MOUNT_ATTR_RDONLY 0x00000001 /* Mount read-only. */ | 199 | #define MOUNT_ATTR_RDONLY 0x00000001 /* Mount read-only. */ |
| ... | @@ -267,10 +271,20 @@ enum fsconfig_command | ... | @@ -267,10 +271,20 @@ enum fsconfig_command |
| 267 | #define FSOPEN_CLOEXEC 0x00000001 | 271 | #define FSOPEN_CLOEXEC 0x00000001 |
| 268 | 272 | ||
| 269 | /* open_tree flags. */ | 273 | /* open_tree flags. */ |
| 270 | #define OPEN_TREE_CLONE 1 /* Clone the target tree and attach the clone */ | 274 | #ifndef OPEN_TREE_CLONE |
| 271 | #define OPEN_TREE_CLOEXEC O_CLOEXEC /* Close the file on execve() */ | 275 | # define OPEN_TREE_CLONE 1 /* Clone the target tree and attach the clone */ |
| 272 | 276 | #endif | |
| 277 | #define OPEN_TREE_NAMESPACE (1 << 1) /* Clone the target tree into a new mount | ||
| 278 | 					namespace */ | ||
| 279 | #ifndef O_CLOEXEC | ||
| 280 | # include <bits/cloexec.h> | ||
| 281 | # define O_CLOEXEC __O_CLOEXEC | ||
| 273 | #endif | 282 | #endif |
| 283 | #ifndef OPEN_TREE_CLOEXEC | ||
| 284 | # define OPEN_TREE_CLOEXEC O_CLOEXEC /* Close the file on execve() */ | ||
| 285 | #endif | ||
| 286 | |||
| 287 | #endif /* (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 36) || __GLIBC__ > 2 */ | ||
| 274 | 288 | ||
| 275 | __BEGIN_DECLS | 289 | __BEGIN_DECLS |
| 276 | 290 |
lib/libc/include/generic-glibc/sys/pidfd.h+26| ... | @@ -64,6 +64,15 @@ | ... | @@ -64,6 +64,15 @@ |
| 64 | #define PIDFD_INFO_EXIT (1UL << 3) | 64 | #define PIDFD_INFO_EXIT (1UL << 3) |
| 65 | /* Only returned if requested. */ | 65 | /* Only returned if requested. */ |
| 66 | #define PIDFD_INFO_COREDUMP (1UL << 4) | 66 | #define PIDFD_INFO_COREDUMP (1UL << 4) |
| 67 | // zig patch: check target glibc version | ||
| 68 | #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 44) || __GLIBC__ > 2 | ||
| 69 | /* Want/got supported mask flags */ | ||
| 70 | #define PIDFD_INFO_SUPPORTED_MASK (1UL << 5) | ||
| 71 | /* Always returned if PIDFD_INFO_COREDUMP is requested. */ | ||
| 72 | #define PIDFD_INFO_COREDUMP_SIGNAL (1UL << 6) | ||
| 73 | /* Always returned if PIDFD_INFO_COREDUMP is requested. */ | ||
| 74 | #define PIDFD_INFO_COREDUMP_CODE (1UL << 7) | ||
| 75 | #endif /* (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 44) || __GLIBC__ > 2 */ | ||
| 67 | 76 | ||
| 68 | 77 | ||
| 69 | /* Value for coredump_mask in pidfd_info. Only valid if PIDFD_INFO_COREDUMP | 78 | /* Value for coredump_mask in pidfd_info. Only valid if PIDFD_INFO_COREDUMP |
| ... | @@ -95,11 +104,28 @@ struct pidfd_info | ... | @@ -95,11 +104,28 @@ struct pidfd_info |
| 95 | __uint32_t fsgid; | 104 | __uint32_t fsgid; |
| 96 | __int32_t exit_code; | 105 | __int32_t exit_code; |
| 97 | __uint32_t coredump_mask; | 106 | __uint32_t coredump_mask; |
| 107 | // zig patch: check target glibc version | ||
| 108 | #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 44) || __GLIBC__ > 2 | ||
| 109 | __uint32_t coredump_signal; | ||
| 110 | __uint32_t coredump_code; | ||
| 111 | __uint32_t coredump_pad; | ||
| 112 | __uint64_t supported_mask; | ||
| 113 | #else | ||
| 98 | __uint32_t __spare1; | 114 | __uint32_t __spare1; |
| 115 | #endif /* (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 44) || __GLIBC__ > 2 */ | ||
| 99 | }; | 116 | }; |
| 100 | 117 | ||
| 101 | /* sizeof first published struct */ | 118 | /* sizeof first published struct */ |
| 102 | #define PIDFD_INFO_SIZE_VER0 64 | 119 | #define PIDFD_INFO_SIZE_VER0 64 |
| 120 | // zig patch: check target glibc version | ||
| 121 | #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 44) || __GLIBC__ > 2 | ||
| 122 | /* sizeof second published struct */ | ||
| 123 | #define PIDFD_INFO_SIZE_VER1 72 | ||
| 124 | /* sizeof third published struct */ | ||
| 125 | #define PIDFD_INFO_SIZE_VER2 80 | ||
| 126 | /* sizeof fourth published struct */ | ||
| 127 | #define PIDFD_INFO_SIZE_VER3 88 | ||
| 128 | #endif /* (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 44) || __GLIBC__ > 2 */ | ||
| 103 | 129 | ||
| 104 | #define PIDFD_GET_INFO _IOWR(PIDFS_IOCTL_MAGIC, 11, struct pidfd_info) | 130 | #define PIDFD_GET_INFO _IOWR(PIDFS_IOCTL_MAGIC, 11, struct pidfd_info) |
| 105 | 131 |
lib/libc/include/generic-glibc/sys/platform/ppc.h deleted-146| ... | @@ -1,146 +0,0 @@ | ||
| 1 | /* Facilities specific to the PowerPC architecture | ||
| 2 | Copyright (C) 2012-2026 Free Software Foundation, Inc. | ||
| 3 | This file is part of the GNU C Library. | ||
| 4 | |||
| 5 | The GNU C Library is free software; you can redistribute it and/or | ||
| 6 | modify it under the terms of the GNU Lesser General Public | ||
| 7 | License as published by the Free Software Foundation; either | ||
| 8 | version 2.1 of the License, or (at your option) any later version. | ||
| 9 | |||
| 10 | The GNU C Library is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 13 | Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public | ||
| 16 | License along with the GNU C Library; if not, see | ||
| 17 | <https://www.gnu.org/licenses/>. */ | ||
| 18 | |||
| 19 | #ifndef _SYS_PLATFORM_PPC_H | ||
| 20 | #define _SYS_PLATFORM_PPC_H	1 | ||
| 21 | |||
| 22 | #include <features.h> | ||
| 23 | #include <stdint.h> | ||
| 24 | #include <bits/ppc.h> | ||
| 25 | |||
| 26 | /* Read the Time Base Register. */ | ||
| 27 | static __inline__ uint64_t | ||
| 28 | __ppc_get_timebase (void) | ||
| 29 | { | ||
| 30 | #if __GNUC_PREREQ (4, 8) | ||
| 31 | return __builtin_ppc_get_timebase (); | ||
| 32 | #else | ||
| 33 | # ifdef __powerpc64__ | ||
| 34 | uint64_t __tb; | ||
| 35 | /* "volatile" is necessary here, because the user expects this assembly | ||
| 36 | isn't moved after an optimization. */ | ||
| 37 | __asm__ volatile ("mfspr %0, 268" : "=r" (__tb)); | ||
| 38 | return __tb; | ||
| 39 | # else /* not __powerpc64__ */ | ||
| 40 | uint32_t __tbu, __tbl, __tmp; \ | ||
| 41 | __asm__ volatile ("0:\n\t" | ||
| 42 | 		 "mftbu %0\n\t" | ||
| 43 | 		 "mftbl %1\n\t" | ||
| 44 | 		 "mftbu %2\n\t" | ||
| 45 | 		 "cmpw %0, %2\n\t" | ||
| 46 | 		 "bne- 0b" | ||
| 47 | 		 : "=r" (__tbu), "=r" (__tbl), "=r" (__tmp)); | ||
| 48 | return (((uint64_t) __tbu << 32) | __tbl); | ||
| 49 | # endif /* not __powerpc64__ */ | ||
| 50 | #endif | ||
| 51 | } | ||
| 52 | |||
| 53 | /* The following functions provide hints about the usage of shared processor | ||
| 54 | resources, as defined in ISA 2.06 and newer. */ | ||
| 55 | |||
| 56 | /* Provides a hint that performance will probably be improved if shared | ||
| 57 | resources dedicated to the executing processor are released for use by other | ||
| 58 | processors. */ | ||
| 59 | static __inline__ void | ||
| 60 | __ppc_yield (void) | ||
| 61 | { | ||
| 62 | __asm__ volatile ("or 27,27,27"); | ||
| 63 | } | ||
| 64 | |||
| 65 | /* Provides a hint that performance will probably be improved if shared | ||
| 66 | resources dedicated to the executing processor are released until | ||
| 67 | all outstanding storage accesses to caching-inhibited storage have been | ||
| 68 | completed. */ | ||
| 69 | static __inline__ void | ||
| 70 | __ppc_mdoio (void) | ||
| 71 | { | ||
| 72 | __asm__ volatile ("or 29,29,29"); | ||
| 73 | } | ||
| 74 | |||
| 75 | /* Provides a hint that performance will probably be improved if shared | ||
| 76 | resources dedicated to the executing processor are released until all | ||
| 77 | outstanding storage accesses to cacheable storage for which the data is not | ||
| 78 | in the cache have been completed. */ | ||
| 79 | static __inline__ void | ||
| 80 | __ppc_mdoom (void) | ||
| 81 | { | ||
| 82 | __asm__ volatile ("or 30,30,30"); | ||
| 83 | } | ||
| 84 | |||
| 85 | |||
| 86 | /* ISA 2.05 and beyond support the Program Priority Register (PPR) to adjust | ||
| 87 | thread priorities based on lock acquisition, wait and release. The ISA | ||
| 88 | defines the use of form 'or Rx,Rx,Rx' as the way to modify the PRI field. | ||
| 89 | The unprivileged priorities are: | ||
| 90 | Rx = 1 (low) | ||
| 91 | Rx = 2 (medium) | ||
| 92 | Rx = 6 (medium-low/normal) | ||
| 93 | The 'or' instruction form is a nop in previous hardware, so it is safe to | ||
| 94 | use unguarded. The default value is 'medium'. | ||
| 95 | */ | ||
| 96 | |||
| 97 | static __inline__ void | ||
| 98 | __ppc_set_ppr_med (void) | ||
| 99 | { | ||
| 100 | __asm__ volatile ("or 2,2,2"); | ||
| 101 | } | ||
| 102 | |||
| 103 | static __inline__ void | ||
| 104 | __ppc_set_ppr_med_low (void) | ||
| 105 | { | ||
| 106 | __asm__ volatile ("or 6,6,6"); | ||
| 107 | } | ||
| 108 | |||
| 109 | static __inline__ void | ||
| 110 | __ppc_set_ppr_low (void) | ||
| 111 | { | ||
| 112 | __asm__ volatile ("or 1,1,1"); | ||
| 113 | } | ||
| 114 | |||
| 115 | /* Power ISA 2.07 (Book II, Chapter 3) extends the priorities that can be set | ||
| 116 | to the Program Priority Register (PPR). The form 'or Rx,Rx,Rx' is used to | ||
| 117 | modify the PRI field of the PPR, the same way as described above. | ||
| 118 | The new priority levels are: | ||
| 119 | Rx = 31 (very low) | ||
| 120 | Rx = 5 (medium high) | ||
| 121 | Any program can set the priority to very low, low, medium low, and medium, | ||
| 122 | as these are unprivileged. | ||
| 123 | The medium high priority, on the other hand, is privileged, and may only be | ||
| 124 | set during certain time intervals by problem-state programs. If the program | ||
| 125 | priority is medium high when the time interval expires or if an attempt is | ||
| 126 | made to set the priority to medium high when it is not allowed, the PRI | ||
| 127 | field is set to medium. | ||
| 128 | */ | ||
| 129 | |||
| 130 | #ifdef _ARCH_PWR8 | ||
| 131 | |||
| 132 | static __inline__ void | ||
| 133 | __ppc_set_ppr_very_low (void) | ||
| 134 | { | ||
| 135 | __asm__ volatile ("or 31,31,31"); | ||
| 136 | } | ||
| 137 | |||
| 138 | static __inline__ void | ||
| 139 | __ppc_set_ppr_med_high (void) | ||
| 140 | { | ||
| 141 | __asm__ volatile ("or 5,5,5"); | ||
| 142 | } | ||
| 143 | |||
| 144 | #endif | ||
| 145 | |||
| 146 | #endif /* sys/platform/ppc.h */ | ||
| \ No newline at end of file | |||
lib/libc/include/generic-netbsd/fcntl.h+4-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | /*	$NetBSD: fcntl.h,v 1.57 2025/07/25 23:24:46 kre Exp $	*/ | 1 | /*	$NetBSD: fcntl.h,v 1.57.2.1 2026/06/16 09:06:50 martin Exp $	*/ |
| 2 | 2 | ||
| 3 | /*- | 3 | /*- |
| 4 | * Copyright (c) 1983, 1990, 1993 | 4 | * Copyright (c) 1983, 1990, 1993 |
| ... | @@ -121,6 +121,9 @@ | ... | @@ -121,6 +121,9 @@ |
| 121 | #if defined(_NETBSD_SOURCE) | 121 | #if defined(_NETBSD_SOURCE) |
| 122 | #define	O_NOSIGPIPE	0x01000000	/* don't deliver sigpipe */ | 122 | #define	O_NOSIGPIPE	0x01000000	/* don't deliver sigpipe */ |
| 123 | #define	O_REGULAR	0x02000000	/* fail if not a regular file */ | 123 | #define	O_REGULAR	0x02000000	/* fail if not a regular file */ |
| 124 | #endif | ||
| 125 | #if (_POSIX_C_SOURCE - 0) >= 200809L || (_XOPEN_SOURCE - 0 >= 700) || \ | ||
| 126 | defined(_NETBSD_SOURCE) | ||
| 124 | #define	O_EXEC		0x04000000	/* open for executing only */ | 127 | #define	O_EXEC		0x04000000	/* open for executing only */ |
| 125 | #endif | 128 | #endif |
| 126 | #if (_POSIX_C_SOURCE - 0) >= 202405L || (_XOPEN_SOURCE - 0 >= 800) || \ | 129 | #if (_POSIX_C_SOURCE - 0) >= 202405L || (_XOPEN_SOURCE - 0 >= 800) || \ |
lib/libc/include/generic-netbsd/i386/mcontext.h+23-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | /*	$NetBSD: mcontext.h,v 1.19 2024/11/30 01:04:10 christos Exp $	*/ | 1 | /*	$NetBSD: mcontext.h,v 1.19.2.1 2026/07/19 15:57:27 martin Exp $	*/ |
| 2 | 2 | ||
| 3 | /*- | 3 | /*- |
| 4 | * Copyright (c) 1999 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 1999 The NetBSD Foundation, Inc. |
| ... | @@ -40,6 +40,7 @@ | ... | @@ -40,6 +40,7 @@ |
| 40 | #define	_UC_CLRSTACK	_UC_MD_BIT17 | 40 | #define	_UC_CLRSTACK	_UC_MD_BIT17 |
| 41 | #define	_UC_VM		_UC_MD_BIT18 | 41 | #define	_UC_VM		_UC_MD_BIT18 |
| 42 | #define	_UC_TLSBASE	_UC_MD_BIT19 | 42 | #define	_UC_TLSBASE	_UC_MD_BIT19 |
| 43 | #define	_UC_XSAVE	_UC_MD_BIT20 | ||
| 43 | 44 | ||
| 44 | /* | 45 | /* |
| 45 | * Layout of mcontext_t according to the System V Application Binary Interface, | 46 | * Layout of mcontext_t according to the System V Application Binary Interface, |
| ... | @@ -85,6 +86,27 @@ typedef struct { | ... | @@ -85,6 +86,27 @@ typedef struct { |
| 85 | 			char	__fp_xmm[512]; | 86 | 			char	__fp_xmm[512]; |
| 86 | 		} __fp_xmm_state;	/* x87 and xmm regs in fxsave format */ | 87 | 		} __fp_xmm_state;	/* x87 and xmm regs in fxsave format */ |
| 87 | 		int	__fp_fpregs[128]; | 88 | 		int	__fp_fpregs[128]; |
| 89 | 		struct { | ||
| 90 | 			/* | ||
| 91 | 			 * `The XSAVE feature set does not use bytes | ||
| 92 | 			 * 511:416; bytes 463:416 are reserved.' | ||
| 93 | 			 * | ||
| 94 | 			 * We take a part out of this to form a pointer | ||
| 95 | 			 * to an external XSAVE area. This way, we can | ||
| 96 | 			 * replicate the FXSAVE parts for the benefit | ||
| 97 | 			 * of userland programs that aren't aware of | ||
| 98 | 			 * the XSAVE pointer, have used the extended | ||
| 99 | 			 * CPU registers (ymmN/zmmN/&c.), and want to | ||
| 100 | 			 * examine the x87/SSE register state in a | ||
| 101 | 			 * signal handler. The kernel does not use | ||
| 102 | 			 * this part. | ||
| 103 | 			 */ | ||
| 104 | 			char		__fxsave[416]; | ||
| 105 | 			char		__rsvd[48]; | ||
| 106 | 			__greg_t	__xsaveptr; | ||
| 107 | 			__greg_t	__xsavelen; | ||
| 108 | 			char		__pad[40]; | ||
| 109 | 		} __xsave; | ||
| 88 | 	} __fp_reg_set; | 110 | 	} __fp_reg_set; |
| 89 | 	int 	__fp_pad[33];			/* Historic padding */ | 111 | 	int 	__fp_pad[33];			/* Historic padding */ |
| 90 | } __fpregset_t; | 112 | } __fpregset_t; |
lib/libc/include/generic-netbsd/i386/wchar_limits.h+1-1| ... | @@ -44,4 +44,4 @@ | ... | @@ -44,4 +44,4 @@ |
| 44 | #define	WINT_MIN	(-0x7fffffff-1)			/* wint_t	 */ | 44 | #define	WINT_MIN	(-0x7fffffff-1)			/* wint_t	 */ |
| 45 | #define	WINT_MAX	0x7fffffff			/* wint_t	 */ | 45 | #define	WINT_MAX	0x7fffffff			/* wint_t	 */ |
| 46 | 46 | ||
| 47 | #endif /* !_I386_WCHAR_LIMITS_H_ */ | 47 | #endif /* !_I386_WCHAR_LIMITS_H_ */ |
| \ No newline at end of file | |||
lib/libc/include/generic-netbsd/machine/pte.h+32-19| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | /* $NetBSD: pte.h,v 1.14.2.2 2025/10/26 12:28:36 martin Exp $ */ | 1 | /* $NetBSD: pte.h,v 1.14.2.3 2026/06/03 18:17:02 martin Exp $ */ |
| 2 | 2 | ||
| 3 | /* | 3 | /* |
| 4 | * Copyright (c) 2014, 2019, 2021 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 2014, 2019, 2021 The NetBSD Foundation, Inc. |
| ... | @@ -139,6 +139,12 @@ pte_modified_p(pt_entry_t pte) | ... | @@ -139,6 +139,12 @@ pte_modified_p(pt_entry_t pte) |
| 139 | 	return (pte & PTE_D) != 0; | 139 | 	return (pte & PTE_D) != 0; |
| 140 | } | 140 | } |
| 141 | 141 | ||
| 142 | static inline bool | ||
| 143 | pte_referenced_p(pt_entry_t pte) | ||
| 144 | { | ||
| 145 | 	return (pte & PTE_A) != 0; | ||
| 146 | } | ||
| 147 | |||
| 142 | static inline bool | 148 | static inline bool |
| 143 | pte_cached_p(pt_entry_t pte) | 149 | pte_cached_p(pt_entry_t pte) |
| 144 | { | 150 | { |
| ... | @@ -177,9 +183,15 @@ pte_nv_entry(bool kernel_p) | ... | @@ -177,9 +183,15 @@ pte_nv_entry(bool kernel_p) |
| 177 | } | 183 | } |
| 178 | 184 | ||
| 179 | static inline pt_entry_t | 185 | static inline pt_entry_t |
| 180 | pte_prot_nowrite(pt_entry_t pte) | 186 | pte_clear_modify(pt_entry_t pte) |
| 187 | { | ||
| 188 | 	return pte & ~PTE_D; | ||
| 189 | } | ||
| 190 | |||
| 191 | static inline pt_entry_t | ||
| 192 | pte_clear_reference(pt_entry_t pte) | ||
| 181 | { | 193 | { |
| 182 | 	return pte & ~PTE_W; | 194 | 	return pte & ~PTE_A; |
| 183 | } | 195 | } |
| 184 | 196 | ||
| 185 | static inline pt_entry_t | 197 | static inline pt_entry_t |
| ... | @@ -237,28 +249,29 @@ pte_make_enter(paddr_t pa, struct vm_page_md *mdpg, vm_prot_t prot, | ... | @@ -237,28 +249,29 @@ pte_make_enter(paddr_t pa, struct vm_page_md *mdpg, vm_prot_t prot, |
| 237 | 	pte |= pte_prot_bits(mdpg, prot, kernel_p); | 249 | 	pte |= pte_prot_bits(mdpg, prot, kernel_p); |
| 238 | 	pte |= pte_enter_flags_to_pbmt(flags); | 250 | 	pte |= pte_enter_flags_to_pbmt(flags); |
| 239 | 251 | ||
| 240 | 	if (mdpg != NULL) { | 252 | 	/* |
| 253 | 	 * pmap_enter should have checked flags and updated | ||
| 254 | 	 * VM_PAGEMD_{REFERENCED,MODIFIED}_P, so there is no | ||
| 255 | 	 * need here. | ||
| 256 | 	 */ | ||
| 257 | 	KASSERT(((flags & VM_PROT_ALL) == 0) || VM_PAGEMD_REFERENCED_P(mdpg)); | ||
| 258 | 	KASSERT(((flags & VM_PROT_WRITE) == 0) || VM_PAGEMD_MODIFIED_P(mdpg)); | ||
| 241 | 259 | ||
| 242 | 		if ((prot & VM_PROT_WRITE) != 0 && | 260 | 	if (mdpg != NULL) { |
| 243 | 		 ((flags & VM_PROT_WRITE) != 0 || VM_PAGEMD_MODIFIED_P(mdpg))) { | 261 | 		if ((prot & VM_PROT_WRITE) != 0 && VM_PAGEMD_MODIFIED_P(mdpg)) { |
| 244 | 			/* | 262 | 			/* |
| 245 | 			* This is a writable mapping, and the page's mod state | 263 | 			 * This is a writable mapping, and the page's mod state |
| 246 | 			* indicates it has already been modified. No need for | 264 | 			 * indicates it has already been modified. No need for |
| 247 | 			* modified emulation. | 265 | 			 * reference or modified emulation. |
| 248 | 			*/ | 266 | 			 */ |
| 249 | 			pte |= PTE_A | PTE_D; | 267 | 			pte |= PTE_A | PTE_D; |
| 250 | 		} else if ((flags & VM_PROT_ALL) || VM_PAGEMD_REFERENCED_P(mdpg)) { | 268 | 		} else if (VM_PAGEMD_REFERENCED_P(mdpg)) { |
| 251 | 			/* | 269 | 			/* |
| 252 | 			* - The access type indicates that we don't need to do | 270 | 			 * The physical page has already been referenced so no need |
| 253 | 			* referenced emulation. | 271 | 			 * to re-do referenced emulation here. |
| 254 | 			* OR | 272 | 			 */ |
| 255 | 			* - The physical page has already been referenced so no need | ||
| 256 | 			* to re-do referenced emulation here. | ||
| 257 | 			*/ | ||
| 258 | 			pte |= PTE_A; | 273 | 			pte |= PTE_A; |
| 259 | 		} | 274 | 		} |
| 260 | 	} else { | ||
| 261 | 		pte |= PTE_A | PTE_D; | ||
| 262 | 	} | 275 | 	} |
| 263 | 276 | ||
| 264 | 	return pte; | 277 | 	return pte; |
lib/libc/include/generic-netbsd/machine/vmparam.h+21-9| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | /*	$NetBSD: vmparam.h,v 1.14 2023/05/07 12:41:48 skrll Exp $	*/ | 1 | /*	$NetBSD: vmparam.h,v 1.14.8.2 2026/06/03 18:17:02 martin Exp $	*/ |
| 2 | 2 | ||
| 3 | /*- | 3 | /*- |
| 4 | * Copyright (c) 2014, 2020 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 2014, 2020 The NetBSD Foundation, Inc. |
| ... | @@ -50,6 +50,25 @@ | ... | @@ -50,6 +50,25 @@ |
| 50 | #define	PAGE_SIZE	(1 << PAGE_SHIFT) | 50 | #define	PAGE_SIZE	(1 << PAGE_SHIFT) |
| 51 | #define	PAGE_MASK	(PAGE_SIZE - 1) | 51 | #define	PAGE_MASK	(PAGE_SIZE - 1) |
| 52 | 52 | ||
| 53 | #ifdef _LP64 | ||
| 54 | /* | ||
| 55 | * Default pager_map of 16MB is awfully small. There is plenty | ||
| 56 | * of VA so use it. | ||
| 57 | */ | ||
| 58 | #define	PAGER_MAP_DEFAULT_SIZE (512 * 1024 * 1024) | ||
| 59 | |||
| 60 | /* | ||
| 61 | * Defaults for Unified Buffer Cache parameters. | ||
| 62 | */ | ||
| 63 | |||
| 64 | #ifndef UBC_WINSHIFT | ||
| 65 | #define	UBC_WINSHIFT	16	/* 64kB */ | ||
| 66 | #endif | ||
| 67 | #ifndef UBC_NWINS | ||
| 68 | #define	UBC_NWINS	4096	/* 256MB */ | ||
| 69 | #endif | ||
| 70 | #endif | ||
| 71 | |||
| 53 | /* | 72 | /* |
| 54 | * USRSTACK is the top (end) of the user stack. | 73 | * USRSTACK is the top (end) of the user stack. |
| 55 | * | 74 | * |
| ... | @@ -125,12 +144,6 @@ | ... | @@ -125,12 +144,6 @@ |
| 125 | #define VM_MAX_KERNEL_ADDRESS	((vaddr_t)0xffffffd000000000) | 144 | #define VM_MAX_KERNEL_ADDRESS	((vaddr_t)0xffffffd000000000) |
| 126 | 145 | ||
| 127 | #else		/* Sv32 */ | 146 | #else		/* Sv32 */ |
| 128 | /* | ||
| 129 | * kernel virtual space layout: | ||
| 130 | * 0x8000_0000 - 64GiB KERNEL VM Space (inc. text/data/bss) | ||
| 131 | * (0x4000_0000 +1GiB) KERNEL VM start of KVA | ||
| 132 | * (0x0000_0000 64GiB) reserved | ||
| 133 | */ | ||
| 134 | 147 | ||
| 135 | /* | 148 | /* |
| 136 | * kernel virtual space layout without direct map (common case) | 149 | * kernel virtual space layout without direct map (common case) |
| ... | @@ -154,13 +167,12 @@ | ... | @@ -154,13 +167,12 @@ |
| 154 | * | 167 | * |
| 155 | */ | 168 | */ |
| 156 | 169 | ||
| 157 | |||
| 158 | |||
| 159 | #define VM_MAXUSER_ADDRESS	((vaddr_t)-0x7fffffff-1)/* 0xffff_ffff_8000_0000 */ | 170 | #define VM_MAXUSER_ADDRESS	((vaddr_t)-0x7fffffff-1)/* 0xffff_ffff_8000_0000 */ |
| 160 | #define VM_MIN_KERNEL_ADDRESS	((vaddr_t)-0x7fffffff-1)/* 0xffff_ffff_8000_0000 */ | 171 | #define VM_MIN_KERNEL_ADDRESS	((vaddr_t)-0x7fffffff-1)/* 0xffff_ffff_8000_0000 */ |
| 161 | #define VM_MAX_KERNEL_ADDRESS	((vaddr_t)-0x10000000)	/* 0xffff_ffff_f000_0000 */ | 172 | #define VM_MAX_KERNEL_ADDRESS	((vaddr_t)-0x10000000)	/* 0xffff_ffff_f000_0000 */ |
| 162 | 173 | ||
| 163 | #endif | 174 | #endif |
| 175 | |||
| 164 | #define VM_KERNEL_BASE		VM_MIN_KERNEL_ADDRESS | 176 | #define VM_KERNEL_BASE		VM_MIN_KERNEL_ADDRESS |
| 165 | #define VM_KERNEL_SIZE		0x2000000	/* 32 MiB (8 / 16 megapages) */ | 177 | #define VM_KERNEL_SIZE		0x2000000	/* 32 MiB (8 / 16 megapages) */ |
| 166 | #define VM_KERNEL_DTB_BASE	(VM_KERNEL_BASE + VM_KERNEL_SIZE) | 178 | #define VM_KERNEL_DTB_BASE	(VM_KERNEL_BASE + VM_KERNEL_SIZE) |
lib/libc/include/generic-netbsd/mips/pte.h+14-2| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | /*	$NetBSD: pte.h,v 1.27 2020/08/22 15:34:51 skrll Exp $	*/ | 1 | /*	$NetBSD: pte.h,v 1.27.28.1 2026/06/03 18:17:03 martin Exp $	*/ |
| 2 | 2 | ||
| 3 | /*- | 3 | /*- |
| 4 | * Copyright (c) 1997 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 1997 The NetBSD Foundation, Inc. |
| ... | @@ -269,6 +269,12 @@ pte_modified_p(pt_entry_t pte) | ... | @@ -269,6 +269,12 @@ pte_modified_p(pt_entry_t pte) |
| 269 | 	return (pte & MIPS_MMU(PG_D)) != 0; | 269 | 	return (pte & MIPS_MMU(PG_D)) != 0; |
| 270 | } | 270 | } |
| 271 | 271 | ||
| 272 | static inline bool | ||
| 273 | pte_referenced_p(pt_entry_t pte) | ||
| 274 | { | ||
| 275 | 	return false; | ||
| 276 | } | ||
| 277 | |||
| 272 | static inline bool | 278 | static inline bool |
| 273 | pte_global_p(pt_entry_t pte) | 279 | pte_global_p(pt_entry_t pte) |
| 274 | { | 280 | { |
| ... | @@ -340,11 +346,17 @@ pte_prot_downgrade(pt_entry_t pte, vm_prot_t prot) | ... | @@ -340,11 +346,17 @@ pte_prot_downgrade(pt_entry_t pte, vm_prot_t prot) |
| 340 | } | 346 | } |
| 341 | 347 | ||
| 342 | static inline pt_entry_t | 348 | static inline pt_entry_t |
| 343 | pte_prot_nowrite(pt_entry_t pte) | 349 | pte_clear_modify(pt_entry_t pte) |
| 344 | { | 350 | { |
| 345 | 	return pte & ~MIPS_MMU(PG_D); | 351 | 	return pte & ~MIPS_MMU(PG_D); |
| 346 | } | 352 | } |
| 347 | 353 | ||
| 354 | static inline pt_entry_t | ||
| 355 | pte_clear_reference(pt_entry_t pte) | ||
| 356 | { | ||
| 357 | 	return pte; | ||
| 358 | } | ||
| 359 | |||
| 348 | static inline pt_entry_t | 360 | static inline pt_entry_t |
| 349 | pte_cached_change(pt_entry_t pte, bool cached) | 361 | pte_cached_change(pt_entry_t pte, bool cached) |
| 350 | { | 362 | { |
lib/libc/include/generic-netbsd/netinet/tcp_timer.h+2-2| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | /*	$NetBSD: tcp_timer.h,v 1.30 2019/08/06 15:48:18 riastradh Exp $	*/ | 1 | /*	$NetBSD: tcp_timer.h,v 1.30.34.1 2026/07/19 15:51:03 martin Exp $	*/ |
| 2 | 2 | ||
| 3 | /*- | 3 | /*- |
| 4 | * Copyright (c) 2001, 2005 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 2001, 2005 The NetBSD Foundation, Inc. |
| ... | @@ -119,7 +119,7 @@ | ... | @@ -119,7 +119,7 @@ |
| 119 | #define	TCPTV_MSL	( 30*PR_SLOWHZ)		/* max seg lifetime (hah!) */ | 119 | #define	TCPTV_MSL	( 30*PR_SLOWHZ)		/* max seg lifetime (hah!) */ |
| 120 | #define	TCPTV_SRTTBASE	0			/* base roundtrip time; | 120 | #define	TCPTV_SRTTBASE	0			/* base roundtrip time; |
| 121 | 						 if 0, no idea yet */ | 121 | 						 if 0, no idea yet */ |
| 122 | #define	TCPTV_SRTTDFLT	( 3*PR_SLOWHZ)		/* assumed RTT if no info */ | 122 | #define	TCPTV_SRTTDFLT	( 1*PR_SLOWHZ)		/* initial RTO; RFC 6298 (2.1) */ |
| 123 | 123 | ||
| 124 | #define	TCPTV_PERSMIN	( 5*PR_SLOWHZ)		/* retransmit persistance */ | 124 | #define	TCPTV_PERSMIN	( 5*PR_SLOWHZ)		/* retransmit persistance */ |
| 125 | #define	TCPTV_PERSMAX	( 60*PR_SLOWHZ)		/* maximum persist interval */ | 125 | #define	TCPTV_PERSMAX	( 60*PR_SLOWHZ)		/* maximum persist interval */ |
lib/libc/include/generic-netbsd/nfs/nfs.h+3-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | /*	$NetBSD: nfs.h,v 1.81 2024/12/07 02:05:55 riastradh Exp $	*/ | 1 | /*	$NetBSD: nfs.h,v 1.81.2.1 2026/06/27 09:46:05 martin Exp $	*/ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 1989, 1993, 1995 | 3 | * Copyright (c) 1989, 1993, 1995 |
| 4 | *	The Regents of the University of California. All rights reserved. | 4 | *	The Regents of the University of California. All rights reserved. |
| ... | @@ -451,6 +451,8 @@ struct nfssvc_sock { | ... | @@ -451,6 +451,8 @@ struct nfssvc_sock { |
| 451 | 	int		ns_sflags;		/* b: */ | 451 | 	int		ns_sflags;		/* b: */ |
| 452 | 	int		ns_cc;			/* b: */ | 452 | 	int		ns_cc;			/* b: */ |
| 453 | 	int		ns_reclen;		/* b: */ | 453 | 	int		ns_reclen;		/* b: */ |
| 454 | 	int		ns_frag_count;		/* b: */ | ||
| 455 | 	int		ns_streamlen;		/* b: */ | ||
| 454 | 	int		ns_numuids; | 456 | 	int		ns_numuids; |
| 455 | 	u_int32_t	ns_sref;		/* g: */ | 457 | 	u_int32_t	ns_sref;		/* g: */ |
| 456 | 	SIMPLEQ_HEAD(, nfsrv_descript) ns_sendq; /* s: send reply list */ | 458 | 	SIMPLEQ_HEAD(, nfsrv_descript) ns_sendq; /* s: send reply list */ |
lib/libc/include/generic-netbsd/nfs/nfsmount.h+4-2| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | /*	$NetBSD: nfsmount.h,v 1.54 2024/12/07 02:05:55 riastradh Exp $	*/ | 1 | /*	$NetBSD: nfsmount.h,v 1.54.2.1 2026/06/03 18:46:36 martin Exp $	*/ |
| 2 | 2 | ||
| 3 | /* | 3 | /* |
| 4 | * Copyright (c) 1989, 1993 | 4 | * Copyright (c) 1989, 1993 |
| ... | @@ -92,13 +92,15 @@ struct nfs_args { | ... | @@ -92,13 +92,15 @@ struct nfs_args { |
| 92 | #define	NFSMNT_READDIRSIZE	0x00020000 /* Set readdir size */ | 92 | #define	NFSMNT_READDIRSIZE	0x00020000 /* Set readdir size */ |
| 93 | #define NFSMNT_XLATECOOKIE	0x00040000 /* 32<->64 dir cookie xlation */ | 93 | #define NFSMNT_XLATECOOKIE	0x00040000 /* 32<->64 dir cookie xlation */ |
| 94 | #define	NFSMNT_NOAC		0x00080000 /* Turn off attribute cache */ | 94 | #define	NFSMNT_NOAC		0x00080000 /* Turn off attribute cache */ |
| 95 | #define	NFSMNT_NOWCCMSG		0x00100000 /* Turn off attribute wcc messages */ | ||
| 95 | 96 | ||
| 96 | #define NFSMNT_BITS	"\177\20" \ | 97 | #define NFSMNT_BITS	"\177\20" \ |
| 97 | "b\00soft\0b\01wsize\0b\02rsize\0b\03timeo\0" \ | 98 | "b\00soft\0b\01wsize\0b\02rsize\0b\03timeo\0" \ |
| 98 | "b\04retrans\0b\05maxgrps\0b\06intr\0b\07noconn\0" \ | 99 | "b\04retrans\0b\05maxgrps\0b\06intr\0b\07noconn\0" \ |
| 99 | "b\10nqnfs\0b\11nfsv3\0b\12kerb\0b\13dumbtimr\0" \ | 100 | "b\10nqnfs\0b\11nfsv3\0b\12kerb\0b\13dumbtimr\0" \ |
| 100 | "b\14leaseterm\0b\15readahead\0b\16deadthresh\0b\17resvport\0" \ | 101 | "b\14leaseterm\0b\15readahead\0b\16deadthresh\0b\17resvport\0" \ |
| 101 | "b\20rdirplus\0b\21readdirsize\0b\22xlatecookie\0b\23noac\0" | 102 | "b\20rdirplus\0b\21readdirsize\0b\22xlatecookie\0b\23noac\0" \ |
| 103 | "b\24nowccmsg\0" | ||
| 102 | 104 | ||
| 103 | /* | 105 | /* |
| 104 | * NFS internal flags (nm_iflag) */ | 106 | * NFS internal flags (nm_iflag) */ |
lib/libc/include/generic-netbsd/pthread.h+1-1| ... | @@ -461,4 +461,4 @@ __END_DECLS | ... | @@ -461,4 +461,4 @@ __END_DECLS |
| 461 | 461 | ||
| 462 | #endif /* __LIBPTHREAD_SOURCE__ */ | 462 | #endif /* __LIBPTHREAD_SOURCE__ */ |
| 463 | 463 | ||
| 464 | #endif /* _LIB_PTHREAD_H */ | 464 | #endif /* _LIB_PTHREAD_H */ |
| \ No newline at end of file | |||
lib/libc/include/generic-netbsd/riscv/pte.h+32-19| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | /* $NetBSD: pte.h,v 1.14.2.2 2025/10/26 12:28:36 martin Exp $ */ | 1 | /* $NetBSD: pte.h,v 1.14.2.3 2026/06/03 18:17:02 martin Exp $ */ |
| 2 | 2 | ||
| 3 | /* | 3 | /* |
| 4 | * Copyright (c) 2014, 2019, 2021 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 2014, 2019, 2021 The NetBSD Foundation, Inc. |
| ... | @@ -139,6 +139,12 @@ pte_modified_p(pt_entry_t pte) | ... | @@ -139,6 +139,12 @@ pte_modified_p(pt_entry_t pte) |
| 139 | 	return (pte & PTE_D) != 0; | 139 | 	return (pte & PTE_D) != 0; |
| 140 | } | 140 | } |
| 141 | 141 | ||
| 142 | static inline bool | ||
| 143 | pte_referenced_p(pt_entry_t pte) | ||
| 144 | { | ||
| 145 | 	return (pte & PTE_A) != 0; | ||
| 146 | } | ||
| 147 | |||
| 142 | static inline bool | 148 | static inline bool |
| 143 | pte_cached_p(pt_entry_t pte) | 149 | pte_cached_p(pt_entry_t pte) |
| 144 | { | 150 | { |
| ... | @@ -177,9 +183,15 @@ pte_nv_entry(bool kernel_p) | ... | @@ -177,9 +183,15 @@ pte_nv_entry(bool kernel_p) |
| 177 | } | 183 | } |
| 178 | 184 | ||
| 179 | static inline pt_entry_t | 185 | static inline pt_entry_t |
| 180 | pte_prot_nowrite(pt_entry_t pte) | 186 | pte_clear_modify(pt_entry_t pte) |
| 187 | { | ||
| 188 | 	return pte & ~PTE_D; | ||
| 189 | } | ||
| 190 | |||
| 191 | static inline pt_entry_t | ||
| 192 | pte_clear_reference(pt_entry_t pte) | ||
| 181 | { | 193 | { |
| 182 | 	return pte & ~PTE_W; | 194 | 	return pte & ~PTE_A; |
| 183 | } | 195 | } |
| 184 | 196 | ||
| 185 | static inline pt_entry_t | 197 | static inline pt_entry_t |
| ... | @@ -237,28 +249,29 @@ pte_make_enter(paddr_t pa, struct vm_page_md *mdpg, vm_prot_t prot, | ... | @@ -237,28 +249,29 @@ pte_make_enter(paddr_t pa, struct vm_page_md *mdpg, vm_prot_t prot, |
| 237 | 	pte |= pte_prot_bits(mdpg, prot, kernel_p); | 249 | 	pte |= pte_prot_bits(mdpg, prot, kernel_p); |
| 238 | 	pte |= pte_enter_flags_to_pbmt(flags); | 250 | 	pte |= pte_enter_flags_to_pbmt(flags); |
| 239 | 251 | ||
| 240 | 	if (mdpg != NULL) { | 252 | 	/* |
| 253 | 	 * pmap_enter should have checked flags and updated | ||
| 254 | 	 * VM_PAGEMD_{REFERENCED,MODIFIED}_P, so there is no | ||
| 255 | 	 * need here. | ||
| 256 | 	 */ | ||
| 257 | 	KASSERT(((flags & VM_PROT_ALL) == 0) || VM_PAGEMD_REFERENCED_P(mdpg)); | ||
| 258 | 	KASSERT(((flags & VM_PROT_WRITE) == 0) || VM_PAGEMD_MODIFIED_P(mdpg)); | ||
| 241 | 259 | ||
| 242 | 		if ((prot & VM_PROT_WRITE) != 0 && | 260 | 	if (mdpg != NULL) { |
| 243 | 		 ((flags & VM_PROT_WRITE) != 0 || VM_PAGEMD_MODIFIED_P(mdpg))) { | 261 | 		if ((prot & VM_PROT_WRITE) != 0 && VM_PAGEMD_MODIFIED_P(mdpg)) { |
| 244 | 			/* | 262 | 			/* |
| 245 | 			* This is a writable mapping, and the page's mod state | 263 | 			 * This is a writable mapping, and the page's mod state |
| 246 | 			* indicates it has already been modified. No need for | 264 | 			 * indicates it has already been modified. No need for |
| 247 | 			* modified emulation. | 265 | 			 * reference or modified emulation. |
| 248 | 			*/ | 266 | 			 */ |
| 249 | 			pte |= PTE_A | PTE_D; | 267 | 			pte |= PTE_A | PTE_D; |
| 250 | 		} else if ((flags & VM_PROT_ALL) || VM_PAGEMD_REFERENCED_P(mdpg)) { | 268 | 		} else if (VM_PAGEMD_REFERENCED_P(mdpg)) { |
| 251 | 			/* | 269 | 			/* |
| 252 | 			* - The access type indicates that we don't need to do | 270 | 			 * The physical page has already been referenced so no need |
| 253 | 			* referenced emulation. | 271 | 			 * to re-do referenced emulation here. |
| 254 | 			* OR | 272 | 			 */ |
| 255 | 			* - The physical page has already been referenced so no need | ||
| 256 | 			* to re-do referenced emulation here. | ||
| 257 | 			*/ | ||
| 258 | 			pte |= PTE_A; | 273 | 			pte |= PTE_A; |
| 259 | 		} | 274 | 		} |
| 260 | 	} else { | ||
| 261 | 		pte |= PTE_A | PTE_D; | ||
| 262 | 	} | 275 | 	} |
| 263 | 276 | ||
| 264 | 	return pte; | 277 | 	return pte; |
lib/libc/include/generic-netbsd/riscv/vmparam.h+21-9| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | /*	$NetBSD: vmparam.h,v 1.14 2023/05/07 12:41:48 skrll Exp $	*/ | 1 | /*	$NetBSD: vmparam.h,v 1.14.8.2 2026/06/03 18:17:02 martin Exp $	*/ |
| 2 | 2 | ||
| 3 | /*- | 3 | /*- |
| 4 | * Copyright (c) 2014, 2020 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 2014, 2020 The NetBSD Foundation, Inc. |
| ... | @@ -50,6 +50,25 @@ | ... | @@ -50,6 +50,25 @@ |
| 50 | #define	PAGE_SIZE	(1 << PAGE_SHIFT) | 50 | #define	PAGE_SIZE	(1 << PAGE_SHIFT) |
| 51 | #define	PAGE_MASK	(PAGE_SIZE - 1) | 51 | #define	PAGE_MASK	(PAGE_SIZE - 1) |
| 52 | 52 | ||
| 53 | #ifdef _LP64 | ||
| 54 | /* | ||
| 55 | * Default pager_map of 16MB is awfully small. There is plenty | ||
| 56 | * of VA so use it. | ||
| 57 | */ | ||
| 58 | #define	PAGER_MAP_DEFAULT_SIZE (512 * 1024 * 1024) | ||
| 59 | |||
| 60 | /* | ||
| 61 | * Defaults for Unified Buffer Cache parameters. | ||
| 62 | */ | ||
| 63 | |||
| 64 | #ifndef UBC_WINSHIFT | ||
| 65 | #define	UBC_WINSHIFT	16	/* 64kB */ | ||
| 66 | #endif | ||
| 67 | #ifndef UBC_NWINS | ||
| 68 | #define	UBC_NWINS	4096	/* 256MB */ | ||
| 69 | #endif | ||
| 70 | #endif | ||
| 71 | |||
| 53 | /* | 72 | /* |
| 54 | * USRSTACK is the top (end) of the user stack. | 73 | * USRSTACK is the top (end) of the user stack. |
| 55 | * | 74 | * |
| ... | @@ -125,12 +144,6 @@ | ... | @@ -125,12 +144,6 @@ |
| 125 | #define VM_MAX_KERNEL_ADDRESS	((vaddr_t)0xffffffd000000000) | 144 | #define VM_MAX_KERNEL_ADDRESS	((vaddr_t)0xffffffd000000000) |
| 126 | 145 | ||
| 127 | #else		/* Sv32 */ | 146 | #else		/* Sv32 */ |
| 128 | /* | ||
| 129 | * kernel virtual space layout: | ||
| 130 | * 0x8000_0000 - 64GiB KERNEL VM Space (inc. text/data/bss) | ||
| 131 | * (0x4000_0000 +1GiB) KERNEL VM start of KVA | ||
| 132 | * (0x0000_0000 64GiB) reserved | ||
| 133 | */ | ||
| 134 | 147 | ||
| 135 | /* | 148 | /* |
| 136 | * kernel virtual space layout without direct map (common case) | 149 | * kernel virtual space layout without direct map (common case) |
| ... | @@ -154,13 +167,12 @@ | ... | @@ -154,13 +167,12 @@ |
| 154 | * | 167 | * |
| 155 | */ | 168 | */ |
| 156 | 169 | ||
| 157 | |||
| 158 | |||
| 159 | #define VM_MAXUSER_ADDRESS	((vaddr_t)-0x7fffffff-1)/* 0xffff_ffff_8000_0000 */ | 170 | #define VM_MAXUSER_ADDRESS	((vaddr_t)-0x7fffffff-1)/* 0xffff_ffff_8000_0000 */ |
| 160 | #define VM_MIN_KERNEL_ADDRESS	((vaddr_t)-0x7fffffff-1)/* 0xffff_ffff_8000_0000 */ | 171 | #define VM_MIN_KERNEL_ADDRESS	((vaddr_t)-0x7fffffff-1)/* 0xffff_ffff_8000_0000 */ |
| 161 | #define VM_MAX_KERNEL_ADDRESS	((vaddr_t)-0x10000000)	/* 0xffff_ffff_f000_0000 */ | 172 | #define VM_MAX_KERNEL_ADDRESS	((vaddr_t)-0x10000000)	/* 0xffff_ffff_f000_0000 */ |
| 162 | 173 | ||
| 163 | #endif | 174 | #endif |
| 175 | |||
| 164 | #define VM_KERNEL_BASE		VM_MIN_KERNEL_ADDRESS | 176 | #define VM_KERNEL_BASE		VM_MIN_KERNEL_ADDRESS |
| 165 | #define VM_KERNEL_SIZE		0x2000000	/* 32 MiB (8 / 16 megapages) */ | 177 | #define VM_KERNEL_SIZE		0x2000000	/* 32 MiB (8 / 16 megapages) */ |
| 166 | #define VM_KERNEL_DTB_BASE	(VM_KERNEL_BASE + VM_KERNEL_SIZE) | 178 | #define VM_KERNEL_DTB_BASE	(VM_KERNEL_BASE + VM_KERNEL_SIZE) |
lib/libc/include/generic-netbsd/sys/fcntl.h+4-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | /*	$NetBSD: fcntl.h,v 1.57 2025/07/25 23:24:46 kre Exp $	*/ | 1 | /*	$NetBSD: fcntl.h,v 1.57.2.1 2026/06/16 09:06:50 martin Exp $	*/ |
| 2 | 2 | ||
| 3 | /*- | 3 | /*- |
| 4 | * Copyright (c) 1983, 1990, 1993 | 4 | * Copyright (c) 1983, 1990, 1993 |
| ... | @@ -121,6 +121,9 @@ | ... | @@ -121,6 +121,9 @@ |
| 121 | #if defined(_NETBSD_SOURCE) | 121 | #if defined(_NETBSD_SOURCE) |
| 122 | #define	O_NOSIGPIPE	0x01000000	/* don't deliver sigpipe */ | 122 | #define	O_NOSIGPIPE	0x01000000	/* don't deliver sigpipe */ |
| 123 | #define	O_REGULAR	0x02000000	/* fail if not a regular file */ | 123 | #define	O_REGULAR	0x02000000	/* fail if not a regular file */ |
| 124 | #endif | ||
| 125 | #if (_POSIX_C_SOURCE - 0) >= 200809L || (_XOPEN_SOURCE - 0 >= 700) || \ | ||
| 126 | defined(_NETBSD_SOURCE) | ||
| 124 | #define	O_EXEC		0x04000000	/* open for executing only */ | 127 | #define	O_EXEC		0x04000000	/* open for executing only */ |
| 125 | #endif | 128 | #endif |
| 126 | #if (_POSIX_C_SOURCE - 0) >= 202405L || (_XOPEN_SOURCE - 0 >= 800) || \ | 129 | #if (_POSIX_C_SOURCE - 0) >= 202405L || (_XOPEN_SOURCE - 0 >= 800) || \ |
lib/libc/include/generic-netbsd/sys/lua.h+3-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | /*	$NetBSD: lua.h,v 1.9 2023/07/11 14:57:21 martin Exp $ */ | 1 | /*	$NetBSD: lua.h,v 1.9.8.1 2026/06/29 19:52:23 martin Exp $ */ |
| 2 | 2 | ||
| 3 | /* | 3 | /* |
| 4 | * Copyright (c) 2014 by Lourival Vieira Neto <lneto@NetBSD.org>. | 4 | * Copyright (c) 2014 by Lourival Vieira Neto <lneto@NetBSD.org>. |
| ... | @@ -33,7 +33,9 @@ | ... | @@ -33,7 +33,9 @@ |
| 33 | #define _SYS_LUA_H_ | 33 | #define _SYS_LUA_H_ |
| 34 | 34 | ||
| 35 | #include <sys/param.h> | 35 | #include <sys/param.h> |
| 36 | |||
| 36 | #include <sys/ioccom.h> | 37 | #include <sys/ioccom.h> |
| 38 | #include <sys/stdbool.h> | ||
| 37 | 39 | ||
| 38 | #include <lua.h>		/* for lua_State */ | 40 | #include <lua.h>		/* for lua_State */ |
| 39 | 41 |
lib/libc/include/generic-netbsd/sys/param.h+2-2| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | /*	$NetBSD: param.h,v 1.738.2.5 2026/05/12 04:23:51 martin Exp $	*/ | 1 | /*	$NetBSD: param.h,v 1.738.2.9 2026/07/30 15:23:12 martin Exp $	*/ |
| 2 | 2 | ||
| 3 | /*- | 3 | /*- |
| 4 | * Copyright (c) 1982, 1986, 1989, 1993 | 4 | * Copyright (c) 1982, 1986, 1989, 1993 |
| ... | @@ -566,4 +566,4 @@ extern size_t coherency_unit; | ... | @@ -566,4 +566,4 @@ extern size_t coherency_unit; |
| 566 | #endif | 566 | #endif |
| 567 | #endif /* !__ASSEMBLER__ */ | 567 | #endif /* !__ASSEMBLER__ */ |
| 568 | 568 | ||
| 569 | #endif /* !_SYS_PARAM_H_ */ | 569 | #endif /* !_SYS_PARAM_H_ */ |
| \ No newline at end of file | |||
lib/libc/include/generic-netbsd/x86/cpu_extended_state.h+3-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | /*	$NetBSD: cpu_extended_state.h,v 1.19 2025/04/24 01:50:39 riastradh Exp $	*/ | 1 | /*	$NetBSD: cpu_extended_state.h,v 1.19.2.1 2026/07/19 15:57:27 martin Exp $	*/ |
| 2 | 2 | ||
| 3 | #ifndef _X86_CPU_EXTENDED_STATE_H_ | 3 | #ifndef _X86_CPU_EXTENDED_STATE_H_ |
| 4 | #define _X86_CPU_EXTENDED_STATE_H_ | 4 | #define _X86_CPU_EXTENDED_STATE_H_ |
| ... | @@ -142,6 +142,8 @@ struct xsave_header { | ... | @@ -142,6 +142,8 @@ struct xsave_header { |
| 142 | }; | 142 | }; |
| 143 | __CTASSERT(sizeof(struct xsave_header) == 512 + 64); | 143 | __CTASSERT(sizeof(struct xsave_header) == 512 + 64); |
| 144 | 144 | ||
| 145 | #define	XSAVE_ALIGN	64 | ||
| 146 | |||
| 145 | /* | 147 | /* |
| 146 | * The ymm save area actually follows the xsave_header. | 148 | * The ymm save area actually follows the xsave_header. |
| 147 | */ | 149 | */ |
lib/libc/include/generic-netbsd/x86/fpu.h+7-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | /*	$NetBSD: fpu.h,v 1.23 2020/10/24 07:14:29 mgorny Exp $	*/ | 1 | /*	$NetBSD: fpu.h,v 1.23.28.1 2026/07/19 15:57:27 martin Exp $	*/ |
| 2 | 2 | ||
| 3 | #ifndef	_X86_FPU_H_ | 3 | #ifndef	_X86_FPU_H_ |
| 4 | #define	_X86_FPU_H_ | 4 | #define	_X86_FPU_H_ |
| ... | @@ -46,6 +46,12 @@ int process_read_xstate(struct lwp *, struct xstate *); | ... | @@ -46,6 +46,12 @@ int process_read_xstate(struct lwp *, struct xstate *); |
| 46 | int process_verify_xstate(const struct xstate *); | 46 | int process_verify_xstate(const struct xstate *); |
| 47 | int process_write_xstate(struct lwp *, const struct xstate *); | 47 | int process_write_xstate(struct lwp *, const struct xstate *); |
| 48 | 48 | ||
| 49 | bool process_xsave_needed_p(struct lwp *); | ||
| 50 | void process_read_xsave(struct lwp *, const struct xsave_header **, size_t *); | ||
| 51 | int process_verify_xsavelen(struct lwp *, size_t); | ||
| 52 | int process_verify_xsave(struct lwp *, const struct xsave_header *, size_t); | ||
| 53 | void process_write_xsave(struct lwp *, const struct xsave_header *, size_t); | ||
| 54 | |||
| 49 | #endif | 55 | #endif |
| 50 | 56 | ||
| 51 | #endif /* _X86_FPU_H_ */ | 57 | #endif /* _X86_FPU_H_ */ |
| \ No newline at end of file | |||
lib/libc/include/generic-netbsd/x86/specialreg.h+71-5| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | /*	$NetBSD: specialreg.h,v 1.219 2025/04/28 13:01:27 riastradh Exp $	*/ | 1 | /*	$NetBSD: specialreg.h,v 1.219.2.1 2026/07/19 15:57:27 martin Exp $	*/ |
| 2 | 2 | ||
| 3 | /* | 3 | /* |
| 4 | * Copyright (c) 2014-2020 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 2014-2020 The NetBSD Foundation, Inc. |
| ... | @@ -183,16 +183,82 @@ | ... | @@ -183,16 +183,82 @@ |
| 183 | 	"\0" | 183 | 	"\0" |
| 184 | 184 | ||
| 185 | /* | 185 | /* |
| 186 | * Known FPU bits, only these get enabled. The save area is sized for all the | 186 | * XCR0_FPU: Known FPU bits, only these get enabled. The save area is |
| 187 | * fields below. | 187 | * sized for all the fields below. |
| 188 | * | ||
| 189 | * Any bits added to this will expand the extended CPU state that we | ||
| 190 | * may have to save and restore with XSAVE for userland processes, | ||
| 191 | * either in the kernel when preempting threads, or on the user's stack | ||
| 192 | * when delivering a signal. | ||
| 193 | * | ||
| 194 | * The kernel can dyanmically allocate larger sizes (on amd64, anyway, | ||
| 195 | * though not currently on i386 or Xen PV). But if the XSAVE area is | ||
| 196 | * expanded so much that it and mcontext_t exceed MINSIGSTKSZ | ||
| 197 | * (currently 8192), a userland ABI change and compatibility layer is | ||
| 198 | * required to accommodate that, because existing programs may use | ||
| 199 | * sigaltstack(2) with stacks sized for the old MINSIGSTKSZ. | ||
| 200 | * | ||
| 201 | * The current stack requirement is 3160 bytes of space plus up to | ||
| 202 | * 63+15+8=86 bytes of padding for alignment (could be reduced by | ||
| 203 | * around 512 bytes by having mcontext_t overlap with the XSAVE area a | ||
| 204 | * little in machdep.c cpu_getmcontext_xsave, but we don't do that | ||
| 205 | * right now): | ||
| 206 | * | ||
| 207 | * - mcontext_t (728 bytes: general registers and 512-byte FXSAVE area) | ||
| 208 | * - XSAVE header (576 bytes: 512 bytes of FXSAVE, 64 bytes of metadata) | ||
| 209 | * - AVX state: ymm0..ymm15 high 128-bit halves (256 bytes) | ||
| 210 | * - AVX-512 state: | ||
| 211 | * . k0..k7 opmask registers (64 bytes) | ||
| 212 | * . zmm0..zmm15 high 256-bit halves (512 bytes) | ||
| 213 | * . zmm16..zmm31 registers (1024 bytes) | ||
| 214 | * | ||
| 215 | * Likely future extensions that would expand the state beyond | ||
| 216 | * MINSIGSTKSZ: | ||
| 217 | * | ||
| 218 | * - AMX (Advanced Matrix Extensions) and ACE (AI Compute Extensions) | ||
| 219 | * state: | ||
| 220 | * . [AMX/ACE] TILECFG (64 bytes) | ||
| 221 | * . [AMX/ACE] TILEDATA (8192 bytes) | ||
| 222 | * . [ACE] SCALEDATA (128 bytes) | ||
| 223 | * | ||
| 224 | * As a precaution against ABI breakage, x86/identcpu.c will panic at | ||
| 225 | * boot if the XSAVE state size enabled in XCR0 exceeds MINSIGSTKSZ. | ||
| 226 | * | ||
| 227 | * References: | ||
| 228 | * | ||
| 229 | * - Intel 64 and IA-32 Architectures Software Developer's Manual, | ||
| 230 | * Volume 1: Basic Architecture, Intel, Order Number: 253665-092US, | ||
| 231 | * June 2026, Sec. 13.1 `XSAVE-Supported Features and State-Component | ||
| 232 | * Bitmaps', pp. 13-1 -- 13-2. | ||
| 233 | * https://web.archive.org/web/20260709150417/https://cdrdv2-public.intel.com/922477/253665-092-sdm-vol-1.pdf | ||
| 234 | * | ||
| 235 | * - AI Compute Extensions (ACE) Specification, x86 Ecosystem Advisory | ||
| 236 | * Group, Version 1.15, 2026-05-15, Sec 15.4.1 `XSAVE State | ||
| 237 | * Components', p. 86. | ||
| 238 | * https://web.archive.org/web/20260619062626/https://x86ecosystem.org/wp-content/uploads/2026/06/ACE_v1_Specification_public_1_15.pdf | ||
| 188 | */ | 239 | */ |
| 189 | #if defined __i386__ || defined XENPV /* XXX XENPV PR kern/59371 */ | 240 | #if defined __i386__ || defined XENPV /* XXX XENPV PR kern/59371 */ |
| 190 | #define XCR0_FPU	(XCR0_X87 | XCR0_SSE | XCR0_YMM_Hi128 | \ | 241 | #define XCR0_FPU	(XCR0_X87 | XCR0_SSE | XCR0_YMM_Hi128 | \ |
| 191 | 			 XCR0_Opmask | XCR0_ZMM_Hi256 | XCR0_Hi16_ZMM) | 242 | 			 XCR0_Opmask | XCR0_ZMM_Hi256 | XCR0_Hi16_ZMM) |
| 192 | #else | 243 | #else |
| 193 | #define XCR0_FPU	(XCR0_X87 | XCR0_SSE | XCR0_YMM_Hi128 | \ | 244 | #define XCR0_FPU	(XCR0_X87 | XCR0_SSE | XCR0_YMM_Hi128 | \ |
| 194 | 			 XCR0_Opmask | XCR0_ZMM_Hi256 | XCR0_Hi16_ZMM | \ | 245 | 			 XCR0_Opmask | XCR0_ZMM_Hi256 | XCR0_Hi16_ZMM) |
| 195 | 			 XCR0_TILECFG | XCR0_TILEDATA) | 246 | #endif |
| 247 | |||
| 248 | /* | ||
| 249 | * Maximum size of XSAVE state that we can handle without ABI changes | ||
| 250 | * to userland. Must match usage in cpu_getmcontext. Extra 8 is neeed | ||
| 251 | * on amd64 to have space for return address in 16-byte-aligned stack | ||
| 252 | * frame. | ||
| 253 | */ | ||
| 254 | #ifdef __x86_64__ | ||
| 255 | #define	XSAVE_MAX_BYTES							 \ | ||
| 256 | 	(MINSIGSTKSZ - (8 + STACK_ALIGNBYTES +				 \ | ||
| 257 | 	 sizeof(struct sigframe_siginfo) + (XSAVE_ALIGN - 1))) | ||
| 258 | #else | ||
| 259 | #define	XSAVE_MAX_BYTES							 \ | ||
| 260 | 	(MINSIGSTKSZ - (STACK_ALIGNBYTES +				 \ | ||
| 261 | 	 sizeof(struct sigframe_siginfo) + (XSAVE_ALIGN - 1))) | ||
| 196 | #endif | 262 | #endif |
| 197 | 263 | ||
| 198 | /* | 264 | /* |
lib/libc/include/loongarch-linux-gnu/bits/hwcap.h+3-1| ... | @@ -36,4 +36,6 @@ | ... | @@ -36,4 +36,6 @@ |
| 36 | #define HWCAP_LOONGARCH_LBT_ARM (1 << 11) | 36 | #define HWCAP_LOONGARCH_LBT_ARM (1 << 11) |
| 37 | #define HWCAP_LOONGARCH_LBT_MIPS (1 << 12) | 37 | #define HWCAP_LOONGARCH_LBT_MIPS (1 << 12) |
| 38 | #define HWCAP_LOONGARCH_PTW (1 << 13) | 38 | #define HWCAP_LOONGARCH_PTW (1 << 13) |
| 39 | #define HWCAP_LOONGARCH_LSPW (1 << 14) | ||
| \ No newline at end of file | |||
| 39 | #define HWCAP_LOONGARCH_LSPW (1 << 14) | ||
| 40 | #define HWCAP_LOONGARCH_SCQ (1 << 15) | ||
| 41 | #define HWCAP_LOONGARCH_LAM_BH (1 << 16) | ||
| \ No newline at end of file | |||
lib/libc/include/loongarch-linux-gnu/bits/long-double.h deleted-21| ... | @@ -1,21 +0,0 @@ | ||
| 1 | /* Properties of long double type. ldbl-128 version. | ||
| 2 | Copyright (C) 2016-2026 Free Software Foundation, Inc. | ||
| 3 | This file is part of the GNU C Library. | ||
| 4 | |||
| 5 | The GNU C Library is free software; you can redistribute it and/or | ||
| 6 | modify it under the terms of the GNU Lesser General Public | ||
| 7 | License published by the Free Software Foundation; either | ||
| 8 | version 2.1 of the License, or (at your option) any later version. | ||
| 9 | |||
| 10 | The GNU C Library is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 13 | Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public | ||
| 16 | License along with the GNU C Library; if not, see | ||
| 17 | <https://www.gnu.org/licenses/>. */ | ||
| 18 | |||
| 19 | /* long double is distinct from double, so there is nothing to | ||
| 20 | define here. */ | ||
| 21 | #define __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI 0 | ||
| \ No newline at end of file | |||
lib/libc/include/loongarch-linux-gnu/bits/struct_stat.h deleted-127| ... | @@ -1,127 +0,0 @@ | ||
| 1 | /* Definition for struct stat. | ||
| 2 | Copyright (C) 2020-2026 Free Software Foundation, Inc. | ||
| 3 | This file is part of the GNU C Library. | ||
| 4 | |||
| 5 | The GNU C Library is free software; you can redistribute it and/or | ||
| 6 | modify it under the terms of the GNU Lesser General Public | ||
| 7 | License as published by the Free Software Foundation; either | ||
| 8 | version 2.1 of the License, or (at your option) any later version. | ||
| 9 | |||
| 10 | The GNU C Library is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 13 | Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public | ||
| 16 | License along with the GNU C Library. If not, see | ||
| 17 | <https://www.gnu.org/licenses/>. */ | ||
| 18 | |||
| 19 | #if !defined _SYS_STAT_H && !defined _FCNTL_H | ||
| 20 | # error "Never include <bits/struct_stat.h> directly; use <sys/stat.h> instead." | ||
| 21 | #endif | ||
| 22 | |||
| 23 | #ifndef _BITS_STRUCT_STAT_H | ||
| 24 | #define _BITS_STRUCT_STAT_H	1 | ||
| 25 | |||
| 26 | #include <bits/endian.h> | ||
| 27 | #include <bits/wordsize.h> | ||
| 28 | |||
| 29 | #if defined __USE_FILE_OFFSET64 | ||
| 30 | # define __field64(type, type64, name) type64 name | ||
| 31 | #elif __WORDSIZE == 64 || defined __INO_T_MATCHES_INO64_T | ||
| 32 | # if defined __INO_T_MATCHES_INO64_T && !defined __OFF_T_MATCHES_OFF64_T | ||
| 33 | # error "ino_t and off_t must both be the same type" | ||
| 34 | # endif | ||
| 35 | # define __field64(type, type64, name) type name | ||
| 36 | #elif __BYTE_ORDER == __LITTLE_ENDIAN | ||
| 37 | # define __field64(type, type64, name) \ | ||
| 38 | type name __attribute__((__aligned__ (__alignof__ (type64)))); int __##name##_pad | ||
| 39 | #else | ||
| 40 | # define __field64(type, type64, name) \ | ||
| 41 | int __##name##_pad __attribute__((__aligned__ (__alignof__ (type64)))); type name | ||
| 42 | #endif | ||
| 43 | |||
| 44 | struct stat | ||
| 45 | { | ||
| 46 | __dev_t st_dev;		/* Device. */ | ||
| 47 | __field64(__ino_t, __ino64_t, st_ino); /* File serial number. */ | ||
| 48 | __mode_t st_mode;		/* File mode. */ | ||
| 49 | __nlink_t st_nlink;		/* Link count. */ | ||
| 50 | __uid_t st_uid;		/* User ID of the file's owner.	*/ | ||
| 51 | __gid_t st_gid;		/* Group ID of the file's group.*/ | ||
| 52 | __dev_t st_rdev;		/* Device number, if device. */ | ||
| 53 | __dev_t __pad1; | ||
| 54 | __field64(__off_t, __off64_t, st_size); /* Size of file, in bytes. */ | ||
| 55 | __blksize_t st_blksize;	/* Optimal block size for I/O. */ | ||
| 56 | int __pad2; | ||
| 57 | __field64(__blkcnt_t, __blkcnt64_t, st_blocks); /* 512-byte blocks */ | ||
| 58 | #ifdef __USE_XOPEN2K8 | ||
| 59 | /* Nanosecond resolution timestamps are stored in a format | ||
| 60 | equivalent to 'struct timespec'. This is the type used | ||
| 61 | whenever possible but the Unix namespace rules do not allow the | ||
| 62 | identifier 'timespec' to appear in the <sys/stat.h> header. | ||
| 63 | Therefore we have to handle the use of this header in strictly | ||
| 64 | standard-compliant sources special. */ | ||
| 65 | struct timespec st_atim;		/* Time of last access. */ | ||
| 66 | struct timespec st_mtim;		/* Time of last modification. */ | ||
| 67 | struct timespec st_ctim;		/* Time of last status change. */ | ||
| 68 | # define st_atime st_atim.tv_sec	/* Backward compatibility. */ | ||
| 69 | # define st_mtime st_mtim.tv_sec | ||
| 70 | # define st_ctime st_ctim.tv_sec | ||
| 71 | #else | ||
| 72 | __time_t st_atime;			/* Time of last access. */ | ||
| 73 | unsigned long int st_atimensec;	/* Nscecs of last access. */ | ||
| 74 | __time_t st_mtime;			/* Time of last modification. */ | ||
| 75 | unsigned long int st_mtimensec;	/* Nsecs of last modification. */ | ||
| 76 | __time_t st_ctime;			/* Time of last status change. */ | ||
| 77 | unsigned long int st_ctimensec;	/* Nsecs of last status change. */ | ||
| 78 | #endif | ||
| 79 | int __glibc_reserved[2]; | ||
| 80 | }; | ||
| 81 | |||
| 82 | #undef __field64 | ||
| 83 | |||
| 84 | #ifdef __USE_LARGEFILE64 | ||
| 85 | struct stat64 | ||
| 86 | { | ||
| 87 | __dev_t st_dev;		/* Device. */ | ||
| 88 | __ino64_t st_ino;		/* File serial number.	*/ | ||
| 89 | __mode_t st_mode;		/* File mode. */ | ||
| 90 | __nlink_t st_nlink;		/* Link count. */ | ||
| 91 | __uid_t st_uid;		/* User ID of the file's owner.	*/ | ||
| 92 | __gid_t st_gid;		/* Group ID of the file's group.*/ | ||
| 93 | __dev_t st_rdev;		/* Device number, if device. */ | ||
| 94 | __dev_t __pad1; | ||
| 95 | __off64_t st_size;		/* Size of file, in bytes. */ | ||
| 96 | __blksize_t st_blksize;	/* Optimal block size for I/O. */ | ||
| 97 | int __pad2; | ||
| 98 | __blkcnt64_t st_blocks;	/* Nr. 512-byte blocks allocated. */ | ||
| 99 | #ifdef __USE_XOPEN2K8 | ||
| 100 | /* Nanosecond resolution timestamps are stored in a format | ||
| 101 | equivalent to 'struct timespec'. This is the type used | ||
| 102 | whenever possible but the Unix namespace rules do not allow the | ||
| 103 | identifier 'timespec' to appear in the <sys/stat.h> header. | ||
| 104 | Therefore we have to handle the use of this header in strictly | ||
| 105 | standard-compliant sources special. */ | ||
| 106 | struct timespec st_atim;		/* Time of last access. */ | ||
| 107 | struct timespec st_mtim;		/* Time of last modification. */ | ||
| 108 | struct timespec st_ctim;		/* Time of last status change. */ | ||
| 109 | #else | ||
| 110 | __time_t st_atime;			/* Time of last access. */ | ||
| 111 | unsigned long int st_atimensec;	/* Nscecs of last access. */ | ||
| 112 | __time_t st_mtime;			/* Time of last modification. */ | ||
| 113 | unsigned long int st_mtimensec;	/* Nsecs of last modification. */ | ||
| 114 | __time_t st_ctime;			/* Time of last status change. */ | ||
| 115 | unsigned long int st_ctimensec;	/* Nsecs of last status change. */ | ||
| 116 | #endif | ||
| 117 | int __glibc_reserved[2]; | ||
| 118 | }; | ||
| 119 | #endif | ||
| 120 | |||
| 121 | /* Tell code we have these members. */ | ||
| 122 | #define	_STATBUF_ST_BLKSIZE | ||
| 123 | #define _STATBUF_ST_RDEV | ||
| 124 | /* Nanosecond resolution time values are supported. */ | ||
| 125 | #define _STATBUF_ST_NSEC | ||
| 126 | |||
| 127 | #endif /* _BITS_STRUCT_STAT_H */ | ||
| \ No newline at end of file | |||
lib/libc/include/loongarch-linux-gnu/bits/timesize.h deleted-20| ... | @@ -1,20 +0,0 @@ | ||
| 1 | /* Bit size of the time_t type at glibc build time, general case. | ||
| 2 | Copyright (C) 2018-2026 Free Software Foundation, Inc. | ||
| 3 | This file is part of the GNU C Library. | ||
| 4 | |||
| 5 | The GNU C Library is free software; you can redistribute it and/or | ||
| 6 | modify it under the terms of the GNU Lesser General Public | ||
| 7 | License as published by the Free Software Foundation; either | ||
| 8 | version 2.1 of the License, or (at your option) any later version. | ||
| 9 | |||
| 10 | The GNU C Library is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 13 | Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public | ||
| 16 | License along with the GNU C Library; if not, see | ||
| 17 | <https://www.gnu.org/licenses/>. */ | ||
| 18 | |||
| 19 | /* Size in bits of the 'time_t' type of the default ABI. */ | ||
| 20 | #define __TIMESIZE	64 | ||
| \ No newline at end of file | |||
lib/libc/include/loongarch-linux-gnu/bits/wordsize.h+13-2| ... | @@ -15,5 +15,16 @@ | ... | @@ -15,5 +15,16 @@ |
| 15 | License along with the GNU C Library; if not, see | 15 | License along with the GNU C Library; if not, see |
| 16 | <https://www.gnu.org/licenses/>. */ | 16 | <https://www.gnu.org/licenses/>. */ |
| 17 | 17 | ||
| 18 | #define __WORDSIZE			64 | ||
| 19 | #define __WORDSIZE_TIME64_COMPAT32	0 | ||
| \ No newline at end of file | |||
| 18 | // zig patch: handle 32-bit and 64-bit in the same header | ||
| 19 | #if __loongarch_grlen == (__SIZEOF_POINTER__ * 8) | ||
| 20 | # define __WORDSIZE __loongarch_grlen | ||
| 21 | #else | ||
| 22 | # error unsupported ABI | ||
| 23 | #endif | ||
| 24 | |||
| 25 | #define __WORDSIZE_TIME64_COMPAT32	0 | ||
| 26 | |||
| 27 | #if __WORDSIZE == 32 | ||
| 28 | # define __WORDSIZE32_SIZE_ULONG 0 | ||
| 29 | # define __WORDSIZE32_PTRDIFF_LONG 0 | ||
| 30 | #endif | ||
lib/libc/include/loongarch-linux-gnu/fpu_control.h+9| ... | @@ -94,6 +94,15 @@ extern void __loongarch_fpu_setcw (fpu_control_t) __THROW; | ... | @@ -94,6 +94,15 @@ extern void __loongarch_fpu_setcw (fpu_control_t) __THROW; |
| 94 | #define _FPU_GETCW(cw) __asm__ volatile ("movfcsr2gr %0,$fcsr0" : "=r"(cw)) | 94 | #define _FPU_GETCW(cw) __asm__ volatile ("movfcsr2gr %0,$fcsr0" : "=r"(cw)) |
| 95 | #define _FPU_SETCW(cw) __asm__ volatile ("movgr2fcsr $fcsr0,%0" : : "r"(cw)) | 95 | #define _FPU_SETCW(cw) __asm__ volatile ("movgr2fcsr $fcsr0,%0" : : "r"(cw)) |
| 96 | 96 | ||
| 97 | #define _FPU_GET_ENABLES(cw) __asm__ volatile ("movfcsr2gr %0,$fcsr1" : "=r"(cw)) | ||
| 98 | #define _FPU_SET_ENABLES(cw) __asm__ volatile ("movgr2fcsr $fcsr1,%0" : : "r"(cw)) | ||
| 99 | |||
| 100 | #define _FPU_GET_FLAGS_CAUSE(cw) __asm__ volatile ("movfcsr2gr %0,$fcsr2" : "=r"(cw)) | ||
| 101 | #define _FPU_SET_FLAGS_CAUSE(cw) __asm__ volatile ("movgr2fcsr $fcsr2,%0" : : "r"(cw)) | ||
| 102 | |||
| 103 | #define _FPU_GET_RM(cw) __asm__ volatile ("movfcsr2gr %0,$fcsr3" : "=r"(cw)) | ||
| 104 | #define _FPU_SET_RM(cw) __asm__ volatile ("movgr2fcsr $fcsr3,%0" : : "r"(cw)) | ||
| 105 | |||
| 97 | /* Default control word set at startup. */ | 106 | /* Default control word set at startup. */ |
| 98 | extern fpu_control_t __fpu_control; | 107 | extern fpu_control_t __fpu_control; |
| 99 | 108 |
lib/libc/include/loongarch-linux-gnu/gnu/lib-names-ilp32d.h created+28| ... | @@ -0,0 +1,28 @@ | ||
| 1 | /* This file is automatically generated. */ | ||
| 2 | #ifndef __GNU_LIB_NAMES_H | ||
| 3 | # error "Never use <gnu/lib-names-ilp32d.h> directly; include <gnu/lib-names.h> instead." | ||
| 4 | #endif | ||
| 5 | |||
| 6 | #define LD_LINUX_LOONGARCH_ILP32D_SO "ld-linux-loongarch-ilp32d.so.1" | ||
| 7 | #define LD_SO "ld-linux-loongarch-ilp32d.so.1" | ||
| 8 | #define LIBANL_SO "libanl.so.1" | ||
| 9 | #define LIBBROKENLOCALE_SO "libBrokenLocale.so.1" | ||
| 10 | #define LIBC_MALLOC_DEBUG_SO "libc_malloc_debug.so.0" | ||
| 11 | #define LIBC_SO "libc.so.6" | ||
| 12 | #define LIBDL_SO "libdl.so.2" | ||
| 13 | #define LIBGCC_S_SO "libgcc_s.so.1" | ||
| 14 | #define LIBMVEC_SO "libmvec.so.1" | ||
| 15 | #define LIBM_SO "libm.so.6" | ||
| 16 | #define LIBNSL_SO "libnsl.so.1" | ||
| 17 | #define LIBNSS_COMPAT_SO "libnss_compat.so.2" | ||
| 18 | #define LIBNSS_DB_SO "libnss_db.so.2" | ||
| 19 | #define LIBNSS_DNS_SO "libnss_dns.so.2" | ||
| 20 | #define LIBNSS_FILES_SO "libnss_files.so.2" | ||
| 21 | #define LIBNSS_HESIOD_SO "libnss_hesiod.so.2" | ||
| 22 | #define LIBNSS_LDAP_SO "libnss_ldap.so.2" | ||
| 23 | #define LIBPTHREAD_SO "libpthread.so.0" | ||
| 24 | #define LIBRESOLV_SO "libresolv.so.2" | ||
| 25 | #define LIBRT_SO "librt.so.1" | ||
| 26 | #define LIBTHREAD_DB_SO "libthread_db.so.1" | ||
| 27 | #define LIBUNWIND_SO "libunwind.so.1" | ||
| 28 | #define LIBUTIL_SO "libutil.so.1" | ||
| \ No newline at end of file | |||
lib/libc/include/loongarch-linux-gnu/gnu/lib-names-ilp32s.h created+28| ... | @@ -0,0 +1,28 @@ | ||
| 1 | /* This file is automatically generated. */ | ||
| 2 | #ifndef __GNU_LIB_NAMES_H | ||
| 3 | # error "Never use <gnu/lib-names-ilp32s.h> directly; include <gnu/lib-names.h> instead." | ||
| 4 | #endif | ||
| 5 | |||
| 6 | #define LD_LINUX_LOONGARCH_ILP32S_SO "ld-linux-loongarch-ilp32s.so.1" | ||
| 7 | #define LD_SO "ld-linux-loongarch-ilp32s.so.1" | ||
| 8 | #define LIBANL_SO "libanl.so.1" | ||
| 9 | #define LIBBROKENLOCALE_SO "libBrokenLocale.so.1" | ||
| 10 | #define LIBC_MALLOC_DEBUG_SO "libc_malloc_debug.so.0" | ||
| 11 | #define LIBC_SO "libc.so.6" | ||
| 12 | #define LIBDL_SO "libdl.so.2" | ||
| 13 | #define LIBGCC_S_SO "libgcc_s.so.1" | ||
| 14 | #define LIBMVEC_SO "libmvec.so.1" | ||
| 15 | #define LIBM_SO "libm.so.6" | ||
| 16 | #define LIBNSL_SO "libnsl.so.1" | ||
| 17 | #define LIBNSS_COMPAT_SO "libnss_compat.so.2" | ||
| 18 | #define LIBNSS_DB_SO "libnss_db.so.2" | ||
| 19 | #define LIBNSS_DNS_SO "libnss_dns.so.2" | ||
| 20 | #define LIBNSS_FILES_SO "libnss_files.so.2" | ||
| 21 | #define LIBNSS_HESIOD_SO "libnss_hesiod.so.2" | ||
| 22 | #define LIBNSS_LDAP_SO "libnss_ldap.so.2" | ||
| 23 | #define LIBPTHREAD_SO "libpthread.so.0" | ||
| 24 | #define LIBRESOLV_SO "libresolv.so.2" | ||
| 25 | #define LIBRT_SO "librt.so.1" | ||
| 26 | #define LIBTHREAD_DB_SO "libthread_db.so.1" | ||
| 27 | #define LIBUNWIND_SO "libunwind.so.1" | ||
| 28 | #define LIBUTIL_SO "libutil.so.1" | ||
| \ No newline at end of file | |||
lib/libc/include/loongarch-linux-gnu/gnu/lib-names-lp64d.h+1| ... | @@ -24,4 +24,5 @@ | ... | @@ -24,4 +24,5 @@ |
| 24 | #define LIBRESOLV_SO "libresolv.so.2" | 24 | #define LIBRESOLV_SO "libresolv.so.2" |
| 25 | #define LIBRT_SO "librt.so.1" | 25 | #define LIBRT_SO "librt.so.1" |
| 26 | #define LIBTHREAD_DB_SO "libthread_db.so.1" | 26 | #define LIBTHREAD_DB_SO "libthread_db.so.1" |
| 27 | #define LIBUNWIND_SO "libunwind.so.1" | ||
| 27 | #define LIBUTIL_SO "libutil.so.1" | 28 | #define LIBUTIL_SO "libutil.so.1" |
| \ No newline at end of file | |||
lib/libc/include/loongarch-linux-gnu/gnu/lib-names-lp64s.h+1| ... | @@ -24,4 +24,5 @@ | ... | @@ -24,4 +24,5 @@ |
| 24 | #define LIBRESOLV_SO "libresolv.so.2" | 24 | #define LIBRESOLV_SO "libresolv.so.2" |
| 25 | #define LIBRT_SO "librt.so.1" | 25 | #define LIBRT_SO "librt.so.1" |
| 26 | #define LIBTHREAD_DB_SO "libthread_db.so.1" | 26 | #define LIBTHREAD_DB_SO "libthread_db.so.1" |
| 27 | #define LIBUNWIND_SO "libunwind.so.1" | ||
| 27 | #define LIBUTIL_SO "libutil.so.1" | 28 | #define LIBUTIL_SO "libutil.so.1" |
| \ No newline at end of file | |||
lib/libc/include/loongarch-linux-gnu/gnu/lib-names.h+6| ... | @@ -6,6 +6,12 @@ | ... | @@ -6,6 +6,12 @@ |
| 6 | 6 | ||
| 7 | #include <bits/wordsize.h> | 7 | #include <bits/wordsize.h> |
| 8 | 8 | ||
| 9 | #if __WORDSIZE == 32 && defined __loongarch_soft_float | ||
| 10 | # include <gnu/lib-names-ilp32s.h> | ||
| 11 | #endif | ||
| 12 | #if __WORDSIZE == 32 && defined __loongarch_double_float | ||
| 13 | # include <gnu/lib-names-ilp32d.h> | ||
| 14 | #endif | ||
| 9 | #if __WORDSIZE == 64 && defined __loongarch_soft_float | 15 | #if __WORDSIZE == 64 && defined __loongarch_soft_float |
| 10 | # include <gnu/lib-names-lp64s.h> | 16 | # include <gnu/lib-names-lp64s.h> |
| 11 | #endif | 17 | #endif |
lib/libc/include/loongarch-linux-gnu/gnu/stubs-ilp32d.h created+21| ... | @@ -0,0 +1,21 @@ | ||
| 1 | /* This file is automatically generated. | ||
| 2 | It defines a symbol `__stub_FUNCTION' for each function | ||
| 3 | in the C library which is a stub, meaning it will fail | ||
| 4 | every time called, usually setting errno to ENOSYS. */ | ||
| 5 | |||
| 6 | #ifdef _LIBC | ||
| 7 | #error Applications may not define the macro _LIBC | ||
| 8 | #endif | ||
| 9 | |||
| 10 | #define __stub___compat_bdflush | ||
| 11 | #define __stub___compat_create_module | ||
| 12 | #define __stub___compat_get_kernel_syms | ||
| 13 | #define __stub___compat_query_module | ||
| 14 | #define __stub___compat_uselib | ||
| 15 | #define __stub_chflags | ||
| 16 | #define __stub_fchflags | ||
| 17 | #define __stub_gtty | ||
| 18 | #define __stub_revoke | ||
| 19 | #define __stub_setlogin | ||
| 20 | #define __stub_sigreturn | ||
| 21 | #define __stub_stty | ||
| \ No newline at end of file | |||
lib/libc/include/loongarch-linux-gnu/gnu/stubs-ilp32s.h created+38| ... | @@ -0,0 +1,38 @@ | ||
| 1 | /* This file is automatically generated. | ||
| 2 | It defines a symbol `__stub_FUNCTION' for each function | ||
| 3 | in the C library which is a stub, meaning it will fail | ||
| 4 | every time called, usually setting errno to ENOSYS. */ | ||
| 5 | |||
| 6 | #ifdef _LIBC | ||
| 7 | #error Applications may not define the macro _LIBC | ||
| 8 | #endif | ||
| 9 | |||
| 10 | #define __stub___compat_bdflush | ||
| 11 | #define __stub___compat_create_module | ||
| 12 | #define __stub___compat_get_kernel_syms | ||
| 13 | #define __stub___compat_query_module | ||
| 14 | #define __stub___compat_uselib | ||
| 15 | #define __stub_chflags | ||
| 16 | #define __stub_fchflags | ||
| 17 | #define __stub_feclearexcept | ||
| 18 | #define __stub_fedisableexcept | ||
| 19 | #define __stub_feenableexcept | ||
| 20 | #define __stub_fegetenv | ||
| 21 | #define __stub_fegetexcept | ||
| 22 | #define __stub_fegetexceptflag | ||
| 23 | #define __stub_fegetmode | ||
| 24 | #define __stub_fegetround | ||
| 25 | #define __stub_feholdexcept | ||
| 26 | #define __stub_feraiseexcept | ||
| 27 | #define __stub_fesetenv | ||
| 28 | #define __stub_fesetexcept | ||
| 29 | #define __stub_fesetexceptflag | ||
| 30 | #define __stub_fesetmode | ||
| 31 | #define __stub_fesetround | ||
| 32 | #define __stub_fetestexcept | ||
| 33 | #define __stub_feupdateenv | ||
| 34 | #define __stub_gtty | ||
| 35 | #define __stub_revoke | ||
| 36 | #define __stub_setlogin | ||
| 37 | #define __stub_sigreturn | ||
| 38 | #define __stub_stty | ||
| \ No newline at end of file | |||
lib/libc/include/loongarch-linux-gnu/gnu/stubs.h+6| ... | @@ -4,6 +4,12 @@ | ... | @@ -4,6 +4,12 @@ |
| 4 | 4 | ||
| 5 | #include <bits/wordsize.h> | 5 | #include <bits/wordsize.h> |
| 6 | 6 | ||
| 7 | #if __WORDSIZE == 32 && defined __loongarch_soft_float | ||
| 8 | # include <gnu/stubs-ilp32s.h> | ||
| 9 | #endif | ||
| 10 | #if __WORDSIZE == 32 && defined __loongarch_double_float | ||
| 11 | # include <gnu/stubs-ilp32d.h> | ||
| 12 | #endif | ||
| 7 | #if __WORDSIZE == 64 && defined __loongarch_soft_float | 13 | #if __WORDSIZE == 64 && defined __loongarch_soft_float |
| 8 | # include <gnu/stubs-lp64s.h> | 14 | # include <gnu/stubs-lp64s.h> |
| 9 | #endif | 15 | #endif |
lib/libc/include/loongarch-linux-gnu/sys/asm.h+32-6| ... | @@ -23,10 +23,8 @@ | ... | @@ -23,10 +23,8 @@ |
| 23 | #include <sysdeps/generic/sysdep.h> | 23 | #include <sysdeps/generic/sysdep.h> |
| 24 | 24 | ||
| 25 | /* Macros to handle different pointer/register sizes for 32/64-bit code. */ | 25 | /* Macros to handle different pointer/register sizes for 32/64-bit code. */ |
| 26 | #if __loongarch_grlen == 64 | ||
| 26 | #define SZREG 8 | 27 | #define SZREG 8 |
| 27 | #define SZFREG 8 | ||
| 28 | #define SZVREG 16 | ||
| 29 | #define SZXREG 32 | ||
| 30 | #define REG_L ld.d | 28 | #define REG_L ld.d |
| 31 | #define REG_S st.d | 29 | #define REG_S st.d |
| 32 | #define SRLI srli.d | 30 | #define SRLI srli.d |
| ... | @@ -34,10 +32,38 @@ | ... | @@ -34,10 +32,38 @@ |
| 34 | #define ADDI addi.d | 32 | #define ADDI addi.d |
| 35 | #define ADD add.d | 33 | #define ADD add.d |
| 36 | #define SUB sub.d | 34 | #define SUB sub.d |
| 37 | #define BSTRINS bstrins.d | ||
| 38 | #define LI li.d | 35 | #define LI li.d |
| 39 | #define FREG_L fld.d | 36 | #define BSTRINS bstrins.d |
| 40 | #define FREG_S fst.d | 37 | |
| 38 | #elif __loongarch_grlen == 32 | ||
| 39 | |||
| 40 | #define SZREG 4 | ||
| 41 | #define REG_L ld.w | ||
| 42 | #define REG_S st.w | ||
| 43 | #define SRLI srli.w | ||
| 44 | #define SLLI slli.w | ||
| 45 | #define ADDI addi.w | ||
| 46 | #define ADD add.w | ||
| 47 | #define SUB sub.w | ||
| 48 | #define LI li.w | ||
| 49 | #define BSTRINS bstrins.w | ||
| 50 | |||
| 51 | #else | ||
| 52 | #error __loongarch_grlen must equal 32 or 64 | ||
| 53 | #endif | ||
| 54 | |||
| 55 | #if __loongarch_frlen == 64 | ||
| 56 | #define SZFREG 8 | ||
| 57 | #define FREG_L fld.d | ||
| 58 | #define FREG_S fst.d | ||
| 59 | #elif __loongarch_frlen == 32 | ||
| 60 | #define SZFREG 4 | ||
| 61 | #define FREG_L fld.s | ||
| 62 | #define FREG_S fst.s | ||
| 63 | #endif | ||
| 64 | |||
| 65 | #define SZVREG 16 | ||
| 66 | #define SZXREG 32 | ||
| 41 | 67 | ||
| 42 | /* Declare leaf routine. | 68 | /* Declare leaf routine. |
| 43 | The usage of macro LEAF/ENTRY is as follows: | 69 | The usage of macro LEAF/ENTRY is as follows: |
lib/libc/include/m68k-linux-gnu/gnu/lib-names.h+1| ... | @@ -24,6 +24,7 @@ | ... | @@ -24,6 +24,7 @@ |
| 24 | #define LIBRESOLV_SO "libresolv.so.2" | 24 | #define LIBRESOLV_SO "libresolv.so.2" |
| 25 | #define LIBRT_SO "librt.so.1" | 25 | #define LIBRT_SO "librt.so.1" |
| 26 | #define LIBTHREAD_DB_SO "libthread_db.so.1" | 26 | #define LIBTHREAD_DB_SO "libthread_db.so.1" |
| 27 | #define LIBUNWIND_SO "libunwind.so.1" | ||
| 27 | #define LIBUTIL_SO "libutil.so.1" | 28 | #define LIBUTIL_SO "libutil.so.1" |
| 28 | 29 | ||
| 29 | #endif	/* gnu/lib-names.h */ | 30 | #endif	/* gnu/lib-names.h */ |
| \ No newline at end of file | |||
lib/libc/include/mips-linux-gnu/bits/long-double.h created+24| ... | @@ -0,0 +1,24 @@ | ||
| 1 | /* Properties of long double type. MIPS version. | ||
| 2 | Copyright (C) 2016-2026 Free Software Foundation, Inc. | ||
| 3 | This file is part of the GNU C Library. | ||
| 4 | |||
| 5 | The GNU C Library is free software; you can redistribute it and/or | ||
| 6 | modify it under the terms of the GNU Lesser General Public | ||
| 7 | License published by the Free Software Foundation; either | ||
| 8 | version 2.1 of the License, or (at your option) any later version. | ||
| 9 | |||
| 10 | The GNU C Library is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 13 | Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public | ||
| 16 | License along with the GNU C Library; if not, see | ||
| 17 | <https://www.gnu.org/licenses/>. */ | ||
| 18 | |||
| 19 | #include <sgidefs.h> | ||
| 20 | |||
| 21 | #if !defined __NO_LONG_DOUBLE_MATH && _MIPS_SIM == _ABIO32 | ||
| 22 | # define __NO_LONG_DOUBLE_MATH	1 | ||
| 23 | #endif | ||
| 24 | #define __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI 0 | ||
| \ No newline at end of file | |||
lib/libc/include/mips-linux-gnu/bits/struct_stat.h created+237| ... | @@ -0,0 +1,237 @@ | ||
| 1 | /* Definition for struct stat. | ||
| 2 | Copyright (C) 2020-2026 Free Software Foundation, Inc. | ||
| 3 | This file is part of the GNU C Library. | ||
| 4 | |||
| 5 | The GNU C Library is free software; you can redistribute it and/or | ||
| 6 | modify it under the terms of the GNU Lesser General Public | ||
| 7 | License as published by the Free Software Foundation; either | ||
| 8 | version 2.1 of the License, or (at your option) any later version. | ||
| 9 | |||
| 10 | The GNU C Library is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 13 | Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public | ||
| 16 | License along with the GNU C Library. If not, see | ||
| 17 | <https://www.gnu.org/licenses/>. */ | ||
| 18 | |||
| 19 | #if !defined _SYS_STAT_H && !defined _FCNTL_H | ||
| 20 | # error "Never include <bits/struct_stat.h> directly; use <sys/stat.h> instead." | ||
| 21 | #endif | ||
| 22 | |||
| 23 | #ifndef _BITS_STRUCT_STAT_H | ||
| 24 | #define _BITS_STRUCT_STAT_H	1 | ||
| 25 | |||
| 26 | #include <sgidefs.h> | ||
| 27 | |||
| 28 | #if _MIPS_SIM == _ABIO32 | ||
| 29 | /* Structure describing file characteristics. */ | ||
| 30 | struct stat | ||
| 31 | { | ||
| 32 | # ifdef __USE_TIME64_REDIRECTS | ||
| 33 | # include <bits/struct_stat_time64_helper.h> | ||
| 34 | # else | ||
| 35 | unsigned long int st_dev; | ||
| 36 | long int st_pad1[3]; | ||
| 37 | # ifndef __USE_FILE_OFFSET64 | ||
| 38 | __ino_t st_ino;		/* File serial number.		*/ | ||
| 39 | # else | ||
| 40 | __ino64_t st_ino;		/* File serial number.		*/ | ||
| 41 | # endif | ||
| 42 | __mode_t st_mode;		/* File mode. */ | ||
| 43 | __nlink_t st_nlink;		/* Link count. */ | ||
| 44 | __uid_t st_uid;		/* User ID of the file's owner.	*/ | ||
| 45 | __gid_t st_gid;		/* Group ID of the file's group.*/ | ||
| 46 | unsigned long int st_rdev;	/* Device number, if device. */ | ||
| 47 | # ifndef __USE_FILE_OFFSET64 | ||
| 48 | long int st_pad2[2]; | ||
| 49 | __off_t st_size;		/* Size of file, in bytes. */ | ||
| 50 | /* SVR4 added this extra long to allow for expansion of off_t. */ | ||
| 51 | long int st_pad3; | ||
| 52 | # else | ||
| 53 | long int st_pad2[3]; | ||
| 54 | __off64_t st_size;		/* Size of file, in bytes. */ | ||
| 55 | # endif | ||
| 56 | # ifdef __USE_XOPEN2K8 | ||
| 57 | /* Nanosecond resolution timestamps are stored in a format | ||
| 58 | equivalent to 'struct timespec'. This is the type used | ||
| 59 | whenever possible but the Unix namespace rules do not allow the | ||
| 60 | identifier 'timespec' to appear in the <sys/stat.h> header. | ||
| 61 | Therefore we have to handle the use of this header in strictly | ||
| 62 | standard-compliant sources special. */ | ||
| 63 | struct timespec st_atim; /* Time of last access. */ | ||
| 64 | struct timespec st_mtim; /* Time of last modification. */ | ||
| 65 | struct timespec st_ctim; /* Time of last status change. */ | ||
| 66 | # define st_atime st_atim.tv_sec /* Backward compatibility. */ | ||
| 67 | # define st_mtime st_mtim.tv_sec | ||
| 68 | # define st_ctime st_ctim.tv_sec | ||
| 69 | # else | ||
| 70 | __time_t st_atime;			/* Time of last access. */ | ||
| 71 | unsigned long int st_atimensec;	/* Nscecs of last access. */ | ||
| 72 | __time_t st_mtime;			/* Time of last modification. */ | ||
| 73 | unsigned long int st_mtimensec;	/* Nsecs of last modification. */ | ||
| 74 | __time_t st_ctime;			/* Time of last status change. */ | ||
| 75 | unsigned long int st_ctimensec;	/* Nsecs of last status change. */ | ||
| 76 | # endif | ||
| 77 | __blksize_t st_blksize;	/* Optimal block size for I/O. */ | ||
| 78 | # ifndef __USE_FILE_OFFSET64 | ||
| 79 | __blkcnt_t st_blocks;	/* Number of 512-byte blocks allocated. */ | ||
| 80 | # else | ||
| 81 | long int st_pad4; | ||
| 82 | __blkcnt64_t st_blocks;	/* Number of 512-byte blocks allocated. */ | ||
| 83 | # endif | ||
| 84 | long int st_pad5[14]; | ||
| 85 | # endif /* __USE_TIME64_REDIRECTS */ | ||
| 86 | }; | ||
| 87 | |||
| 88 | # ifdef __USE_LARGEFILE64 | ||
| 89 | struct stat64 | ||
| 90 | { | ||
| 91 | # ifdef __USE_TIME64_REDIRECTS | ||
| 92 | # include <bits/struct_stat_time64_helper.h> | ||
| 93 | # else | ||
| 94 | unsigned long int st_dev; | ||
| 95 | long int st_pad1[3]; | ||
| 96 | __ino64_t st_ino;		/* File serial number.		*/ | ||
| 97 | __mode_t st_mode;		/* File mode. */ | ||
| 98 | __nlink_t st_nlink;		/* Link count. */ | ||
| 99 | __uid_t st_uid;		/* User ID of the file's owner.	*/ | ||
| 100 | __gid_t st_gid;		/* Group ID of the file's group.*/ | ||
| 101 | unsigned long int st_rdev;	/* Device number, if device. */ | ||
| 102 | long int st_pad2[3]; | ||
| 103 | __off64_t st_size;		/* Size of file, in bytes. */ | ||
| 104 | # ifdef __USE_XOPEN2K8 | ||
| 105 | /* Nanosecond resolution timestamps are stored in a format | ||
| 106 | equivalent to 'struct timespec'. This is the type used | ||
| 107 | whenever possible but the Unix namespace rules do not allow the | ||
| 108 | identifier 'timespec' to appear in the <sys/stat.h> header. | ||
| 109 | Therefore we have to handle the use of this header in strictly | ||
| 110 | standard-compliant sources special. */ | ||
| 111 | struct timespec st_atim; /* Time of last access. */ | ||
| 112 | struct timespec st_mtim; /* Time of last modification. */ | ||
| 113 | struct timespec st_ctim; /* Time of last status change. */ | ||
| 114 | # else | ||
| 115 | __time_t st_atime;			/* Time of last access. */ | ||
| 116 | unsigned long int st_atimensec;	/* Nscecs of last access. */ | ||
| 117 | __time_t st_mtime;			/* Time of last modification. */ | ||
| 118 | unsigned long int st_mtimensec;	/* Nsecs of last modification. */ | ||
| 119 | __time_t st_ctime;			/* Time of last status change. */ | ||
| 120 | unsigned long int st_ctimensec;	/* Nsecs of last status change. */ | ||
| 121 | # endif | ||
| 122 | __blksize_t st_blksize;	/* Optimal block size for I/O. */ | ||
| 123 | long int st_pad3; | ||
| 124 | __blkcnt64_t st_blocks;	/* Number of 512-byte blocks allocated. */ | ||
| 125 | long int st_pad4[14]; | ||
| 126 | # endif /* __USE_TIME64_REDIRECTS */ | ||
| 127 | }; | ||
| 128 | # endif /* __USE_LARGEFILE64 */ | ||
| 129 | |||
| 130 | #else /* _MIPS_SIM != _ABIO32 */ | ||
| 131 | |||
| 132 | struct stat | ||
| 133 | { | ||
| 134 | # ifdef __USE_TIME64_REDIRECTS | ||
| 135 | # include <bits/struct_stat_time64_helper.h> | ||
| 136 | # else | ||
| 137 | __dev_t st_dev; | ||
| 138 | int	st_pad1[3];		/* Reserved for st_dev expansion */ | ||
| 139 | # ifndef __USE_FILE_OFFSET64 | ||
| 140 | __ino_t st_ino; | ||
| 141 | # else | ||
| 142 | __ino64_t st_ino; | ||
| 143 | # endif | ||
| 144 | __mode_t st_mode; | ||
| 145 | __nlink_t st_nlink; | ||
| 146 | __uid_t st_uid; | ||
| 147 | __gid_t st_gid; | ||
| 148 | __dev_t st_rdev; | ||
| 149 | # if !defined __USE_FILE_OFFSET64 | ||
| 150 | unsigned int st_pad2[2];	/* Reserved for st_rdev expansion */ | ||
| 151 | __off_t st_size; | ||
| 152 | int st_pad3; | ||
| 153 | # else | ||
| 154 | unsigned int st_pad2[3];	/* Reserved for st_rdev expansion */ | ||
| 155 | __off64_t st_size; | ||
| 156 | # endif | ||
| 157 | # ifdef __USE_XOPEN2K8 | ||
| 158 | /* Nanosecond resolution timestamps are stored in a format | ||
| 159 | equivalent to 'struct timespec'. This is the type used | ||
| 160 | whenever possible but the Unix namespace rules do not allow the | ||
| 161 | identifier 'timespec' to appear in the <sys/stat.h> header. | ||
| 162 | Therefore we have to handle the use of this header in strictly | ||
| 163 | standard-compliant sources special. */ | ||
| 164 | struct timespec st_atim; /* Time of last access. */ | ||
| 165 | struct timespec st_mtim; /* Time of last modification. */ | ||
| 166 | struct timespec st_ctim; /* Time of last status change. */ | ||
| 167 | # define st_atime st_atim.tv_sec /* Backward compatibility. */ | ||
| 168 | # define st_mtime st_mtim.tv_sec | ||
| 169 | # define st_ctime st_ctim.tv_sec | ||
| 170 | # else | ||
| 171 | __time_t st_atime;			/* Time of last access. */ | ||
| 172 | unsigned long int st_atimensec;	/* Nscecs of last access. */ | ||
| 173 | __time_t st_mtime;			/* Time of last modification. */ | ||
| 174 | unsigned long int st_mtimensec;	/* Nsecs of last modification. */ | ||
| 175 | __time_t st_ctime;			/* Time of last status change. */ | ||
| 176 | unsigned long int st_ctimensec;	/* Nsecs of last status change. */ | ||
| 177 | # endif | ||
| 178 | __blksize_t st_blksize; | ||
| 179 | unsigned int st_pad4; | ||
| 180 | # ifndef __USE_FILE_OFFSET64 | ||
| 181 | __blkcnt_t st_blocks; | ||
| 182 | # else | ||
| 183 | __blkcnt64_t st_blocks; | ||
| 184 | # endif | ||
| 185 | int st_pad5[14]; | ||
| 186 | # endif | ||
| 187 | }; | ||
| 188 | |||
| 189 | #ifdef __USE_LARGEFILE64 | ||
| 190 | struct stat64 | ||
| 191 | { | ||
| 192 | # ifdef __USE_TIME64_REDIRECTS | ||
| 193 | # include <bits/struct_stat_time64_helper.h> | ||
| 194 | # else | ||
| 195 | __dev_t st_dev; | ||
| 196 | unsigned int st_pad1[3];	/* Reserved for st_dev expansion */ | ||
| 197 | __ino64_t st_ino; | ||
| 198 | __mode_t st_mode; | ||
| 199 | __nlink_t st_nlink; | ||
| 200 | __uid_t st_uid; | ||
| 201 | __gid_t st_gid; | ||
| 202 | __dev_t st_rdev; | ||
| 203 | unsigned int st_pad2[3];	/* Reserved for st_rdev expansion */ | ||
| 204 | __off64_t st_size; | ||
| 205 | # ifdef __USE_XOPEN2K8 | ||
| 206 | /* Nanosecond resolution timestamps are stored in a format | ||
| 207 | equivalent to 'struct timespec'. This is the type used | ||
| 208 | whenever possible but the Unix namespace rules do not allow the | ||
| 209 | identifier 'timespec' to appear in the <sys/stat.h> header. | ||
| 210 | Therefore we have to handle the use of this header in strictly | ||
| 211 | standard-compliant sources special. */ | ||
| 212 | struct timespec st_atim; /* Time of last access. */ | ||
| 213 | struct timespec st_mtim; /* Time of last modification. */ | ||
| 214 | struct timespec st_ctim; /* Time of last status change. */ | ||
| 215 | # else | ||
| 216 | __time_t st_atime;			/* Time of last access. */ | ||
| 217 | unsigned long int st_atimensec;	/* Nscecs of last access. */ | ||
| 218 | __time_t st_mtime;			/* Time of last modification. */ | ||
| 219 | unsigned long int st_mtimensec;	/* Nsecs of last modification. */ | ||
| 220 | __time_t st_ctime;			/* Time of last status change. */ | ||
| 221 | unsigned long int st_ctimensec;	/* Nsecs of last status change. */ | ||
| 222 | # endif | ||
| 223 | __blksize_t st_blksize; | ||
| 224 | unsigned int st_pad3; | ||
| 225 | __blkcnt64_t st_blocks; | ||
| 226 | int st_pad4[14]; | ||
| 227 | # endif /* __USE_TIME64_REDIRECTS */ | ||
| 228 | }; | ||
| 229 | #endif | ||
| 230 | |||
| 231 | #endif | ||
| 232 | |||
| 233 | /* Tell code we have these members. */ | ||
| 234 | #define	_STATBUF_ST_BLKSIZE | ||
| 235 | #define	_STATBUF_ST_RDEV | ||
| 236 | |||
| 237 | #endif /* _BITS_STRUCT_STAT_H */ | ||
| \ No newline at end of file | |||
lib/libc/include/mips-linux-gnu/bits/timesize.h created+22| ... | @@ -0,0 +1,22 @@ | ||
| 1 | /* Bit size of the time_t type at glibc build time, Linux/MIPS. | ||
| 2 | Copyright (C) 2021-2026 Free Software Foundation, Inc. | ||
| 3 | This file is part of the GNU C Library. | ||
| 4 | |||
| 5 | The GNU C Library is free software; you can redistribute it and/or | ||
| 6 | modify it under the terms of the GNU Lesser General Public | ||
| 7 | License as published by the Free Software Foundation; either | ||
| 8 | version 2.1 of the License, or (at your option) any later version. | ||
| 9 | |||
| 10 | The GNU C Library is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 13 | Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public | ||
| 16 | License along with the GNU C Library; if not, see | ||
| 17 | <https://www.gnu.org/licenses/>. */ | ||
| 18 | |||
| 19 | #include <bits/wordsize.h> | ||
| 20 | |||
| 21 | /* Size in bits of the 'time_t' type of the default ABI. */ | ||
| 22 | #define __TIMESIZE	__WORDSIZE | ||
| \ No newline at end of file | |||
lib/libc/include/mips-linux-gnu/bits/waitstatus.h created+68| ... | @@ -0,0 +1,68 @@ | ||
| 1 | /* Definitions of status bits for `wait' et al. | ||
| 2 | MIPS version, based on the generic version (bits/waitstatus.h). | ||
| 3 | |||
| 4 | Copyright (C) 1992-2026 Free Software Foundation, Inc. | ||
| 5 | This file is part of the GNU C Library. | ||
| 6 | |||
| 7 | The GNU C Library is free software; you can redistribute it and/or | ||
| 8 | modify it under the terms of the GNU Lesser General Public | ||
| 9 | License as published by the Free Software Foundation; either | ||
| 10 | version 2.1 of the License, or (at your option) any later version. | ||
| 11 | |||
| 12 | The GNU C Library is distributed in the hope that it will be useful, | ||
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 15 | Lesser General Public License for more details. | ||
| 16 | |||
| 17 | You should have received a copy of the GNU Lesser General Public | ||
| 18 | License along with the GNU C Library; if not, see | ||
| 19 | <https://www.gnu.org/licenses/>. */ | ||
| 20 | |||
| 21 | #if !defined _SYS_WAIT_H && !defined _STDLIB_H | ||
| 22 | # error "Never include <bits/waitstatus.h> directly; use <sys/wait.h> instead." | ||
| 23 | #endif | ||
| 24 | |||
| 25 | |||
| 26 | /* On MIPS SIGRTMAX is 127, so we need to handle the status code 127 | ||
| 27 | which is impossible on other ports. */ | ||
| 28 | |||
| 29 | /* If WIFEXITED(STATUS), the low-order 8 bits of the status. */ | ||
| 30 | #define __WEXITSTATUS(status) (((status) & 0xff00) >> 8) | ||
| 31 | |||
| 32 | /* If WIFSIGNALED(STATUS), the terminating signal. */ | ||
| 33 | #define __WTERMSIG(status) ((status) & 0x7f) | ||
| 34 | |||
| 35 | /* If WIFSTOPPED(STATUS), the signal that stopped the child. */ | ||
| 36 | #define __WSTOPSIG(status) __WEXITSTATUS(status) | ||
| 37 | |||
| 38 | /* Nonzero if STATUS indicates normal termination. */ | ||
| 39 | #define __WIFEXITED(status) (__WTERMSIG(status) == 0) | ||
| 40 | |||
| 41 | /* Nonzero if STATUS indicates termination by a signal. */ | ||
| 42 | static __inline int | ||
| 43 | __WIFSIGNALED (int __status) | ||
| 44 | { | ||
| 45 | return ((signed char) ((__status & 0x7f) + 1) >> 1) > 0 || __status == 0x7f; | ||
| 46 | } | ||
| 47 | |||
| 48 | /* Nonzero if STATUS indicates the child is stopped. */ | ||
| 49 | static __inline int | ||
| 50 | __WIFSTOPPED (int __status) | ||
| 51 | { | ||
| 52 | return (__status & 0xff) == 0x7f && __status != 0x7f; | ||
| 53 | } | ||
| 54 | |||
| 55 | /* Nonzero if STATUS indicates the child continued after a stop. We only | ||
| 56 | define this if <bits/waitflags.h> provides the WCONTINUED flag bit. */ | ||
| 57 | #ifdef WCONTINUED | ||
| 58 | # define __WIFCONTINUED(status) ((status) == __W_CONTINUED) | ||
| 59 | #endif | ||
| 60 | |||
| 61 | /* Nonzero if STATUS indicates the child dumped core. */ | ||
| 62 | #define __WCOREDUMP(status) ((status) & __WCOREFLAG) | ||
| 63 | |||
| 64 | /* Macros for constructing status values. */ | ||
| 65 | #define __W_EXITCODE(ret, sig) ((ret) << 8 | (sig)) | ||
| 66 | #define __W_STOPCODE(sig) ((sig) << 8 | 0x7f) | ||
| 67 | #define __W_CONTINUED 0xffff | ||
| 68 | #define __WCOREFLAG 0x80 | ||
| \ No newline at end of file | |||
lib/libc/include/powerpc-linux-gnu/bits/long-double.h+1-1| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | /* Properties of long double type. ldbl-opt version. | 1 | /* Properties of long double type. ldbl-opt version. |
| 2 | Copyright (C) 2016-2026 Free Software Foundation, Inc. | 2 | Copyright (C) 2019-2026 Free Software Foundation, Inc. |
| 3 | This file is part of the GNU C Library. | 3 | This file is part of the GNU C Library. |
| 4 | 4 | ||
| 5 | The GNU C Library is free software; you can redistribute it and/or | 5 | The GNU C Library is free software; you can redistribute it and/or |
lib/libc/include/powerpc-linux-gnu/bits/ppc.h created+33| ... | @@ -0,0 +1,33 @@ | ||
| 1 | /* Facilities specific to the PowerPC architecture on Linux | ||
| 2 | Copyright (C) 2012-2026 Free Software Foundation, Inc. | ||
| 3 | This file is part of the GNU C Library. | ||
| 4 | |||
| 5 | The GNU C Library is free software; you can redistribute it and/or | ||
| 6 | modify it under the terms of the GNU Lesser General Public | ||
| 7 | License as published by the Free Software Foundation; either | ||
| 8 | version 2.1 of the License, or (at your option) any later version. | ||
| 9 | |||
| 10 | The GNU C Library is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 13 | Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public | ||
| 16 | License along with the GNU C Library; if not, see | ||
| 17 | <https://www.gnu.org/licenses/>. */ | ||
| 18 | |||
| 19 | #ifndef _BITS_PPC_H | ||
| 20 | #define _BITS_PPC_H | ||
| 21 | |||
| 22 | #ifndef _SYS_PLATFORM_PPC_H | ||
| 23 | # error "Never include this file directly; use <sys/platform/ppc.h> instead." | ||
| 24 | #endif | ||
| 25 | |||
| 26 | __BEGIN_DECLS | ||
| 27 | |||
| 28 | /* Read the time base frequency. */ | ||
| 29 | extern uint64_t __ppc_get_timebase_freq (void); | ||
| 30 | |||
| 31 | __END_DECLS | ||
| 32 | |||
| 33 | #endif | ||
| \ No newline at end of file | |||
lib/libc/include/powerpc-linux-gnu/bits/struct_mutex.h+1-1| ... | @@ -59,4 +59,4 @@ struct __pthread_mutex_s | ... | @@ -59,4 +59,4 @@ struct __pthread_mutex_s |
| 59 | 0, 0, 0, __kind, 0, { { 0, 0 } } | 59 | 0, 0, 0, __kind, 0, { { 0, 0 } } |
| 60 | #endif | 60 | #endif |
| 61 | 61 | ||
| 62 | #endif | 62 | #endif |
| \ No newline at end of file | |||
lib/libc/include/powerpc-linux-gnu/gnu/lib-names-32.h deleted-26| ... | @@ -1,26 +0,0 @@ | ||
| 1 | /* This file is automatically generated. */ | ||
| 2 | #ifndef __GNU_LIB_NAMES_H | ||
| 3 | # error "Never use <gnu/lib-names-32.h> directly; include <gnu/lib-names.h> instead." | ||
| 4 | #endif | ||
| 5 | |||
| 6 | #define LD_SO "ld.so.1" | ||
| 7 | #define LIBANL_SO "libanl.so.1" | ||
| 8 | #define LIBBROKENLOCALE_SO "libBrokenLocale.so.1" | ||
| 9 | #define LIBC_MALLOC_DEBUG_SO "libc_malloc_debug.so.0" | ||
| 10 | #define LIBC_SO "libc.so.6" | ||
| 11 | #define LIBDL_SO "libdl.so.2" | ||
| 12 | #define LIBGCC_S_SO "libgcc_s.so.1" | ||
| 13 | #define LIBMVEC_SO "libmvec.so.1" | ||
| 14 | #define LIBM_SO "libm.so.6" | ||
| 15 | #define LIBNSL_SO "libnsl.so.1" | ||
| 16 | #define LIBNSS_COMPAT_SO "libnss_compat.so.2" | ||
| 17 | #define LIBNSS_DB_SO "libnss_db.so.2" | ||
| 18 | #define LIBNSS_DNS_SO "libnss_dns.so.2" | ||
| 19 | #define LIBNSS_FILES_SO "libnss_files.so.2" | ||
| 20 | #define LIBNSS_HESIOD_SO "libnss_hesiod.so.2" | ||
| 21 | #define LIBNSS_LDAP_SO "libnss_ldap.so.2" | ||
| 22 | #define LIBPTHREAD_SO "libpthread.so.0" | ||
| 23 | #define LIBRESOLV_SO "libresolv.so.2" | ||
| 24 | #define LIBRT_SO "librt.so.1" | ||
| 25 | #define LIBTHREAD_DB_SO "libthread_db.so.1" | ||
| 26 | #define LIBUTIL_SO "libutil.so.1" | ||
| \ No newline at end of file | |||
lib/libc/include/powerpc-linux-gnu/gnu/lib-names-64-v1.h deleted-27| ... | @@ -1,27 +0,0 @@ | ||
| 1 | /* This file is automatically generated. */ | ||
| 2 | #ifndef __GNU_LIB_NAMES_H | ||
| 3 | # error "Never use <gnu/lib-names-64-v1.h> directly; include <gnu/lib-names.h> instead." | ||
| 4 | #endif | ||
| 5 | |||
| 6 | #define LD64_SO "ld64.so.1" | ||
| 7 | #define LD_SO "ld64.so.1" | ||
| 8 | #define LIBANL_SO "libanl.so.1" | ||
| 9 | #define LIBBROKENLOCALE_SO "libBrokenLocale.so.1" | ||
| 10 | #define LIBC_MALLOC_DEBUG_SO "libc_malloc_debug.so.0" | ||
| 11 | #define LIBC_SO "libc.so.6" | ||
| 12 | #define LIBDL_SO "libdl.so.2" | ||
| 13 | #define LIBGCC_S_SO "libgcc_s.so.1" | ||
| 14 | #define LIBMVEC_SO "libmvec.so.1" | ||
| 15 | #define LIBM_SO "libm.so.6" | ||
| 16 | #define LIBNSL_SO "libnsl.so.1" | ||
| 17 | #define LIBNSS_COMPAT_SO "libnss_compat.so.2" | ||
| 18 | #define LIBNSS_DB_SO "libnss_db.so.2" | ||
| 19 | #define LIBNSS_DNS_SO "libnss_dns.so.2" | ||
| 20 | #define LIBNSS_FILES_SO "libnss_files.so.2" | ||
| 21 | #define LIBNSS_HESIOD_SO "libnss_hesiod.so.2" | ||
| 22 | #define LIBNSS_LDAP_SO "libnss_ldap.so.2" | ||
| 23 | #define LIBPTHREAD_SO "libpthread.so.0" | ||
| 24 | #define LIBRESOLV_SO "libresolv.so.2" | ||
| 25 | #define LIBRT_SO "librt.so.1" | ||
| 26 | #define LIBTHREAD_DB_SO "libthread_db.so.1" | ||
| 27 | #define LIBUTIL_SO "libutil.so.1" | ||
| \ No newline at end of file | |||
lib/libc/include/powerpc-linux-gnu/gnu/lib-names-64-v2.h+1| ... | @@ -24,4 +24,5 @@ | ... | @@ -24,4 +24,5 @@ |
| 24 | #define LIBRESOLV_SO "libresolv.so.2" | 24 | #define LIBRESOLV_SO "libresolv.so.2" |
| 25 | #define LIBRT_SO "librt.so.1" | 25 | #define LIBRT_SO "librt.so.1" |
| 26 | #define LIBTHREAD_DB_SO "libthread_db.so.1" | 26 | #define LIBTHREAD_DB_SO "libthread_db.so.1" |
| 27 | #define LIBUNWIND_SO "libunwind.so.1" | ||
| 27 | #define LIBUTIL_SO "libutil.so.1" | 28 | #define LIBUTIL_SO "libutil.so.1" |
| \ No newline at end of file | |||
lib/libc/include/powerpc-linux-gnu/gnu/stubs-64-v1.h deleted-16| ... | @@ -1,16 +0,0 @@ | ||
| 1 | /* This file is automatically generated. | ||
| 2 | It defines a symbol `__stub_FUNCTION' for each function | ||
| 3 | in the C library which is a stub, meaning it will fail | ||
| 4 | every time called, usually setting errno to ENOSYS. */ | ||
| 5 | |||
| 6 | #ifdef _LIBC | ||
| 7 | #error Applications may not define the macro _LIBC | ||
| 8 | #endif | ||
| 9 | |||
| 10 | #define __stub_chflags | ||
| 11 | #define __stub_fchflags | ||
| 12 | #define __stub_gtty | ||
| 13 | #define __stub_revoke | ||
| 14 | #define __stub_setlogin | ||
| 15 | #define __stub_sigreturn | ||
| 16 | #define __stub_stty | ||
| \ No newline at end of file | |||
lib/libc/include/powerpc-linux-gnu/sys/platform/ppc.h created+146| ... | @@ -0,0 +1,146 @@ | ||
| 1 | /* Facilities specific to the PowerPC architecture | ||
| 2 | Copyright (C) 2012-2026 Free Software Foundation, Inc. | ||
| 3 | This file is part of the GNU C Library. | ||
| 4 | |||
| 5 | The GNU C Library is free software; you can redistribute it and/or | ||
| 6 | modify it under the terms of the GNU Lesser General Public | ||
| 7 | License as published by the Free Software Foundation; either | ||
| 8 | version 2.1 of the License, or (at your option) any later version. | ||
| 9 | |||
| 10 | The GNU C Library is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 13 | Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public | ||
| 16 | License along with the GNU C Library; if not, see | ||
| 17 | <https://www.gnu.org/licenses/>. */ | ||
| 18 | |||
| 19 | #ifndef _SYS_PLATFORM_PPC_H | ||
| 20 | #define _SYS_PLATFORM_PPC_H	1 | ||
| 21 | |||
| 22 | #include <features.h> | ||
| 23 | #include <stdint.h> | ||
| 24 | #include <bits/ppc.h> | ||
| 25 | |||
| 26 | /* Read the Time Base Register. */ | ||
| 27 | static __inline__ uint64_t | ||
| 28 | __ppc_get_timebase (void) | ||
| 29 | { | ||
| 30 | #if __GNUC_PREREQ (4, 8) | ||
| 31 | return __builtin_ppc_get_timebase (); | ||
| 32 | #else | ||
| 33 | # ifdef __powerpc64__ | ||
| 34 | uint64_t __tb; | ||
| 35 | /* "volatile" is necessary here, because the user expects this assembly | ||
| 36 | isn't moved after an optimization. */ | ||
| 37 | __asm__ volatile ("mfspr %0, 268" : "=r" (__tb)); | ||
| 38 | return __tb; | ||
| 39 | # else /* not __powerpc64__ */ | ||
| 40 | uint32_t __tbu, __tbl, __tmp; \ | ||
| 41 | __asm__ volatile ("0:\n\t" | ||
| 42 | 		 "mftbu %0\n\t" | ||
| 43 | 		 "mftbl %1\n\t" | ||
| 44 | 		 "mftbu %2\n\t" | ||
| 45 | 		 "cmpw %0, %2\n\t" | ||
| 46 | 		 "bne- 0b" | ||
| 47 | 		 : "=r" (__tbu), "=r" (__tbl), "=r" (__tmp)); | ||
| 48 | return (((uint64_t) __tbu << 32) | __tbl); | ||
| 49 | # endif /* not __powerpc64__ */ | ||
| 50 | #endif | ||
| 51 | } | ||
| 52 | |||
| 53 | /* The following functions provide hints about the usage of shared processor | ||
| 54 | resources, as defined in ISA 2.06 and newer. */ | ||
| 55 | |||
| 56 | /* Provides a hint that performance will probably be improved if shared | ||
| 57 | resources dedicated to the executing processor are released for use by other | ||
| 58 | processors. */ | ||
| 59 | static __inline__ void | ||
| 60 | __ppc_yield (void) | ||
| 61 | { | ||
| 62 | __asm__ volatile ("or 27,27,27"); | ||
| 63 | } | ||
| 64 | |||
| 65 | /* Provides a hint that performance will probably be improved if shared | ||
| 66 | resources dedicated to the executing processor are released until | ||
| 67 | all outstanding storage accesses to caching-inhibited storage have been | ||
| 68 | completed. */ | ||
| 69 | static __inline__ void | ||
| 70 | __ppc_mdoio (void) | ||
| 71 | { | ||
| 72 | __asm__ volatile ("or 29,29,29"); | ||
| 73 | } | ||
| 74 | |||
| 75 | /* Provides a hint that performance will probably be improved if shared | ||
| 76 | resources dedicated to the executing processor are released until all | ||
| 77 | outstanding storage accesses to cacheable storage for which the data is not | ||
| 78 | in the cache have been completed. */ | ||
| 79 | static __inline__ void | ||
| 80 | __ppc_mdoom (void) | ||
| 81 | { | ||
| 82 | __asm__ volatile ("or 30,30,30"); | ||
| 83 | } | ||
| 84 | |||
| 85 | |||
| 86 | /* ISA 2.05 and beyond support the Program Priority Register (PPR) to adjust | ||
| 87 | thread priorities based on lock acquisition, wait and release. The ISA | ||
| 88 | defines the use of form 'or Rx,Rx,Rx' as the way to modify the PRI field. | ||
| 89 | The unprivileged priorities are: | ||
| 90 | Rx = 1 (low) | ||
| 91 | Rx = 2 (medium) | ||
| 92 | Rx = 6 (medium-low/normal) | ||
| 93 | The 'or' instruction form is a nop in previous hardware, so it is safe to | ||
| 94 | use unguarded. The default value is 'medium'. | ||
| 95 | */ | ||
| 96 | |||
| 97 | static __inline__ void | ||
| 98 | __ppc_set_ppr_med (void) | ||
| 99 | { | ||
| 100 | __asm__ volatile ("or 2,2,2"); | ||
| 101 | } | ||
| 102 | |||
| 103 | static __inline__ void | ||
| 104 | __ppc_set_ppr_med_low (void) | ||
| 105 | { | ||
| 106 | __asm__ volatile ("or 6,6,6"); | ||
| 107 | } | ||
| 108 | |||
| 109 | static __inline__ void | ||
| 110 | __ppc_set_ppr_low (void) | ||
| 111 | { | ||
| 112 | __asm__ volatile ("or 1,1,1"); | ||
| 113 | } | ||
| 114 | |||
| 115 | /* Power ISA 2.07 (Book II, Chapter 3) extends the priorities that can be set | ||
| 116 | to the Program Priority Register (PPR). The form 'or Rx,Rx,Rx' is used to | ||
| 117 | modify the PRI field of the PPR, the same way as described above. | ||
| 118 | The new priority levels are: | ||
| 119 | Rx = 31 (very low) | ||
| 120 | Rx = 5 (medium high) | ||
| 121 | Any program can set the priority to very low, low, medium low, and medium, | ||
| 122 | as these are unprivileged. | ||
| 123 | The medium high priority, on the other hand, is privileged, and may only be | ||
| 124 | set during certain time intervals by problem-state programs. If the program | ||
| 125 | priority is medium high when the time interval expires or if an attempt is | ||
| 126 | made to set the priority to medium high when it is not allowed, the PRI | ||
| 127 | field is set to medium. | ||
| 128 | */ | ||
| 129 | |||
| 130 | #ifdef _ARCH_PWR8 | ||
| 131 | |||
| 132 | static __inline__ void | ||
| 133 | __ppc_set_ppr_very_low (void) | ||
| 134 | { | ||
| 135 | __asm__ volatile ("or 31,31,31"); | ||
| 136 | } | ||
| 137 | |||
| 138 | static __inline__ void | ||
| 139 | __ppc_set_ppr_med_high (void) | ||
| 140 | { | ||
| 141 | __asm__ volatile ("or 5,5,5"); | ||
| 142 | } | ||
| 143 | |||
| 144 | #endif | ||
| 145 | |||
| 146 | #endif /* sys/platform/ppc.h */ | ||
| \ No newline at end of file | |||
lib/libc/include/powerpc-netbsd-eabi/powerpc/oea/pmap.h+6-4| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | /*	$NetBSD: pmap.h,v 1.39 2023/12/15 09:42:33 rin Exp $	*/ | 1 | /*	$NetBSD: pmap.h,v 1.39.4.1 2026/07/03 17:51:59 martin Exp $	*/ |
| 2 | 2 | ||
| 3 | /*- | 3 | /*- |
| 4 | * Copyright (C) 1995, 1996 Wolfgang Solfrank. | 4 | * Copyright (C) 1995, 1996 Wolfgang Solfrank. |
| ... | @@ -122,11 +122,13 @@ __BEGIN_DECLS | ... | @@ -122,11 +122,13 @@ __BEGIN_DECLS |
| 122 | #include <sys/systm.h> | 122 | #include <sys/systm.h> |
| 123 | 123 | ||
| 124 | /* | 124 | /* |
| 125 | * For OEA and OEA64_BRIDGE, we guarantee that pa below USER_ADDR | 125 | * Physical memory below PMAP_DIRECT_MAPPED_LEN is direct-mapped |
| 126 | * (== 3GB < VM_MIN_KERNEL_ADDRESS) is direct-mapped. | 126 | * (pa == va). Direct region covers the segments below BOTH |
| 127 | * the user copyin window (USER_SR) and the kernel HTAB window | ||
| 128 | * (KERNEL_SR), so it can never overlap. | ||
| 127 | */ | 129 | */ |
| 128 | #if defined(PPC_OEA) || defined(PPC_OEA64_BRIDGE) | 130 | #if defined(PPC_OEA) || defined(PPC_OEA64_BRIDGE) |
| 129 | #define	PMAP_DIRECT_MAPPED_SR	(USER_SR - 1) | 131 | #define	PMAP_DIRECT_MAPPED_SR	(MIN(USER_SR, KERNEL_SR) - 1) |
| 130 | #define	PMAP_DIRECT_MAPPED_LEN \ | 132 | #define	PMAP_DIRECT_MAPPED_LEN \ |
| 131 | ((vaddr_t)SEGMENT_LENGTH * (PMAP_DIRECT_MAPPED_SR + 1)) | 133 | ((vaddr_t)SEGMENT_LENGTH * (PMAP_DIRECT_MAPPED_SR + 1)) |
| 132 | #endif | 134 | #endif |
lib/libc/include/riscv-linux-gnu/bits/long-double.h deleted-21| ... | @@ -1,21 +0,0 @@ | ||
| 1 | /* Properties of long double type. ldbl-128 version. | ||
| 2 | Copyright (C) 2016-2026 Free Software Foundation, Inc. | ||
| 3 | This file is part of the GNU C Library. | ||
| 4 | |||
| 5 | The GNU C Library is free software; you can redistribute it and/or | ||
| 6 | modify it under the terms of the GNU Lesser General Public | ||
| 7 | License published by the Free Software Foundation; either | ||
| 8 | version 2.1 of the License, or (at your option) any later version. | ||
| 9 | |||
| 10 | The GNU C Library is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 13 | Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public | ||
| 16 | License along with the GNU C Library; if not, see | ||
| 17 | <https://www.gnu.org/licenses/>. */ | ||
| 18 | |||
| 19 | /* long double is distinct from double, so there is nothing to | ||
| 20 | define here. */ | ||
| 21 | #define __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI 0 | ||
| \ No newline at end of file | |||
lib/libc/include/riscv-linux-gnu/bits/struct_stat.h deleted-127| ... | @@ -1,127 +0,0 @@ | ||
| 1 | /* Definition for struct stat. | ||
| 2 | Copyright (C) 2020-2026 Free Software Foundation, Inc. | ||
| 3 | This file is part of the GNU C Library. | ||
| 4 | |||
| 5 | The GNU C Library is free software; you can redistribute it and/or | ||
| 6 | modify it under the terms of the GNU Lesser General Public | ||
| 7 | License as published by the Free Software Foundation; either | ||
| 8 | version 2.1 of the License, or (at your option) any later version. | ||
| 9 | |||
| 10 | The GNU C Library is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 13 | Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public | ||
| 16 | License along with the GNU C Library. If not, see | ||
| 17 | <https://www.gnu.org/licenses/>. */ | ||
| 18 | |||
| 19 | #if !defined _SYS_STAT_H && !defined _FCNTL_H | ||
| 20 | # error "Never include <bits/struct_stat.h> directly; use <sys/stat.h> instead." | ||
| 21 | #endif | ||
| 22 | |||
| 23 | #ifndef _BITS_STRUCT_STAT_H | ||
| 24 | #define _BITS_STRUCT_STAT_H	1 | ||
| 25 | |||
| 26 | #include <bits/endian.h> | ||
| 27 | #include <bits/wordsize.h> | ||
| 28 | |||
| 29 | #if defined __USE_FILE_OFFSET64 | ||
| 30 | # define __field64(type, type64, name) type64 name | ||
| 31 | #elif __WORDSIZE == 64 || defined __INO_T_MATCHES_INO64_T | ||
| 32 | # if defined __INO_T_MATCHES_INO64_T && !defined __OFF_T_MATCHES_OFF64_T | ||
| 33 | # error "ino_t and off_t must both be the same type" | ||
| 34 | # endif | ||
| 35 | # define __field64(type, type64, name) type name | ||
| 36 | #elif __BYTE_ORDER == __LITTLE_ENDIAN | ||
| 37 | # define __field64(type, type64, name) \ | ||
| 38 | type name __attribute__((__aligned__ (__alignof__ (type64)))); int __##name##_pad | ||
| 39 | #else | ||
| 40 | # define __field64(type, type64, name) \ | ||
| 41 | int __##name##_pad __attribute__((__aligned__ (__alignof__ (type64)))); type name | ||
| 42 | #endif | ||
| 43 | |||
| 44 | struct stat | ||
| 45 | { | ||
| 46 | __dev_t st_dev;		/* Device. */ | ||
| 47 | __field64(__ino_t, __ino64_t, st_ino); /* File serial number. */ | ||
| 48 | __mode_t st_mode;		/* File mode. */ | ||
| 49 | __nlink_t st_nlink;		/* Link count. */ | ||
| 50 | __uid_t st_uid;		/* User ID of the file's owner.	*/ | ||
| 51 | __gid_t st_gid;		/* Group ID of the file's group.*/ | ||
| 52 | __dev_t st_rdev;		/* Device number, if device. */ | ||
| 53 | __dev_t __pad1; | ||
| 54 | __field64(__off_t, __off64_t, st_size); /* Size of file, in bytes. */ | ||
| 55 | __blksize_t st_blksize;	/* Optimal block size for I/O. */ | ||
| 56 | int __pad2; | ||
| 57 | __field64(__blkcnt_t, __blkcnt64_t, st_blocks); /* 512-byte blocks */ | ||
| 58 | #ifdef __USE_XOPEN2K8 | ||
| 59 | /* Nanosecond resolution timestamps are stored in a format | ||
| 60 | equivalent to 'struct timespec'. This is the type used | ||
| 61 | whenever possible but the Unix namespace rules do not allow the | ||
| 62 | identifier 'timespec' to appear in the <sys/stat.h> header. | ||
| 63 | Therefore we have to handle the use of this header in strictly | ||
| 64 | standard-compliant sources special. */ | ||
| 65 | struct timespec st_atim;		/* Time of last access. */ | ||
| 66 | struct timespec st_mtim;		/* Time of last modification. */ | ||
| 67 | struct timespec st_ctim;		/* Time of last status change. */ | ||
| 68 | # define st_atime st_atim.tv_sec	/* Backward compatibility. */ | ||
| 69 | # define st_mtime st_mtim.tv_sec | ||
| 70 | # define st_ctime st_ctim.tv_sec | ||
| 71 | #else | ||
| 72 | __time_t st_atime;			/* Time of last access. */ | ||
| 73 | unsigned long int st_atimensec;	/* Nscecs of last access. */ | ||
| 74 | __time_t st_mtime;			/* Time of last modification. */ | ||
| 75 | unsigned long int st_mtimensec;	/* Nsecs of last modification. */ | ||
| 76 | __time_t st_ctime;			/* Time of last status change. */ | ||
| 77 | unsigned long int st_ctimensec;	/* Nsecs of last status change. */ | ||
| 78 | #endif | ||
| 79 | int __glibc_reserved[2]; | ||
| 80 | }; | ||
| 81 | |||
| 82 | #undef __field64 | ||
| 83 | |||
| 84 | #ifdef __USE_LARGEFILE64 | ||
| 85 | struct stat64 | ||
| 86 | { | ||
| 87 | __dev_t st_dev;		/* Device. */ | ||
| 88 | __ino64_t st_ino;		/* File serial number.	*/ | ||
| 89 | __mode_t st_mode;		/* File mode. */ | ||
| 90 | __nlink_t st_nlink;		/* Link count. */ | ||
| 91 | __uid_t st_uid;		/* User ID of the file's owner.	*/ | ||
| 92 | __gid_t st_gid;		/* Group ID of the file's group.*/ | ||
| 93 | __dev_t st_rdev;		/* Device number, if device. */ | ||
| 94 | __dev_t __pad1; | ||
| 95 | __off64_t st_size;		/* Size of file, in bytes. */ | ||
| 96 | __blksize_t st_blksize;	/* Optimal block size for I/O. */ | ||
| 97 | int __pad2; | ||
| 98 | __blkcnt64_t st_blocks;	/* Nr. 512-byte blocks allocated. */ | ||
| 99 | #ifdef __USE_XOPEN2K8 | ||
| 100 | /* Nanosecond resolution timestamps are stored in a format | ||
| 101 | equivalent to 'struct timespec'. This is the type used | ||
| 102 | whenever possible but the Unix namespace rules do not allow the | ||
| 103 | identifier 'timespec' to appear in the <sys/stat.h> header. | ||
| 104 | Therefore we have to handle the use of this header in strictly | ||
| 105 | standard-compliant sources special. */ | ||
| 106 | struct timespec st_atim;		/* Time of last access. */ | ||
| 107 | struct timespec st_mtim;		/* Time of last modification. */ | ||
| 108 | struct timespec st_ctim;		/* Time of last status change. */ | ||
| 109 | #else | ||
| 110 | __time_t st_atime;			/* Time of last access. */ | ||
| 111 | unsigned long int st_atimensec;	/* Nscecs of last access. */ | ||
| 112 | __time_t st_mtime;			/* Time of last modification. */ | ||
| 113 | unsigned long int st_mtimensec;	/* Nsecs of last modification. */ | ||
| 114 | __time_t st_ctime;			/* Time of last status change. */ | ||
| 115 | unsigned long int st_ctimensec;	/* Nsecs of last status change. */ | ||
| 116 | #endif | ||
| 117 | int __glibc_reserved[2]; | ||
| 118 | }; | ||
| 119 | #endif | ||
| 120 | |||
| 121 | /* Tell code we have these members. */ | ||
| 122 | #define	_STATBUF_ST_BLKSIZE | ||
| 123 | #define _STATBUF_ST_RDEV | ||
| 124 | /* Nanosecond resolution time values are supported. */ | ||
| 125 | #define _STATBUF_ST_NSEC | ||
| 126 | |||
| 127 | #endif /* _BITS_STRUCT_STAT_H */ | ||
| \ No newline at end of file | |||
lib/libc/include/riscv-linux-gnu/bits/timesize.h deleted-20| ... | @@ -1,20 +0,0 @@ | ||
| 1 | /* Bit size of the time_t type at glibc build time, general case. | ||
| 2 | Copyright (C) 2018-2026 Free Software Foundation, Inc. | ||
| 3 | This file is part of the GNU C Library. | ||
| 4 | |||
| 5 | The GNU C Library is free software; you can redistribute it and/or | ||
| 6 | modify it under the terms of the GNU Lesser General Public | ||
| 7 | License as published by the Free Software Foundation; either | ||
| 8 | version 2.1 of the License, or (at your option) any later version. | ||
| 9 | |||
| 10 | The GNU C Library is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 13 | Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public | ||
| 16 | License along with the GNU C Library; if not, see | ||
| 17 | <https://www.gnu.org/licenses/>. */ | ||
| 18 | |||
| 19 | /* Size in bits of the 'time_t' type of the default ABI. */ | ||
| 20 | #define __TIMESIZE	64 | ||
| \ No newline at end of file | |||
lib/libc/include/riscv-linux-gnu/gnu/lib-names-ilp32d.h+1| ... | @@ -24,4 +24,5 @@ | ... | @@ -24,4 +24,5 @@ |
| 24 | #define LIBRESOLV_SO "libresolv.so.2" | 24 | #define LIBRESOLV_SO "libresolv.so.2" |
| 25 | #define LIBRT_SO "librt.so.1" | 25 | #define LIBRT_SO "librt.so.1" |
| 26 | #define LIBTHREAD_DB_SO "libthread_db.so.1" | 26 | #define LIBTHREAD_DB_SO "libthread_db.so.1" |
| 27 | #define LIBUNWIND_SO "libunwind.so.1" | ||
| 27 | #define LIBUTIL_SO "libutil.so.1" | 28 | #define LIBUTIL_SO "libutil.so.1" |
| \ No newline at end of file | |||
lib/libc/include/riscv-linux-gnu/gnu/lib-names-lp64d.h+1| ... | @@ -24,4 +24,5 @@ | ... | @@ -24,4 +24,5 @@ |
| 24 | #define LIBRESOLV_SO "libresolv.so.2" | 24 | #define LIBRESOLV_SO "libresolv.so.2" |
| 25 | #define LIBRT_SO "librt.so.1" | 25 | #define LIBRT_SO "librt.so.1" |
| 26 | #define LIBTHREAD_DB_SO "libthread_db.so.1" | 26 | #define LIBTHREAD_DB_SO "libthread_db.so.1" |
| 27 | #define LIBUNWIND_SO "libunwind.so.1" | ||
| 27 | #define LIBUTIL_SO "libutil.so.1" | 28 | #define LIBUTIL_SO "libutil.so.1" |
| \ No newline at end of file | |||
lib/libc/include/s390x-linux-gnu/bits/elfclass.h+1-6| ... | @@ -27,11 +27,6 @@ | ... | @@ -27,11 +27,6 @@ |
| 27 | 27 | ||
| 28 | #define __ELF_NATIVE_CLASS __WORDSIZE | 28 | #define __ELF_NATIVE_CLASS __WORDSIZE |
| 29 | 29 | ||
| 30 | #if __WORDSIZE == 64 | ||
| 31 | /* 64 bit Linux for S/390 is exceptional as it has .hash section with | 30 | /* 64 bit Linux for S/390 is exceptional as it has .hash section with |
| 32 | 64 bit entries. */ | 31 | 64 bit entries. */ |
| 33 | typedef uint64_t Elf_Symndx; | ||
| 34 | #else | ||
| 35 | /* 32 bit Linux for S/390 has normal .hash section entries with 32 bits. */ | ||
| 36 | typedef uint32_t Elf_Symndx; | ||
| 37 | #endif | ||
| \ No newline at end of file | |||
| 32 | typedef uint64_t Elf_Symndx; | ||
| \ No newline at end of file | |||
lib/libc/include/s390x-linux-gnu/bits/environments.h deleted-96| ... | @@ -1,96 +0,0 @@ | ||
| 1 | /* Copyright (C) 1999-2026 Free Software Foundation, Inc. | ||
| 2 | This file is part of the GNU C Library. | ||
| 3 | |||
| 4 | The GNU C Library is free software; you can redistribute it and/or | ||
| 5 | modify it under the terms of the GNU Lesser General Public | ||
| 6 | License as published by the Free Software Foundation; either | ||
| 7 | version 2.1 of the License, or (at your option) any later version. | ||
| 8 | |||
| 9 | The GNU C Library is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 12 | Lesser General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU Lesser General Public | ||
| 15 | License along with the GNU C Library; if not, see | ||
| 16 | <https://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | #ifndef _UNISTD_H | ||
| 19 | # error "Never include this file directly. Use <unistd.h> instead" | ||
| 20 | #endif | ||
| 21 | |||
| 22 | #include <bits/wordsize.h> | ||
| 23 | |||
| 24 | /* This header should define the following symbols under the described | ||
| 25 | situations. A value `1' means that the model is always supported, | ||
| 26 | `-1' means it is never supported. Undefined means it cannot be | ||
| 27 | statically decided. | ||
| 28 | |||
| 29 | _POSIX_V7_ILP32_OFF32 32bit int, long, pointers, and off_t type | ||
| 30 | _POSIX_V7_ILP32_OFFBIG 32bit int, long, and pointers and larger off_t type | ||
| 31 | |||
| 32 | _POSIX_V7_LP64_OFF32	 64bit long and pointers and 32bit off_t type | ||
| 33 | _POSIX_V7_LPBIG_OFFBIG 64bit long and pointers and large off_t type | ||
| 34 | |||
| 35 | The macros _POSIX_V6_ILP32_OFF32, _POSIX_V6_ILP32_OFFBIG, | ||
| 36 | _POSIX_V6_LP64_OFF32, _POSIX_V6_LPBIG_OFFBIG, _XBS5_ILP32_OFF32, | ||
| 37 | _XBS5_ILP32_OFFBIG, _XBS5_LP64_OFF32, and _XBS5_LPBIG_OFFBIG were | ||
| 38 | used in previous versions of the Unix standard and are available | ||
| 39 | only for compatibility. | ||
| 40 | */ | ||
| 41 | |||
| 42 | #if __WORDSIZE == 64 | ||
| 43 | |||
| 44 | /* Environments with 32-bit wide pointers are optionally provided. | ||
| 45 | Therefore following macros aren't defined: | ||
| 46 | # undef _POSIX_V7_ILP32_OFF32 | ||
| 47 | # undef _POSIX_V7_ILP32_OFFBIG | ||
| 48 | # undef _POSIX_V6_ILP32_OFF32 | ||
| 49 | # undef _POSIX_V6_ILP32_OFFBIG | ||
| 50 | # undef _XBS5_ILP32_OFF32 | ||
| 51 | # undef _XBS5_ILP32_OFFBIG | ||
| 52 | and users need to check at runtime. */ | ||
| 53 | |||
| 54 | /* We also have no use (for now) for an environment with bigger pointers | ||
| 55 | and offsets. */ | ||
| 56 | # define _POSIX_V7_LPBIG_OFFBIG	-1 | ||
| 57 | # define _POSIX_V6_LPBIG_OFFBIG	-1 | ||
| 58 | # define _XBS5_LPBIG_OFFBIG	-1 | ||
| 59 | |||
| 60 | /* By default we have 64-bit wide `long int', pointers and `off_t'. */ | ||
| 61 | # define _POSIX_V7_LP64_OFF64	1 | ||
| 62 | # define _POSIX_V6_LP64_OFF64	1 | ||
| 63 | # define _XBS5_LP64_OFF64	1 | ||
| 64 | |||
| 65 | #else /* __WORDSIZE == 32 */ | ||
| 66 | |||
| 67 | /* By default we have 32-bit wide `int', `long int', pointers and `off_t' | ||
| 68 | and all platforms support LFS. */ | ||
| 69 | # define _POSIX_V7_ILP32_OFF32	1 | ||
| 70 | # define _POSIX_V7_ILP32_OFFBIG	1 | ||
| 71 | # define _POSIX_V6_ILP32_OFF32	1 | ||
| 72 | # define _POSIX_V6_ILP32_OFFBIG	1 | ||
| 73 | # define _XBS5_ILP32_OFF32	1 | ||
| 74 | # define _XBS5_ILP32_OFFBIG	1 | ||
| 75 | |||
| 76 | /* We optionally provide an environment with the above size but an 64-bit | ||
| 77 | side `off_t'. Therefore we don't define _POSIX_V7_ILP32_OFFBIG. */ | ||
| 78 | |||
| 79 | /* Environments with 64-bit wide pointers can be provided, | ||
| 80 | so these macros aren't defined: | ||
| 81 | # undef _POSIX_V7_LP64_OFF64 | ||
| 82 | # undef _POSIX_V7_LPBIG_OFFBIG | ||
| 83 | # undef _POSIX_V6_LP64_OFF64 | ||
| 84 | # undef _POSIX_V6_LPBIG_OFFBIG | ||
| 85 | # undef _XBS5_LP64_OFF64 | ||
| 86 | # undef _XBS5_LPBIG_OFFBIG | ||
| 87 | and sysconf tests for it at runtime. */ | ||
| 88 | |||
| 89 | #endif /* __WORDSIZE == 32 */ | ||
| 90 | |||
| 91 | #define __ILP32_OFF32_CFLAGS	"-m31" | ||
| 92 | #define __ILP32_OFFBIG_CFLAGS	"-m31 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64" | ||
| 93 | #define __ILP32_OFF32_LDFLAGS	"-m31" | ||
| 94 | #define __ILP32_OFFBIG_LDFLAGS	"-m31" | ||
| 95 | #define __LP64_OFF64_CFLAGS	"-m64" | ||
| 96 | #define __LP64_OFF64_LDFLAGS	"-m64" | ||
| \ No newline at end of file | |||
lib/libc/include/s390x-linux-gnu/bits/fcntl.h+6-20| ... | @@ -22,29 +22,20 @@ | ... | @@ -22,29 +22,20 @@ |
| 22 | 22 | ||
| 23 | #include <bits/wordsize.h> | 23 | #include <bits/wordsize.h> |
| 24 | 24 | ||
| 25 | #if __WORDSIZE == 64 | ||
| 26 | /* Not necessary, files are always with 64bit off_t. */ | 25 | /* Not necessary, files are always with 64bit off_t. */ |
| 27 | # define __O_LARGEFILE	0 | 26 | #define __O_LARGEFILE	0 |
| 28 | #endif | ||
| 29 | 27 | ||
| 30 | #if __WORDSIZE == 64 | ||
| 31 | /* Not necessary, we always have 64-bit offsets. */ | 28 | /* Not necessary, we always have 64-bit offsets. */ |
| 32 | # define F_GETLK64	5	/* Get record locking info. */ | 29 | #define F_GETLK64	5	/* Get record locking info. */ |
| 33 | # define F_SETLK64	6	/* Set record locking info (non-blocking). */ | 30 | #define F_SETLK64	6	/* Set record locking info (non-blocking). */ |
| 34 | # define F_SETLKW64	7	/* Set record locking info (blocking).	*/ | 31 | #define F_SETLKW64	7	/* Set record locking info (blocking).	*/ |
| 35 | #endif | ||
| 36 | 32 | ||
| 37 | struct flock | 33 | struct flock |
| 38 | { | 34 | { |
| 39 | short int l_type;	/* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK.	*/ | 35 | short int l_type;	/* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK.	*/ |
| 40 | short int l_whence;	/* Where `l_start' is relative to (like `lseek'). */ | 36 | short int l_whence;	/* Where `l_start' is relative to (like `lseek'). */ |
| 41 | #if __WORDSIZE == 64 || !defined __USE_FILE_OFFSET64 | ||
| 42 | __off_t l_start;	/* Offset where the lock begins. */ | 37 | __off_t l_start;	/* Offset where the lock begins. */ |
| 43 | __off_t l_len;	/* Size of the locked area; zero means until EOF. */ | 38 | __off_t l_len;	/* Size of the locked area; zero means until EOF. */ |
| 44 | #else | ||
| 45 | __off64_t l_start;	/* Offset where the lock begins. */ | ||
| 46 | __off64_t l_len;	/* Size of the locked area; zero means until EOF. */ | ||
| 47 | #endif | ||
| 48 | __pid_t l_pid;	/* Process holding the lock. */ | 39 | __pid_t l_pid;	/* Process holding the lock. */ |
| 49 | }; | 40 | }; |
| 50 | 41 | ||
| ... | @@ -59,13 +50,8 @@ struct flock64 | ... | @@ -59,13 +50,8 @@ struct flock64 |
| 59 | }; | 50 | }; |
| 60 | #endif | 51 | #endif |
| 61 | 52 | ||
| 62 | #if __WORDSIZE == 64 | 53 | #define __POSIX_FADV_DONTNEED	6 /* Don't need these pages. */ |
| 63 | # define __POSIX_FADV_DONTNEED	6 /* Don't need these pages. */ | 54 | #define __POSIX_FADV_NOREUSE	7 /* Data will be accessed once. */ |
| 64 | # define __POSIX_FADV_NOREUSE	7 /* Data will be accessed once. */ | ||
| 65 | #else | ||
| 66 | # define __POSIX_FADV_DONTNEED	4 /* Don't need these pages. */ | ||
| 67 | # define __POSIX_FADV_NOREUSE	5 /* Data will be accessed once. */ | ||
| 68 | #endif | ||
| 69 | 55 | ||
| 70 | /* Include generic Linux declarations. */ | 56 | /* Include generic Linux declarations. */ |
| 71 | #include <bits/fcntl-linux.h> | 57 | #include <bits/fcntl-linux.h> |
| \ No newline at end of file | |||
lib/libc/include/s390x-linux-gnu/bits/fenv.h+4-4| ... | @@ -77,9 +77,9 @@ typedef struct | ... | @@ -77,9 +77,9 @@ typedef struct |
| 77 | { | 77 | { |
| 78 | fexcept_t __fpc; | 78 | fexcept_t __fpc; |
| 79 | void *__glibc_reserved; | 79 | void *__glibc_reserved; |
| 80 | /* The field __unused (formerly __ieee_instruction_pointer) is a relict from | 80 | /* The field __glibc_reserved (formerly __ieee_instruction_pointer) is a |
| 81 | commit "Remove PTRACE_PEEKUSER" (87b9b50f0d4b92248905e95a06a13c513dc45e59) | 81 | relict from commit "Remove PTRACE_PEEKUSER" |
| 82 | and isn't used anymore. */ | 82 | (87b9b50f0d4b92248905e95a06a13c513dc45e59) and isn't used anymore. */ |
| 83 | } fenv_t; | 83 | } fenv_t; |
| 84 | 84 | ||
| 85 | /* If the default argument is used we use this value. */ | 85 | /* If the default argument is used we use this value. */ |
| ... | @@ -96,4 +96,4 @@ typedef unsigned int femode_t; | ... | @@ -96,4 +96,4 @@ typedef unsigned int femode_t; |
| 96 | 96 | ||
| 97 | /* Default floating-point control modes. */ | 97 | /* Default floating-point control modes. */ |
| 98 | # define FE_DFL_MODE	((const femode_t *) -1L) | 98 | # define FE_DFL_MODE	((const femode_t *) -1L) |
| 99 | #endif | 99 | #endif |
| \ No newline at end of file | |||
lib/libc/include/s390x-linux-gnu/bits/link.h+1-61| ... | @@ -23,64 +23,6 @@ | ... | @@ -23,64 +23,6 @@ |
| 23 | typedef char La_s390_vr[16]; | 23 | typedef char La_s390_vr[16]; |
| 24 | #endif | 24 | #endif |
| 25 | 25 | ||
| 26 | #if __ELF_NATIVE_CLASS == 32 | ||
| 27 | |||
| 28 | /* Registers for entry into PLT on s390-32. */ | ||
| 29 | typedef struct La_s390_32_regs | ||
| 30 | { | ||
| 31 | uint32_t lr_r2; | ||
| 32 | uint32_t lr_r3; | ||
| 33 | uint32_t lr_r4; | ||
| 34 | uint32_t lr_r5; | ||
| 35 | uint32_t lr_r6; | ||
| 36 | double lr_fp0; | ||
| 37 | double lr_fp2; | ||
| 38 | # if defined HAVE_S390_VX_ASM_SUPPORT | ||
| 39 | La_s390_vr lr_v24; | ||
| 40 | La_s390_vr lr_v25; | ||
| 41 | La_s390_vr lr_v26; | ||
| 42 | La_s390_vr lr_v27; | ||
| 43 | La_s390_vr lr_v28; | ||
| 44 | La_s390_vr lr_v29; | ||
| 45 | La_s390_vr lr_v30; | ||
| 46 | La_s390_vr lr_v31; | ||
| 47 | # endif | ||
| 48 | } La_s390_32_regs; | ||
| 49 | |||
| 50 | /* Return values for calls from PLT on s390-32. */ | ||
| 51 | typedef struct La_s390_32_retval | ||
| 52 | { | ||
| 53 | uint32_t lrv_r2; | ||
| 54 | uint32_t lrv_r3; | ||
| 55 | double lrv_fp0; | ||
| 56 | # if defined HAVE_S390_VX_ASM_SUPPORT | ||
| 57 | La_s390_vr lrv_v24; | ||
| 58 | # endif | ||
| 59 | } La_s390_32_retval; | ||
| 60 | |||
| 61 | |||
| 62 | __BEGIN_DECLS | ||
| 63 | |||
| 64 | extern Elf32_Addr la_s390_32_gnu_pltenter (Elf32_Sym *__sym, | ||
| 65 | 					 unsigned int __ndx, | ||
| 66 | 					 uintptr_t *__refcook, | ||
| 67 | 					 uintptr_t *__defcook, | ||
| 68 | 					 La_s390_32_regs *__regs, | ||
| 69 | 					 unsigned int *__flags, | ||
| 70 | 					 const char *__symname, | ||
| 71 | 					 long int *__framesizep); | ||
| 72 | extern unsigned int la_s390_32_gnu_pltexit (Elf32_Sym *__sym, | ||
| 73 | 					 unsigned int __ndx, | ||
| 74 | 					 uintptr_t *__refcook, | ||
| 75 | 					 uintptr_t *__defcook, | ||
| 76 | 					 const La_s390_32_regs *__inregs, | ||
| 77 | 					 La_s390_32_retval *__outregs, | ||
| 78 | 					 const char *symname); | ||
| 79 | |||
| 80 | __END_DECLS | ||
| 81 | |||
| 82 | #else | ||
| 83 | |||
| 84 | /* Registers for entry into PLT on s390-64. */ | 26 | /* Registers for entry into PLT on s390-64. */ |
| 85 | typedef struct La_s390_64_regs | 27 | typedef struct La_s390_64_regs |
| 86 | { | 28 | { |
| ... | @@ -134,6 +76,4 @@ extern unsigned int la_s390_64_gnu_pltexit (Elf64_Sym *__sym, | ... | @@ -134,6 +76,4 @@ extern unsigned int la_s390_64_gnu_pltexit (Elf64_Sym *__sym, |
| 134 | 					 La_s390_64_retval *__outregs, | 76 | 					 La_s390_64_retval *__outregs, |
| 135 | 					 const char *__symname); | 77 | 					 const char *__symname); |
| 136 | 78 | ||
| 137 | __END_DECLS | ||
| 138 | |||
| 139 | #endif | ||
| \ No newline at end of file | |||
| 79 | __END_DECLS | ||
| \ No newline at end of file | |||
lib/libc/include/s390x-linux-gnu/bits/procfs-extra.h deleted-75| ... | @@ -1,75 +0,0 @@ | ||
| 1 | /* Extra sys/procfs.h definitions. S/390 version. | ||
| 2 | Copyright (C) 2000-2026 Free Software Foundation, Inc. | ||
| 3 | This file is part of the GNU C Library. | ||
| 4 | |||
| 5 | The GNU C Library is free software; you can redistribute it and/or | ||
| 6 | modify it under the terms of the GNU Lesser General Public | ||
| 7 | License as published by the Free Software Foundation; either | ||
| 8 | version 2.1 of the License, or (at your option) any later version. | ||
| 9 | |||
| 10 | The GNU C Library is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 13 | Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public | ||
| 16 | License along with the GNU C Library; if not, see | ||
| 17 | <https://www.gnu.org/licenses/>. */ | ||
| 18 | |||
| 19 | #ifndef _SYS_PROCFS_H | ||
| 20 | # error "Never include <bits/procfs-extra.h> directly; use <sys/procfs.h> instead." | ||
| 21 | #endif | ||
| 22 | |||
| 23 | #if __WORDSIZE == 64 | ||
| 24 | |||
| 25 | /* Provide 32-bit variants so that BFD can read 32-bit | ||
| 26 | core files. */ | ||
| 27 | #define ELF_NGREG32	36 | ||
| 28 | typedef unsigned int elf_greg_t32; | ||
| 29 | typedef elf_greg_t32 | ||
| 30 | elf_gregset_t32[ELF_NGREG32] __attribute__ ((__aligned__ (8))); | ||
| 31 | typedef elf_fpregset_t elf_fpregset_t32; | ||
| 32 | |||
| 33 | struct elf_prstatus32 | ||
| 34 | { | ||
| 35 | struct elf_siginfo pr_info;		/* Info associated with signal. */ | ||
| 36 | short int pr_cursig;		/* Current signal. */ | ||
| 37 | unsigned int pr_sigpend;	/* Set of pending signals. */ | ||
| 38 | unsigned int pr_sighold;	/* Set of held signals. */ | ||
| 39 | __pid_t pr_pid; | ||
| 40 | __pid_t pr_ppid; | ||
| 41 | __pid_t pr_pgrp; | ||
| 42 | __pid_t pr_sid; | ||
| 43 | struct | ||
| 44 | { | ||
| 45 | 	int tv_sec, tv_usec; | ||
| 46 | } pr_utime,			/* User time. */ | ||
| 47 | pr_stime,			/* System time. */ | ||
| 48 | pr_cutime,			/* Cumulative user time. */ | ||
| 49 | pr_cstime;			/* Cumulative system time. */ | ||
| 50 | elf_gregset_t32 pr_reg;		/* GP registers. */ | ||
| 51 | int pr_fpvalid;			/* True if math copro being used. */ | ||
| 52 | }; | ||
| 53 | |||
| 54 | struct elf_prpsinfo32 | ||
| 55 | { | ||
| 56 | char pr_state;			/* Numeric process state. */ | ||
| 57 | char pr_sname;			/* Char for pr_state. */ | ||
| 58 | char pr_zomb;			/* Zombie. */ | ||
| 59 | char pr_nice;			/* Nice val. */ | ||
| 60 | unsigned int pr_flag;		/* Flags. */ | ||
| 61 | unsigned short int pr_uid; | ||
| 62 | unsigned short int pr_gid; | ||
| 63 | int pr_pid, pr_ppid, pr_pgrp, pr_sid; | ||
| 64 | /* Lots missing */ | ||
| 65 | char pr_fname[16];			/* Filename of executable. */ | ||
| 66 | char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list. */ | ||
| 67 | }; | ||
| 68 | |||
| 69 | typedef elf_gregset_t32 prgregset32_t; | ||
| 70 | typedef elf_fpregset_t32 prfpregset32_t; | ||
| 71 | |||
| 72 | typedef struct elf_prstatus32 prstatus32_t; | ||
| 73 | typedef struct elf_prpsinfo32 prpsinfo32_t; | ||
| 74 | |||
| 75 | #endif | ||
| \ No newline at end of file | |||
lib/libc/include/s390x-linux-gnu/bits/procfs-id.h deleted-30| ... | @@ -1,30 +0,0 @@ | ||
| 1 | /* Types of pr_uid and pr_gid in struct elf_prpsinfo. S/390 version. | ||
| 2 | Copyright (C) 2018-2026 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is part of the GNU C Library. | ||
| 5 | |||
| 6 | The GNU C Library is free software; you can redistribute it and/or | ||
| 7 | modify it under the terms of the GNU Lesser General Public | ||
| 8 | License as published by the Free Software Foundation; either | ||
| 9 | version 2.1 of the License, or (at your option) any later version. | ||
| 10 | |||
| 11 | The GNU C Library is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 14 | Lesser General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU Lesser General Public | ||
| 17 | License along with the GNU C Library; if not, see | ||
| 18 | <https://www.gnu.org/licenses/>. */ | ||
| 19 | |||
| 20 | #ifndef _SYS_PROCFS_H | ||
| 21 | # error "Never include <bits/procfs-id.h> directly; use <sys/procfs.h> instead." | ||
| 22 | #endif | ||
| 23 | |||
| 24 | #if __WORDSIZE == 64 | ||
| 25 | typedef unsigned int __pr_uid_t; | ||
| 26 | typedef unsigned int __pr_gid_t; | ||
| 27 | #else | ||
| 28 | typedef unsigned short int __pr_uid_t; | ||
| 29 | typedef unsigned short int __pr_gid_t; | ||
| 30 | #endif | ||
| \ No newline at end of file | |||
lib/libc/include/s390x-linux-gnu/bits/setjmp.h-6| ... | @@ -33,13 +33,7 @@ typedef struct __s390_jmp_buf | ... | @@ -33,13 +33,7 @@ typedef struct __s390_jmp_buf |
| 33 | /* We save registers 6-15. */ | 33 | /* We save registers 6-15. */ |
| 34 | long int __gregs[10]; | 34 | long int __gregs[10]; |
| 35 | 35 | ||
| 36 | # if __WORDSIZE == 64 | ||
| 37 | /* We save fpu registers f8 - f15. */ | ||
| 38 | long __fpregs[8]; | 36 | long __fpregs[8]; |
| 39 | # else | ||
| 40 | /* We save fpu registers 4 and 6. */ | ||
| 41 | long __fpregs[4]; | ||
| 42 | # endif | ||
| 43 | } __jmp_buf[1]; | 37 | } __jmp_buf[1]; |
| 44 | 38 | ||
| 45 | #endif | 39 | #endif |
lib/libc/include/s390x-linux-gnu/bits/sigaction.h+1-34| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | /* Definitions for 31 & 64 bit S/390 sigaction. | 1 | /* Definitions for 64 bit S/390 sigaction. |
| 2 | Copyright (C) 2001-2026 Free Software Foundation, Inc. | 2 | Copyright (C) 2001-2026 Free Software Foundation, Inc. |
| 3 | This file is part of the GNU C Library. | 3 | This file is part of the GNU C Library. |
| 4 | 4 | ||
| ... | @@ -23,9 +23,6 @@ | ... | @@ -23,9 +23,6 @@ |
| 23 | # error "Never include <bits/sigaction.h> directly; use <signal.h> instead." | 23 | # error "Never include <bits/sigaction.h> directly; use <signal.h> instead." |
| 24 | #endif | 24 | #endif |
| 25 | 25 | ||
| 26 | #include <bits/wordsize.h> | ||
| 27 | |||
| 28 | #if __WORDSIZE == 64 | ||
| 29 | /* Structure describing the action to be taken when a signal arrives. */ | 26 | /* Structure describing the action to be taken when a signal arrives. */ |
| 30 | struct sigaction | 27 | struct sigaction |
| 31 | { | 28 | { |
| ... | @@ -55,36 +52,6 @@ struct sigaction | ... | @@ -55,36 +52,6 @@ struct sigaction |
| 55 | /* Additional set of signals to be blocked.	 */ | 52 | /* Additional set of signals to be blocked.	 */ |
| 56 | __sigset_t sa_mask; | 53 | __sigset_t sa_mask; |
| 57 | }; | 54 | }; |
| 58 | #else | ||
| 59 | /* Structure describing the action to be taken when a signal arrives. */ | ||
| 60 | struct sigaction | ||
| 61 | { | ||
| 62 | /* Signal handler. */ | ||
| 63 | #if defined __USE_POSIX199309 || defined __USE_XOPEN_EXTENDED | ||
| 64 | union | ||
| 65 | { | ||
| 66 | 	/* Used if SA_SIGINFO is not set. */ | ||
| 67 | 	__sighandler_t sa_handler; | ||
| 68 | 	/* Used if SA_SIGINFO is set. */ | ||
| 69 | 	void (*sa_sigaction) (int, siginfo_t *, void *); | ||
| 70 | } | ||
| 71 | __sigaction_handler; | ||
| 72 | # define sa_handler	__sigaction_handler.sa_handler | ||
| 73 | # define sa_sigaction	__sigaction_handler.sa_sigaction | ||
| 74 | #else | ||
| 75 | __sighandler_t sa_handler; | ||
| 76 | #endif | ||
| 77 | |||
| 78 | /* Additional set of signals to be blocked. */ | ||
| 79 | __sigset_t sa_mask; | ||
| 80 | |||
| 81 | /* Special flags. */ | ||
| 82 | int sa_flags; | ||
| 83 | |||
| 84 | /* Restore handler. */ | ||
| 85 | void (*sa_restorer) (void); | ||
| 86 | }; | ||
| 87 | #endif | ||
| 88 | 55 | ||
| 89 | /* Bits in `sa_flags'. */ | 56 | /* Bits in `sa_flags'. */ |
| 90 | #define	SA_NOCLDSTOP 1		 /* Don't send SIGCHLD when children stop. */ | 57 | #define	SA_NOCLDSTOP 1		 /* Don't send SIGCHLD when children stop. */ |
lib/libc/include/s390x-linux-gnu/bits/struct_mutex.h+2-24| ... | @@ -24,39 +24,17 @@ struct __pthread_mutex_s | ... | @@ -24,39 +24,17 @@ struct __pthread_mutex_s |
| 24 | int __lock; | 24 | int __lock; |
| 25 | unsigned int __count; | 25 | unsigned int __count; |
| 26 | int __owner; | 26 | int __owner; |
| 27 | #if __WORDSIZE == 64 | ||
| 28 | unsigned int __nusers; | 27 | unsigned int __nusers; |
| 29 | #endif | ||
| 30 | /* KIND must stay at this position in the structure to maintain | 28 | /* KIND must stay at this position in the structure to maintain |
| 31 | binary compatibility with static initializers. */ | 29 | binary compatibility with static initializers. */ |
| 32 | int __kind; | 30 | int __kind; |
| 33 | #if __WORDSIZE == 64 | ||
| 34 | short __spins; | 31 | short __spins; |
| 35 | short __glibc_reserved; | 32 | short __glibc_reserved; |
| 36 | __pthread_list_t __list; | 33 | __pthread_list_t __list; |
| 37 | # define __PTHREAD_MUTEX_HAVE_PREV 1 | 34 | # define __PTHREAD_MUTEX_HAVE_PREV 1 |
| 38 | #else | ||
| 39 | unsigned int __nusers; | ||
| 40 | __extension__ union | ||
| 41 | { | ||
| 42 | struct | ||
| 43 | { | ||
| 44 | short __data_spins; | ||
| 45 | short __data_unused; | ||
| 46 | } __data; | ||
| 47 | # define __spins __data.__data_spins | ||
| 48 | __pthread_slist_t __list; | ||
| 49 | }; | ||
| 50 | # define __PTHREAD_MUTEX_HAVE_PREV 0 | ||
| 51 | #endif | ||
| 52 | }; | 35 | }; |
| 53 | 36 | ||
| 54 | #if __WORDSIZE == 64 | 37 | #define __PTHREAD_MUTEX_INITIALIZER(__kind) \ |
| 55 | # define __PTHREAD_MUTEX_INITIALIZER(__kind) \ | ||
| 56 | 0, 0, 0, 0, __kind, 0, 0, { 0, 0 } | 38 | 0, 0, 0, 0, __kind, 0, 0, { 0, 0 } |
| 57 | #else | ||
| 58 | # define __PTHREAD_MUTEX_INITIALIZER(__kind) \ | ||
| 59 | 0, 0, 0, __kind, 0, { { 0, 0 } } | ||
| 60 | #endif | ||
| 61 | 39 | ||
| 62 | #endif | 40 | #endif |
| \ No newline at end of file | |||
lib/libc/include/s390x-linux-gnu/bits/struct_rwlock.h+1-16| ... | @@ -28,7 +28,6 @@ struct __pthread_rwlock_arch_t | ... | @@ -28,7 +28,6 @@ struct __pthread_rwlock_arch_t |
| 28 | unsigned int __writers_futex; | 28 | unsigned int __writers_futex; |
| 29 | unsigned int __pad3; | 29 | unsigned int __pad3; |
| 30 | unsigned int __pad4; | 30 | unsigned int __pad4; |
| 31 | #if __WORDSIZE == 64 | ||
| 32 | int __cur_writer; | 31 | int __cur_writer; |
| 33 | int __shared; | 32 | int __shared; |
| 34 | unsigned long int __pad1; | 33 | unsigned long int __pad1; |
| ... | @@ -36,23 +35,9 @@ struct __pthread_rwlock_arch_t | ... | @@ -36,23 +35,9 @@ struct __pthread_rwlock_arch_t |
| 36 | /* FLAGS must stay at this position in the structure to maintain | 35 | /* FLAGS must stay at this position in the structure to maintain |
| 37 | binary compatibility. */ | 36 | binary compatibility. */ |
| 38 | unsigned int __flags; | 37 | unsigned int __flags; |
| 39 | # else | ||
| 40 | unsigned char __pad1; | ||
| 41 | unsigned char __pad2; | ||
| 42 | unsigned char __shared; | ||
| 43 | /* FLAGS must stay at this position in the structure to maintain | ||
| 44 | binary compatibility. */ | ||
| 45 | unsigned char __flags; | ||
| 46 | int __cur_writer; | ||
| 47 | #endif | ||
| 48 | }; | 38 | }; |
| 49 | 39 | ||
| 50 | #if __WORDSIZE == 64 | 40 | #define __PTHREAD_RWLOCK_INITIALIZER(__flags) \ |
| 51 | # define __PTHREAD_RWLOCK_INITIALIZER(__flags) \ | ||
| 52 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, __flags | 41 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, __flags |
| 53 | #else | ||
| 54 | # define __PTHREAD_RWLOCK_INITIALIZER(__flags) \ | ||
| 55 | 0, 0, 0, 0, 0, 0, 0, 0, 0, __flags, 0 | ||
| 56 | #endif | ||
| 57 | 42 | ||
| 58 | #endif | 43 | #endif |
| \ No newline at end of file | |||
lib/libc/include/s390x-linux-gnu/bits/struct_stat.h+6-114| ... | @@ -25,7 +25,6 @@ | ... | @@ -25,7 +25,6 @@ |
| 25 | 25 | ||
| 26 | #include <bits/wordsize.h> | 26 | #include <bits/wordsize.h> |
| 27 | 27 | ||
| 28 | #if __WORDSIZE == 64 | ||
| 29 | struct stat | 28 | struct stat |
| 30 | { | 29 | { |
| 31 | __dev_t st_dev;		/* Device. */ | 30 | __dev_t st_dev;		/* Device. */ |
| ... | @@ -62,70 +61,8 @@ struct stat | ... | @@ -62,70 +61,8 @@ struct stat |
| 62 | __blkcnt_t st_blocks;	/* Nr. 512-byte blocks allocated. */ | 61 | __blkcnt_t st_blocks;	/* Nr. 512-byte blocks allocated. */ |
| 63 | long int __glibc_reserved[3]; | 62 | long int __glibc_reserved[3]; |
| 64 | }; | 63 | }; |
| 65 | #else | ||
| 66 | struct stat | ||
| 67 | { | ||
| 68 | # ifdef __USE_TIME64_REDIRECTS | ||
| 69 | # include <bits/struct_stat_time64_helper.h> | ||
| 70 | # else | ||
| 71 | __dev_t st_dev;			/* Device. */ | ||
| 72 | unsigned int __pad1; | ||
| 73 | # ifndef __USE_FILE_OFFSET64 | ||
| 74 | __ino_t st_ino;			/* File serial number.	*/ | ||
| 75 | # else | ||
| 76 | __ino_t __st_ino;			/* 32bit file serial number.	*/ | ||
| 77 | # endif | ||
| 78 | __mode_t st_mode;			/* File mode. */ | ||
| 79 | __nlink_t st_nlink;			/* Link count. */ | ||
| 80 | __uid_t st_uid;			/* User ID of the file's owner.	*/ | ||
| 81 | __gid_t st_gid;			/* Group ID of the file's group.*/ | ||
| 82 | __dev_t st_rdev;			/* Device number, if device. */ | ||
| 83 | unsigned int __pad2; | ||
| 84 | # ifndef __USE_FILE_OFFSET64 | ||
| 85 | __off_t st_size;			/* Size of file, in bytes. */ | ||
| 86 | # else | ||
| 87 | __off64_t st_size;			/* Size of file, in bytes. */ | ||
| 88 | # endif | ||
| 89 | __blksize_t st_blksize;		/* Optimal block size for I/O. */ | ||
| 90 | |||
| 91 | # ifndef __USE_FILE_OFFSET64 | ||
| 92 | __blkcnt_t st_blocks;		/* Number 512-byte blocks allocated. */ | ||
| 93 | # else | ||
| 94 | __blkcnt64_t st_blocks;		/* Number 512-byte blocks allocated. */ | ||
| 95 | # endif | ||
| 96 | # ifdef __USE_XOPEN2K8 | ||
| 97 | /* Nanosecond resolution timestamps are stored in a format | ||
| 98 | equivalent to 'struct timespec'. This is the type used | ||
| 99 | whenever possible but the Unix namespace rules do not allow the | ||
| 100 | identifier 'timespec' to appear in the <sys/stat.h> header. | ||
| 101 | Therefore we have to handle the use of this header in strictly | ||
| 102 | standard-compliant sources special. */ | ||
| 103 | struct timespec st_atim;		/* Time of last access. */ | ||
| 104 | struct timespec st_mtim;		/* Time of last modification. */ | ||
| 105 | struct timespec st_ctim;		/* Time of last status change. */ | ||
| 106 | # define st_atime st_atim.tv_sec	/* Backward compatibility. */ | ||
| 107 | # define st_mtime st_mtim.tv_sec | ||
| 108 | # define st_ctime st_ctim.tv_sec | ||
| 109 | # else | ||
| 110 | __time_t st_atime;			/* Time of last access. */ | ||
| 111 | unsigned long int st_atimensec;	/* Nscecs of last access. */ | ||
| 112 | __time_t st_mtime;			/* Time of last modification. */ | ||
| 113 | unsigned long int st_mtimensec;	/* Nsecs of last modification. */ | ||
| 114 | __time_t st_ctime;			/* Time of last status change. */ | ||
| 115 | unsigned long int st_ctimensec;	/* Nsecs of last status change. */ | ||
| 116 | # endif | ||
| 117 | # ifndef __USE_FILE_OFFSET64 | ||
| 118 | unsigned long int __glibc_reserved4; | ||
| 119 | unsigned long int __glibc_reserved5; | ||
| 120 | # else | ||
| 121 | __ino64_t st_ino;			/* File serial number.	*/ | ||
| 122 | # endif | ||
| 123 | # endif | ||
| 124 | }; | ||
| 125 | # endif | ||
| 126 | 64 | ||
| 127 | #ifdef __USE_LARGEFILE64 | 65 | #ifdef __USE_LARGEFILE64 |
| 128 | # if __WORDSIZE == 64 | ||
| 129 | /* Note stat64 is the same shape as stat. */ | 66 | /* Note stat64 is the same shape as stat. */ |
| 130 | struct stat64 | 67 | struct stat64 |
| 131 | { | 68 | { |
| ... | @@ -138,7 +75,7 @@ struct stat64 | ... | @@ -138,7 +75,7 @@ struct stat64 |
| 138 | int __glibc_reserved0; | 75 | int __glibc_reserved0; |
| 139 | __dev_t st_rdev;		/* Device number, if device. */ | 76 | __dev_t st_rdev;		/* Device number, if device. */ |
| 140 | __off_t st_size;		/* Size of file, in bytes. */ | 77 | __off_t st_size;		/* Size of file, in bytes. */ |
| 141 | # ifdef __USE_XOPEN2K8 | 78 | # ifdef __USE_XOPEN2K8 |
| 142 | /* Nanosecond resolution timestamps are stored in a format | 79 | /* Nanosecond resolution timestamps are stored in a format |
| 143 | equivalent to 'struct timespec'. This is the type used | 80 | equivalent to 'struct timespec'. This is the type used |
| 144 | whenever possible but the Unix namespace rules do not allow the | 81 | whenever possible but the Unix namespace rules do not allow the |
| ... | @@ -148,66 +85,21 @@ struct stat64 | ... | @@ -148,66 +85,21 @@ struct stat64 |
| 148 | struct timespec st_atim;		/* Time of last access. */ | 85 | struct timespec st_atim;		/* Time of last access. */ |
| 149 | struct timespec st_mtim;		/* Time of last modification. */ | 86 | struct timespec st_mtim;		/* Time of last modification. */ |
| 150 | struct timespec st_ctim;		/* Time of last status change. */ | 87 | struct timespec st_ctim;		/* Time of last status change. */ |
| 151 | # define st_atime st_atim.tv_sec	/* Backward compatibility. */ | 88 | # define st_atime st_atim.tv_sec	/* Backward compatibility. */ |
| 152 | # define st_mtime st_mtim.tv_sec | 89 | # define st_mtime st_mtim.tv_sec |
| 153 | # define st_ctime st_ctim.tv_sec | 90 | # define st_ctime st_ctim.tv_sec |
| 154 | # else | 91 | # else |
| 155 | __time_t st_atime;			/* Time of last access. */ | 92 | __time_t st_atime;			/* Time of last access. */ |
| 156 | unsigned long int st_atimensec;	/* Nscecs of last access. */ | 93 | unsigned long int st_atimensec;	/* Nscecs of last access. */ |
| 157 | __time_t st_mtime;			/* Time of last modification. */ | 94 | __time_t st_mtime;			/* Time of last modification. */ |
| 158 | unsigned long int st_mtimensec;	/* Nsecs of last modification. */ | 95 | unsigned long int st_mtimensec;	/* Nsecs of last modification. */ |
| 159 | __time_t st_ctime;			/* Time of last status change. */ | 96 | __time_t st_ctime;			/* Time of last status change. */ |
| 160 | unsigned long int st_ctimensec;	/* Nsecs of last status change. */ | 97 | unsigned long int st_ctimensec;	/* Nsecs of last status change. */ |
| 161 | # endif | 98 | # endif |
| 162 | __blksize_t st_blksize;	/* Optimal block size for I/O.	*/ | 99 | __blksize_t st_blksize;	/* Optimal block size for I/O.	*/ |
| 163 | __blkcnt64_t st_blocks;	/* Nr. 512-byte blocks allocated. */ | 100 | __blkcnt64_t st_blocks;	/* Nr. 512-byte blocks allocated. */ |
| 164 | long int __glibc_reserved[3]; | 101 | long int __glibc_reserved[3]; |
| 165 | }; | 102 | }; |
| 166 | # else | ||
| 167 | struct stat64 | ||
| 168 | { | ||
| 169 | # ifdef __USE_TIME64_REDIRECTS | ||
| 170 | # include <bits/struct_stat_time64_helper.h> | ||
| 171 | # else | ||
| 172 | __dev_t st_dev;			/* Device. */ | ||
| 173 | unsigned int __pad1; | ||
| 174 | |||
| 175 | __ino_t __st_ino;			/* 32bit file serial number.	*/ | ||
| 176 | __mode_t st_mode;			/* File mode. */ | ||
| 177 | __nlink_t st_nlink;			/* Link count. */ | ||
| 178 | __uid_t st_uid;			/* User ID of the file's owner.	*/ | ||
| 179 | __gid_t st_gid;			/* Group ID of the file's group.*/ | ||
| 180 | __dev_t st_rdev;			/* Device number, if device. */ | ||
| 181 | unsigned int __pad2; | ||
| 182 | __off64_t st_size;			/* Size of file, in bytes. */ | ||
| 183 | __blksize_t st_blksize;		/* Optimal block size for I/O. */ | ||
| 184 | |||
| 185 | __blkcnt64_t st_blocks;		/* Number 512-byte blocks allocated. */ | ||
| 186 | # ifdef __USE_XOPEN2K8 | ||
| 187 | /* Nanosecond resolution timestamps are stored in a format | ||
| 188 | equivalent to 'struct timespec'. This is the type used | ||
| 189 | whenever possible but the Unix namespace rules do not allow the | ||
| 190 | identifier 'timespec' to appear in the <sys/stat.h> header. | ||
| 191 | Therefore we have to handle the use of this header in strictly | ||
| 192 | standard-compliant sources special. */ | ||
| 193 | struct timespec st_atim;		/* Time of last access. */ | ||
| 194 | struct timespec st_mtim;		/* Time of last modification. */ | ||
| 195 | struct timespec st_ctim;		/* Time of last status change. */ | ||
| 196 | # define st_atime st_atim.tv_sec	/* Backward compatibility. */ | ||
| 197 | # define st_mtime st_mtim.tv_sec | ||
| 198 | # define st_ctime st_ctim.tv_sec | ||
| 199 | # else | ||
| 200 | __time_t st_atime;			/* Time of last access. */ | ||
| 201 | unsigned long int st_atimensec;	/* Nscecs of last access. */ | ||
| 202 | __time_t st_mtime;			/* Time of last modification. */ | ||
| 203 | unsigned long int st_mtimensec;	/* Nsecs of last modification. */ | ||
| 204 | __time_t st_ctime;			/* Time of last status change. */ | ||
| 205 | unsigned long int st_ctimensec;	/* Nsecs of last status change. */ | ||
| 206 | # endif | ||
| 207 | __ino64_t st_ino;			/* File serial number.		*/ | ||
| 208 | # endif | ||
| 209 | }; | ||
| 210 | # endif | ||
| 211 | #endif | 103 | #endif |
| 212 | 104 | ||
| 213 | /* Tell code we have these members. */ | 105 | /* Tell code we have these members. */ |
lib/libc/include/s390x-linux-gnu/bits/timesize.h deleted-22| ... | @@ -1,22 +0,0 @@ | ||
| 1 | /* Bit size of the time_t type at glibc build time, Linux/s390. | ||
| 2 | Copyright (C) 2021-2026 Free Software Foundation, Inc. | ||
| 3 | This file is part of the GNU C Library. | ||
| 4 | |||
| 5 | The GNU C Library is free software; you can redistribute it and/or | ||
| 6 | modify it under the terms of the GNU Lesser General Public | ||
| 7 | License as published by the Free Software Foundation; either | ||
| 8 | version 2.1 of the License, or (at your option) any later version. | ||
| 9 | |||
| 10 | The GNU C Library is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 13 | Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public | ||
| 16 | License along with the GNU C Library; if not, see | ||
| 17 | <https://www.gnu.org/licenses/>. */ | ||
| 18 | |||
| 19 | #include <bits/wordsize.h> | ||
| 20 | |||
| 21 | /* Size in bits of the 'time_t' type of the default ABI. */ | ||
| 22 | #define __TIMESIZE	__WORDSIZE | ||
| \ No newline at end of file | |||
lib/libc/include/s390x-linux-gnu/bits/typesizes.h+14-22| ... | @@ -57,42 +57,34 @@ | ... | @@ -57,42 +57,34 @@ |
| 57 | #define __TIMER_T_TYPE		void * | 57 | #define __TIMER_T_TYPE		void * |
| 58 | #define __BLKSIZE_T_TYPE	__SLONGWORD_TYPE | 58 | #define __BLKSIZE_T_TYPE	__SLONGWORD_TYPE |
| 59 | #define __FSID_T_TYPE		struct { int __val[2]; } | 59 | #define __FSID_T_TYPE		struct { int __val[2]; } |
| 60 | #if defined __GNUC__ && __GNUC__ <= 2 | 60 | |
| 61 | /* Compatibility with g++ 2.95.x. */ | 61 | /* With s390-32, __SSIZE_T_TYPE was __SWORD_TYPE for compatibility with |
| 62 | #define __SSIZE_T_TYPE		__SWORD_TYPE | 62 | g++ 2.95.x. Afterwards __SLONGWORD_TYPE was needed as size_t was |
| 63 | #else | 63 | unsigned long int on s390-32. |
| 64 | /* size_t is unsigned long int on s390 -m31. */ | 64 | Now as only s390-64 exists, __SWORD_TYPE can be used as also used in the |
| 65 | #define __SSIZE_T_TYPE		__SLONGWORD_TYPE | 65 | generic version as both types result in long int. */ |
| 66 | #endif | 66 | #define __SSIZE_T_TYPE __SWORD_TYPE |
| 67 | |||
| 67 | #define __SYSCALL_SLONG_TYPE	__SLONGWORD_TYPE | 68 | #define __SYSCALL_SLONG_TYPE	__SLONGWORD_TYPE |
| 68 | #define __SYSCALL_ULONG_TYPE	__ULONGWORD_TYPE | 69 | #define __SYSCALL_ULONG_TYPE	__ULONGWORD_TYPE |
| 69 | #define __CPU_MASK_TYPE 	__ULONGWORD_TYPE | 70 | #define __CPU_MASK_TYPE		__ULONGWORD_TYPE |
| 70 | 71 | ||
| 71 | #ifdef __s390x__ | ||
| 72 | /* Tell the libc code that off_t and off64_t are actually the same type | 72 | /* Tell the libc code that off_t and off64_t are actually the same type |
| 73 | for all ABI purposes, even if possibly expressed as different base types | 73 | for all ABI purposes, even if possibly expressed as different base types |
| 74 | for C type-checking purposes. */ | 74 | for C type-checking purposes. */ |
| 75 | # define __OFF_T_MATCHES_OFF64_T	1 | 75 | #define __OFF_T_MATCHES_OFF64_T	1 |
| 76 | 76 | ||
| 77 | /* Same for ino_t and ino64_t. */ | 77 | /* Same for ino_t and ino64_t. */ |
| 78 | # define __INO_T_MATCHES_INO64_T	1 | 78 | #define __INO_T_MATCHES_INO64_T	1 |
| 79 | 79 | ||
| 80 | /* And for __rlim_t and __rlim64_t. */ | 80 | /* And for __rlim_t and __rlim64_t. */ |
| 81 | # define __RLIM_T_MATCHES_RLIM64_T	1 | 81 | #define __RLIM_T_MATCHES_RLIM64_T	1 |
| 82 | 82 | ||
| 83 | /* And for fsblkcnt_t, fsblkcnt64_t, fsfilcnt_t and fsfilcnt64_t. */ | 83 | /* And for fsblkcnt_t, fsblkcnt64_t, fsfilcnt_t and fsfilcnt64_t. */ |
| 84 | # define __STATFS_MATCHES_STATFS64 1 | 84 | #define __STATFS_MATCHES_STATFS64 1 |
| 85 | 85 | ||
| 86 | /* And for getitimer, setitimer and rusage */ | 86 | /* And for getitimer, setitimer and rusage */ |
| 87 | # define __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 1 | 87 | #define __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 1 |
| 88 | #else | ||
| 89 | # define __RLIM_T_MATCHES_RLIM64_T	0 | ||
| 90 | |||
| 91 | # define __STATFS_MATCHES_STATFS64 0 | ||
| 92 | |||
| 93 | /* And for getitimer, setitimer and rusage */ | ||
| 94 | # define __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 0 | ||
| 95 | #endif | ||
| 96 | 88 | ||
| 97 | /* Number of descriptors that can fit in an `fd_set'. */ | 89 | /* Number of descriptors that can fit in an `fd_set'. */ |
| 98 | #define	__FD_SETSIZE		1024 | 90 | #define	__FD_SETSIZE		1024 |
lib/libc/include/s390x-linux-gnu/bits/utmp.h deleted-127| ... | @@ -1,127 +0,0 @@ | ||
| 1 | /* The `struct utmp' type, describing entries in the utmp file. GNU version. | ||
| 2 | Copyright (C) 1993-2026 Free Software Foundation, Inc. | ||
| 3 | This file is part of the GNU C Library. | ||
| 4 | |||
| 5 | The GNU C Library is free software; you can redistribute it and/or | ||
| 6 | modify it under the terms of the GNU Lesser General Public | ||
| 7 | License as published by the Free Software Foundation; either | ||
| 8 | version 2.1 of the License, or (at your option) any later version. | ||
| 9 | |||
| 10 | The GNU C Library is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 13 | Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public | ||
| 16 | License along with the GNU C Library; if not, see | ||
| 17 | <https://www.gnu.org/licenses/>. */ | ||
| 18 | |||
| 19 | #ifndef _UTMP_H | ||
| 20 | # error "Never include <bits/utmp.h> directly; use <utmp.h> instead." | ||
| 21 | #endif | ||
| 22 | |||
| 23 | #include <paths.h> | ||
| 24 | #include <sys/time.h> | ||
| 25 | #include <sys/types.h> | ||
| 26 | #include <bits/wordsize.h> | ||
| 27 | |||
| 28 | |||
| 29 | #define UT_LINESIZE	32 | ||
| 30 | #define UT_NAMESIZE	32 | ||
| 31 | #define UT_HOSTSIZE	256 | ||
| 32 | |||
| 33 | |||
| 34 | /* The structure describing an entry in the database of | ||
| 35 | previous logins. */ | ||
| 36 | struct lastlog | ||
| 37 | { | ||
| 38 | #if __WORDSIZE == 32 | ||
| 39 | int64_t ll_time; | ||
| 40 | #else | ||
| 41 | __time_t ll_time; | ||
| 42 | #endif | ||
| 43 | char ll_line[UT_LINESIZE]; | ||
| 44 | char ll_host[UT_HOSTSIZE]; | ||
| 45 | }; | ||
| 46 | |||
| 47 | |||
| 48 | /* The structure describing the status of a terminated process. This | ||
| 49 | type is used in `struct utmp' below. */ | ||
| 50 | struct exit_status | ||
| 51 | { | ||
| 52 | short int e_termination;	/* Process termination status. */ | ||
| 53 | short int e_exit;		/* Process exit status. */ | ||
| 54 | }; | ||
| 55 | |||
| 56 | |||
| 57 | /* The structure describing an entry in the user accounting database. */ | ||
| 58 | struct utmp | ||
| 59 | { | ||
| 60 | short int ut_type;		/* Type of login. */ | ||
| 61 | pid_t ut_pid;			/* Process ID of login process. */ | ||
| 62 | char ut_line[UT_LINESIZE] | ||
| 63 | __attribute_nonstring__;	/* Devicename. */ | ||
| 64 | char ut_id[4] | ||
| 65 | __attribute_nonstring__;	/* Inittab ID. */ | ||
| 66 | char ut_user[UT_NAMESIZE] | ||
| 67 | __attribute_nonstring__;	/* Username. */ | ||
| 68 | char ut_host[UT_HOSTSIZE] | ||
| 69 | __attribute_nonstring__;	/* Hostname for remote login. */ | ||
| 70 | struct exit_status ut_exit;	/* Exit status of a process marked | ||
| 71 | 				 as DEAD_PROCESS. */ | ||
| 72 | /* The ut_session and ut_tv fields must be the same size when compiled | ||
| 73 | 32- and 64-bit. This allows data files and shared memory to be | ||
| 74 | shared between 32- and 64-bit applications. */ | ||
| 75 | #if __WORDSIZE == 32 | ||
| 76 | int64_t ut_session;		/* Session ID, used for windowing. */ | ||
| 77 | struct | ||
| 78 | { | ||
| 79 | int64_t tv_sec;		/* Seconds. */ | ||
| 80 | int64_t tv_usec;		/* Microseconds. */ | ||
| 81 | } ut_tv;			/* Time entry was made. */ | ||
| 82 | #else | ||
| 83 | long int ut_session;		/* Session ID, used for windowing. */ | ||
| 84 | struct timeval ut_tv;		/* Time entry was made. */ | ||
| 85 | #endif | ||
| 86 | |||
| 87 | int32_t ut_addr_v6[4];	/* Internet address of remote host. */ | ||
| 88 | char __glibc_reserved[20];		/* Reserved for future use. */ | ||
| 89 | }; | ||
| 90 | |||
| 91 | /* Backwards compatibility hacks. */ | ||
| 92 | #define ut_name		ut_user | ||
| 93 | #ifndef _NO_UT_TIME | ||
| 94 | /* We have a problem here: `ut_time' is also used otherwise. Define | ||
| 95 | _NO_UT_TIME if the compiler complains. */ | ||
| 96 | # define ut_time	ut_tv.tv_sec | ||
| 97 | #endif | ||
| 98 | #define ut_xtime	ut_tv.tv_sec | ||
| 99 | #define ut_addr		ut_addr_v6[0] | ||
| 100 | |||
| 101 | |||
| 102 | /* Values for the `ut_type' field of a `struct utmp'. */ | ||
| 103 | #define EMPTY		0	/* No valid user accounting information. */ | ||
| 104 | |||
| 105 | #define RUN_LVL		1	/* The system's runlevel. */ | ||
| 106 | #define BOOT_TIME	2	/* Time of system boot. */ | ||
| 107 | #define NEW_TIME	3	/* Time after system clock changed. */ | ||
| 108 | #define OLD_TIME	4	/* Time when system clock changed. */ | ||
| 109 | |||
| 110 | #define INIT_PROCESS	5	/* Process spawned by the init process. */ | ||
| 111 | #define LOGIN_PROCESS	6	/* Session leader of a logged in user. */ | ||
| 112 | #define USER_PROCESS	7	/* Normal process. */ | ||
| 113 | #define DEAD_PROCESS	8	/* Terminated process. */ | ||
| 114 | |||
| 115 | #define ACCOUNTING	9 | ||
| 116 | |||
| 117 | /* Old Linux name for the EMPTY type. */ | ||
| 118 | #define UT_UNKNOWN	EMPTY | ||
| 119 | |||
| 120 | |||
| 121 | /* Tell the user that we have a modern system with UT_HOST, UT_PID, | ||
| 122 | UT_TYPE, UT_ID and UT_TV fields. */ | ||
| 123 | #define _HAVE_UT_TYPE	1 | ||
| 124 | #define _HAVE_UT_PID	1 | ||
| 125 | #define _HAVE_UT_ID	1 | ||
| 126 | #define _HAVE_UT_TV	1 | ||
| 127 | #define _HAVE_UT_HOST	1 | ||
| \ No newline at end of file | |||
lib/libc/include/s390x-linux-gnu/bits/utmpx.h deleted-106| ... | @@ -1,106 +0,0 @@ | ||
| 1 | /* Structures and definitions for the user accounting database. GNU version. | ||
| 2 | Copyright (C) 1997-2026 Free Software Foundation, Inc. | ||
| 3 | This file is part of the GNU C Library. | ||
| 4 | |||
| 5 | The GNU C Library is free software; you can redistribute it and/or | ||
| 6 | modify it under the terms of the GNU Lesser General Public | ||
| 7 | License as published by the Free Software Foundation; either | ||
| 8 | version 2.1 of the License, or (at your option) any later version. | ||
| 9 | |||
| 10 | The GNU C Library is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 13 | Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public | ||
| 16 | License along with the GNU C Library; if not, see | ||
| 17 | <https://www.gnu.org/licenses/>. */ | ||
| 18 | |||
| 19 | #ifndef _UTMPX_H | ||
| 20 | # error "Never include <bits/utmpx.h> directly; use <utmpx.h> instead." | ||
| 21 | #endif | ||
| 22 | |||
| 23 | #include <bits/types.h> | ||
| 24 | #include <sys/time.h> | ||
| 25 | #include <bits/wordsize.h> | ||
| 26 | |||
| 27 | |||
| 28 | #ifdef __USE_GNU | ||
| 29 | # include <paths.h> | ||
| 30 | # define _PATH_UTMPX	_PATH_UTMP | ||
| 31 | # define _PATH_WTMPX	_PATH_WTMP | ||
| 32 | #endif | ||
| 33 | |||
| 34 | |||
| 35 | #define __UT_LINESIZE	32 | ||
| 36 | #define __UT_NAMESIZE	32 | ||
| 37 | #define __UT_HOSTSIZE	256 | ||
| 38 | |||
| 39 | |||
| 40 | /* The structure describing the status of a terminated process. This | ||
| 41 | type is used in `struct utmpx' below. */ | ||
| 42 | struct __exit_status | ||
| 43 | { | ||
| 44 | #ifdef __USE_GNU | ||
| 45 | short int e_termination;	/* Process termination status. */ | ||
| 46 | short int e_exit;		/* Process exit status. */ | ||
| 47 | #else | ||
| 48 | short int __e_termination;	/* Process termination status. */ | ||
| 49 | short int __e_exit;		/* Process exit status. */ | ||
| 50 | #endif | ||
| 51 | }; | ||
| 52 | |||
| 53 | |||
| 54 | /* The structure describing an entry in the user accounting database. */ | ||
| 55 | struct utmpx | ||
| 56 | { | ||
| 57 | short int ut_type;		/* Type of login. */ | ||
| 58 | __pid_t ut_pid;		/* Process ID of login process. */ | ||
| 59 | char ut_line[__UT_LINESIZE] | ||
| 60 | __attribute_nonstring__;	/* Devicename. */ | ||
| 61 | char ut_id[4] | ||
| 62 | __attribute_nonstring__;	/* Inittab ID. */ | ||
| 63 | char ut_user[__UT_NAMESIZE] | ||
| 64 | __attribute_nonstring__;	/* Username. */ | ||
| 65 | char ut_host[__UT_HOSTSIZE] | ||
| 66 | __attribute_nonstring__;	/* Hostname for remote login. */ | ||
| 67 | struct __exit_status ut_exit;	/* Exit status of a process marked | ||
| 68 | 				 as DEAD_PROCESS. */ | ||
| 69 | |||
| 70 | /* The fields ut_session and ut_tv must be the same size when compiled | ||
| 71 | 32- and 64-bit. This allows files and shared memory to be shared | ||
| 72 | between 32- and 64-bit applications. */ | ||
| 73 | #if __WORDSIZE == 32 | ||
| 74 | __int64_t ut_session;		/* Session ID, used for windowing. */ | ||
| 75 | struct | ||
| 76 | { | ||
| 77 | __int64_t tv_sec;		/* Seconds. */ | ||
| 78 | __int64_t tv_usec;		/* Microseconds. */ | ||
| 79 | } ut_tv;			/* Time entry was made. */ | ||
| 80 | #else | ||
| 81 | long int ut_session;		/* Session ID, used for windowing. */ | ||
| 82 | struct timeval ut_tv;		/* Time entry was made. */ | ||
| 83 | #endif | ||
| 84 | __int32_t ut_addr_v6[4];	/* Internet address of remote host. */ | ||
| 85 | char __glibc_reserved[20];		/* Reserved for future use. */ | ||
| 86 | }; | ||
| 87 | |||
| 88 | |||
| 89 | /* Values for the `ut_type' field of a `struct utmpx'. */ | ||
| 90 | #define EMPTY		0	/* No valid user accounting information. */ | ||
| 91 | |||
| 92 | #ifdef __USE_GNU | ||
| 93 | # define RUN_LVL	1	/* The system's runlevel. */ | ||
| 94 | #endif | ||
| 95 | #define BOOT_TIME	2	/* Time of system boot. */ | ||
| 96 | #define NEW_TIME	3	/* Time after system clock changed. */ | ||
| 97 | #define OLD_TIME	4	/* Time when system clock changed. */ | ||
| 98 | |||
| 99 | #define INIT_PROCESS	5	/* Process spawned by the init process. */ | ||
| 100 | #define LOGIN_PROCESS	6	/* Session leader of a logged in user. */ | ||
| 101 | #define USER_PROCESS	7	/* Normal process. */ | ||
| 102 | #define DEAD_PROCESS	8	/* Terminated process. */ | ||
| 103 | |||
| 104 | #ifdef __USE_GNU | ||
| 105 | # define ACCOUNTING	9	/* System accounting. */ | ||
| 106 | #endif | ||
| \ No newline at end of file | |||
lib/libc/include/s390x-linux-gnu/bits/wordsize.h+17-9| ... | @@ -1,11 +1,19 @@ | ... | @@ -1,11 +1,19 @@ |
| 1 | /* Determine the wordsize from the preprocessor defines. */ | 1 | /* Copyright (C) 1999-2026 Free Software Foundation, Inc. |
| 2 | This file is part of the GNU C Library. | ||
| 2 | 3 | ||
| 3 | #if defined __s390x__ | 4 | The GNU C Library is free software; you can redistribute it and/or |
| 4 | # define __WORDSIZE	64 | 5 | modify it under the terms of the GNU Lesser General Public |
| 5 | #else | 6 | License as published by the Free Software Foundation; either |
| 6 | # define __WORDSIZE	32 | 7 | version 2.1 of the License, or (at your option) any later version. |
| 7 | # define __WORDSIZE32_SIZE_ULONG 1 | ||
| 8 | # define __WORDSIZE32_PTRDIFF_LONG 0 | ||
| 9 | #endif | ||
| 10 | 8 | ||
| 11 | #define __WORDSIZE_TIME64_COMPAT32 0 | ||
| \ No newline at end of file | |||
| 9 | The GNU C Library is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 12 | Lesser General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU Lesser General Public | ||
| 15 | License along with the GNU C Library; if not, see | ||
| 16 | <https://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | #define __WORDSIZE			64 | ||
| 19 | #define __WORDSIZE_TIME64_COMPAT32	0 | ||
| \ No newline at end of file | |||
lib/libc/include/s390x-linux-gnu/gnu/lib-names-64.h deleted-27| ... | @@ -1,27 +0,0 @@ | ||
| 1 | /* This file is automatically generated. */ | ||
| 2 | #ifndef __GNU_LIB_NAMES_H | ||
| 3 | # error "Never use <gnu/lib-names-64.h> directly; include <gnu/lib-names.h> instead." | ||
| 4 | #endif | ||
| 5 | |||
| 6 | #define LD64_SO "ld64.so.1" | ||
| 7 | #define LD_SO "ld64.so.1" | ||
| 8 | #define LIBANL_SO "libanl.so.1" | ||
| 9 | #define LIBBROKENLOCALE_SO "libBrokenLocale.so.1" | ||
| 10 | #define LIBC_MALLOC_DEBUG_SO "libc_malloc_debug.so.0" | ||
| 11 | #define LIBC_SO "libc.so.6" | ||
| 12 | #define LIBDL_SO "libdl.so.2" | ||
| 13 | #define LIBGCC_S_SO "libgcc_s.so.1" | ||
| 14 | #define LIBMVEC_SO "libmvec.so.1" | ||
| 15 | #define LIBM_SO "libm.so.6" | ||
| 16 | #define LIBNSL_SO "libnsl.so.1" | ||
| 17 | #define LIBNSS_COMPAT_SO "libnss_compat.so.2" | ||
| 18 | #define LIBNSS_DB_SO "libnss_db.so.2" | ||
| 19 | #define LIBNSS_DNS_SO "libnss_dns.so.2" | ||
| 20 | #define LIBNSS_FILES_SO "libnss_files.so.2" | ||
| 21 | #define LIBNSS_HESIOD_SO "libnss_hesiod.so.2" | ||
| 22 | #define LIBNSS_LDAP_SO "libnss_ldap.so.2" | ||
| 23 | #define LIBPTHREAD_SO "libpthread.so.0" | ||
| 24 | #define LIBRESOLV_SO "libresolv.so.2" | ||
| 25 | #define LIBRT_SO "librt.so.1" | ||
| 26 | #define LIBTHREAD_DB_SO "libthread_db.so.1" | ||
| 27 | #define LIBUTIL_SO "libutil.so.1" | ||
| \ No newline at end of file | |||
lib/libc/include/s390x-linux-gnu/gnu/lib-names.h+23-8| ... | @@ -4,13 +4,28 @@ | ... | @@ -4,13 +4,28 @@ |
| 4 | #ifndef __GNU_LIB_NAMES_H | 4 | #ifndef __GNU_LIB_NAMES_H |
| 5 | #define __GNU_LIB_NAMES_H	1 | 5 | #define __GNU_LIB_NAMES_H	1 |
| 6 | 6 | ||
| 7 | #include <bits/wordsize.h> | 7 | #define LD64_SO "ld64.so.1" |
| 8 | 8 | #define LD_SO "ld64.so.1" | |
| 9 | #if __WORDSIZE == 32 | 9 | #define LIBANL_SO "libanl.so.1" |
| 10 | # include <gnu/lib-names-32.h> | 10 | #define LIBBROKENLOCALE_SO "libBrokenLocale.so.1" |
| 11 | #endif | 11 | #define LIBC_MALLOC_DEBUG_SO "libc_malloc_debug.so.0" |
| 12 | #if __WORDSIZE == 64 | 12 | #define LIBC_SO "libc.so.6" |
| 13 | # include <gnu/lib-names-64.h> | 13 | #define LIBDL_SO "libdl.so.2" |
| 14 | #endif | 14 | #define LIBGCC_S_SO "libgcc_s.so.1" |
| 15 | #define LIBMVEC_SO "libmvec.so.1" | ||
| 16 | #define LIBM_SO "libm.so.6" | ||
| 17 | #define LIBNSL_SO "libnsl.so.1" | ||
| 18 | #define LIBNSS_COMPAT_SO "libnss_compat.so.2" | ||
| 19 | #define LIBNSS_DB_SO "libnss_db.so.2" | ||
| 20 | #define LIBNSS_DNS_SO "libnss_dns.so.2" | ||
| 21 | #define LIBNSS_FILES_SO "libnss_files.so.2" | ||
| 22 | #define LIBNSS_HESIOD_SO "libnss_hesiod.so.2" | ||
| 23 | #define LIBNSS_LDAP_SO "libnss_ldap.so.2" | ||
| 24 | #define LIBPTHREAD_SO "libpthread.so.0" | ||
| 25 | #define LIBRESOLV_SO "libresolv.so.2" | ||
| 26 | #define LIBRT_SO "librt.so.1" | ||
| 27 | #define LIBTHREAD_DB_SO "libthread_db.so.1" | ||
| 28 | #define LIBUNWIND_SO "libunwind.so.1" | ||
| 29 | #define LIBUTIL_SO "libutil.so.1" | ||
| 15 | 30 | ||
| 16 | #endif	/* gnu/lib-names.h */ | 31 | #endif	/* gnu/lib-names.h */ |
| \ No newline at end of file | |||
lib/libc/include/s390x-linux-gnu/gnu/stubs.h+13-9| ... | @@ -1,12 +1,16 @@ | ... | @@ -1,12 +1,16 @@ |
| 1 | /* This file is automatically generated. | 1 | /* This file is automatically generated. |
| 2 | This file selects the right generated file of `__stub_FUNCTION' macros | 2 | It defines a symbol `__stub_FUNCTION' for each function |
| 3 | based on the architecture being compiled for. */ | 3 | in the C library which is a stub, meaning it will fail |
| 4 | every time called, usually setting errno to ENOSYS. */ | ||
| 4 | 5 | ||
| 5 | #include <bits/wordsize.h> | 6 | #ifdef _LIBC |
| 6 | 7 | #error Applications may not define the macro _LIBC | |
| 7 | #if __WORDSIZE == 32 | ||
| 8 | # include <gnu/stubs-32.h> | ||
| 9 | #endif | 8 | #endif |
| 10 | #if __WORDSIZE == 64 | ||
| 11 | # include <gnu/stubs-64.h> | ||
| 12 | #endif | ||
| \ No newline at end of file | |||
| 9 | |||
| 10 | #define __stub_chflags | ||
| 11 | #define __stub_fchflags | ||
| 12 | #define __stub_gtty | ||
| 13 | #define __stub_revoke | ||
| 14 | #define __stub_setlogin | ||
| 15 | #define __stub_sigreturn | ||
| 16 | #define __stub_stty | ||
| \ No newline at end of file | |||
lib/libc/include/s390x-linux-gnu/sys/ucontext.h+1-5| ... | @@ -45,11 +45,7 @@ typedef unsigned long greg_t; | ... | @@ -45,11 +45,7 @@ typedef unsigned long greg_t; |
| 45 | the register set is an array, we make gregset_t a simple array | 45 | the register set is an array, we make gregset_t a simple array |
| 46 | that has the same size as s390_regs. This is needed for the | 46 | that has the same size as s390_regs. This is needed for the |
| 47 | elf_prstatus structure. */ | 47 | elf_prstatus structure. */ |
| 48 | #if __WORDSIZE == 64 | 48 | #define __NGREG 27 |
| 49 | # define __NGREG 27 | ||
| 50 | #else | ||
| 51 | # define __NGREG 36 | ||
| 52 | #endif | ||
| 53 | #ifdef __USE_MISC | 49 | #ifdef __USE_MISC |
| 54 | # define NGREG __NGREG | 50 | # define NGREG __NGREG |
| 55 | #endif | 51 | #endif |
lib/libc/include/sparc-linux-gnu/bits/cloexec.h created+1| ... | @@ -0,0 +1 @@ | ||
| 1 | #define __O_CLOEXEC 0x400000 | ||
| \ No newline at end of file | |||
lib/libc/include/sparc-linux-gnu/gnu/lib-names-64.h+1| ... | @@ -24,4 +24,5 @@ | ... | @@ -24,4 +24,5 @@ |
| 24 | #define LIBRESOLV_SO "libresolv.so.2" | 24 | #define LIBRESOLV_SO "libresolv.so.2" |
| 25 | #define LIBRT_SO "librt.so.1" | 25 | #define LIBRT_SO "librt.so.1" |
| 26 | #define LIBTHREAD_DB_SO "libthread_db.so.1" | 26 | #define LIBTHREAD_DB_SO "libthread_db.so.1" |
| 27 | #define LIBUNWIND_SO "libunwind.so.1" | ||
| 27 | #define LIBUTIL_SO "libutil.so.1" | 28 | #define LIBUTIL_SO "libutil.so.1" |
| \ No newline at end of file | |||
lib/libc/include/sparc-linux-gnu/gnu/stubs-64.h created+16| ... | @@ -0,0 +1,16 @@ | ||
| 1 | /* This file is automatically generated. | ||
| 2 | It defines a symbol `__stub_FUNCTION' for each function | ||
| 3 | in the C library which is a stub, meaning it will fail | ||
| 4 | every time called, usually setting errno to ENOSYS. */ | ||
| 5 | |||
| 6 | #ifdef _LIBC | ||
| 7 | #error Applications may not define the macro _LIBC | ||
| 8 | #endif | ||
| 9 | |||
| 10 | #define __stub_chflags | ||
| 11 | #define __stub_fchflags | ||
| 12 | #define __stub_gtty | ||
| 13 | #define __stub_revoke | ||
| 14 | #define __stub_setlogin | ||
| 15 | #define __stub_sigreturn | ||
| 16 | #define __stub_stty | ||
| \ No newline at end of file | |||
lib/libc/include/x86-linux-gnu/bits/struct_mutex.h+1-1| ... | @@ -59,4 +59,4 @@ struct __pthread_mutex_s | ... | @@ -59,4 +59,4 @@ struct __pthread_mutex_s |
| 59 | 0, 0, 0, __kind, 0, { { 0, 0 } } | 59 | 0, 0, 0, __kind, 0, { { 0, 0 } } |
| 60 | #endif | 60 | #endif |
| 61 | 61 | ||
| 62 | #endif | 62 | #endif |
| \ No newline at end of file | |||
lib/libc/include/x86-linux-gnu/gnu/lib-names-64.h+1| ... | @@ -24,4 +24,5 @@ | ... | @@ -24,4 +24,5 @@ |
| 24 | #define LIBRESOLV_SO "libresolv.so.2" | 24 | #define LIBRESOLV_SO "libresolv.so.2" |
| 25 | #define LIBRT_SO "librt.so.1" | 25 | #define LIBRT_SO "librt.so.1" |
| 26 | #define LIBTHREAD_DB_SO "libthread_db.so.1" | 26 | #define LIBTHREAD_DB_SO "libthread_db.so.1" |
| 27 | #define LIBUNWIND_SO "libunwind.so.1" | ||
| 27 | #define LIBUTIL_SO "libutil.so.1" | 28 | #define LIBUTIL_SO "libutil.so.1" |
| \ No newline at end of file | |||
lib/libc/include/x86-linux-gnu/gnu/lib-names-x32.h+1| ... | @@ -24,4 +24,5 @@ | ... | @@ -24,4 +24,5 @@ |
| 24 | #define LIBRESOLV_SO "libresolv.so.2" | 24 | #define LIBRESOLV_SO "libresolv.so.2" |
| 25 | #define LIBRT_SO "librt.so.1" | 25 | #define LIBRT_SO "librt.so.1" |
| 26 | #define LIBTHREAD_DB_SO "libthread_db.so.1" | 26 | #define LIBTHREAD_DB_SO "libthread_db.so.1" |
| 27 | #define LIBUNWIND_SO "libunwind.so.1" | ||
| 27 | #define LIBUTIL_SO "libutil.so.1" | 28 | #define LIBUTIL_SO "libutil.so.1" |
| \ No newline at end of file | |||
lib/libc/include/x86-netbsd-none/machine/mcontext.h+23-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | /*	$NetBSD: mcontext.h,v 1.19 2024/11/30 01:04:10 christos Exp $	*/ | 1 | /*	$NetBSD: mcontext.h,v 1.19.2.1 2026/07/19 15:57:27 martin Exp $	*/ |
| 2 | 2 | ||
| 3 | /*- | 3 | /*- |
| 4 | * Copyright (c) 1999 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 1999 The NetBSD Foundation, Inc. |
| ... | @@ -40,6 +40,7 @@ | ... | @@ -40,6 +40,7 @@ |
| 40 | #define	_UC_CLRSTACK	_UC_MD_BIT17 | 40 | #define	_UC_CLRSTACK	_UC_MD_BIT17 |
| 41 | #define	_UC_VM		_UC_MD_BIT18 | 41 | #define	_UC_VM		_UC_MD_BIT18 |
| 42 | #define	_UC_TLSBASE	_UC_MD_BIT19 | 42 | #define	_UC_TLSBASE	_UC_MD_BIT19 |
| 43 | #define	_UC_XSAVE	_UC_MD_BIT20 | ||
| 43 | 44 | ||
| 44 | /* | 45 | /* |
| 45 | * Layout of mcontext_t according to the System V Application Binary Interface, | 46 | * Layout of mcontext_t according to the System V Application Binary Interface, |
| ... | @@ -85,6 +86,27 @@ typedef struct { | ... | @@ -85,6 +86,27 @@ typedef struct { |
| 85 | 			char	__fp_xmm[512]; | 86 | 			char	__fp_xmm[512]; |
| 86 | 		} __fp_xmm_state;	/* x87 and xmm regs in fxsave format */ | 87 | 		} __fp_xmm_state;	/* x87 and xmm regs in fxsave format */ |
| 87 | 		int	__fp_fpregs[128]; | 88 | 		int	__fp_fpregs[128]; |
| 89 | 		struct { | ||
| 90 | 			/* | ||
| 91 | 			 * `The XSAVE feature set does not use bytes | ||
| 92 | 			 * 511:416; bytes 463:416 are reserved.' | ||
| 93 | 			 * | ||
| 94 | 			 * We take a part out of this to form a pointer | ||
| 95 | 			 * to an external XSAVE area. This way, we can | ||
| 96 | 			 * replicate the FXSAVE parts for the benefit | ||
| 97 | 			 * of userland programs that aren't aware of | ||
| 98 | 			 * the XSAVE pointer, have used the extended | ||
| 99 | 			 * CPU registers (ymmN/zmmN/&c.), and want to | ||
| 100 | 			 * examine the x87/SSE register state in a | ||
| 101 | 			 * signal handler. The kernel does not use | ||
| 102 | 			 * this part. | ||
| 103 | 			 */ | ||
| 104 | 			char		__fxsave[416]; | ||
| 105 | 			char		__rsvd[48]; | ||
| 106 | 			__greg_t	__xsaveptr; | ||
| 107 | 			__greg_t	__xsavelen; | ||
| 108 | 			char		__pad[40]; | ||
| 109 | 		} __xsave; | ||
| 88 | 	} __fp_reg_set; | 110 | 	} __fp_reg_set; |
| 89 | 	int 	__fp_pad[33];			/* Historic padding */ | 111 | 	int 	__fp_pad[33];			/* Historic padding */ |
| 90 | } __fpregset_t; | 112 | } __fpregset_t; |
lib/libc/include/x86_64-netbsd-none/amd64/mcontext.h+31-2| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | /*	$NetBSD: mcontext.h,v 1.24 2024/11/30 01:04:06 christos Exp $	*/ | 1 | /*	$NetBSD: mcontext.h,v 1.24.2.1 2026/07/19 15:57:26 martin Exp $	*/ |
| 2 | 2 | ||
| 3 | /*- | 3 | /*- |
| 4 | * Copyright (c) 1999 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 1999 The NetBSD Foundation, Inc. |
| ... | @@ -56,7 +56,28 @@ typedef	__greg_t	__gregset_t[_NGREG]; | ... | @@ -56,7 +56,28 @@ typedef	__greg_t	__gregset_t[_NGREG]; |
| 56 | * which requires 16 byte alignment. However the mcontext version | 56 | * which requires 16 byte alignment. However the mcontext version |
| 57 | * is never directly accessed. | 57 | * is never directly accessed. |
| 58 | */ | 58 | */ |
| 59 | typedef char __fpregset_t[512] __aligned(8); | 59 | typedef union { |
| 60 | 	char	__fxsave[512] __aligned(8); | ||
| 61 | 	struct { | ||
| 62 | 		/* | ||
| 63 | 		 * `The XSAVE feature set does not use bytes 511:416; | ||
| 64 | 		 * bytes 463:416 are reserved.' | ||
| 65 | 		 * | ||
| 66 | 		 * We take a part out of this to form a pointer to an | ||
| 67 | 		 * external XSAVE area. This way, we can replicate the | ||
| 68 | 		 * FXSAVE parts for the benefit of userland programs | ||
| 69 | 		 * that aren't aware of the XSAVE pointer, have used | ||
| 70 | 		 * the extended CPU registers (ymmN/zmmN/&c.), and want | ||
| 71 | 		 * to examine the x87/SSE register state in a signal | ||
| 72 | 		 * handler. The kernel does not use this part. | ||
| 73 | 		 */ | ||
| 74 | 		char		__fxsave[416]; | ||
| 75 | 		char		__rsvd[48]; | ||
| 76 | 		__greg_t	__xsaveptr; | ||
| 77 | 		__greg_t	__xsavelen; | ||
| 78 | 		char		__pad[32]; | ||
| 79 | 	}	__xsave; | ||
| 80 | } __fpregset_t; | ||
| 60 | 81 | ||
| 61 | typedef struct { | 82 | typedef struct { |
| 62 | 	__gregset_t	__gregs; | 83 | 	__gregset_t	__gregs; |
| ... | @@ -75,6 +96,7 @@ typedef struct { | ... | @@ -75,6 +96,7 @@ typedef struct { |
| 75 | #define	_UC_MACHINE_SET_PC(uc, pc)	_UC_MACHINE_PC(uc) = (pc) | 96 | #define	_UC_MACHINE_SET_PC(uc, pc)	_UC_MACHINE_PC(uc) = (pc) |
| 76 | 97 | ||
| 77 | #define	_UC_TLSBASE	_UC_MD_BIT19 | 98 | #define	_UC_TLSBASE	_UC_MD_BIT19 |
| 99 | #define	_UC_XSAVE	_UC_MD_BIT20 | ||
| 78 | 100 | ||
| 79 | /* | 101 | /* |
| 80 | * mcontext extensions to handle signal delivery. | 102 | * mcontext extensions to handle signal delivery. |
| ... | @@ -127,6 +149,13 @@ typedef struct { | ... | @@ -127,6 +149,13 @@ typedef struct { |
| 127 | 		struct { | 149 | 		struct { |
| 128 | 			char	__fp_xmm[512]; | 150 | 			char	__fp_xmm[512]; |
| 129 | 		} __fp_xmm_state; | 151 | 		} __fp_xmm_state; |
| 152 | 		struct { | ||
| 153 | 			char		__fxsave[416]; | ||
| 154 | 			char		__rsvd[48]; | ||
| 155 | 			__greg32_t	__xsaveptr; | ||
| 156 | 			__greg32_t	__xsavelen; | ||
| 157 | 			char		__pad[40]; | ||
| 158 | 		} __xsave; | ||
| 130 | 	} __fp_reg_set; | 159 | 	} __fp_reg_set; |
| 131 | 	int	__fp_pad[33];			/* Historic padding */ | 160 | 	int	__fp_pad[33];			/* Historic padding */ |
| 132 | } __fpregset32_t; | 161 | } __fpregset32_t; |
lib/libc/include/x86_64-netbsd-none/machine/mcontext.h+31-2| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | /*	$NetBSD: mcontext.h,v 1.24 2024/11/30 01:04:06 christos Exp $	*/ | 1 | /*	$NetBSD: mcontext.h,v 1.24.2.1 2026/07/19 15:57:26 martin Exp $	*/ |
| 2 | 2 | ||
| 3 | /*- | 3 | /*- |
| 4 | * Copyright (c) 1999 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 1999 The NetBSD Foundation, Inc. |
| ... | @@ -56,7 +56,28 @@ typedef	__greg_t	__gregset_t[_NGREG]; | ... | @@ -56,7 +56,28 @@ typedef	__greg_t	__gregset_t[_NGREG]; |
| 56 | * which requires 16 byte alignment. However the mcontext version | 56 | * which requires 16 byte alignment. However the mcontext version |
| 57 | * is never directly accessed. | 57 | * is never directly accessed. |
| 58 | */ | 58 | */ |
| 59 | typedef char __fpregset_t[512] __aligned(8); | 59 | typedef union { |
| 60 | 	char	__fxsave[512] __aligned(8); | ||
| 61 | 	struct { | ||
| 62 | 		/* | ||
| 63 | 		 * `The XSAVE feature set does not use bytes 511:416; | ||
| 64 | 		 * bytes 463:416 are reserved.' | ||
| 65 | 		 * | ||
| 66 | 		 * We take a part out of this to form a pointer to an | ||
| 67 | 		 * external XSAVE area. This way, we can replicate the | ||
| 68 | 		 * FXSAVE parts for the benefit of userland programs | ||
| 69 | 		 * that aren't aware of the XSAVE pointer, have used | ||
| 70 | 		 * the extended CPU registers (ymmN/zmmN/&c.), and want | ||
| 71 | 		 * to examine the x87/SSE register state in a signal | ||
| 72 | 		 * handler. The kernel does not use this part. | ||
| 73 | 		 */ | ||
| 74 | 		char		__fxsave[416]; | ||
| 75 | 		char		__rsvd[48]; | ||
| 76 | 		__greg_t	__xsaveptr; | ||
| 77 | 		__greg_t	__xsavelen; | ||
| 78 | 		char		__pad[32]; | ||
| 79 | 	}	__xsave; | ||
| 80 | } __fpregset_t; | ||
| 60 | 81 | ||
| 61 | typedef struct { | 82 | typedef struct { |
| 62 | 	__gregset_t	__gregs; | 83 | 	__gregset_t	__gregs; |
| ... | @@ -75,6 +96,7 @@ typedef struct { | ... | @@ -75,6 +96,7 @@ typedef struct { |
| 75 | #define	_UC_MACHINE_SET_PC(uc, pc)	_UC_MACHINE_PC(uc) = (pc) | 96 | #define	_UC_MACHINE_SET_PC(uc, pc)	_UC_MACHINE_PC(uc) = (pc) |
| 76 | 97 | ||
| 77 | #define	_UC_TLSBASE	_UC_MD_BIT19 | 98 | #define	_UC_TLSBASE	_UC_MD_BIT19 |
| 99 | #define	_UC_XSAVE	_UC_MD_BIT20 | ||
| 78 | 100 | ||
| 79 | /* | 101 | /* |
| 80 | * mcontext extensions to handle signal delivery. | 102 | * mcontext extensions to handle signal delivery. |
| ... | @@ -127,6 +149,13 @@ typedef struct { | ... | @@ -127,6 +149,13 @@ typedef struct { |
| 127 | 		struct { | 149 | 		struct { |
| 128 | 			char	__fp_xmm[512]; | 150 | 			char	__fp_xmm[512]; |
| 129 | 		} __fp_xmm_state; | 151 | 		} __fp_xmm_state; |
| 152 | 		struct { | ||
| 153 | 			char		__fxsave[416]; | ||
| 154 | 			char		__rsvd[48]; | ||
| 155 | 			__greg32_t	__xsaveptr; | ||
| 156 | 			__greg32_t	__xsavelen; | ||
| 157 | 			char		__pad[40]; | ||
| 158 | 		} __xsave; | ||
| 130 | 	} __fp_reg_set; | 159 | 	} __fp_reg_set; |
| 131 | 	int	__fp_pad[33];			/* Historic padding */ | 160 | 	int	__fp_pad[33];			/* Historic padding */ |
| 132 | } __fpregset32_t; | 161 | } __fpregset32_t; |
lib/std/Build.zig+48-44| ... | @@ -45,17 +45,6 @@ debug_log_scopes: []const []const u8 = &.{}, | ... | @@ -45,17 +45,6 @@ debug_log_scopes: []const []const u8 = &.{}, |
| 45 | /// Set to 0 to disable stack collection. | 45 | /// Set to 0 to disable stack collection. |
| 46 | debug_stack_frames_count: u8 = 8, | 46 | debug_stack_frames_count: u8 = 8, |
| 47 | 47 | ||
| 48 | /// Experimental. Use system Darling installation to run cross compiled macOS build artifacts. | ||
| 49 | enable_darling: bool = false, | ||
| 50 | /// Use system QEMU installation to run cross compiled foreign architecture build artifacts. | ||
| 51 | enable_qemu: bool = false, | ||
| 52 | /// Darwin. Use Rosetta to run x86_64 macOS build artifacts on arm64 macOS. | ||
| 53 | enable_rosetta: bool = false, | ||
| 54 | /// Use system Wasmtime installation to run cross compiled wasm/wasi build artifacts. | ||
| 55 | enable_wasmtime: bool = false, | ||
| 56 | /// Use system Wine installation to run cross compiled Windows build artifacts. | ||
| 57 | enable_wine: bool = false, | ||
| 58 | |||
| 59 | dep_prefix: []const u8 = "", | 48 | dep_prefix: []const u8 = "", |
| 60 | 49 | ||
| 61 | modules: std.array_hash_map.String(*Module), | 50 | modules: std.array_hash_map.String(*Module), |
| ... | @@ -388,11 +377,6 @@ fn createChild( | ... | @@ -388,11 +377,6 @@ fn createChild( |
| 388 | .default_step = undefined, | 377 | .default_step = undefined, |
| 389 | .top_level_steps = .{}, | 378 | .top_level_steps = .{}, |
| 390 | .debug_log_scopes = parent.debug_log_scopes, | 379 | .debug_log_scopes = parent.debug_log_scopes, |
| 391 | .enable_darling = parent.enable_darling, | ||
| 392 | .enable_qemu = parent.enable_qemu, | ||
| 393 | .enable_rosetta = parent.enable_rosetta, | ||
| 394 | .enable_wasmtime = parent.enable_wasmtime, | ||
| 395 | .enable_wine = parent.enable_wine, | ||
| 396 | .dep_prefix = parent.fmt("{s}{s}.", .{ parent.dep_prefix, dep_name }), | 380 | .dep_prefix = parent.fmt("{s}{s}.", .{ parent.dep_prefix, dep_name }), |
| 397 | .modules = .empty, | 381 | .modules = .empty, |
| 398 | .named_writefiles = .empty, | 382 | .named_writefiles = .empty, |
| ... | @@ -830,7 +814,7 @@ pub fn addTest(b: *Build, options: TestOptions) *Step.Compile { | ... | @@ -830,7 +814,7 @@ pub fn addTest(b: *Build, options: TestOptions) *Step.Compile { |
| 830 | .kind = if (options.emit_object) .test_obj else .@"test", | 814 | .kind = if (options.emit_object) .test_obj else .@"test", |
| 831 | .root_module = options.root_module, | 815 | .root_module = options.root_module, |
| 832 | .max_rss = options.max_rss, | 816 | .max_rss = options.max_rss, |
| 833 | .filters = b.dupeStrings(options.filters), | 817 | .filters = b.graph.dupeStrings(options.filters), |
| 834 | .test_runner = options.test_runner, | 818 | .test_runner = options.test_runner, |
| 835 | .use_llvm = options.use_llvm, | 819 | .use_llvm = options.use_llvm, |
| 836 | .use_lld = options.use_lld, | 820 | .use_lld = options.use_lld, |
| ... | @@ -1125,7 +1109,7 @@ pub fn option(b: *Build, comptime T: type, name_raw: []const u8, description_raw | ... | @@ -1125,7 +1109,7 @@ pub fn option(b: *Build, comptime T: type, name_raw: []const u8, description_raw |
| 1125 | const type_id = comptime typeToEnum(T); | 1109 | const type_id = comptime typeToEnum(T); |
| 1126 | const enum_options = if (type_id == .@"enum" or type_id == .enum_list) blk: { | 1110 | const enum_options = if (type_id == .@"enum" or type_id == .enum_list) blk: { |
| 1127 | const EnumType = if (type_id == .enum_list) @typeInfo(T).pointer.child else T; | 1111 | const EnumType = if (type_id == .enum_list) @typeInfo(T).pointer.child else T; |
| 1128 | const field_names = comptime std.meta.fieldNames(EnumType); | 1112 | const field_names = @typeInfo(EnumType).@"enum".field_names; |
| 1129 | var options = std.array_list.Managed([]const u8).initCapacity(b.allocator, field_names.len) catch @panic("OOM"); | 1113 | var options = std.array_list.Managed([]const u8).initCapacity(b.allocator, field_names.len) catch @panic("OOM"); |
| 1130 | 1114 | ||
| 1131 | inline for (field_names) |field_name| { | 1115 | inline for (field_names) |field_name| { |
| ... | @@ -1210,13 +1194,16 @@ pub fn option(b: *Build, comptime T: type, name_raw: []const u8, description_raw | ... | @@ -1210,13 +1194,16 @@ pub fn option(b: *Build, comptime T: type, name_raw: []const u8, description_raw |
| 1210 | return null; | 1194 | return null; |
| 1211 | }, | 1195 | }, |
| 1212 | .scalar => |s| { | 1196 | .scalar => |s| { |
| 1213 | if (std.meta.stringToEnum(T, s)) |enum_lit| { | 1197 | if (T == std.lang.Optimize) { |
| 1214 | return enum_lit; | 1198 | if (std.lang.Optimize.fromString(s)) |tag| { |
| 1215 | } else { | 1199 | return tag; |
| 1216 | log.err("expected -D{s} to be of type {s}", .{ name, @typeName(T) }); | 1200 | } |
| 1217 | b.markInvalidUserInput(); | 1201 | } else if (std.meta.stringToEnum(T, s)) |tag| { |
| 1218 | return null; | 1202 | return tag; |
| 1219 | } | 1203 | } |
| 1204 | log.err("expected -D{s} to be of type {q}", .{ name, @typeName(T) }); | ||
| 1205 | b.markInvalidUserInput(); | ||
| 1206 | return null; | ||
| 1220 | }, | 1207 | }, |
| 1221 | }, | 1208 | }, |
| 1222 | .string => switch (option_ptr.value) { | 1209 | .string => switch (option_ptr.value) { |
| ... | @@ -1262,23 +1249,36 @@ pub fn option(b: *Build, comptime T: type, name_raw: []const u8, description_raw | ... | @@ -1262,23 +1249,36 @@ pub fn option(b: *Build, comptime T: type, name_raw: []const u8, description_raw |
| 1262 | }, | 1249 | }, |
| 1263 | .scalar => |s| { | 1250 | .scalar => |s| { |
| 1264 | const Child = @typeInfo(T).pointer.child; | 1251 | const Child = @typeInfo(T).pointer.child; |
| 1265 | const value = std.meta.stringToEnum(Child, s) orelse { | 1252 | if (Child == std.lang.Optimize) { |
| 1266 | log.err("expected -D{s} to be of type {s}", .{ name, @typeName(Child) }); | 1253 | if (std.lang.Optimize.fromString(s)) |tag| { |
| 1267 | b.markInvalidUserInput(); | 1254 | return arena.dupe(Child, &.{tag}) catch @panic("OOM"); |
| 1268 | return null; | 1255 | } |
| 1269 | }; | 1256 | } else { |
| 1270 | return arena.dupe(Child, &[_]Child{value}) catch @panic("OOM"); | 1257 | if (std.meta.stringToEnum(Child, s)) |tag| { |
| 1258 | return arena.dupe(Child, &.{tag}) catch @panic("OOM"); | ||
| 1259 | } | ||
| 1260 | } | ||
| 1261 | log.err("expected -D{s} to be of type {q}", .{ name, @typeName(Child) }); | ||
| 1262 | b.markInvalidUserInput(); | ||
| 1263 | return null; | ||
| 1271 | }, | 1264 | }, |
| 1272 | .list => |lst| { | 1265 | .list => |lst| { |
| 1273 | const Child = @typeInfo(T).pointer.child; | 1266 | const Child = @typeInfo(T).pointer.child; |
| 1274 | const new_list = graph.alloc(Child, lst.items.len); | 1267 | const new_list = graph.alloc(Child, lst.items.len); |
| 1275 | for (new_list, lst.items) |*new_item, str| { | 1268 | for (new_list, lst.items) |*new_item, str| { |
| 1276 | new_item.* = std.meta.stringToEnum(Child, str) orelse { | 1269 | if (Child == std.lang.Optimize) { |
| 1277 | log.err("expected -D{s} to be of type {s}", .{ name, @typeName(Child) }); | 1270 | if (std.lang.Optimize.fromString(str)) |tag| { |
| 1278 | b.markInvalidUserInput(); | 1271 | new_item.* = tag; |
| 1279 | arena.free(new_list); | 1272 | continue; |
| 1280 | return null; | 1273 | } |
| 1281 | }; | 1274 | } |
| 1275 | if (std.meta.stringToEnum(Child, str)) |tag| { | ||
| 1276 | new_item.* = tag; | ||
| 1277 | continue; | ||
| 1278 | } | ||
| 1279 | log.err("expected -D{s} to be of type {q}", .{ name, @typeName(Child) }); | ||
| 1280 | b.markInvalidUserInput(); | ||
| 1281 | return null; | ||
| 1282 | } | 1282 | } |
| 1283 | return new_list; | 1283 | return new_list; |
| 1284 | }, | 1284 | }, |
| ... | @@ -1359,14 +1359,14 @@ pub fn standardOptimizeOption(b: *Build, options: StandardOptimizeOptionOptions) | ... | @@ -1359,14 +1359,14 @@ pub fn standardOptimizeOption(b: *Build, options: StandardOptimizeOptionOptions) |
| 1359 | } | 1359 | } |
| 1360 | 1360 | ||
| 1361 | return switch (graph.release_mode) { | 1361 | return switch (graph.release_mode) { |
| 1362 | .off => .Debug, | 1362 | .off => .debug, |
| 1363 | .any => { | 1363 | .any => { |
| 1364 | std.debug.print("the project does not declare a preferred optimization mode. choose: --release=fast, --release=safe, or --release=small\n", .{}); | 1364 | std.debug.print("the project does not declare a preferred optimization mode. choose: --release=fast, --release=safe, or --release=small\n", .{}); |
| 1365 | process.exit(1); | 1365 | process.exit(1); |
| 1366 | }, | 1366 | }, |
| 1367 | .fast => .ReleaseFast, | 1367 | .fast => .fast, |
| 1368 | .safe => .ReleaseSafe, | 1368 | .safe => .safe, |
| 1369 | .small => .ReleaseSmall, | 1369 | .small => .small, |
| 1370 | }; | 1370 | }; |
| 1371 | } | 1371 | } |
| 1372 | 1372 | ||
| ... | @@ -1420,7 +1420,7 @@ pub fn parseTargetQuery(options: std.Target.Query.ParseOptions) error{ParseFaile | ... | @@ -1420,7 +1420,7 @@ pub fn parseTargetQuery(options: std.Target.Query.ParseOptions) error{ParseFaile |
| 1420 | \\available operating systems: | 1420 | \\available operating systems: |
| 1421 | \\ | 1421 | \\ |
| 1422 | , .{diags.os_name.?}); | 1422 | , .{diags.os_name.?}); |
| 1423 | inline for (comptime std.meta.fieldNames(Target.Os.Tag)) |field_name| { | 1423 | inline for (@typeInfo(Target.Os.Tag).@"enum".field_names) |field_name| { |
| 1424 | std.debug.print(" {s}\n", .{field_name}); | 1424 | std.debug.print(" {s}\n", .{field_name}); |
| 1425 | } | 1425 | } |
| 1426 | return error.ParseFailed; | 1426 | return error.ParseFailed; |
| ... | @@ -2144,7 +2144,7 @@ pub fn dependencyLazy(b: *Build, name: []const u8, args: anytype) error{LazyDepe | ... | @@ -2144,7 +2144,7 @@ pub fn dependencyLazy(b: *Build, name: []const u8, args: anytype) error{LazyDepe |
| 2144 | return dependencyResolved(b, name, entry, userInputOptionsFromArgs(b.graph.arena, args)); | 2144 | return dependencyResolved(b, name, entry, userInputOptionsFromArgs(b.graph.arena, args)); |
| 2145 | } | 2145 | } |
| 2146 | 2146 | ||
| 2147 | const PackageEntry = struct { | 2147 | pub const PackageEntry = struct { |
| 2148 | hash: []const u8, | 2148 | hash: []const u8, |
| 2149 | available: bool, | 2149 | available: bool, |
| 2150 | build_root: []const u8, | 2150 | build_root: []const u8, |
| ... | @@ -2152,7 +2152,8 @@ const PackageEntry = struct { | ... | @@ -2152,7 +2152,8 @@ const PackageEntry = struct { |
| 2152 | run_build: ?*const fn (*Build) void, | 2152 | run_build: ?*const fn (*Build) void, |
| 2153 | }; | 2153 | }; |
| 2154 | 2154 | ||
| 2155 | const package_map: std.StaticStringMap(PackageEntry) = blk: { | 2155 | /// Build system implementation detail. |
| 2156 | pub const package_map: std.StaticStringMap(PackageEntry) = blk: { | ||
| 2156 | const deps = @import("root").dependencies; | 2157 | const deps = @import("root").dependencies; |
| 2157 | const decl_names = @typeInfo(deps.packages).@"struct".decl_names; | 2158 | const decl_names = @typeInfo(deps.packages).@"struct".decl_names; |
| 2158 | var kvs: [decl_names.len]struct { []const u8, PackageEntry } = undefined; | 2159 | var kvs: [decl_names.len]struct { []const u8, PackageEntry } = undefined; |
| ... | @@ -2632,7 +2633,10 @@ pub const LazyPath = union(enum) { | ... | @@ -2632,7 +2633,10 @@ pub const LazyPath = union(enum) { |
| 2632 | 2633 | ||
| 2633 | fn dupeInner(lazy_path: LazyPath, arena: Allocator) LazyPath { | 2634 | fn dupeInner(lazy_path: LazyPath, arena: Allocator) LazyPath { |
| 2634 | return switch (lazy_path) { | 2635 | return switch (lazy_path) { |
| 2635 | .src_path => |sp| .{ .src_path = .{ .owner = sp.owner, .sub_path = sp.owner.dupePath(sp.sub_path) } }, | 2636 | .src_path => |sp| .{ .src_path = .{ |
| 2637 | .owner = sp.owner, | ||
| 2638 | .sub_path = sp.owner.graph.dupePath(sp.sub_path), | ||
| 2639 | } }, | ||
| 2636 | .cwd_relative => |p| .{ .cwd_relative = Graph.dupePathInner(arena, p) }, | 2640 | .cwd_relative => |p| .{ .cwd_relative = Graph.dupePathInner(arena, p) }, |
| 2637 | .relative => |r| .{ .relative = r }, | 2641 | .relative => |r| .{ .relative = r }, |
| 2638 | .generated => |gen| .{ .generated = .{ | 2642 | .generated => |gen| .{ .generated = .{ |
lib/std/Build/Configuration.zig+77-334| ... | @@ -15,6 +15,8 @@ unlazy_deps: []String, | ... | @@ -15,6 +15,8 @@ unlazy_deps: []String, |
| 15 | system_integrations: []SystemIntegration, | 15 | system_integrations: []SystemIntegration, |
| 16 | available_options: []AvailableOption, | 16 | available_options: []AvailableOption, |
| 17 | search_prefixes: []String, | 17 | search_prefixes: []String, |
| 18 | /// Index 0 always exists and is the root package. | ||
| 19 | packages: []Package, | ||
| 18 | extra: []u32, | 20 | extra: []u32, |
| 19 | default_step: Step.Index, | 21 | default_step: Step.Index, |
| 20 | generated_files_len: u32, | 22 | generated_files_len: u32, |
| ... | @@ -30,6 +32,7 @@ pub const Header = extern struct { | ... | @@ -30,6 +32,7 @@ pub const Header = extern struct { |
| 30 | system_integrations_len: u32, | 32 | system_integrations_len: u32, |
| 31 | available_options_len: u32, | 33 | available_options_len: u32, |
| 32 | search_prefixes_len: u32, | 34 | search_prefixes_len: u32, |
| 35 | packages_len: u32, | ||
| 33 | extra_len: u32, | 36 | extra_len: u32, |
| 34 | 37 | ||
| 35 | default_step: Step.Index, | 38 | default_step: Step.Index, |
| ... | @@ -58,6 +61,7 @@ pub const Wip = struct { | ... | @@ -58,6 +61,7 @@ pub const Wip = struct { |
| 58 | steps: std.ArrayList(Step) = .empty, | 61 | steps: std.ArrayList(Step) = .empty, |
| 59 | path_deps: std.ArrayList(PathDep) = .empty, | 62 | path_deps: std.ArrayList(PathDep) = .empty, |
| 60 | search_prefixes: std.ArrayList(String) = .empty, | 63 | search_prefixes: std.ArrayList(String) = .empty, |
| 64 | packages: std.ArrayList(Package) = .empty, | ||
| 61 | extra: std.ArrayList(u32) = .empty, | 65 | extra: std.ArrayList(u32) = .empty, |
| 62 | next_generated_file_index: u32 = 0, | 66 | next_generated_file_index: u32 = 0, |
| 63 | cache_poison: bool = false, | 67 | cache_poison: bool = false, |
| ... | @@ -121,7 +125,7 @@ pub const Wip = struct { | ... | @@ -121,7 +125,7 @@ pub const Wip = struct { |
| 121 | } | 125 | } |
| 122 | 126 | ||
| 123 | pub fn hash(_: @This(), adapted_key: []const u8) u64 { | 127 | pub fn hash(_: @This(), adapted_key: []const u8) u64 { |
| 124 | assert(std.mem.indexOfScalar(u8, adapted_key, 0) == null); | 128 | assert(std.mem.findScalar(u8, adapted_key, 0) == null); |
| 125 | return std.hash_map.hashString(adapted_key); | 129 | return std.hash_map.hashString(adapted_key); |
| 126 | } | 130 | } |
| 127 | }; | 131 | }; |
| ... | @@ -139,6 +143,7 @@ pub const Wip = struct { | ... | @@ -139,6 +143,7 @@ pub const Wip = struct { |
| 139 | wip.steps.deinit(gpa); | 143 | wip.steps.deinit(gpa); |
| 140 | wip.path_deps.deinit(gpa); | 144 | wip.path_deps.deinit(gpa); |
| 141 | wip.search_prefixes.deinit(gpa); | 145 | wip.search_prefixes.deinit(gpa); |
| 146 | wip.packages.deinit(gpa); | ||
| 142 | wip.extra.deinit(gpa); | 147 | wip.extra.deinit(gpa); |
| 143 | wip.* = undefined; | 148 | wip.* = undefined; |
| 144 | } | 149 | } |
| ... | @@ -158,6 +163,7 @@ pub const Wip = struct { | ... | @@ -158,6 +163,7 @@ pub const Wip = struct { |
| 158 | .system_integrations_len = @intCast(wip.system_integrations.items.len), | 163 | .system_integrations_len = @intCast(wip.system_integrations.items.len), |
| 159 | .available_options_len = @intCast(wip.available_options.items.len), | 164 | .available_options_len = @intCast(wip.available_options.items.len), |
| 160 | .search_prefixes_len = @intCast(wip.search_prefixes.items.len), | 165 | .search_prefixes_len = @intCast(wip.search_prefixes.items.len), |
| 166 | .packages_len = @intCast(wip.packages.items.len), | ||
| 161 | .extra_len = @intCast(wip.extra.items.len), | 167 | .extra_len = @intCast(wip.extra.items.len), |
| 162 | 168 | ||
| 163 | .default_step = static.default_step, | 169 | .default_step = static.default_step, |
| ... | @@ -175,6 +181,7 @@ pub const Wip = struct { | ... | @@ -175,6 +181,7 @@ pub const Wip = struct { |
| 175 | @ptrCast(wip.system_integrations.items), | 181 | @ptrCast(wip.system_integrations.items), |
| 176 | @ptrCast(wip.available_options.items), | 182 | @ptrCast(wip.available_options.items), |
| 177 | @ptrCast(wip.search_prefixes.items), | 183 | @ptrCast(wip.search_prefixes.items), |
| 184 | @ptrCast(wip.packages.items), | ||
| 178 | @ptrCast(wip.extra.items), | 185 | @ptrCast(wip.extra.items), |
| 179 | }; | 186 | }; |
| 180 | try w.writeVecAll(&buffers); | 187 | try w.writeVecAll(&buffers); |
| ... | @@ -182,7 +189,7 @@ pub const Wip = struct { | ... | @@ -182,7 +189,7 @@ pub const Wip = struct { |
| 182 | 189 | ||
| 183 | pub fn addString(wip: *Wip, bytes: []const u8) Allocator.Error!String { | 190 | pub fn addString(wip: *Wip, bytes: []const u8) Allocator.Error!String { |
| 184 | const gpa = wip.gpa; | 191 | const gpa = wip.gpa; |
| 185 | assert(std.mem.indexOfScalar(u8, bytes, 0) == null); | 192 | assert(std.mem.findScalar(u8, bytes, 0) == null); |
| 186 | const gop = try wip.string_table.getOrPutContextAdapted( | 193 | const gop = try wip.string_table.getOrPutContextAdapted( |
| 187 | gpa, | 194 | gpa, |
| 188 | @as([]const u8, bytes), | 195 | @as([]const u8, bytes), |
| ... | @@ -439,7 +446,7 @@ pub const Wip = struct { | ... | @@ -439,7 +446,7 @@ pub const Wip = struct { |
| 439 | /// Returned slice expires upon next append to the configuration. | 446 | /// Returned slice expires upon next append to the configuration. |
| 440 | pub fn stringSlice(wip: *const Wip, s: String) [:0]const u8 { | 447 | pub fn stringSlice(wip: *const Wip, s: String) [:0]const u8 { |
| 441 | const start_slice = wip.string_bytes.items[@backingInt(s)..]; | 448 | const start_slice = wip.string_bytes.items[@backingInt(s)..]; |
| 442 | return start_slice[0..std.mem.indexOfScalar(u8, start_slice, 0).? :0]; | 449 | return start_slice[0..std.mem.findScalar(u8, start_slice, 0).? :0]; |
| 443 | } | 450 | } |
| 444 | }; | 451 | }; |
| 445 | 452 | ||
| ... | @@ -569,8 +576,7 @@ pub const Step = extern struct { | ... | @@ -569,8 +576,7 @@ pub const Step = extern struct { |
| 569 | flags2: Flags2, | 576 | flags2: Flags2, |
| 570 | args: Storage.LengthPrefixedList(Arg.Index), | 577 | args: Storage.LengthPrefixedList(Arg.Index), |
| 571 | cwd: Storage.FlagOptional(.flags, .cwd, LazyPath.Index), | 578 | cwd: Storage.FlagOptional(.flags, .cwd, LazyPath.Index), |
| 572 | preopen_names: Storage.LengthPrefixedList(String), | 579 | preopens: Storage.FlagLengthPrefixedList(.flags, .preopens, Preopen), |
| 573 | preopen_paths: Storage.LengthPrefixedList(LazyPath.Index), | ||
| 574 | captured_stdout: Storage.FlagOptional(.flags, .captured_stdout, CapturedStream), | 580 | captured_stdout: Storage.FlagOptional(.flags, .captured_stdout, CapturedStream), |
| 575 | captured_stderr: Storage.FlagOptional(.flags, .captured_stderr, CapturedStream), | 581 | captured_stderr: Storage.FlagOptional(.flags, .captured_stderr, CapturedStream), |
| 576 | file_inputs: Storage.LengthPrefixedList(LazyPath.Index), | 582 | file_inputs: Storage.LengthPrefixedList(LazyPath.Index), |
| ... | @@ -627,6 +633,13 @@ pub const Step = extern struct { | ... | @@ -627,6 +633,13 @@ pub const Step = extern struct { |
| 627 | output_file, | 633 | output_file, |
| 628 | output_directory, | 634 | output_directory, |
| 629 | passthru, | 635 | passthru, |
| 636 | /// `prefix` contains the enabled string. | ||
| 637 | /// `suffix` contains the disabled string. | ||
| 638 | enable_darling, | ||
| 639 | enable_qemu, | ||
| 640 | enable_rosetta, | ||
| 641 | enable_wasmtime, | ||
| 642 | enable_wine, | ||
| 630 | }; | 643 | }; |
| 631 | 644 | ||
| 632 | pub const Index = IndexType(@This()); | 645 | pub const Index = IndexType(@This()); |
| ... | @@ -646,6 +659,11 @@ pub const Step = extern struct { | ... | @@ -646,6 +659,11 @@ pub const Step = extern struct { |
| 646 | manual, | 659 | manual, |
| 647 | }; | 660 | }; |
| 648 | 661 | ||
| 662 | pub const Preopen = extern struct { | ||
| 663 | name: String, | ||
| 664 | path: LazyPath.Index, | ||
| 665 | }; | ||
| 666 | |||
| 649 | pub const StdIn = union(@This().Tag) { | 667 | pub const StdIn = union(@This().Tag) { |
| 650 | none: void, | 668 | none: void, |
| 651 | bytes: Bytes, | 669 | bytes: Bytes, |
| ... | @@ -676,7 +694,8 @@ pub const Step = extern struct { | ... | @@ -676,7 +694,8 @@ pub const Step = extern struct { |
| 676 | captured_stdout: bool, | 694 | captured_stdout: bool, |
| 677 | captured_stderr: bool, | 695 | captured_stderr: bool, |
| 678 | environ_map: bool, | 696 | environ_map: bool, |
| 679 | _: u4 = 0, | 697 | preopens: bool, |
| 698 | _: u3 = 0, | ||
| 680 | }; | 699 | }; |
| 681 | 700 | ||
| 682 | pub const Flags2 = packed struct(u32) { | 701 | pub const Flags2 = packed struct(u32) { |
| ... | @@ -979,8 +998,6 @@ pub const Step = extern struct { | ... | @@ -979,8 +998,6 @@ pub const Step = extern struct { |
| 979 | }; | 998 | }; |
| 980 | 999 | ||
| 981 | pub const Flags3 = packed struct(u32) { | 1000 | pub const Flags3 = packed struct(u32) { |
| 982 | is_linking_libc: bool, | ||
| 983 | is_linking_libcpp: bool, | ||
| 984 | version: bool, | 1001 | version: bool, |
| 985 | initial_memory: bool, | 1002 | initial_memory: bool, |
| 986 | max_memory: bool, | 1003 | max_memory: bool, |
| ... | @@ -998,6 +1015,7 @@ pub const Step = extern struct { | ... | @@ -998,6 +1015,7 @@ pub const Step = extern struct { |
| 998 | entry: Entry, | 1015 | entry: Entry, |
| 999 | lto: Lto, | 1016 | lto: Lto, |
| 1000 | subsystem: Subsystem, | 1017 | subsystem: Subsystem, |
| 1018 | _: u2 = 0, | ||
| 1001 | }; | 1019 | }; |
| 1002 | 1020 | ||
| 1003 | pub const Flags4 = packed struct(u32) { | 1021 | pub const Flags4 = packed struct(u32) { |
| ... | @@ -1076,6 +1094,7 @@ pub const Step = extern struct { | ... | @@ -1076,6 +1094,7 @@ pub const Step = extern struct { |
| 1076 | autoconf_undef, | 1094 | autoconf_undef, |
| 1077 | autoconf_at, | 1095 | autoconf_at, |
| 1078 | cmake, | 1096 | cmake, |
| 1097 | meson, | ||
| 1079 | blank, | 1098 | blank, |
| 1080 | nasm, | 1099 | nasm, |
| 1081 | 1100 | ||
| ... | @@ -1084,6 +1103,7 @@ pub const Step = extern struct { | ... | @@ -1084,6 +1103,7 @@ pub const Step = extern struct { |
| 1084 | .autoconf_undef => .autoconf_undef, | 1103 | .autoconf_undef => .autoconf_undef, |
| 1085 | .autoconf_at => .autoconf_at, | 1104 | .autoconf_at => .autoconf_at, |
| 1086 | .cmake => .cmake, | 1105 | .cmake => .cmake, |
| 1106 | .meson => .meson, | ||
| 1087 | .blank => .blank, | 1107 | .blank => .blank, |
| 1088 | .nasm => .nasm, | 1108 | .nasm => .nasm, |
| 1089 | }; | 1109 | }; |
| ... | @@ -1589,30 +1609,28 @@ pub const OptionalGeneratedFileIndex = enum(u32) { | ... | @@ -1589,30 +1609,28 @@ pub const OptionalGeneratedFileIndex = enum(u32) { |
| 1589 | } | 1609 | } |
| 1590 | }; | 1610 | }; |
| 1591 | 1611 | ||
| 1592 | pub const Package = struct { | 1612 | pub const Package = extern struct { |
| 1593 | dep_prefix: String, | 1613 | dep_prefix: String, |
| 1594 | hash: String, | 1614 | hash: String, |
| 1595 | root_path: String, | 1615 | root_path: String, |
| 1616 | deps: Dep.List.Index, | ||
| 1596 | 1617 | ||
| 1597 | pub const Index = enum(u32) { | 1618 | pub const Index = enum(u32) { |
| 1598 | root = max_u32, | 1619 | root, |
| 1599 | _, | 1620 | _, |
| 1600 | 1621 | ||
| 1601 | /// Returns `null` for root package. | 1622 | pub fn ptr(i: @This(), c: *const Configuration) *const Package { |
| 1602 | pub fn get(i: @This(), c: *const Configuration) ?Package { | 1623 | return &c.packages[@backingInt(i)]; |
| 1603 | if (i == .root) return null; | ||
| 1604 | return extraData(c, Package, @backingInt(i)); | ||
| 1605 | } | 1624 | } |
| 1606 | 1625 | ||
| 1607 | pub fn depPrefixSlice(i: @This(), c: *const Configuration) [:0]const u8 { | 1626 | pub fn depPrefixSlice(i: @This(), c: *const Configuration) [:0]const u8 { |
| 1608 | const package = get(i, c) orelse return ""; | 1627 | return ptr(i, c).dep_prefix.slice(c); |
| 1609 | return package.dep_prefix.slice(c); | ||
| 1610 | } | 1628 | } |
| 1611 | }; | 1629 | }; |
| 1612 | 1630 | ||
| 1613 | pub const OptionalIndex = enum(u32) { | 1631 | pub const OptionalIndex = enum(u32) { |
| 1614 | none = max_u32 - 1, | 1632 | root, |
| 1615 | root = max_u32, | 1633 | none = max_u32, |
| 1616 | _, | 1634 | _, |
| 1617 | 1635 | ||
| 1618 | pub fn init(i: Index) OptionalIndex { | 1636 | pub fn init(i: Index) OptionalIndex { |
| ... | @@ -1629,6 +1647,28 @@ pub const Package = struct { | ... | @@ -1629,6 +1647,28 @@ pub const Package = struct { |
| 1629 | }; | 1647 | }; |
| 1630 | } | 1648 | } |
| 1631 | }; | 1649 | }; |
| 1650 | |||
| 1651 | pub const Dep = extern struct { | ||
| 1652 | name: String, | ||
| 1653 | /// Must not be `.root`. | ||
| 1654 | package: Package.Index, | ||
| 1655 | |||
| 1656 | pub const List = struct { | ||
| 1657 | deps: Storage.LengthPrefixedList(Dep), | ||
| 1658 | |||
| 1659 | pub const Index = enum(u32) { | ||
| 1660 | _, | ||
| 1661 | |||
| 1662 | pub fn get(this: @This(), c: *const Configuration) List { | ||
| 1663 | return extraData(c, List, @backingInt(this)); | ||
| 1664 | } | ||
| 1665 | |||
| 1666 | pub fn slice(this: @This(), c: *const Configuration) []const Dep { | ||
| 1667 | return get(this, c).deps.slice; | ||
| 1668 | } | ||
| 1669 | }; | ||
| 1670 | }; | ||
| 1671 | }; | ||
| 1632 | }; | 1672 | }; |
| 1633 | 1673 | ||
| 1634 | pub const Module = struct { | 1674 | pub const Module = struct { |
| ... | @@ -1655,10 +1695,10 @@ pub const Module = struct { | ... | @@ -1655,10 +1695,10 @@ pub const Module = struct { |
| 1655 | 1695 | ||
| 1656 | pub fn init(o: ?std.builtin.OptimizeMode) Optimize { | 1696 | pub fn init(o: ?std.builtin.OptimizeMode) Optimize { |
| 1657 | return switch (o orelse return .default) { | 1697 | return switch (o orelse return .default) { |
| 1658 | .Debug => .debug, | 1698 | .debug => .debug, |
| 1659 | .ReleaseSafe => .safe, | 1699 | .safe => .safe, |
| 1660 | .ReleaseFast => .fast, | 1700 | .fast => .fast, |
| 1661 | .ReleaseSmall => .small, | 1701 | .small => .small, |
| 1662 | }; | 1702 | }; |
| 1663 | } | 1703 | } |
| 1664 | }; | 1704 | }; |
| ... | @@ -1946,7 +1986,7 @@ pub const String = enum(u32) { | ... | @@ -1946,7 +1986,7 @@ pub const String = enum(u32) { |
| 1946 | 1986 | ||
| 1947 | pub fn slice(index: String, c: *const Configuration) [:0]const u8 { | 1987 | pub fn slice(index: String, c: *const Configuration) [:0]const u8 { |
| 1948 | const start_slice = c.string_bytes[@backingInt(index)..]; | 1988 | const start_slice = c.string_bytes[@backingInt(index)..]; |
| 1949 | return start_slice[0..std.mem.indexOfScalar(u8, start_slice, 0).? :0]; | 1989 | return start_slice[0..std.mem.findScalar(u8, start_slice, 0).? :0]; |
| 1950 | } | 1990 | } |
| 1951 | }; | 1991 | }; |
| 1952 | 1992 | ||
| ... | @@ -2113,27 +2153,18 @@ pub const OptionalCSourceLanguage = enum(u3) { | ... | @@ -2113,27 +2153,18 @@ pub const OptionalCSourceLanguage = enum(u3) { |
| 2113 | objective_cpp, | 2153 | objective_cpp, |
| 2114 | assembly, | 2154 | assembly, |
| 2115 | assembly_with_preprocessor, | 2155 | assembly_with_preprocessor, |
| 2156 | |||
| 2116 | default, | 2157 | default, |
| 2117 | 2158 | ||
| 2118 | pub fn init(x: ?std.Build.Module.CSourceLanguage) @This() { | 2159 | pub fn init(x: ?std.Build.Module.CSourceLanguage) @This() { |
| 2119 | return switch (x orelse return .default) { | 2160 | return switch (x orelse return .default) { |
| 2120 | .c => .c, | 2161 | inline else => |tag| @field(@This(), @tagName(tag)), |
| 2121 | .cpp => .cpp, | ||
| 2122 | .objective_c => .objective_c, | ||
| 2123 | .objective_cpp => .objective_cpp, | ||
| 2124 | .assembly => .assembly, | ||
| 2125 | .assembly_with_preprocessor => .assembly_with_preprocessor, | ||
| 2126 | }; | 2162 | }; |
| 2127 | } | 2163 | } |
| 2128 | 2164 | ||
| 2129 | pub fn get(this: @This()) ?std.Build.Module.CSourceLanguage { | 2165 | pub fn get(this: @This()) ?std.Build.Module.CSourceLanguage { |
| 2130 | return switch (this) { | 2166 | return switch (this) { |
| 2131 | .c => .c, | 2167 | inline else => |tag| @field(std.Build.Module.CSourceLanguage, @tagName(tag)), |
| 2132 | .cpp => .cpp, | ||
| 2133 | .objective_c => .objective_c, | ||
| 2134 | .objective_cpp => .objective_cpp, | ||
| 2135 | .assembly => .assembly, | ||
| 2136 | .assembly_with_preprocessor => .assembly_with_preprocessor, | ||
| 2137 | .default => null, | 2168 | .default => null, |
| 2138 | }; | 2169 | }; |
| 2139 | } | 2170 | } |
| ... | @@ -2261,10 +2292,7 @@ pub const TargetQuery = struct { | ... | @@ -2261,10 +2292,7 @@ pub const TargetQuery = struct { |
| 2261 | 2292 | ||
| 2262 | pub fn init(x: std.Target.Query.CpuModel) @This() { | 2293 | pub fn init(x: std.Target.Query.CpuModel) @This() { |
| 2263 | return switch (x) { | 2294 | return switch (x) { |
| 2264 | .native => .native, | 2295 | inline else => |_, tag| @field(@This(), @tagName(tag)), |
| 2265 | .baseline => .baseline, | ||
| 2266 | .determined_by_arch_os => .determined_by_arch_os, | ||
| 2267 | .explicit => .explicit, | ||
| 2268 | }; | 2296 | }; |
| 2269 | } | 2297 | } |
| 2270 | }; | 2298 | }; |
| ... | @@ -2322,71 +2350,13 @@ pub const TargetQuery = struct { | ... | @@ -2322,71 +2350,13 @@ pub const TargetQuery = struct { |
| 2322 | 2350 | ||
| 2323 | pub fn init(x: ?std.Target.Abi) @This() { | 2351 | pub fn init(x: ?std.Target.Abi) @This() { |
| 2324 | return switch (x orelse return .default) { | 2352 | return switch (x orelse return .default) { |
| 2325 | .none => .none, | 2353 | inline else => |tag| @field(@This(), @tagName(tag)), |
| 2326 | .gnu => .gnu, | ||
| 2327 | .gnuabin32 => .gnuabin32, | ||
| 2328 | .gnuabi64 => .gnuabi64, | ||
| 2329 | .gnueabi => .gnueabi, | ||
| 2330 | .gnueabihf => .gnueabihf, | ||
| 2331 | .gnuf32 => .gnuf32, | ||
| 2332 | .gnusf => .gnusf, | ||
| 2333 | .gnux32 => .gnux32, | ||
| 2334 | .eabi => .eabi, | ||
| 2335 | .eabihf => .eabihf, | ||
| 2336 | .abin32 => .abin32, | ||
| 2337 | .x32 => .x32, | ||
| 2338 | .ilp32 => .ilp32, | ||
| 2339 | .android => .android, | ||
| 2340 | .androideabi => .androideabi, | ||
| 2341 | .musl => .musl, | ||
| 2342 | .muslabin32 => .muslabin32, | ||
| 2343 | .muslabi64 => .muslabi64, | ||
| 2344 | .musleabi => .musleabi, | ||
| 2345 | .musleabihf => .musleabihf, | ||
| 2346 | .muslf32 => .muslf32, | ||
| 2347 | .muslsf => .muslsf, | ||
| 2348 | .muslx32 => .muslx32, | ||
| 2349 | .msvc => .msvc, | ||
| 2350 | .itanium => .itanium, | ||
| 2351 | .simulator => .simulator, | ||
| 2352 | .ohos => .ohos, | ||
| 2353 | .ohoseabi => .ohoseabi, | ||
| 2354 | .call0 => .call0, | ||
| 2355 | }; | 2354 | }; |
| 2356 | } | 2355 | } |
| 2357 | 2356 | ||
| 2358 | pub fn unwrap(this: @This()) ?std.Target.Abi { | 2357 | pub fn unwrap(this: @This()) ?std.Target.Abi { |
| 2359 | return switch (this) { | 2358 | return switch (this) { |
| 2360 | .none => .none, | 2359 | inline else => |tag| @field(std.Target.Abi, @tagName(tag)), |
| 2361 | .gnu => .gnu, | ||
| 2362 | .gnuabin32 => .gnuabin32, | ||
| 2363 | .gnuabi64 => .gnuabi64, | ||
| 2364 | .gnueabi => .gnueabi, | ||
| 2365 | .gnueabihf => .gnueabihf, | ||
| 2366 | .gnuf32 => .gnuf32, | ||
| 2367 | .gnusf => .gnusf, | ||
| 2368 | .gnux32 => .gnux32, | ||
| 2369 | .eabi => .eabi, | ||
| 2370 | .eabihf => .eabihf, | ||
| 2371 | .abin32 => .abin32, | ||
| 2372 | .x32 => .x32, | ||
| 2373 | .ilp32 => .ilp32, | ||
| 2374 | .android => .android, | ||
| 2375 | .androideabi => .androideabi, | ||
| 2376 | .musl => .musl, | ||
| 2377 | .muslabin32 => .muslabin32, | ||
| 2378 | .muslabi64 => .muslabi64, | ||
| 2379 | .musleabi => .musleabi, | ||
| 2380 | .musleabihf => .musleabihf, | ||
| 2381 | .muslf32 => .muslf32, | ||
| 2382 | .muslsf => .muslsf, | ||
| 2383 | .muslx32 => .muslx32, | ||
| 2384 | .msvc => .msvc, | ||
| 2385 | .itanium => .itanium, | ||
| 2386 | .simulator => .simulator, | ||
| 2387 | .ohos => .ohos, | ||
| 2388 | .ohoseabi => .ohoseabi, | ||
| 2389 | .call0 => .call0, | ||
| 2390 | .default => null, | 2360 | .default => null, |
| 2391 | }; | 2361 | }; |
| 2392 | } | 2362 | } |
| ... | @@ -2458,132 +2428,13 @@ pub const TargetQuery = struct { | ... | @@ -2458,132 +2428,13 @@ pub const TargetQuery = struct { |
| 2458 | 2428 | ||
| 2459 | pub fn init(x: ?std.Target.Cpu.Arch) @This() { | 2429 | pub fn init(x: ?std.Target.Cpu.Arch) @This() { |
| 2460 | return switch (x orelse return .default) { | 2430 | return switch (x orelse return .default) { |
| 2461 | .aarch64 => .aarch64, | 2431 | inline else => |tag| @field(@This(), @tagName(tag)), |
| 2462 | .aarch64_be => .aarch64_be, | ||
| 2463 | .alpha => .alpha, | ||
| 2464 | .amdgcn => .amdgcn, | ||
| 2465 | .arc => .arc, | ||
| 2466 | .arceb => .arceb, | ||
| 2467 | .arm => .arm, | ||
| 2468 | .armeb => .armeb, | ||
| 2469 | .avr => .avr, | ||
| 2470 | .bpfeb => .bpfeb, | ||
| 2471 | .bpfel => .bpfel, | ||
| 2472 | .csky => .csky, | ||
| 2473 | .ez80 => .ez80, | ||
| 2474 | .hexagon => .hexagon, | ||
| 2475 | .hppa => .hppa, | ||
| 2476 | .hppa64 => .hppa64, | ||
| 2477 | .kalimba => .kalimba, | ||
| 2478 | .kvx => .kvx, | ||
| 2479 | .lanai => .lanai, | ||
| 2480 | .loongarch32 => .loongarch32, | ||
| 2481 | .loongarch64 => .loongarch64, | ||
| 2482 | .m68k => .m68k, | ||
| 2483 | .m88k => .m88k, | ||
| 2484 | .microblaze => .microblaze, | ||
| 2485 | .microblazeel => .microblazeel, | ||
| 2486 | .mips => .mips, | ||
| 2487 | .mipsel => .mipsel, | ||
| 2488 | .mips64 => .mips64, | ||
| 2489 | .mips64el => .mips64el, | ||
| 2490 | .msp430 => .msp430, | ||
| 2491 | .nvptx => .nvptx, | ||
| 2492 | .nvptx64 => .nvptx64, | ||
| 2493 | .or1k => .or1k, | ||
| 2494 | .powerpc => .powerpc, | ||
| 2495 | .powerpcle => .powerpcle, | ||
| 2496 | .powerpc64 => .powerpc64, | ||
| 2497 | .powerpc64le => .powerpc64le, | ||
| 2498 | .propeller => .propeller, | ||
| 2499 | .riscv32 => .riscv32, | ||
| 2500 | .riscv32be => .riscv32be, | ||
| 2501 | .riscv64 => .riscv64, | ||
| 2502 | .riscv64be => .riscv64be, | ||
| 2503 | .s390x => .s390x, | ||
| 2504 | .sh => .sh, | ||
| 2505 | .sheb => .sheb, | ||
| 2506 | .sparc => .sparc, | ||
| 2507 | .sparc64 => .sparc64, | ||
| 2508 | .spirv32 => .spirv32, | ||
| 2509 | .spirv64 => .spirv64, | ||
| 2510 | .thumb => .thumb, | ||
| 2511 | .thumbeb => .thumbeb, | ||
| 2512 | .ve => .ve, | ||
| 2513 | .wasm32 => .wasm32, | ||
| 2514 | .wasm64 => .wasm64, | ||
| 2515 | .x86_16 => .x86_16, | ||
| 2516 | .x86 => .x86, | ||
| 2517 | .x86_64 => .x86_64, | ||
| 2518 | .xcore => .xcore, | ||
| 2519 | .xtensa => .xtensa, | ||
| 2520 | .xtensaeb => .xtensaeb, | ||
| 2521 | }; | 2432 | }; |
| 2522 | } | 2433 | } |
| 2523 | 2434 | ||
| 2524 | pub fn unwrap(this: @This()) ?std.Target.Cpu.Arch { | 2435 | pub fn unwrap(this: @This()) ?std.Target.Cpu.Arch { |
| 2525 | return switch (this) { | 2436 | return switch (this) { |
| 2526 | .aarch64 => .aarch64, | 2437 | inline else => |tag| @field(std.Target.Cpu.Arch, @tagName(tag)), |
| 2527 | .aarch64_be => .aarch64_be, | ||
| 2528 | .alpha => .alpha, | ||
| 2529 | .amdgcn => .amdgcn, | ||
| 2530 | .arc => .arc, | ||
| 2531 | .arceb => .arceb, | ||
| 2532 | .arm => .arm, | ||
| 2533 | .armeb => .armeb, | ||
| 2534 | .avr => .avr, | ||
| 2535 | .bpfeb => .bpfeb, | ||
| 2536 | .bpfel => .bpfel, | ||
| 2537 | .csky => .csky, | ||
| 2538 | .ez80 => .ez80, | ||
| 2539 | .hexagon => .hexagon, | ||
| 2540 | .hppa => .hppa, | ||
| 2541 | .hppa64 => .hppa64, | ||
| 2542 | .kalimba => .kalimba, | ||
| 2543 | .kvx => .kvx, | ||
| 2544 | .lanai => .lanai, | ||
| 2545 | .loongarch32 => .loongarch32, | ||
| 2546 | .loongarch64 => .loongarch64, | ||
| 2547 | .m68k => .m68k, | ||
| 2548 | .m88k => .m88k, | ||
| 2549 | .microblaze => .microblaze, | ||
| 2550 | .microblazeel => .microblazeel, | ||
| 2551 | .mips => .mips, | ||
| 2552 | .mipsel => .mipsel, | ||
| 2553 | .mips64 => .mips64, | ||
| 2554 | .mips64el => .mips64el, | ||
| 2555 | .msp430 => .msp430, | ||
| 2556 | .nvptx => .nvptx, | ||
| 2557 | .nvptx64 => .nvptx64, | ||
| 2558 | .or1k => .or1k, | ||
| 2559 | .powerpc => .powerpc, | ||
| 2560 | .powerpcle => .powerpcle, | ||
| 2561 | .powerpc64 => .powerpc64, | ||
| 2562 | .powerpc64le => .powerpc64le, | ||
| 2563 | .propeller => .propeller, | ||
| 2564 | .riscv32 => .riscv32, | ||
| 2565 | .riscv32be => .riscv32be, | ||
| 2566 | .riscv64 => .riscv64, | ||
| 2567 | .riscv64be => .riscv64be, | ||
| 2568 | .s390x => .s390x, | ||
| 2569 | .sh => .sh, | ||
| 2570 | .sheb => .sheb, | ||
| 2571 | .sparc => .sparc, | ||
| 2572 | .sparc64 => .sparc64, | ||
| 2573 | .spirv32 => .spirv32, | ||
| 2574 | .spirv64 => .spirv64, | ||
| 2575 | .thumb => .thumb, | ||
| 2576 | .thumbeb => .thumbeb, | ||
| 2577 | .ve => .ve, | ||
| 2578 | .wasm32 => .wasm32, | ||
| 2579 | .wasm64 => .wasm64, | ||
| 2580 | .x86_16 => .x86_16, | ||
| 2581 | .x86 => .x86, | ||
| 2582 | .x86_64 => .x86_64, | ||
| 2583 | .xcore => .xcore, | ||
| 2584 | .xtensa => .xtensa, | ||
| 2585 | .xtensaeb => .xtensaeb, | ||
| 2586 | |||
| 2587 | .default => null, | 2438 | .default => null, |
| 2588 | }; | 2439 | }; |
| 2589 | } | 2440 | } |
| ... | @@ -2642,106 +2493,13 @@ pub const TargetQuery = struct { | ... | @@ -2642,106 +2493,13 @@ pub const TargetQuery = struct { |
| 2642 | 2493 | ||
| 2643 | pub fn init(x: ?std.Target.Os.Tag) @This() { | 2494 | pub fn init(x: ?std.Target.Os.Tag) @This() { |
| 2644 | return switch (x orelse return .default) { | 2495 | return switch (x orelse return .default) { |
| 2645 | .freestanding => .freestanding, | 2496 | inline else => |tag| @field(@This(), @tagName(tag)), |
| 2646 | .other => .other, | ||
| 2647 | .contiki => .contiki, | ||
| 2648 | .fuchsia => .fuchsia, | ||
| 2649 | .hermit => .hermit, | ||
| 2650 | .managarm => .managarm, | ||
| 2651 | .haiku => .haiku, | ||
| 2652 | .hurd => .hurd, | ||
| 2653 | .illumos => .illumos, | ||
| 2654 | .linux => .linux, | ||
| 2655 | .plan9 => .plan9, | ||
| 2656 | .rtems => .rtems, | ||
| 2657 | .serenity => .serenity, | ||
| 2658 | .dragonfly => .dragonfly, | ||
| 2659 | .freebsd => .freebsd, | ||
| 2660 | .netbsd => .netbsd, | ||
| 2661 | .openbsd => .openbsd, | ||
| 2662 | .driverkit => .driverkit, | ||
| 2663 | .ios => .ios, | ||
| 2664 | .maccatalyst => .maccatalyst, | ||
| 2665 | .macos => .macos, | ||
| 2666 | .tvos => .tvos, | ||
| 2667 | .visionos => .visionos, | ||
| 2668 | .watchos => .watchos, | ||
| 2669 | .windows => .windows, | ||
| 2670 | .uefi => .uefi, | ||
| 2671 | .@"3ds" => .@"3ds", | ||
| 2672 | .wiiu => .wiiu, | ||
| 2673 | .@"switch" => .@"switch", | ||
| 2674 | .psx => .psx, | ||
| 2675 | .ps3 => .ps3, | ||
| 2676 | .ps4 => .ps4, | ||
| 2677 | .ps5 => .ps5, | ||
| 2678 | .psp => .psp, | ||
| 2679 | .vita => .vita, | ||
| 2680 | .emscripten => .emscripten, | ||
| 2681 | .wasi => .wasi, | ||
| 2682 | .amdhsa => .amdhsa, | ||
| 2683 | .amdpal => .amdpal, | ||
| 2684 | .cuda => .cuda, | ||
| 2685 | .mesa3d => .mesa3d, | ||
| 2686 | .nvcl => .nvcl, | ||
| 2687 | .opencl => .opencl, | ||
| 2688 | .opengl => .opengl, | ||
| 2689 | .vulkan => .vulkan, | ||
| 2690 | .tios => .tios, | ||
| 2691 | .ashetos => .ashetos, | ||
| 2692 | }; | 2497 | }; |
| 2693 | } | 2498 | } |
| 2694 | 2499 | ||
| 2695 | pub fn unwrap(this: @This()) ?std.Target.Os.Tag { | 2500 | pub fn unwrap(this: @This()) ?std.Target.Os.Tag { |
| 2696 | return switch (this) { | 2501 | return switch (this) { |
| 2697 | .freestanding => .freestanding, | 2502 | inline else => |tag| @field(std.Target.Os.Tag, @tagName(tag)), |
| 2698 | .other => .other, | ||
| 2699 | .contiki => .contiki, | ||
| 2700 | .fuchsia => .fuchsia, | ||
| 2701 | .hermit => .hermit, | ||
| 2702 | .managarm => .managarm, | ||
| 2703 | .haiku => .haiku, | ||
| 2704 | .hurd => .hurd, | ||
| 2705 | .illumos => .illumos, | ||
| 2706 | .linux => .linux, | ||
| 2707 | .plan9 => .plan9, | ||
| 2708 | .rtems => .rtems, | ||
| 2709 | .serenity => .serenity, | ||
| 2710 | .dragonfly => .dragonfly, | ||
| 2711 | .freebsd => .freebsd, | ||
| 2712 | .netbsd => .netbsd, | ||
| 2713 | .openbsd => .openbsd, | ||
| 2714 | .driverkit => .driverkit, | ||
| 2715 | .ios => .ios, | ||
| 2716 | .maccatalyst => .maccatalyst, | ||
| 2717 | .macos => .macos, | ||
| 2718 | .tvos => .tvos, | ||
| 2719 | .visionos => .visionos, | ||
| 2720 | .watchos => .watchos, | ||
| 2721 | .windows => .windows, | ||
| 2722 | .uefi => .uefi, | ||
| 2723 | .@"3ds" => .@"3ds", | ||
| 2724 | .wiiu => .wiiu, | ||
| 2725 | .@"switch" => .@"switch", | ||
| 2726 | .psx => .psx, | ||
| 2727 | .ps3 => .ps3, | ||
| 2728 | .ps4 => .ps4, | ||
| 2729 | .ps5 => .ps5, | ||
| 2730 | .psp => .psp, | ||
| 2731 | .vita => .vita, | ||
| 2732 | .emscripten => .emscripten, | ||
| 2733 | .wasi => .wasi, | ||
| 2734 | .amdhsa => .amdhsa, | ||
| 2735 | .amdpal => .amdpal, | ||
| 2736 | .cuda => .cuda, | ||
| 2737 | .mesa3d => .mesa3d, | ||
| 2738 | .nvcl => .nvcl, | ||
| 2739 | .opencl => .opencl, | ||
| 2740 | .opengl => .opengl, | ||
| 2741 | .vulkan => .vulkan, | ||
| 2742 | .tios => .tios, | ||
| 2743 | .ashetos => .ashetos, | ||
| 2744 | |||
| 2745 | .default => null, | 2503 | .default => null, |
| 2746 | }; | 2504 | }; |
| 2747 | } | 2505 | } |
| ... | @@ -2762,30 +2520,13 @@ pub const TargetQuery = struct { | ... | @@ -2762,30 +2520,13 @@ pub const TargetQuery = struct { |
| 2762 | 2520 | ||
| 2763 | pub fn init(x: ?std.Target.ObjectFormat) @This() { | 2521 | pub fn init(x: ?std.Target.ObjectFormat) @This() { |
| 2764 | return switch (x orelse return .default) { | 2522 | return switch (x orelse return .default) { |
| 2765 | .c => .c, | 2523 | inline else => |tag| @field(@This(), @tagName(tag)), |
| 2766 | .coff => .coff, | ||
| 2767 | .elf => .elf, | ||
| 2768 | .hex => .hex, | ||
| 2769 | .macho => .macho, | ||
| 2770 | .plan9 => .plan9, | ||
| 2771 | .raw => .raw, | ||
| 2772 | .spirv => .spirv, | ||
| 2773 | .wasm => .wasm, | ||
| 2774 | }; | 2524 | }; |
| 2775 | } | 2525 | } |
| 2776 | 2526 | ||
| 2777 | pub fn unwrap(this: @This()) ?std.Target.ObjectFormat { | 2527 | pub fn unwrap(this: @This()) ?std.Target.ObjectFormat { |
| 2778 | return switch (this) { | 2528 | return switch (this) { |
| 2779 | .c => .c, | 2529 | inline else => |tag| @field(std.Target.ObjectFormat, @tagName(tag)), |
| 2780 | .coff => .coff, | ||
| 2781 | .elf => .elf, | ||
| 2782 | .hex => .hex, | ||
| 2783 | .macho => .macho, | ||
| 2784 | .plan9 => .plan9, | ||
| 2785 | .raw => .raw, | ||
| 2786 | .spirv => .spirv, | ||
| 2787 | .wasm => .wasm, | ||
| 2788 | |||
| 2789 | .default => null, | 2530 | .default => null, |
| 2790 | }; | 2531 | }; |
| 2791 | } | 2532 | } |
| ... | @@ -3462,6 +3203,7 @@ pub fn load(arena: Allocator, reader: *Io.Reader) LoadError!Configuration { | ... | @@ -3462,6 +3203,7 @@ pub fn load(arena: Allocator, reader: *Io.Reader) LoadError!Configuration { |
| 3462 | .system_integrations = try arena.alloc(SystemIntegration, header.system_integrations_len), | 3203 | .system_integrations = try arena.alloc(SystemIntegration, header.system_integrations_len), |
| 3463 | .available_options = try arena.alloc(AvailableOption, header.available_options_len), | 3204 | .available_options = try arena.alloc(AvailableOption, header.available_options_len), |
| 3464 | .search_prefixes = try arena.alloc(String, header.search_prefixes_len), | 3205 | .search_prefixes = try arena.alloc(String, header.search_prefixes_len), |
| 3206 | .packages = try arena.alloc(Package, header.packages_len), | ||
| 3465 | .extra = try arena.alloc(u32, header.extra_len), | 3207 | .extra = try arena.alloc(u32, header.extra_len), |
| 3466 | .default_step = header.default_step, | 3208 | .default_step = header.default_step, |
| 3467 | .generated_files_len = header.generated_files_len, | 3209 | .generated_files_len = header.generated_files_len, |
| ... | @@ -3475,6 +3217,7 @@ pub fn load(arena: Allocator, reader: *Io.Reader) LoadError!Configuration { | ... | @@ -3475,6 +3217,7 @@ pub fn load(arena: Allocator, reader: *Io.Reader) LoadError!Configuration { |
| 3475 | @ptrCast(result.system_integrations), | 3217 | @ptrCast(result.system_integrations), |
| 3476 | @ptrCast(result.available_options), | 3218 | @ptrCast(result.available_options), |
| 3477 | @ptrCast(result.search_prefixes), | 3219 | @ptrCast(result.search_prefixes), |
| 3220 | @ptrCast(result.packages), | ||
| 3478 | @ptrCast(result.extra), | 3221 | @ptrCast(result.extra), |
| 3479 | }; | 3222 | }; |
| 3480 | try reader.readVecAll(&vecs); | 3223 | try reader.readVecAll(&vecs); |
lib/std/Build/Module.zig+2-2| ... | @@ -402,8 +402,8 @@ pub fn addCSourceFiles(m: *Module, options: AddCSourceFilesOptions) void { | ... | @@ -402,8 +402,8 @@ pub fn addCSourceFiles(m: *Module, options: AddCSourceFilesOptions) void { |
| 402 | const c_source_files = arena.create(CSourceFiles) catch @panic("OOM"); | 402 | const c_source_files = arena.create(CSourceFiles) catch @panic("OOM"); |
| 403 | c_source_files.* = .{ | 403 | c_source_files.* = .{ |
| 404 | .root = options.root orelse b.path(""), | 404 | .root = options.root orelse b.path(""), |
| 405 | .files = b.dupeStrings(options.files), | 405 | .files = b.graph.dupeStrings(options.files), |
| 406 | .flags = b.dupeStrings(options.flags), | 406 | .flags = b.graph.dupeStrings(options.flags), |
| 407 | .language = options.language, | 407 | .language = options.language, |
| 408 | }; | 408 | }; |
| 409 | m.link_objects.append(arena, .{ .c_source_files = c_source_files }) catch @panic("OOM"); | 409 | m.link_objects.append(arena, .{ .c_source_files = c_source_files }) catch @panic("OOM"); |
lib/std/Build/Serialize.zig+172-22| ... | @@ -10,7 +10,8 @@ const log = std.log; | ... | @@ -10,7 +10,8 @@ const log = std.log; |
| 10 | arena: Allocator, | 10 | arena: Allocator, |
| 11 | wc: *Configuration.Wip, | 11 | wc: *Configuration.Wip, |
| 12 | module_map: std.array_hash_map.Auto(*std.Build.Module, Configuration.Module.Index) = .empty, | 12 | module_map: std.array_hash_map.Auto(*std.Build.Module, Configuration.Module.Index) = .empty, |
| 13 | package_map: std.array_hash_map.Auto(*std.Build, Configuration.Package.Index) = .empty, | 13 | /// Keyed by package hash. |
| 14 | package_map: std.array_hash_map.String(Configuration.Package.Index) = .empty, | ||
| 14 | /// Index corresponds to `Configuration.steps` index. | 15 | /// Index corresponds to `Configuration.steps` index. |
| 15 | step_map: std.array_hash_map.Auto(*Step, void) = .empty, | 16 | step_map: std.array_hash_map.Auto(*Step, void) = .empty, |
| 16 | 17 | ||
| ... | @@ -21,6 +22,10 @@ pub fn write(b: *std.Build, wc: *Configuration.Wip, writer: *std.Io.Writer) !voi | ... | @@ -21,6 +22,10 @@ pub fn write(b: *std.Build, wc: *Configuration.Wip, writer: *std.Io.Writer) !voi |
| 21 | 22 | ||
| 22 | var s: Serialize = .{ .wc = wc, .arena = arena }; | 23 | var s: Serialize = .{ .wc = wc, .arena = arena }; |
| 23 | 24 | ||
| 25 | // Serialize all of the packages first to seed the package_map, which is | ||
| 26 | // later used in calls to packageFromHash. | ||
| 27 | try s.addRootPackage(b); | ||
| 28 | |||
| 24 | try wc.path_deps.ensureTotalCapacityPrecise(gpa, graph.configure_dependencies.items.len); | 29 | try wc.path_deps.ensureTotalCapacityPrecise(gpa, graph.configure_dependencies.items.len); |
| 25 | for ( | 30 | for ( |
| 26 | graph.configure_dependencies.items, | 31 | graph.configure_dependencies.items, |
| ... | @@ -44,10 +49,10 @@ pub fn write(b: *std.Build, wc: *Configuration.Wip, writer: *std.Io.Writer) !voi | ... | @@ -44,10 +49,10 @@ pub fn write(b: *std.Build, wc: *Configuration.Wip, writer: *std.Io.Writer) !voi |
| 44 | .relative => |r| try wc.addString(r.sub_path), | 49 | .relative => |r| try wc.addString(r.sub_path), |
| 45 | }, | 50 | }, |
| 46 | .pkg = switch (src.lazy_path) { | 51 | .pkg = switch (src.lazy_path) { |
| 47 | .src_path => |sp| .init(try s.builderToPackage(sp.owner)), | 52 | .src_path => |sp| .init(s.packageFromHash(sp.owner.pkg_hash)), |
| 48 | .generated => unreachable, | 53 | .generated => unreachable, |
| 49 | .cwd_relative, .relative => .none, | 54 | .cwd_relative, .relative => .none, |
| 50 | .dependency => |d| .init(try s.builderToPackage(d.dependency.builder)), | 55 | .dependency => |d| .init(s.packageFromHash(d.dependency.builder.pkg_hash)), |
| 51 | }, | 56 | }, |
| 52 | }; | 57 | }; |
| 53 | } | 58 | } |
| ... | @@ -84,7 +89,7 @@ pub fn write(b: *std.Build, wc: *Configuration.Wip, writer: *std.Io.Writer) !voi | ... | @@ -84,7 +89,7 @@ pub fn write(b: *std.Build, wc: *Configuration.Wip, writer: *std.Io.Writer) !voi |
| 84 | try wc.steps.ensureTotalCapacity(gpa, s.step_map.entries.capacity); | 89 | try wc.steps.ensureTotalCapacity(gpa, s.step_map.entries.capacity); |
| 85 | wc.steps.appendAssumeCapacity(.{ | 90 | wc.steps.appendAssumeCapacity(.{ |
| 86 | .name = try wc.addString(step.name), | 91 | .name = try wc.addString(step.name), |
| 87 | .owner = try s.builderToPackage(step.owner), | 92 | .owner = s.packageFromHash(step.owner.pkg_hash), |
| 88 | .deps = deps, | 93 | .deps = deps, |
| 89 | .max_rss = .fromBytes(step.max_rss), | 94 | .max_rss = .fromBytes(step.max_rss), |
| 90 | .extended = @fromBackingInt(@intCast(switch (step.tag) { | 95 | .extended = @fromBackingInt(@intCast(switch (step.tag) { |
| ... | @@ -168,8 +173,6 @@ pub fn write(b: *std.Build, wc: *Configuration.Wip, writer: *std.Io.Writer) !voi | ... | @@ -168,8 +173,6 @@ pub fn write(b: *std.Build, wc: *Configuration.Wip, writer: *std.Io.Writer) !voi |
| 168 | .linkage = .init(c.linkage), | 173 | .linkage = .init(c.linkage), |
| 169 | }, | 174 | }, |
| 170 | .flags3 = .{ | 175 | .flags3 = .{ |
| 171 | .is_linking_libc = c.is_linking_libc, | ||
| 172 | .is_linking_libcpp = c.is_linking_libcpp, | ||
| 173 | .version = c.version != null, | 176 | .version = c.version != null, |
| 174 | .compress_debug_sections = c.compress_debug_sections, | 177 | .compress_debug_sections = c.compress_debug_sections, |
| 175 | .initial_memory = c.initial_memory != null, | 178 | .initial_memory = c.initial_memory != null, |
| ... | @@ -454,6 +457,13 @@ pub fn write(b: *std.Build, wc: *Configuration.Wip, writer: *std.Io.Writer) !voi | ... | @@ -454,6 +457,13 @@ pub fn write(b: *std.Build, wc: *Configuration.Wip, writer: *std.Io.Writer) !voi |
| 454 | }, | 457 | }, |
| 455 | else => {}, | 458 | else => {}, |
| 456 | } | 459 | } |
| 460 | const preopens = try arena.alloc( | ||
| 461 | Configuration.Step.Run.Preopen, | ||
| 462 | run.preopens.count(), | ||
| 463 | ); | ||
| 464 | for (preopens, run.preopens.keys(), run.preopens.values()) |*dest, name, path| { | ||
| 465 | dest.* = .{ .name = name, .path = try s.addLazyPath(path) }; | ||
| 466 | } | ||
| 457 | 467 | ||
| 458 | break :e try wc.addExtraErased(Configuration.Step.Run, .{ | 468 | break :e try wc.addExtraErased(Configuration.Step.Run, .{ |
| 459 | .flags = .{ | 469 | .flags = .{ |
| ... | @@ -482,6 +492,7 @@ pub fn write(b: *std.Build, wc: *Configuration.Wip, writer: *std.Io.Writer) !voi | ... | @@ -482,6 +492,7 @@ pub fn write(b: *std.Build, wc: *Configuration.Wip, writer: *std.Io.Writer) !voi |
| 482 | .captured_stdout = run.captured_stdout != null, | 492 | .captured_stdout = run.captured_stdout != null, |
| 483 | .captured_stderr = run.captured_stderr != null, | 493 | .captured_stderr = run.captured_stderr != null, |
| 484 | .environ_map = run.environ_map != null, | 494 | .environ_map = run.environ_map != null, |
| 495 | .preopens = run.preopens.count() > 0, | ||
| 485 | }, | 496 | }, |
| 486 | .flags2 = .{ | 497 | .flags2 = .{ |
| 487 | .expect_stderr_exact = expect_stderr_exact != null, | 498 | .expect_stderr_exact = expect_stderr_exact != null, |
| ... | @@ -496,8 +507,7 @@ pub fn write(b: *std.Build, wc: *Configuration.Wip, writer: *std.Io.Writer) !voi | ... | @@ -496,8 +507,7 @@ pub fn write(b: *std.Build, wc: *Configuration.Wip, writer: *std.Io.Writer) !voi |
| 496 | .file_inputs = .{ .slice = try s.initLazyPathList(run.file_inputs.items) }, | 507 | .file_inputs = .{ .slice = try s.initLazyPathList(run.file_inputs.items) }, |
| 497 | .args = .{ .slice = try s.initArgsList(run.argv.items) }, | 508 | .args = .{ .slice = try s.initArgsList(run.argv.items) }, |
| 498 | .cwd = .{ .value = try s.addOptionalLazyPath(run.cwd) }, | 509 | .cwd = .{ .value = try s.addOptionalLazyPath(run.cwd) }, |
| 499 | .preopen_names = .{ .slice = try s.initStringList(run.preopens.keys()) }, | 510 | .preopens = .{ .slice = preopens }, |
| 500 | .preopen_paths = .{ .slice = try s.initLazyPathList(run.preopens.values()) }, | ||
| 501 | .captured_stdout = .{ .value = if (run.captured_stdout) |cs| .{ | 511 | .captured_stdout = .{ .value = if (run.captured_stdout) |cs| .{ |
| 502 | .basename = try wc.addString(cs.basename), | 512 | .basename = try wc.addString(cs.basename), |
| 503 | .generated_file = cs.generated_file, | 513 | .generated_file = cs.generated_file, |
| ... | @@ -717,19 +727,64 @@ pub fn packageOptions(b: *std.Build, wc: *Configuration.Wip) Allocator.Error!voi | ... | @@ -717,19 +727,64 @@ pub fn packageOptions(b: *std.Build, wc: *Configuration.Wip) Allocator.Error!voi |
| 717 | } | 727 | } |
| 718 | } | 728 | } |
| 719 | 729 | ||
| 720 | fn builderToPackage(s: *Serialize, b: *std.Build) !Configuration.Package.Index { | 730 | fn addRootPackage(s: *Serialize, b: *std.Build) Allocator.Error!void { |
| 721 | if (b.pkg_hash.len == 0) return .root; | ||
| 722 | const arena = s.arena; | 731 | const arena = s.arena; |
| 723 | const wc = s.wc; | 732 | const wc = s.wc; |
| 724 | const gop = try s.package_map.getOrPut(arena, b); | 733 | |
| 725 | if (!gop.found_existing) { | 734 | try wc.packages.append(wc.gpa, .{ |
| 726 | gop.value_ptr.* = try wc.addExtra(Configuration.Package, .{ | 735 | .dep_prefix = .empty, |
| 727 | .hash = try wc.addString(b.pkg_hash), | 736 | .hash = .empty, |
| 728 | .dep_prefix = try wc.addString(b.dep_prefix), | 737 | .root_path = try wc.addString(try b.root.toString(arena)), |
| 729 | .root_path = try wc.addString(try b.root.toString(arena)), | 738 | .deps = undefined, |
| 730 | }); | 739 | }); |
| 731 | } | 740 | |
| 732 | return gop.value_ptr.*; | 741 | const deps = try arena.alloc(Configuration.Package.Dep, b.available_deps.len); |
| 742 | for (deps, b.available_deps) |*dest, src| dest.* = try s.makePackageDep("", src[0], src[1]); | ||
| 743 | |||
| 744 | wc.packages.items[0].deps = try wc.addExtra(Configuration.Package.Dep.List, .{ | ||
| 745 | .deps = .{ .slice = deps }, | ||
| 746 | }); | ||
| 747 | } | ||
| 748 | |||
| 749 | fn makePackageDep(s: *Serialize, parent_dep_prefix: []const u8, name: []const u8, hash: []const u8) Allocator.Error!Configuration.Package.Dep { | ||
| 750 | const arena = s.arena; | ||
| 751 | const wc = s.wc; | ||
| 752 | |||
| 753 | if (s.package_map.get(hash)) |index| return .{ | ||
| 754 | .name = try wc.addString(name), | ||
| 755 | .package = index, | ||
| 756 | }; | ||
| 757 | |||
| 758 | const entry = std.Build.package_map.get(hash) orelse unreachable; | ||
| 759 | |||
| 760 | const dep_prefix = try arena.print("{s}{s}.", .{ parent_dep_prefix, name }); | ||
| 761 | |||
| 762 | const index: Configuration.Package.Index = @fromBackingInt(@intCast(wc.packages.items.len)); | ||
| 763 | try s.package_map.put(arena, hash, index); | ||
| 764 | |||
| 765 | try wc.packages.append(wc.gpa, .{ | ||
| 766 | .dep_prefix = try wc.addString(dep_prefix), | ||
| 767 | .hash = try wc.addString(hash), | ||
| 768 | .root_path = try wc.addString(entry.build_root), | ||
| 769 | .deps = undefined, | ||
| 770 | }); | ||
| 771 | |||
| 772 | const deps = try arena.alloc(Configuration.Package.Dep, entry.deps.len); | ||
| 773 | for (deps, entry.deps) |*dest, src| dest.* = try s.makePackageDep(dep_prefix, src[0], src[1]); | ||
| 774 | |||
| 775 | wc.packages.items[@backingInt(index)].deps = try wc.addExtra(Configuration.Package.Dep.List, .{ | ||
| 776 | .deps = .{ .slice = deps }, | ||
| 777 | }); | ||
| 778 | |||
| 779 | return .{ | ||
| 780 | .name = try wc.addString(name), | ||
| 781 | .package = index, | ||
| 782 | }; | ||
| 783 | } | ||
| 784 | |||
| 785 | fn packageFromHash(s: *Serialize, pkg_hash: []const u8) Configuration.Package.Index { | ||
| 786 | if (pkg_hash.len == 0) return .root; | ||
| 787 | return s.package_map.get(pkg_hash) orelse std.debug.panic("unrecognized package hash: {q}", .{pkg_hash}); | ||
| 733 | } | 788 | } |
| 734 | 789 | ||
| 735 | fn addOptionalLazyPathEnum(s: *Serialize, lp: ?std.Build.LazyPath) !Configuration.LazyPath.OptionalIndex { | 790 | fn addOptionalLazyPathEnum(s: *Serialize, lp: ?std.Build.LazyPath) !Configuration.LazyPath.OptionalIndex { |
| ... | @@ -738,7 +793,7 @@ fn addOptionalLazyPathEnum(s: *Serialize, lp: ?std.Build.LazyPath) !Configuratio | ... | @@ -738,7 +793,7 @@ fn addOptionalLazyPathEnum(s: *Serialize, lp: ?std.Build.LazyPath) !Configuratio |
| 738 | .src_path => |src_path| i: { | 793 | .src_path => |src_path| i: { |
| 739 | const sub_path = try wc.addString(src_path.sub_path); | 794 | const sub_path = try wc.addString(src_path.sub_path); |
| 740 | break :i try wc.addExtraErased(Configuration.LazyPath.SourcePath, .{ | 795 | break :i try wc.addExtraErased(Configuration.LazyPath.SourcePath, .{ |
| 741 | .owner = try s.builderToPackage(src_path.owner), | 796 | .owner = s.packageFromHash(src_path.owner.pkg_hash), |
| 742 | .sub_path = sub_path, | 797 | .sub_path = sub_path, |
| 743 | }); | 798 | }); |
| 744 | }, | 799 | }, |
| ... | @@ -766,7 +821,7 @@ fn addOptionalLazyPathEnum(s: *Serialize, lp: ?std.Build.LazyPath) !Configuratio | ... | @@ -766,7 +821,7 @@ fn addOptionalLazyPathEnum(s: *Serialize, lp: ?std.Build.LazyPath) !Configuratio |
| 766 | .dependency => |dependency| i: { | 821 | .dependency => |dependency| i: { |
| 767 | const sub_path = try wc.addString(dependency.sub_path); | 822 | const sub_path = try wc.addString(dependency.sub_path); |
| 768 | break :i try wc.addExtraErased(Configuration.LazyPath.SourcePath, .{ | 823 | break :i try wc.addExtraErased(Configuration.LazyPath.SourcePath, .{ |
| 769 | .owner = try s.builderToPackage(dependency.dependency.builder), | 824 | .owner = s.packageFromHash(dependency.dependency.builder.pkg_hash), |
| 770 | .sub_path = sub_path, | 825 | .sub_path = sub_path, |
| 771 | }); | 826 | }); |
| 772 | }, | 827 | }, |
| ... | @@ -1012,6 +1067,101 @@ fn initArgsList(s: *Serialize, args: []const Step.Run.Arg) ![]const Configuratio | ... | @@ -1012,6 +1067,101 @@ fn initArgsList(s: *Serialize, args: []const Step.Run.Arg) ![]const Configuratio |
| 1012 | .producer = .{ .value = null }, | 1067 | .producer = .{ .value = null }, |
| 1013 | .generated = .{ .value = null }, | 1068 | .generated = .{ .value = null }, |
| 1014 | }, | 1069 | }, |
| 1070 | .enable_darling => |a| .{ | ||
| 1071 | .flags = .{ | ||
| 1072 | .tag = .enable_darling, | ||
| 1073 | .prefix = a.enabled != null, | ||
| 1074 | .suffix = a.disabled != null, | ||
| 1075 | .basename = false, | ||
| 1076 | .path = false, | ||
| 1077 | .producer = false, | ||
| 1078 | .generated = false, | ||
| 1079 | .dep_file = false, | ||
| 1080 | .make_absolute = false, | ||
| 1081 | }, | ||
| 1082 | .prefix = .{ .value = try s.addOptionalString(a.enabled) }, | ||
| 1083 | .suffix = .{ .value = try s.addOptionalString(a.disabled) }, | ||
| 1084 | .basename = .{ .value = null }, | ||
| 1085 | .path = .{ .value = null }, | ||
| 1086 | .producer = .{ .value = null }, | ||
| 1087 | .generated = .{ .value = null }, | ||
| 1088 | }, | ||
| 1089 | .enable_qemu => |a| .{ | ||
| 1090 | .flags = .{ | ||
| 1091 | .tag = .enable_qemu, | ||
| 1092 | .prefix = a.enabled != null, | ||
| 1093 | .suffix = a.disabled != null, | ||
| 1094 | .basename = false, | ||
| 1095 | .path = false, | ||
| 1096 | .producer = false, | ||
| 1097 | .generated = false, | ||
| 1098 | .dep_file = false, | ||
| 1099 | .make_absolute = false, | ||
| 1100 | }, | ||
| 1101 | .prefix = .{ .value = try s.addOptionalString(a.enabled) }, | ||
| 1102 | .suffix = .{ .value = try s.addOptionalString(a.disabled) }, | ||
| 1103 | .basename = .{ .value = null }, | ||
| 1104 | .path = .{ .value = null }, | ||
| 1105 | .producer = .{ .value = null }, | ||
| 1106 | .generated = .{ .value = null }, | ||
| 1107 | }, | ||
| 1108 | .enable_rosetta => |a| .{ | ||
| 1109 | .flags = .{ | ||
| 1110 | .tag = .enable_rosetta, | ||
| 1111 | .prefix = a.enabled != null, | ||
| 1112 | .suffix = a.disabled != null, | ||
| 1113 | .basename = false, | ||
| 1114 | .path = false, | ||
| 1115 | .producer = false, | ||
| 1116 | .generated = false, | ||
| 1117 | .dep_file = false, | ||
| 1118 | .make_absolute = false, | ||
| 1119 | }, | ||
| 1120 | .prefix = .{ .value = try s.addOptionalString(a.enabled) }, | ||
| 1121 | .suffix = .{ .value = try s.addOptionalString(a.disabled) }, | ||
| 1122 | .basename = .{ .value = null }, | ||
| 1123 | .path = .{ .value = null }, | ||
| 1124 | .producer = .{ .value = null }, | ||
| 1125 | .generated = .{ .value = null }, | ||
| 1126 | }, | ||
| 1127 | .enable_wasmtime => |a| .{ | ||
| 1128 | .flags = .{ | ||
| 1129 | .tag = .enable_wasmtime, | ||
| 1130 | .prefix = a.enabled != null, | ||
| 1131 | .suffix = a.disabled != null, | ||
| 1132 | .basename = false, | ||
| 1133 | .path = false, | ||
| 1134 | .producer = false, | ||
| 1135 | .generated = false, | ||
| 1136 | .dep_file = false, | ||
| 1137 | .make_absolute = false, | ||
| 1138 | }, | ||
| 1139 | .prefix = .{ .value = try s.addOptionalString(a.enabled) }, | ||
| 1140 | .suffix = .{ .value = try s.addOptionalString(a.disabled) }, | ||
| 1141 | .basename = .{ .value = null }, | ||
| 1142 | .path = .{ .value = null }, | ||
| 1143 | .producer = .{ .value = null }, | ||
| 1144 | .generated = .{ .value = null }, | ||
| 1145 | }, | ||
| 1146 | .enable_wine => |a| .{ | ||
| 1147 | .flags = .{ | ||
| 1148 | .tag = .enable_wine, | ||
| 1149 | .prefix = a.enabled != null, | ||
| 1150 | .suffix = a.disabled != null, | ||
| 1151 | .basename = false, | ||
| 1152 | .path = false, | ||
| 1153 | .producer = false, | ||
| 1154 | .generated = false, | ||
| 1155 | .dep_file = false, | ||
| 1156 | .make_absolute = false, | ||
| 1157 | }, | ||
| 1158 | .prefix = .{ .value = try s.addOptionalString(a.enabled) }, | ||
| 1159 | .suffix = .{ .value = try s.addOptionalString(a.disabled) }, | ||
| 1160 | .basename = .{ .value = null }, | ||
| 1161 | .path = .{ .value = null }, | ||
| 1162 | .producer = .{ .value = null }, | ||
| 1163 | .generated = .{ .value = null }, | ||
| 1164 | }, | ||
| 1015 | }); | 1165 | }); |
| 1016 | } | 1166 | } |
| 1017 | return result; | 1167 | return result; |
| ... | @@ -1131,7 +1281,7 @@ fn addModule(s: *Serialize, m: *std.Build.Module) !Configuration.Module.Index { | ... | @@ -1131,7 +1281,7 @@ fn addModule(s: *Serialize, m: *std.Build.Module) !Configuration.Module.Index { |
| 1131 | .link_libcpp = .init(m.link_libcpp), | 1281 | .link_libcpp = .init(m.link_libcpp), |
| 1132 | .no_builtin = .init(m.no_builtin), | 1282 | .no_builtin = .init(m.no_builtin), |
| 1133 | }, | 1283 | }, |
| 1134 | .owner = try s.builderToPackage(m.owner), | 1284 | .owner = s.packageFromHash(m.owner.pkg_hash), |
| 1135 | .root_source_file = try s.addOptionalLazyPathEnum(m.root_source_file), | 1285 | .root_source_file = try s.addOptionalLazyPathEnum(m.root_source_file), |
| 1136 | .import_table = .invalid, | 1286 | .import_table = .invalid, |
| 1137 | .resolved_target = try addOptionalResolvedTarget(wc, m.resolved_target), | 1287 | .resolved_target = try addOptionalResolvedTarget(wc, m.resolved_target), |
lib/std/Build/Step/Compile.zig+4-9| ... | @@ -101,7 +101,7 @@ each_lib_rpath: ?bool = null, | ... | @@ -101,7 +101,7 @@ each_lib_rpath: ?bool = null, |
| 101 | /// This option overrides the CLI argument passed to `zig build`. | 101 | /// This option overrides the CLI argument passed to `zig build`. |
| 102 | build_id: ?std.zig.BuildId = null, | 102 | build_id: ?std.zig.BuildId = null, |
| 103 | 103 | ||
| 104 | /// Create a .eh_frame_hdr section and a PT_GNU_EH_FRAME segment in the ELF | 104 | /// Create a .eh_frame_hdr section and a PT.GNU_EH_FRAME segment in the ELF |
| 105 | /// file. | 105 | /// file. |
| 106 | link_eh_frame_hdr: bool = false, | 106 | link_eh_frame_hdr: bool = false, |
| 107 | link_emit_relocs: bool = false, | 107 | link_emit_relocs: bool = false, |
| ... | @@ -220,11 +220,6 @@ expect_errors: ?ExpectedCompileErrors = null, | ... | @@ -220,11 +220,6 @@ expect_errors: ?ExpectedCompileErrors = null, |
| 220 | /// `std.math.maxInt(u16)`. Overrides the argument passed to `zig build`. | 220 | /// `std.math.maxInt(u16)`. Overrides the argument passed to `zig build`. |
| 221 | error_limit: ?u32 = null, | 221 | error_limit: ?u32 = null, |
| 222 | 222 | ||
| 223 | /// Computed during make(). | ||
| 224 | is_linking_libc: bool = false, | ||
| 225 | /// Computed during make(). | ||
| 226 | is_linking_libcpp: bool = false, | ||
| 227 | |||
| 228 | /// Enables coverage instrumentation that is only useful if you are using third | 223 | /// Enables coverage instrumentation that is only useful if you are using third |
| 229 | /// party fuzzers that depend on it. Otherwise, slows down the instrumented | 224 | /// party fuzzers that depend on it. Otherwise, slows down the instrumented |
| 230 | /// binary with unnecessary function calls. | 225 | /// binary with unnecessary function calls. |
| ... | @@ -375,7 +370,7 @@ pub fn create(owner: *std.Build, options: Options) *Compile { | ... | @@ -375,7 +370,7 @@ pub fn create(owner: *std.Build, options: Options) *Compile { |
| 375 | const graph = owner.graph; | 370 | const graph = owner.graph; |
| 376 | const arena = graph.arena; | 371 | const arena = graph.arena; |
| 377 | 372 | ||
| 378 | const name = owner.dupe(options.name); | 373 | const name = owner.graph.dupeString(options.name); |
| 379 | if (mem.find(u8, name, "/") != null or mem.find(u8, name, "\\") != null) { | 374 | if (mem.find(u8, name, "/") != null or mem.find(u8, name, "\\") != null) { |
| 380 | panic("invalid name: '{s}'. It looks like a file path, but it is supposed to be the library or application name.", .{name}); | 375 | panic("invalid name: '{s}'. It looks like a file path, but it is supposed to be the library or application name.", .{name}); |
| 381 | } | 376 | } |
| ... | @@ -390,7 +385,7 @@ pub fn create(owner: *std.Build, options: Options) *Compile { | ... | @@ -390,7 +385,7 @@ pub fn create(owner: *std.Build, options: Options) *Compile { |
| 390 | @tagName(options.kind) | 385 | @tagName(options.kind) |
| 391 | else | 386 | else |
| 392 | owner.fmt("{t} {s}", .{ options.kind, name }), | 387 | owner.fmt("{t} {s}", .{ options.kind, name }), |
| 393 | @tagName(options.root_module.optimize orelse .Debug), | 388 | @tagName(options.root_module.optimize orelse .debug), |
| 394 | resolved_target.query.zigTriple(arena) catch @panic("OOM"), | 389 | resolved_target.query.zigTriple(arena) catch @panic("OOM"), |
| 395 | }); | 390 | }); |
| 396 | 391 | ||
| ... | @@ -645,7 +640,7 @@ pub fn producesPdbFile(compile: *Compile) bool { | ... | @@ -645,7 +640,7 @@ pub fn producesPdbFile(compile: *Compile) bool { |
| 645 | if (target.ofmt == .c) return false; | 640 | if (target.ofmt == .c) return false; |
| 646 | if (compile.use_llvm == false) return false; | 641 | if (compile.use_llvm == false) return false; |
| 647 | if (compile.root_module.strip == true or | 642 | if (compile.root_module.strip == true or |
| 648 | (compile.root_module.strip == null and compile.root_module.optimize == .ReleaseSmall)) | 643 | (compile.root_module.strip == null and compile.root_module.optimize == .small)) |
| 649 | { | 644 | { |
| 650 | return false; | 645 | return false; |
| 651 | } | 646 | } |
lib/std/Build/Step/ConfigHeader.zig+4-1| ... | @@ -27,6 +27,9 @@ pub const Style = union(enum) { | ... | @@ -27,6 +27,9 @@ pub const Style = union(enum) { |
| 27 | /// The configure format supported by CMake. It uses `@FOO@`, `${}` and | 27 | /// The configure format supported by CMake. It uses `@FOO@`, `${}` and |
| 28 | /// `#cmakedefine` for template substitution. | 28 | /// `#cmakedefine` for template substitution. |
| 29 | cmake: std.Build.LazyPath, | 29 | cmake: std.Build.LazyPath, |
| 30 | /// The configure format supported by Meson. It uses `@FOO@`, and | ||
| 31 | /// `#mesondefine` for template substitution. | ||
| 32 | meson: std.Build.LazyPath, | ||
| 30 | /// Instead of starting with an input file, start with nothing. | 33 | /// Instead of starting with an input file, start with nothing. |
| 31 | blank, | 34 | blank, |
| 32 | /// Start with nothing, like blank, and output a nasm .asm file. | 35 | /// Start with nothing, like blank, and output a nasm .asm file. |
| ... | @@ -34,7 +37,7 @@ pub const Style = union(enum) { | ... | @@ -34,7 +37,7 @@ pub const Style = union(enum) { |
| 34 | 37 | ||
| 35 | pub fn getPath(style: Style) ?std.Build.LazyPath { | 38 | pub fn getPath(style: Style) ?std.Build.LazyPath { |
| 36 | switch (style) { | 39 | switch (style) { |
| 37 | .autoconf_undef, .autoconf_at, .cmake => |s| return s, | 40 | .autoconf_undef, .autoconf_at, .cmake, .meson => |s| return s, |
| 38 | .blank, .nasm => return null, | 41 | .blank, .nasm => return null, |
| 39 | } | 42 | } |
| 40 | } | 43 | } |
lib/std/Build/Step/Run.zig+58-2| ... | @@ -28,7 +28,7 @@ environ_map: ?*EnvMap, | ... | @@ -28,7 +28,7 @@ environ_map: ?*EnvMap, |
| 28 | 28 | ||
| 29 | /// Named files that will be provided to the parent process. | 29 | /// Named files that will be provided to the parent process. |
| 30 | /// See `std.process.Preopens`. | 30 | /// See `std.process.Preopens`. |
| 31 | preopens: std.array_hash_map.String(Build.LazyPath), | 31 | preopens: std.array_hash_map.Auto(Configuration.String, Build.LazyPath), |
| 32 | 32 | ||
| 33 | /// Controls the `NO_COLOR` and `CLICOLOR_FORCE` environment variables. | 33 | /// Controls the `NO_COLOR` and `CLICOLOR_FORCE` environment variables. |
| 34 | color: Color = .auto, | 34 | color: Color = .auto, |
| ... | @@ -68,9 +68,11 @@ rename_step_with_output_arg: bool, | ... | @@ -68,9 +68,11 @@ rename_step_with_output_arg: bool, |
| 68 | /// executed binary will not fail the build if the binary cannot be executed | 68 | /// executed binary will not fail the build if the binary cannot be executed |
| 69 | /// due to being for a foreign binary to the host system which is running the | 69 | /// due to being for a foreign binary to the host system which is running the |
| 70 | /// build graph. | 70 | /// build graph. |
| 71 | /// | ||
| 71 | /// Command-line arguments such as -fqemu and -fwasmtime may affect whether a | 72 | /// Command-line arguments such as -fqemu and -fwasmtime may affect whether a |
| 72 | /// binary is detected as foreign, as well as system configuration such as | 73 | /// binary is detected as foreign, as well as system configuration such as |
| 73 | /// Rosetta (macOS) and binfmt_misc (Linux). | 74 | /// Rosetta (macOS) and binfmt_misc (Linux). |
| 75 | /// | ||
| 74 | /// If this Run step is considered to have side-effects, then this flag does | 76 | /// If this Run step is considered to have side-effects, then this flag does |
| 75 | /// nothing. | 77 | /// nothing. |
| 76 | skip_foreign_checks: bool, | 78 | skip_foreign_checks: bool, |
| ... | @@ -149,6 +151,19 @@ pub const Arg = union(enum) { | ... | @@ -149,6 +151,19 @@ pub const Arg = union(enum) { |
| 149 | output_directory: *Output, | 151 | output_directory: *Output, |
| 150 | /// The arguments passed after "--" on the "zig build" CLI. | 152 | /// The arguments passed after "--" on the "zig build" CLI. |
| 151 | passthru, | 153 | passthru, |
| 154 | |||
| 155 | enable_darling: ToggleFlags, | ||
| 156 | enable_qemu: ToggleFlags, | ||
| 157 | enable_rosetta: ToggleFlags, | ||
| 158 | enable_wasmtime: ToggleFlags, | ||
| 159 | enable_wine: ToggleFlags, | ||
| 160 | }; | ||
| 161 | |||
| 162 | pub const ToggleFlags = struct { | ||
| 163 | /// The string to pass when enabled, or null to omit the arg. | ||
| 164 | enabled: ?[]const u8 = null, | ||
| 165 | /// The string to pass when disabled, or null to omit the arg. | ||
| 166 | disabled: ?[]const u8 = null, | ||
| 152 | }; | 167 | }; |
| 153 | 168 | ||
| 154 | pub const DecoratedArtifact = struct { | 169 | pub const DecoratedArtifact = struct { |
| ... | @@ -576,6 +591,46 @@ pub fn addPassthruArgs(run: *Run) void { | ... | @@ -576,6 +591,46 @@ pub fn addPassthruArgs(run: *Run) void { |
| 576 | run.argv.append(arena, .passthru) catch @panic("OOM"); | 591 | run.argv.append(arena, .passthru) catch @panic("OOM"); |
| 577 | } | 592 | } |
| 578 | 593 | ||
| 594 | /// Appends a custom string to the command line depending on the `-fdarling` | ||
| 595 | /// value passed to `zig build`. | ||
| 596 | pub fn addThirdPartyEnabledArgDarling(run: *Run, toggle_flags: ToggleFlags) void { | ||
| 597 | const graph = run.step.owner.graph; | ||
| 598 | const arena = graph.arena; | ||
| 599 | run.argv.append(arena, .{ .enable_darling = toggle_flags }) catch @panic("OOM"); | ||
| 600 | } | ||
| 601 | |||
| 602 | /// Appends a custom string to the command line depending on the `-fqemu` | ||
| 603 | /// value passed to `zig build`. | ||
| 604 | pub fn addThirdPartyEnabledArgQemu(run: *Run, toggle_flags: ToggleFlags) void { | ||
| 605 | const graph = run.step.owner.graph; | ||
| 606 | const arena = graph.arena; | ||
| 607 | run.argv.append(arena, .{ .enable_qemu = toggle_flags }) catch @panic("OOM"); | ||
| 608 | } | ||
| 609 | |||
| 610 | /// Appends a custom string to the command line depending on the `-frosetta` | ||
| 611 | /// value passed to `zig build`. | ||
| 612 | pub fn addThirdPartyEnabledArgRosetta(run: *Run, toggle_flags: ToggleFlags) void { | ||
| 613 | const graph = run.step.owner.graph; | ||
| 614 | const arena = graph.arena; | ||
| 615 | run.argv.append(arena, .{ .enable_rosetta = toggle_flags }) catch @panic("OOM"); | ||
| 616 | } | ||
| 617 | |||
| 618 | /// Appends a custom string to the command line depending on the `-fwasmtime` | ||
| 619 | /// value passed to `zig build`. | ||
| 620 | pub fn addThirdPartyEnabledArgWasmtime(run: *Run, toggle_flags: ToggleFlags) void { | ||
| 621 | const graph = run.step.owner.graph; | ||
| 622 | const arena = graph.arena; | ||
| 623 | run.argv.append(arena, .{ .enable_wasmtime = toggle_flags }) catch @panic("OOM"); | ||
| 624 | } | ||
| 625 | |||
| 626 | /// Appends a custom string to the command line depending on the `-fwine` | ||
| 627 | /// value passed to `zig build`. | ||
| 628 | pub fn addThirdPartyEnabledArgWine(run: *Run, toggle_flags: ToggleFlags) void { | ||
| 629 | const graph = run.step.owner.graph; | ||
| 630 | const arena = graph.arena; | ||
| 631 | run.argv.append(arena, .{ .enable_wine = toggle_flags }) catch @panic("OOM"); | ||
| 632 | } | ||
| 633 | |||
| 579 | pub fn setStdIn(run: *Run, stdin: StdIn) void { | 634 | pub fn setStdIn(run: *Run, stdin: StdIn) void { |
| 580 | switch (stdin) { | 635 | switch (stdin) { |
| 581 | .lazy_path => |lazy_path| lazy_path.addStepDependencies(&run.step), | 636 | .lazy_path => |lazy_path| lazy_path.addStepDependencies(&run.step), |
| ... | @@ -624,11 +679,12 @@ pub fn removeEnvironmentVariable(run: *Run, key: []const u8) void { | ... | @@ -624,11 +679,12 @@ pub fn removeEnvironmentVariable(run: *Run, key: []const u8) void { |
| 624 | 679 | ||
| 625 | pub fn setPreopen(run: *Run, name: []const u8, resource: Build.LazyPath) void { | 680 | pub fn setPreopen(run: *Run, name: []const u8, resource: Build.LazyPath) void { |
| 626 | const graph = run.step.owner.graph; | 681 | const graph = run.step.owner.graph; |
| 682 | const wc = &graph.wip_configuration; | ||
| 627 | const arena = graph.arena; | 683 | const arena = graph.arena; |
| 628 | resource.addStepDependencies(&run.step); | 684 | resource.addStepDependencies(&run.step); |
| 629 | run.preopens.put( | 685 | run.preopens.put( |
| 630 | arena, | 686 | arena, |
| 631 | graph.dupeString(name), | 687 | wc.addString(name) catch @panic("OOM"), |
| 632 | resource.dupe(graph), | 688 | resource.dupe(graph), |
| 633 | ) catch @panic("OOM"); | 689 | ) catch @panic("OOM"); |
| 634 | } | 690 | } |
lib/std/Io.zig+12-6| ... | @@ -238,7 +238,7 @@ pub const VTable = struct { | ... | @@ -238,7 +238,7 @@ pub const VTable = struct { |
| 238 | netSend: *const fn (?*anyopaque, net.Socket.Handle, []net.OutgoingMessage, net.SendFlags) struct { ?net.Socket.SendError, usize }, | 238 | netSend: *const fn (?*anyopaque, net.Socket.Handle, []net.OutgoingMessage, net.SendFlags) struct { ?net.Socket.SendError, usize }, |
| 239 | netWrite: *const fn (?*anyopaque, dest: net.Socket.Handle, header: []const u8, data: []const []const u8, splat: usize) net.Stream.Writer.Error!usize, | 239 | netWrite: *const fn (?*anyopaque, dest: net.Socket.Handle, header: []const u8, data: []const []const u8, splat: usize) net.Stream.Writer.Error!usize, |
| 240 | netWriteFile: *const fn (?*anyopaque, net.Socket.Handle, header: []const u8, *Io.File.Reader, Io.Limit) net.Stream.Writer.WriteFileError!usize, | 240 | netWriteFile: *const fn (?*anyopaque, net.Socket.Handle, header: []const u8, *Io.File.Reader, Io.Limit) net.Stream.Writer.WriteFileError!usize, |
| 241 | netClose: *const fn (?*anyopaque, handle: []const net.Socket.Handle) void, | 241 | netClose: *const fn (?*anyopaque, sockets: []const net.Socket) void, |
| 242 | netShutdown: *const fn (?*anyopaque, handle: net.Socket.Handle, how: net.ShutdownHow) net.ShutdownError!void, | 242 | netShutdown: *const fn (?*anyopaque, handle: net.Socket.Handle, how: net.ShutdownHow) net.ShutdownError!void, |
| 243 | netInterfaceNameResolve: *const fn (?*anyopaque, *const net.Interface.Name) net.Interface.Name.ResolveError!net.Interface, | 243 | netInterfaceNameResolve: *const fn (?*anyopaque, *const net.Interface.Name) net.Interface.Name.ResolveError!net.Interface, |
| 244 | netInterfaceName: *const fn (?*anyopaque, net.Interface) net.Interface.NameError!net.Interface.Name, | 244 | netInterfaceName: *const fn (?*anyopaque, net.Interface) net.Interface.NameError!net.Interface.Name, |
| ... | @@ -467,6 +467,7 @@ pub const OperateTimeoutError = Cancelable || Timeout.Error || ConcurrentError; | ... | @@ -467,6 +467,7 @@ pub const OperateTimeoutError = Cancelable || Timeout.Error || ConcurrentError; |
| 467 | 467 | ||
| 468 | /// Performs one `Operation` with provided `timeout`. | 468 | /// Performs one `Operation` with provided `timeout`. |
| 469 | pub fn operateTimeout(io: Io, operation: Operation, timeout: Timeout) OperateTimeoutError!Operation.Result { | 469 | pub fn operateTimeout(io: Io, operation: Operation, timeout: Timeout) OperateTimeoutError!Operation.Result { |
| 470 | if (timeout == .none) return io.vtable.operate(io.userdata, operation); | ||
| 470 | var storage: [1]Operation.Storage = undefined; | 471 | var storage: [1]Operation.Storage = undefined; |
| 471 | var batch: Batch = .init(&storage); | 472 | var batch: Batch = .init(&storage); |
| 472 | batch.addAt(0, operation); | 473 | batch.addAt(0, operation); |
| ... | @@ -778,10 +779,10 @@ pub const Clock = enum { | ... | @@ -778,10 +779,10 @@ pub const Clock = enum { |
| 778 | /// * On Linux, corresponds `CLOCK_BOOTTIME`. | 779 | /// * On Linux, corresponds `CLOCK_BOOTTIME`. |
| 779 | /// * On macOS, corresponds to `CLOCK_MONOTONIC_RAW`. | 780 | /// * On macOS, corresponds to `CLOCK_MONOTONIC_RAW`. |
| 780 | boot, | 781 | boot, |
| 781 | /// Tracks the amount of CPU in user or kernel mode used by the calling | 782 | /// Tracks the amount of CPU time in user or kernel mode used by the calling |
| 782 | /// process. | 783 | /// process. |
| 783 | cpu_process, | 784 | cpu_process, |
| 784 | /// Tracks the amount of CPU in user or kernel mode used by the calling | 785 | /// Tracks the amount of CPU time in user or kernel mode used by the calling |
| 785 | /// thread. | 786 | /// thread. |
| 786 | cpu_thread, | 787 | cpu_thread, |
| 787 | 788 | ||
| ... | @@ -980,6 +981,10 @@ pub const Timestamp = struct { | ... | @@ -980,6 +981,10 @@ pub const Timestamp = struct { |
| 980 | const now_ts = clock.now(io); | 981 | const now_ts = clock.now(io); |
| 981 | return t.durationTo(now_ts); | 982 | return t.durationTo(now_ts); |
| 982 | } | 983 | } |
| 984 | |||
| 985 | pub fn compare(lhs: Timestamp, op: math.CompareOperator, rhs: Timestamp) bool { | ||
| 986 | return math.compare(lhs.nanoseconds, op, rhs.nanoseconds); | ||
| 987 | } | ||
| 983 | }; | 988 | }; |
| 984 | 989 | ||
| 985 | pub const Duration = struct { | 990 | pub const Duration = struct { |
| ... | @@ -1147,6 +1152,7 @@ pub const Duration = struct { | ... | @@ -1147,6 +1152,7 @@ pub const Duration = struct { |
| 1147 | 1152 | ||
| 1148 | /// Declares under what conditions an operation should return `error.Timeout`. | 1153 | /// Declares under what conditions an operation should return `error.Timeout`. |
| 1149 | pub const Timeout = union(enum) { | 1154 | pub const Timeout = union(enum) { |
| 1155 | /// `.none` will wait forever | ||
| 1150 | none, | 1156 | none, |
| 1151 | duration: Clock.Duration, | 1157 | duration: Clock.Duration, |
| 1152 | deadline: Clock.Timestamp, | 1158 | deadline: Clock.Timestamp, |
| ... | @@ -2525,7 +2531,7 @@ pub fn lockStderr(io: Io, buffer: []u8, terminal_mode: ?Terminal.Mode) Cancelabl | ... | @@ -2525,7 +2531,7 @@ pub fn lockStderr(io: Io, buffer: []u8, terminal_mode: ?Terminal.Mode) Cancelabl |
| 2525 | 2531 | ||
| 2526 | /// Same as `lockStderr` but non-blocking. | 2532 | /// Same as `lockStderr` but non-blocking. |
| 2527 | pub fn tryLockStderr(io: Io, buffer: []u8, terminal_mode: ?Terminal.Mode) Cancelable!?LockedStderr { | 2533 | pub fn tryLockStderr(io: Io, buffer: []u8, terminal_mode: ?Terminal.Mode) Cancelable!?LockedStderr { |
| 2528 | const ls = (try io.vtable.tryLockStderr(io.userdata, buffer, terminal_mode)) orelse return null; | 2534 | const ls = (try io.vtable.tryLockStderr(io.userdata, terminal_mode)) orelse return null; |
| 2529 | try ls.clear(buffer); | 2535 | try ls.clear(buffer); |
| 2530 | return ls; | 2536 | return ls; |
| 2531 | } | 2537 | } |
| ... | @@ -3476,9 +3482,9 @@ pub fn failingNetWriteFile(userdata: ?*anyopaque, handle: net.Socket.Handle, hea | ... | @@ -3476,9 +3482,9 @@ pub fn failingNetWriteFile(userdata: ?*anyopaque, handle: net.Socket.Handle, hea |
| 3476 | return error.NetworkDown; | 3482 | return error.NetworkDown; |
| 3477 | } | 3483 | } |
| 3478 | 3484 | ||
| 3479 | pub fn unreachableNetClose(userdata: ?*anyopaque, handle: []const net.Socket.Handle) void { | 3485 | pub fn unreachableNetClose(userdata: ?*anyopaque, sockets: []const net.Socket) void { |
| 3480 | _ = userdata; | 3486 | _ = userdata; |
| 3481 | _ = handle; | 3487 | _ = sockets; |
| 3482 | unreachable; | 3488 | unreachable; |
| 3483 | } | 3489 | } |
| 3484 | 3490 |
lib/std/Io/Dispatch.zig+9-8| ... | @@ -580,6 +580,7 @@ pub fn deinit(ev: *Evented) void { | ... | @@ -580,6 +580,7 @@ pub fn deinit(ev: *Evented) void { |
| 580 | ev.stderr_mutex.deinit(); | 580 | ev.stderr_mutex.deinit(); |
| 581 | for (&ev.futexes) |*futex| futex.deinit(); | 581 | for (&ev.futexes) |*futex| futex.deinit(); |
| 582 | ev.exit_semaphore.as_object().release(); | 582 | ev.exit_semaphore.as_object().release(); |
| 583 | ev.backing_allocator_mutex.deinit(); | ||
| 583 | ev.backing_allocator.free(ev.main_loop_stack[0..main_loop_stack_size]); | 584 | ev.backing_allocator.free(ev.main_loop_stack[0..main_loop_stack_size]); |
| 584 | ev.queue.as_object().release(); | 585 | ev.queue.as_object().release(); |
| 585 | } | 586 | } |
| ... | @@ -825,7 +826,7 @@ const Mutex = struct { | ... | @@ -825,7 +826,7 @@ const Mutex = struct { |
| 825 | sleeper: Sleeper = undefined, | 826 | sleeper: Sleeper = undefined, |
| 826 | cancelable: Cancelable, | 827 | cancelable: Cancelable, |
| 827 | mutex: *Mutex, | 828 | mutex: *Mutex, |
| 828 | node: std.DoublyLinkedList.Node = undefined, | 829 | node: std.DoublyLinkedList.Node = .{}, |
| 829 | 830 | ||
| 830 | fn add(context: ?*anyopaque) callconv(.c) void { | 831 | fn add(context: ?*anyopaque) callconv(.c) void { |
| 831 | const waiter: *Waiter = @ptrCast(@alignCast(context)); | 832 | const waiter: *Waiter = @ptrCast(@alignCast(context)); |
| ... | @@ -2781,7 +2782,7 @@ fn realPath(ev: *Evented, fd: c.fd_t, out_buffer: []u8) File.RealPathError!usize | ... | @@ -2781,7 +2782,7 @@ fn realPath(ev: *Evented, fd: c.fd_t, out_buffer: []u8) File.RealPathError!usize |
| 2781 | else => |err| return unexpectedErrno(err), | 2782 | else => |err| return unexpectedErrno(err), |
| 2782 | } | 2783 | } |
| 2783 | } | 2784 | } |
| 2784 | const n = std.mem.indexOfScalar(u8, &buffer, 0) orelse buffer.len; | 2785 | const n = std.mem.findScalar(u8, &buffer, 0) orelse buffer.len; |
| 2785 | if (n > out_buffer.len) return error.NameTooLong; | 2786 | if (n > out_buffer.len) return error.NameTooLong; |
| 2786 | @memcpy(out_buffer[0..n], buffer[0..n]); | 2787 | @memcpy(out_buffer[0..n], buffer[0..n]); |
| 2787 | return n; | 2788 | return n; |
| ... | @@ -2803,7 +2804,7 @@ fn dirRealPathFile( | ... | @@ -2803,7 +2804,7 @@ fn dirRealPathFile( |
| 2803 | while (true) { | 2804 | while (true) { |
| 2804 | if (c.realpath(sub_path_posix, out_buffer.ptr)) |redundant_pointer| { | 2805 | if (c.realpath(sub_path_posix, out_buffer.ptr)) |redundant_pointer| { |
| 2805 | assert(redundant_pointer == out_buffer.ptr); | 2806 | assert(redundant_pointer == out_buffer.ptr); |
| 2806 | return std.mem.indexOfScalar(u8, out_buffer, 0) orelse out_buffer.len; | 2807 | return std.mem.findScalar(u8, out_buffer, 0) orelse out_buffer.len; |
| 2807 | } | 2808 | } |
| 2808 | const err: c.E = @fromBackingInt(@intCast(c._errno().*)); | 2809 | const err: c.E = @fromBackingInt(@intCast(c._errno().*)); |
| 2809 | switch (err) { | 2810 | switch (err) { |
| ... | @@ -3791,7 +3792,7 @@ fn fileRealPath(userdata: ?*anyopaque, file: File, out_buffer: []u8) File.RealPa | ... | @@ -3791,7 +3792,7 @@ fn fileRealPath(userdata: ?*anyopaque, file: File, out_buffer: []u8) File.RealPa |
| 3791 | else => |err| return unexpectedErrno(err), | 3792 | else => |err| return unexpectedErrno(err), |
| 3792 | } | 3793 | } |
| 3793 | } | 3794 | } |
| 3794 | const n = std.mem.indexOfScalar(u8, &buffer, 0) orelse buffer.len; | 3795 | const n = std.mem.findScalar(u8, &buffer, 0) orelse buffer.len; |
| 3795 | if (n > out_buffer.len) return error.NameTooLong; | 3796 | if (n > out_buffer.len) return error.NameTooLong; |
| 3796 | @memcpy(out_buffer[0..n], buffer[0..n]); | 3797 | @memcpy(out_buffer[0..n], buffer[0..n]); |
| 3797 | return n; | 3798 | return n; |
| ... | @@ -3897,7 +3898,7 @@ fn fileMemoryMapDestroy(userdata: ?*anyopaque, mm: *File.MemoryMap) void { | ... | @@ -3897,7 +3898,7 @@ fn fileMemoryMapDestroy(userdata: ?*anyopaque, mm: *File.MemoryMap) void { |
| 3897 | if (memory.len == 0) return; | 3898 | if (memory.len == 0) return; |
| 3898 | switch (c.errno(c.munmap(memory.ptr, memory.len))) { | 3899 | switch (c.errno(c.munmap(memory.ptr, memory.len))) { |
| 3899 | .SUCCESS => {}, | 3900 | .SUCCESS => {}, |
| 3900 | else => |err| if (builtin.mode == .Debug) | 3901 | else => |err| if (builtin.mode == .debug) |
| 3901 | std.log.err("failed to unmap {d} bytes at {*}: {t}", .{ memory.len, memory.ptr, err }), | 3902 | std.log.err("failed to unmap {d} bytes at {*}: {t}", .{ memory.len, memory.ptr, err }), |
| 3902 | } | 3903 | } |
| 3903 | mm.* = undefined; | 3904 | mm.* = undefined; |
| ... | @@ -4714,7 +4715,7 @@ fn sleep(userdata: ?*anyopaque, timeout: Io.Timeout) Io.Cancelable!void { | ... | @@ -4714,7 +4715,7 @@ fn sleep(userdata: ?*anyopaque, timeout: Io.Timeout) Io.Cancelable!void { |
| 4714 | return ev.yield(.{ .after = ev.timeFromTimeout(timeout) }); | 4715 | return ev.yield(.{ .after = ev.timeFromTimeout(timeout) }); |
| 4715 | }; | 4716 | }; |
| 4716 | var waiter: SleepWaiter = .{ | 4717 | var waiter: SleepWaiter = .{ |
| 4717 | .cancelable = .{ .queue = queue, .cancel = &Futex.Waiter.canceled }, | 4718 | .cancelable = .{ .queue = queue, .cancel = &SleepWaiter.canceled }, |
| 4718 | .timer = timer, | 4719 | .timer = timer, |
| 4719 | }; | 4720 | }; |
| 4720 | timer.as_object().set_context(&waiter); | 4721 | timer.as_object().set_context(&waiter); |
| ... | @@ -4911,10 +4912,10 @@ fn netWriteFileUnavailable( | ... | @@ -4911,10 +4912,10 @@ fn netWriteFileUnavailable( |
| 4911 | return error.Unimplemented; | 4912 | return error.Unimplemented; |
| 4912 | } | 4913 | } |
| 4913 | 4914 | ||
| 4914 | fn netClose(userdata: ?*anyopaque, handles: []const net.Socket.Handle) void { | 4915 | fn netClose(userdata: ?*anyopaque, sockets: []const net.Socket) void { |
| 4915 | const ev: *Evented = @ptrCast(@alignCast(userdata)); | 4916 | const ev: *Evented = @ptrCast(@alignCast(userdata)); |
| 4916 | _ = ev; | 4917 | _ = ev; |
| 4917 | for (handles) |handle| closeFd(handle); | 4918 | for (sockets) |socket| closeFd(socket.handle); |
| 4918 | } | 4919 | } |
| 4919 | 4920 | ||
| 4920 | fn netShutdownUnavailable( | 4921 | fn netShutdownUnavailable( |
lib/std/Io/Kqueue.zig+3-2| ... | @@ -1280,10 +1280,10 @@ fn netWrite(userdata: ?*anyopaque, dest: net.Socket.Handle, header: []const u8, | ... | @@ -1280,10 +1280,10 @@ fn netWrite(userdata: ?*anyopaque, dest: net.Socket.Handle, header: []const u8, |
| 1280 | @panic("TODO"); | 1280 | @panic("TODO"); |
| 1281 | } | 1281 | } |
| 1282 | 1282 | ||
| 1283 | fn netClose(userdata: ?*anyopaque, handles: []const net.Socket.Handle) void { | 1283 | fn netClose(userdata: ?*anyopaque, sockets: []const net.Socket) void { |
| 1284 | const k: *Kqueue = @ptrCast(@alignCast(userdata)); | 1284 | const k: *Kqueue = @ptrCast(@alignCast(userdata)); |
| 1285 | _ = k; | 1285 | _ = k; |
| 1286 | _ = handles; | 1286 | _ = sockets; |
| 1287 | @panic("TODO"); | 1287 | @panic("TODO"); |
| 1288 | } | 1288 | } |
| 1289 | 1289 | ||
| ... | @@ -1422,6 +1422,7 @@ fn posixBind( | ... | @@ -1422,6 +1422,7 @@ fn posixBind( |
| 1422 | .INTR => continue, | 1422 | .INTR => continue, |
| 1423 | .CANCELED => return error.Canceled, | 1423 | .CANCELED => return error.Canceled, |
| 1424 | 1424 | ||
| 1425 | .ACCES => return error.AccessDenied, | ||
| 1425 | .ADDRINUSE => return error.AddressInUse, | 1426 | .ADDRINUSE => return error.AddressInUse, |
| 1426 | .BADF => |err| return errnoBug(err), // File descriptor used after closed. | 1427 | .BADF => |err| return errnoBug(err), // File descriptor used after closed. |
| 1427 | .INVAL => |err| return errnoBug(err), // invalid parameters | 1428 | .INVAL => |err| return errnoBug(err), // invalid parameters |
lib/std/Io/Reader.zig+3-5| ... | @@ -718,7 +718,7 @@ pub inline fn readSliceEndian( | ... | @@ -718,7 +718,7 @@ pub inline fn readSliceEndian( |
| 718 | endian: std.builtin.Endian, | 718 | endian: std.builtin.Endian, |
| 719 | ) Error!void { | 719 | ) Error!void { |
| 720 | try readSliceAll(r, @ptrCast(buffer)); | 720 | try readSliceAll(r, @ptrCast(buffer)); |
| 721 | if (native_endian != endian) for (buffer) |*elem| std.mem.byteSwapAllFields(Elem, elem); | 721 | if (native_endian != endian) std.mem.byteSwapAllElements(Elem, buffer); |
| 722 | } | 722 | } |
| 723 | 723 | ||
| 724 | pub const ReadAllocError = Error || Allocator.Error; | 724 | pub const ReadAllocError = Error || Allocator.Error; |
| ... | @@ -734,8 +734,7 @@ pub inline fn readSliceEndianAlloc( | ... | @@ -734,8 +734,7 @@ pub inline fn readSliceEndianAlloc( |
| 734 | ) ReadAllocError![]Elem { | 734 | ) ReadAllocError![]Elem { |
| 735 | const dest = try allocator.alloc(Elem, len); | 735 | const dest = try allocator.alloc(Elem, len); |
| 736 | errdefer allocator.free(dest); | 736 | errdefer allocator.free(dest); |
| 737 | try readSliceAll(r, @ptrCast(dest)); | 737 | try r.readSliceEndian(Elem, dest, endian); |
| 738 | if (native_endian != endian) for (dest) |*elem| std.mem.byteSwapAllFields(Elem, elem); | ||
| 739 | return dest; | 738 | return dest; |
| 740 | } | 739 | } |
| 741 | 740 | ||
| ... | @@ -1227,8 +1226,7 @@ pub inline fn takeStruct(r: *Reader, comptime T: type, endian: std.builtin.Endia | ... | @@ -1227,8 +1226,7 @@ pub inline fn takeStruct(r: *Reader, comptime T: type, endian: std.builtin.Endia |
| 1227 | .auto => @compileError("ill-defined memory layout"), | 1226 | .auto => @compileError("ill-defined memory layout"), |
| 1228 | .@"extern" => { | 1227 | .@"extern" => { |
| 1229 | var res: T = undefined; | 1228 | var res: T = undefined; |
| 1230 | try r.readSliceAll(std.mem.asBytes(&res)); | 1229 | try r.readSliceEndian(T, (&res)[0..1], endian); |
| 1231 | if (native_endian != endian) std.mem.byteSwapAllFields(T, &res); | ||
| 1232 | return res; | 1230 | return res; |
| 1233 | }, | 1231 | }, |
| 1234 | .@"packed" => { | 1232 | .@"packed" => { |
lib/std/Io/RwLock.zig-2| ... | @@ -284,8 +284,6 @@ test "concurrent access" { | ... | @@ -284,8 +284,6 @@ test "concurrent access" { |
| 284 | } | 284 | } |
| 285 | 285 | ||
| 286 | test "lock canceling" { | 286 | test "lock canceling" { |
| 287 | if (builtin.cpu.arch.isSPARC() and builtin.os.tag == .linux) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/35347 | ||
| 288 | |||
| 289 | const io = testing.io; | 287 | const io = testing.io; |
| 290 | 288 | ||
| 291 | var rl: Io.RwLock = .init; | 289 | var rl: Io.RwLock = .init; |
lib/std/Io/Semaphore.zig-2| ... | @@ -4,8 +4,6 @@ | ... | @@ -4,8 +4,6 @@ |
| 4 | //! This API supports static initialization and does not require deinitialization. | 4 | //! This API supports static initialization and does not require deinitialization. |
| 5 | const Semaphore = @This(); | 5 | const Semaphore = @This(); |
| 6 | 6 | ||
| 7 | const builtin = @import("builtin"); | ||
| 8 | |||
| 9 | const std = @import("../std.zig"); | 7 | const std = @import("../std.zig"); |
| 10 | const Io = std.Io; | 8 | const Io = std.Io; |
| 11 | const testing = std.testing; | 9 | const testing = std.testing; |
lib/std/Io/Threaded.zig+156-38| ... | @@ -4,7 +4,7 @@ const builtin = @import("builtin"); | ... | @@ -4,7 +4,7 @@ const builtin = @import("builtin"); |
| 4 | const native_os = builtin.os.tag; | 4 | const native_os = builtin.os.tag; |
| 5 | const is_windows = native_os == .windows; | 5 | const is_windows = native_os == .windows; |
| 6 | const is_darwin = native_os.isDarwin(); | 6 | const is_darwin = native_os.isDarwin(); |
| 7 | const is_debug = builtin.mode == .Debug; | 7 | const is_debug = builtin.mode == .debug; |
| 8 | 8 | ||
| 9 | const std = @import("../std.zig"); | 9 | const std = @import("../std.zig"); |
| 10 | const Io = std.Io; | 10 | const Io = std.Io; |
| ... | @@ -440,12 +440,12 @@ pub const UseFchmodat2 = if (have_fchmodat2 and !have_fchmodat_flags) enum { | ... | @@ -440,12 +440,12 @@ pub const UseFchmodat2 = if (have_fchmodat2 and !have_fchmodat_flags) enum { |
| 440 | pub const apc_align = @max(default_fn_align, 2); | 440 | pub const apc_align = @max(default_fn_align, 2); |
| 441 | 441 | ||
| 442 | const default_fn_align = switch (builtin.mode) { | 442 | const default_fn_align = switch (builtin.mode) { |
| 443 | .Debug, .ReleaseSafe, .ReleaseFast => switch (builtin.cpu.arch) { | 443 | .debug, .safe, .fast => switch (builtin.cpu.arch) { |
| 444 | else => |arch| @compileError("Unsupported architecture: " ++ @tagName(arch)), | 444 | else => |arch| @compileError("Unsupported architecture: " ++ @tagName(arch)), |
| 445 | .arm, .thumb => 4, | 445 | .arm, .thumb => 4, |
| 446 | .aarch64, .x86, .x86_64 => 16, | 446 | .aarch64, .x86, .x86_64 => 16, |
| 447 | }, | 447 | }, |
| 448 | .ReleaseSmall => 1, | 448 | .small => 1, |
| 449 | }; | 449 | }; |
| 450 | 450 | ||
| 451 | const Runnable = struct { | 451 | const Runnable = struct { |
| ... | @@ -829,6 +829,7 @@ const Thread = struct { | ... | @@ -829,6 +829,7 @@ const Thread = struct { |
| 829 | /// Always released when `Status.cancelation` is set to `.parked`. | 829 | /// Always released when `Status.cancelation` is set to `.parked`. |
| 830 | futex_waiter: if (use_parking_futex) ?*parking_futex.Waiter else ?noreturn, | 830 | futex_waiter: if (use_parking_futex) ?*parking_futex.Waiter else ?noreturn, |
| 831 | unpark_flag: UnparkFlag, | 831 | unpark_flag: UnparkFlag, |
| 832 | park_tid: if (ParkTid == std.Thread.Id) void else ParkTid, | ||
| 832 | 833 | ||
| 833 | csprng: Csprng, | 834 | csprng: Csprng, |
| 834 | 835 | ||
| ... | @@ -1220,7 +1221,7 @@ const Thread = struct { | ... | @@ -1220,7 +1221,7 @@ const Thread = struct { |
| 1220 | parking_futex.removeCanceledWaiter(futex_waiter); | 1221 | parking_futex.removeCanceledWaiter(futex_waiter); |
| 1221 | } | 1222 | } |
| 1222 | if (need_unpark_flag) setUnparkFlag(&thread.unpark_flag); | 1223 | if (need_unpark_flag) setUnparkFlag(&thread.unpark_flag); |
| 1223 | unpark(&.{thread.id}, null); | 1224 | unpark(&.{if (ParkTid == std.Thread.Id) thread.id else thread.park_tid}, null); |
| 1224 | return false; | 1225 | return false; |
| 1225 | }, | 1226 | }, |
| 1226 | 1227 | ||
| ... | @@ -1749,6 +1750,7 @@ fn worker(t: *Threaded) void { | ... | @@ -1749,6 +1750,7 @@ fn worker(t: *Threaded) void { |
| 1749 | .cancel_protection = .unblocked, | 1750 | .cancel_protection = .unblocked, |
| 1750 | .futex_waiter = undefined, | 1751 | .futex_waiter = undefined, |
| 1751 | .unpark_flag = unpark_flag_init, | 1752 | .unpark_flag = unpark_flag_init, |
| 1753 | .park_tid = if (ParkTid == std.Thread.Id) {} else getParkTid(), | ||
| 1752 | .csprng = .uninitialized, | 1754 | .csprng = .uninitialized, |
| 1753 | }; | 1755 | }; |
| 1754 | Thread.current = &thread; | 1756 | Thread.current = &thread; |
| ... | @@ -3858,7 +3860,26 @@ fn fileLength(userdata: ?*anyopaque, file: File) File.LengthError!u64 { | ... | @@ -3858,7 +3860,26 @@ fn fileLength(userdata: ?*anyopaque, file: File) File.LengthError!u64 { |
| 3858 | } | 3860 | } |
| 3859 | } | 3861 | } |
| 3860 | } else if (is_windows) { | 3862 | } else if (is_windows) { |
| 3861 | // TODO call NtQueryInformationFile and ask for only the size instead of "all" | 3863 | var io_status_block: windows.IO_STATUS_BLOCK = undefined; |
| 3864 | var info: windows.FILE.STANDARD_INFORMATION = undefined; | ||
| 3865 | const syscall: Syscall = try .start(); | ||
| 3866 | while (true) switch (windows.ntdll.NtQueryInformationFile( | ||
| 3867 | file.handle, | ||
| 3868 | &io_status_block, | ||
| 3869 | &info, | ||
| 3870 | @sizeOf(windows.FILE.STANDARD_INFORMATION), | ||
| 3871 | .Standard, | ||
| 3872 | )) { | ||
| 3873 | .SUCCESS => break syscall.finish(), | ||
| 3874 | .INVALID_PARAMETER => |err| return syscall.ntstatusBug(err), | ||
| 3875 | .ACCESS_DENIED => return syscall.fail(error.AccessDenied), | ||
| 3876 | .CANCELLED => { | ||
| 3877 | try syscall.checkCancel(); | ||
| 3878 | continue; | ||
| 3879 | }, | ||
| 3880 | else => |s| return syscall.unexpectedNtstatus(s), | ||
| 3881 | }; | ||
| 3882 | return @as(u64, @bitCast(info.EndOfFile)); | ||
| 3862 | } | 3883 | } |
| 3863 | 3884 | ||
| 3864 | const stat = try fileStat(t, file); | 3885 | const stat = try fileStat(t, file); |
| ... | @@ -4382,7 +4403,7 @@ fn dirCreateFilePosix( | ... | @@ -4382,7 +4403,7 @@ fn dirCreateFilePosix( |
| 4382 | } | 4403 | } |
| 4383 | }; | 4404 | }; |
| 4384 | 4405 | ||
| 4385 | fl_flags |= @as(usize, 1 << @bitOffsetOf(posix.O, "NONBLOCK")); | 4406 | fl_flags &= ~@as(usize, 1 << @bitOffsetOf(posix.O, "NONBLOCK")); |
| 4386 | 4407 | ||
| 4387 | const syscall: Syscall = try .start(); | 4408 | const syscall: Syscall = try .start(); |
| 4388 | while (true) { | 4409 | while (true) { |
| ... | @@ -4978,7 +4999,7 @@ fn dirOpenFilePosix( | ... | @@ -4978,7 +4999,7 @@ fn dirOpenFilePosix( |
| 4978 | } | 4999 | } |
| 4979 | }; | 5000 | }; |
| 4980 | 5001 | ||
| 4981 | fl_flags |= @as(usize, 1 << @bitOffsetOf(posix.O, "NONBLOCK")); | 5002 | fl_flags &= ~@as(usize, 1 << @bitOffsetOf(posix.O, "NONBLOCK")); |
| 4982 | 5003 | ||
| 4983 | const syscall: Syscall = try .start(); | 5004 | const syscall: Syscall = try .start(); |
| 4984 | while (true) { | 5005 | while (true) { |
| ... | @@ -5053,7 +5074,7 @@ pub fn dirOpenFileWtf16( | ... | @@ -5053,7 +5074,7 @@ pub fn dirOpenFileWtf16( |
| 5053 | .VALID_FLAGS, | 5074 | .VALID_FLAGS, |
| 5054 | .OPEN, | 5075 | .OPEN, |
| 5055 | .{ | 5076 | .{ |
| 5056 | .IO = if (flags.follow_symlinks) .SYNCHRONOUS_NONALERT else .ASYNCHRONOUS, | 5077 | .IO = .SYNCHRONOUS_NONALERT, |
| 5057 | .NON_DIRECTORY_FILE = !allow_directory, | 5078 | .NON_DIRECTORY_FILE = !allow_directory, |
| 5058 | .OPEN_REPARSE_POINT = !flags.follow_symlinks, | 5079 | .OPEN_REPARSE_POINT = !flags.follow_symlinks, |
| 5059 | }, | 5080 | }, |
| ... | @@ -6817,7 +6838,7 @@ fn dirRealPathFilePosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, o | ... | @@ -6817,7 +6838,7 @@ fn dirRealPathFilePosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, o |
| 6817 | if (std.c.realpath(sub_path_posix, out_buffer.ptr)) |redundant_pointer| { | 6838 | if (std.c.realpath(sub_path_posix, out_buffer.ptr)) |redundant_pointer| { |
| 6818 | syscall.finish(); | 6839 | syscall.finish(); |
| 6819 | assert(redundant_pointer == out_buffer.ptr); | 6840 | assert(redundant_pointer == out_buffer.ptr); |
| 6820 | return std.mem.indexOfScalar(u8, out_buffer, 0) orelse out_buffer.len; | 6841 | return std.mem.findScalar(u8, out_buffer, 0) orelse out_buffer.len; |
| 6821 | } | 6842 | } |
| 6822 | const err: posix.E = @fromBackingInt(@intCast(std.c._errno().*)); | 6843 | const err: posix.E = @fromBackingInt(@intCast(std.c._errno().*)); |
| 6823 | if (err == .INTR) { | 6844 | if (err == .INTR) { |
| ... | @@ -6961,7 +6982,7 @@ fn realPathPosix(fd: posix.fd_t, out_buffer: []u8) File.RealPathError!usize { | ... | @@ -6961,7 +6982,7 @@ fn realPathPosix(fd: posix.fd_t, out_buffer: []u8) File.RealPathError!usize { |
| 6961 | }, | 6982 | }, |
| 6962 | } | 6983 | } |
| 6963 | } | 6984 | } |
| 6964 | const n = std.mem.indexOfScalar(u8, &sufficient_buffer, 0) orelse sufficient_buffer.len; | 6985 | const n = std.mem.findScalar(u8, &sufficient_buffer, 0) orelse sufficient_buffer.len; |
| 6965 | if (n > out_buffer.len) return error.NameTooLong; | 6986 | if (n > out_buffer.len) return error.NameTooLong; |
| 6966 | @memcpy(out_buffer[0..n], sufficient_buffer[0..n]); | 6987 | @memcpy(out_buffer[0..n], sufficient_buffer[0..n]); |
| 6967 | return n; | 6988 | return n; |
| ... | @@ -7119,9 +7140,10 @@ fn dirDeleteFileWasi(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8) Dir. | ... | @@ -7119,9 +7140,10 @@ fn dirDeleteFileWasi(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8) Dir. |
| 7119 | if (builtin.link_libc) return dirDeleteFilePosix(userdata, dir, sub_path); | 7140 | if (builtin.link_libc) return dirDeleteFilePosix(userdata, dir, sub_path); |
| 7120 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | 7141 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 7121 | _ = t; | 7142 | _ = t; |
| 7143 | const wasi = std.os.wasi; | ||
| 7122 | const syscall: Syscall = try .start(); | 7144 | const syscall: Syscall = try .start(); |
| 7123 | while (true) { | 7145 | while (true) { |
| 7124 | const res = std.os.wasi.path_unlink_file(dir.handle, sub_path.ptr, sub_path.len); | 7146 | const res = wasi.path_unlink_file(dir.handle, sub_path.ptr, sub_path.len); |
| 7125 | switch (res) { | 7147 | switch (res) { |
| 7126 | .SUCCESS => { | 7148 | .SUCCESS => { |
| 7127 | syscall.finish(); | 7149 | syscall.finish(); |
| ... | @@ -7131,11 +7153,35 @@ fn dirDeleteFileWasi(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8) Dir. | ... | @@ -7131,11 +7153,35 @@ fn dirDeleteFileWasi(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8) Dir. |
| 7131 | try syscall.checkCancel(); | 7153 | try syscall.checkCancel(); |
| 7132 | continue; | 7154 | continue; |
| 7133 | }, | 7155 | }, |
| 7156 | .ACCES, .PERM => |e| { | ||
| 7157 | const original_error: Dir.DeleteFileError = switch (e) { | ||
| 7158 | .ACCES => error.AccessDenied, | ||
| 7159 | .PERM => error.PermissionDenied, | ||
| 7160 | else => unreachable, | ||
| 7161 | }; | ||
| 7162 | var stat: wasi.filestat_t = undefined; | ||
| 7163 | while (true) { | ||
| 7164 | try syscall.checkCancel(); | ||
| 7165 | switch (wasi.path_filestat_get(dir.handle, .{}, sub_path.ptr, sub_path.len, &stat)) { | ||
| 7166 | .SUCCESS => { | ||
| 7167 | syscall.finish(); | ||
| 7168 | break; | ||
| 7169 | }, | ||
| 7170 | .INTR => continue, | ||
| 7171 | else => { | ||
| 7172 | syscall.finish(); | ||
| 7173 | return original_error; | ||
| 7174 | }, | ||
| 7175 | } | ||
| 7176 | } | ||
| 7177 | if (stat.filetype == .DIRECTORY) | ||
| 7178 | return error.IsDir | ||
| 7179 | else | ||
| 7180 | return original_error; | ||
| 7181 | }, | ||
| 7134 | else => |e| { | 7182 | else => |e| { |
| 7135 | syscall.finish(); | 7183 | syscall.finish(); |
| 7136 | switch (e) { | 7184 | switch (e) { |
| 7137 | .ACCES => return error.AccessDenied, | ||
| 7138 | .PERM => return error.PermissionDenied, | ||
| 7139 | .BUSY => return error.FileBusy, | 7185 | .BUSY => return error.FileBusy, |
| 7140 | .FAULT => |err| return errnoBug(err), | 7186 | .FAULT => |err| return errnoBug(err), |
| 7141 | .IO => return error.FileSystem, | 7187 | .IO => return error.FileSystem, |
| ... | @@ -8111,7 +8157,7 @@ fn dirReadLinkWindows(dir: Dir, sub_path: []const u8, buffer: []u8) Dir.ReadLink | ... | @@ -8111,7 +8157,7 @@ fn dirReadLinkWindows(dir: Dir, sub_path: []const u8, buffer: []u8) Dir.ReadLink |
| 8111 | .{ | 8157 | .{ |
| 8112 | .DIRECTORY_FILE = false, | 8158 | .DIRECTORY_FILE = false, |
| 8113 | .NON_DIRECTORY_FILE = false, | 8159 | .NON_DIRECTORY_FILE = false, |
| 8114 | .IO = .ASYNCHRONOUS, | 8160 | .IO = .SYNCHRONOUS_NONALERT, |
| 8115 | .OPEN_REPARSE_POINT = true, | 8161 | .OPEN_REPARSE_POINT = true, |
| 8116 | }, | 8162 | }, |
| 8117 | null, | 8163 | null, |
| ... | @@ -8177,7 +8223,7 @@ fn dirReadLinkWindows(dir: Dir, sub_path: []const u8, buffer: []u8) Dir.ReadLink | ... | @@ -8177,7 +8223,7 @@ fn dirReadLinkWindows(dir: Dir, sub_path: []const u8, buffer: []u8) Dir.ReadLink |
| 8177 | 8223 | ||
| 8178 | var reparse_buf: [windows.MAXIMUM_REPARSE_DATA_BUFFER_SIZE]u8 align(@alignOf(windows.REPARSE_DATA_BUFFER)) = undefined; | 8224 | var reparse_buf: [windows.MAXIMUM_REPARSE_DATA_BUFFER_SIZE]u8 align(@alignOf(windows.REPARSE_DATA_BUFFER)) = undefined; |
| 8179 | switch ((try deviceIoControl(&.{ | 8225 | switch ((try deviceIoControl(&.{ |
| 8180 | .file = .{ .handle = result_handle, .flags = .{ .nonblocking = true } }, | 8226 | .file = .{ .handle = result_handle, .flags = .{ .nonblocking = false } }, |
| 8181 | .code = .GET_REPARSE_POINT, | 8227 | .code = .GET_REPARSE_POINT, |
| 8182 | .out = &reparse_buf, | 8228 | .out = &reparse_buf, |
| 8183 | })).u.Status) { | 8229 | })).u.Status) { |
| ... | @@ -8955,7 +9001,7 @@ fn isCygwinPty(file: File) Io.Cancelable!bool { | ... | @@ -8955,7 +9001,7 @@ fn isCygwinPty(file: File) Io.Cancelable!bool { |
| 8955 | // The name we get from NtQueryInformationFile will be prefixed with a '\', e.g. \msys-1888ae32e00d56aa-pty0-to-master | 9001 | // The name we get from NtQueryInformationFile will be prefixed with a '\', e.g. \msys-1888ae32e00d56aa-pty0-to-master |
| 8956 | return (std.mem.startsWith(u16, name_wide, &[_]u16{ '\\', 'm', 's', 'y', 's', '-' }) or | 9002 | return (std.mem.startsWith(u16, name_wide, &[_]u16{ '\\', 'm', 's', 'y', 's', '-' }) or |
| 8957 | std.mem.startsWith(u16, name_wide, &[_]u16{ '\\', 'c', 'y', 'g', 'w', 'i', 'n', '-' })) and | 9003 | std.mem.startsWith(u16, name_wide, &[_]u16{ '\\', 'c', 'y', 'g', 'w', 'i', 'n', '-' })) and |
| 8958 | std.mem.indexOf(u16, name_wide, &[_]u16{ '-', 'p', 't', 'y' }) != null; | 9004 | std.mem.find(u16, name_wide, &[_]u16{ '-', 'p', 't', 'y' }) != null; |
| 8959 | } | 9005 | } |
| 8960 | 9006 | ||
| 8961 | fn fileSetLength(userdata: ?*anyopaque, file: File, length: u64) File.SetLengthError!void { | 9007 | fn fileSetLength(userdata: ?*anyopaque, file: File, length: u64) File.SetLengthError!void { |
| ... | @@ -11184,7 +11230,10 @@ fn fileWriteFileStreaming( | ... | @@ -11184,7 +11230,10 @@ fn fileWriteFileStreaming( |
| 11184 | var off: std.os.linux.off_t = undefined; | 11230 | var off: std.os.linux.off_t = undefined; |
| 11185 | const off_ptr: ?*std.os.linux.off_t, const count: usize = switch (file_reader.mode) { | 11231 | const off_ptr: ?*std.os.linux.off_t, const count: usize = switch (file_reader.mode) { |
| 11186 | .positional => o: { | 11232 | .positional => o: { |
| 11187 | const size = file_reader.getSize() catch return 0; | 11233 | const size = file_reader.getSize() catch |err| switch (err) { |
| 11234 | error.Canceled => |e| return e, | ||
| 11235 | else => break :sf, | ||
| 11236 | }; | ||
| 11188 | off = std.math.cast(std.os.linux.off_t, file_reader.pos) orelse return error.ReadFailed; | 11237 | off = std.math.cast(std.os.linux.off_t, file_reader.pos) orelse return error.ReadFailed; |
| 11189 | break :o .{ &off, @min(@backingInt(limit), size - file_reader.pos, max_count) }; | 11238 | break :o .{ &off, @min(@backingInt(limit), size - file_reader.pos, max_count) }; |
| 11190 | }, | 11239 | }, |
| ... | @@ -11533,7 +11582,10 @@ fn fileWriteFilePositional( | ... | @@ -11533,7 +11582,10 @@ fn fileWriteFilePositional( |
| 11533 | if (file_reader.pos != 0) break :fcf; | 11582 | if (file_reader.pos != 0) break :fcf; |
| 11534 | if (offset != 0) break :fcf; | 11583 | if (offset != 0) break :fcf; |
| 11535 | if (limit != .unlimited) break :fcf; | 11584 | if (limit != .unlimited) break :fcf; |
| 11536 | const size = file_reader.getSize() catch break :fcf; | 11585 | const size = file_reader.getSize() catch |err| switch (err) { |
| 11586 | error.Canceled => |e| return e, | ||
| 11587 | else => break :fcf, | ||
| 11588 | }; | ||
| 11537 | if (header.len != 0 or reader_buffered.len != 0) { | 11589 | if (header.len != 0 or reader_buffered.len != 0) { |
| 11538 | const n = try fileWritePositional(t, file, header, &.{limit.slice(reader_buffered)}, 1, offset); | 11590 | const n = try fileWritePositional(t, file, header, &.{limit.slice(reader_buffered)}, 1, offset); |
| 11539 | file_reader.interface.toss(n -| header.len); | 11591 | file_reader.interface.toss(n -| header.len); |
| ... | @@ -11725,7 +11777,6 @@ fn nowWasi(clock: Io.Clock) Io.Timestamp { | ... | @@ -11725,7 +11777,6 @@ fn nowWasi(clock: Io.Clock) Io.Timestamp { |
| 11725 | 11777 | ||
| 11726 | fn sleep(userdata: ?*anyopaque, timeout: Io.Timeout) Io.Cancelable!void { | 11778 | fn sleep(userdata: ?*anyopaque, timeout: Io.Timeout) Io.Cancelable!void { |
| 11727 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | 11779 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 11728 | if (timeout == .none) return; | ||
| 11729 | if (use_parking_sleep) return parking_sleep.sleep(timeout); | 11780 | if (use_parking_sleep) return parking_sleep.sleep(timeout); |
| 11730 | if (native_os == .wasi) return sleepWasi(t, timeout); | 11781 | if (native_os == .wasi) return sleepWasi(t, timeout); |
| 11731 | if (@TypeOf(posix.system.clock_nanosleep) != void) return sleepPosix(timeout); | 11782 | if (@TypeOf(posix.system.clock_nanosleep) != void) return sleepPosix(timeout); |
| ... | @@ -12042,6 +12093,7 @@ fn posixBind( | ... | @@ -12042,6 +12093,7 @@ fn posixBind( |
| 12042 | else => |e| { | 12093 | else => |e| { |
| 12043 | syscall.finish(); | 12094 | syscall.finish(); |
| 12044 | switch (e) { | 12095 | switch (e) { |
| 12096 | .ACCES => return error.AccessDenied, | ||
| 12045 | .ADDRINUSE => return error.AddressInUse, | 12097 | .ADDRINUSE => return error.AddressInUse, |
| 12046 | .BADF => |err| return errnoBug(err), // File descriptor used after closed. | 12098 | .BADF => |err| return errnoBug(err), // File descriptor used after closed. |
| 12047 | .INVAL => |err| return errnoBug(err), // invalid parameters | 12099 | .INVAL => |err| return errnoBug(err), // invalid parameters |
| ... | @@ -12124,6 +12176,7 @@ fn posixConnectUnix( | ... | @@ -12124,6 +12176,7 @@ fn posixConnectUnix( |
| 12124 | .NOTDIR => return error.NotDir, | 12176 | .NOTDIR => return error.NotDir, |
| 12125 | .ROFS => return error.ReadOnlyFileSystem, | 12177 | .ROFS => return error.ReadOnlyFileSystem, |
| 12126 | .PERM => return error.PermissionDenied, | 12178 | .PERM => return error.PermissionDenied, |
| 12179 | .CONNREFUSED => return error.ConnectionRefused, | ||
| 12127 | 12180 | ||
| 12128 | .BADF => |err| return errnoBug(err), // File descriptor used after closed. | 12181 | .BADF => |err| return errnoBug(err), // File descriptor used after closed. |
| 12129 | .CONNABORTED => |err| return errnoBug(err), | 12182 | .CONNABORTED => |err| return errnoBug(err), |
| ... | @@ -13362,13 +13415,13 @@ fn addBuf(v: []posix.iovec_const, i: *iovlen_t, bytes: []const u8) void { | ... | @@ -13362,13 +13415,13 @@ fn addBuf(v: []posix.iovec_const, i: *iovlen_t, bytes: []const u8) void { |
| 13362 | i.* += 1; | 13415 | i.* += 1; |
| 13363 | } | 13416 | } |
| 13364 | 13417 | ||
| 13365 | fn netClose(userdata: ?*anyopaque, handles: []const net.Socket.Handle) void { | 13418 | fn netClose(userdata: ?*anyopaque, sockets: []const net.Socket) void { |
| 13366 | if (!have_networking) unreachable; | 13419 | if (!have_networking) unreachable; |
| 13367 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | 13420 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 13368 | _ = t; | 13421 | _ = t; |
| 13369 | for (handles) |handle| switch (native_os) { | 13422 | for (sockets) |socket| switch (native_os) { |
| 13370 | .windows => windows.CloseHandle(handle), | 13423 | .windows => windows.CloseHandle(socket.handle), |
| 13371 | else => closeFd(handle), | 13424 | else => closeFd(socket.handle), |
| 13372 | }; | 13425 | }; |
| 13373 | } | 13426 | } |
| 13374 | 13427 | ||
| ... | @@ -13870,9 +13923,14 @@ fn netLookupFallible( | ... | @@ -13870,9 +13923,14 @@ fn netLookupFallible( |
| 13870 | var port_buffer: [8]u8 = undefined; | 13923 | var port_buffer: [8]u8 = undefined; |
| 13871 | const port_c = std.fmt.bufPrintSentinel(&port_buffer, "{d}", .{options.port}, 0) catch unreachable; | 13924 | const port_c = std.fmt.bufPrintSentinel(&port_buffer, "{d}", .{options.port}, 0) catch unreachable; |
| 13872 | 13925 | ||
| 13926 | const family: i32 = if (options.family) |f| switch (f) { | ||
| 13927 | .ip4 => posix.AF.INET, | ||
| 13928 | .ip6 => posix.AF.INET6, | ||
| 13929 | } else posix.AF.UNSPEC; | ||
| 13930 | |||
| 13873 | const hints: posix.addrinfo = .{ | 13931 | const hints: posix.addrinfo = .{ |
| 13874 | .flags = .{ .CANONNAME = options.canonical_name_buffer != null, .NUMERICSERV = true }, | 13932 | .flags = .{ .CANONNAME = options.canonical_name_buffer != null, .NUMERICSERV = true }, |
| 13875 | .family = posix.AF.UNSPEC, | 13933 | .family = family, |
| 13876 | .socktype = posix.SOCK.STREAM, | 13934 | .socktype = posix.SOCK.STREAM, |
| 13877 | .protocol = posix.IPPROTO.TCP, | 13935 | .protocol = posix.IPPROTO.TCP, |
| 13878 | .canonname = null, | 13936 | .canonname = null, |
| ... | @@ -15302,8 +15360,7 @@ fn childKillWindows(t: *Threaded, child: *process.Child, exit_code: windows.UINT | ... | @@ -15302,8 +15360,7 @@ fn childKillWindows(t: *Threaded, child: *process.Child, exit_code: windows.UINT |
| 15302 | _ = windows.ntdll.RtlReportSilentProcessExit(handle, @fromBackingInt(@intCast(exit_code))); | 15360 | _ = windows.ntdll.RtlReportSilentProcessExit(handle, @fromBackingInt(@intCast(exit_code))); |
| 15303 | switch (windows.ntdll.NtTerminateProcess(handle, @fromBackingInt(@intCast(exit_code)))) { | 15361 | switch (windows.ntdll.NtTerminateProcess(handle, @fromBackingInt(@intCast(exit_code)))) { |
| 15304 | .SUCCESS, .PROCESS_IS_TERMINATING => { | 15362 | .SUCCESS, .PROCESS_IS_TERMINATING => { |
| 15305 | const infinite_timeout: windows.LARGE_INTEGER = std.math.minInt(windows.LARGE_INTEGER); | 15363 | _ = windows.ntdll.NtWaitForSingleObject(handle, .FALSE, null); |
| 15306 | _ = windows.ntdll.NtWaitForSingleObject(handle, .FALSE, &infinite_timeout); | ||
| 15307 | childCleanupWindows(child); | 15364 | childCleanupWindows(child); |
| 15308 | }, | 15365 | }, |
| 15309 | .ACCESS_DENIED => { | 15366 | .ACCESS_DENIED => { |
| ... | @@ -15326,8 +15383,7 @@ fn childWaitWindows(child: *process.Child) process.Child.WaitError!process.Child | ... | @@ -15326,8 +15383,7 @@ fn childWaitWindows(child: *process.Child) process.Child.WaitError!process.Child |
| 15326 | const handle = child.id.?; | 15383 | const handle = child.id.?; |
| 15327 | 15384 | ||
| 15328 | const alertable_syscall: AlertableSyscall = try .start(); | 15385 | const alertable_syscall: AlertableSyscall = try .start(); |
| 15329 | const infinite_timeout: windows.LARGE_INTEGER = std.math.minInt(windows.LARGE_INTEGER); | 15386 | while (true) switch (windows.ntdll.NtWaitForSingleObject(handle, .TRUE, null)) { |
| 15330 | while (true) switch (windows.ntdll.NtWaitForSingleObject(handle, .TRUE, &infinite_timeout)) { | ||
| 15331 | windows.NTSTATUS.WAIT_0 => break alertable_syscall.finish(), | 15387 | windows.NTSTATUS.WAIT_0 => break alertable_syscall.finish(), |
| 15332 | .USER_APC, .ALERTED, .TIMEOUT => { | 15388 | .USER_APC, .ALERTED, .TIMEOUT => { |
| 15333 | try alertable_syscall.checkCancel(); | 15389 | try alertable_syscall.checkCancel(); |
| ... | @@ -16272,7 +16328,7 @@ fn windowsCreateProcessPathExt( | ... | @@ -16272,7 +16328,7 @@ fn windowsCreateProcessPathExt( |
| 16272 | 16328 | ||
| 16273 | const is_bat_or_cmd = bat_or_cmd: { | 16329 | const is_bat_or_cmd = bat_or_cmd: { |
| 16274 | const app_name = app_buf.items[0..app_name_len]; | 16330 | const app_name = app_buf.items[0..app_name_len]; |
| 16275 | const ext_start = std.mem.lastIndexOfScalar(u16, app_name, '.') orelse break :bat_or_cmd false; | 16331 | const ext_start = std.mem.findScalarLast(u16, app_name, '.') orelse break :bat_or_cmd false; |
| 16276 | const ext = app_name[ext_start..]; | 16332 | const ext = app_name[ext_start..]; |
| 16277 | const ext_enum = windowsCreateProcessSupportsExtension(ext) orelse break :bat_or_cmd false; | 16333 | const ext_enum = windowsCreateProcessSupportsExtension(ext) orelse break :bat_or_cmd false; |
| 16278 | switch (ext_enum) { | 16334 | switch (ext_enum) { |
| ... | @@ -16308,7 +16364,7 @@ fn windowsCreateProcessPathExt( | ... | @@ -16308,7 +16364,7 @@ fn windowsCreateProcessPathExt( |
| 16308 | // it's treated as an unrecoverable error. Otherwise, it'll be | 16364 | // it's treated as an unrecoverable error. Otherwise, it'll be |
| 16309 | // skipped as normal. | 16365 | // skipped as normal. |
| 16310 | const app_name = app_buf.items[0..app_name_len]; | 16366 | const app_name = app_buf.items[0..app_name_len]; |
| 16311 | const ext_start = std.mem.lastIndexOfScalar(u16, app_name, '.') orelse break :unappended err; | 16367 | const ext_start = std.mem.findScalarLast(u16, app_name, '.') orelse break :unappended err; |
| 16312 | const ext = app_name[ext_start..]; | 16368 | const ext = app_name[ext_start..]; |
| 16313 | if (windows.eqlIgnoreCaseWtf16(ext, std.unicode.utf8ToUtf16LeStringLiteral(".EXE"))) { | 16369 | if (windows.eqlIgnoreCaseWtf16(ext, std.unicode.utf8ToUtf16LeStringLiteral(".EXE"))) { |
| 16314 | return error.UnrecoverableInvalidExe; | 16370 | return error.UnrecoverableInvalidExe; |
| ... | @@ -17387,6 +17443,7 @@ const use_parking_futex = switch (native_os) { | ... | @@ -17387,6 +17443,7 @@ const use_parking_futex = switch (native_os) { |
| 17387 | .windows => true, // RtlWaitOnAddress is a userland implementation anyway | 17443 | .windows => true, // RtlWaitOnAddress is a userland implementation anyway |
| 17388 | .netbsd => true, // NetBSD has `futex(2)`, but it's historically been quite buggy. TODO: evaluate whether it's okay to use now. | 17444 | .netbsd => true, // NetBSD has `futex(2)`, but it's historically been quite buggy. TODO: evaluate whether it's okay to use now. |
| 17389 | .illumos => true, // Illumos has no futex mechanism | 17445 | .illumos => true, // Illumos has no futex mechanism |
| 17446 | .haiku => true, // Haiku has no futex mechanism | ||
| 17390 | else => false, | 17447 | else => false, |
| 17391 | }; | 17448 | }; |
| 17392 | const use_parking_sleep = switch (native_os) { | 17449 | const use_parking_sleep = switch (native_os) { |
| ... | @@ -17432,7 +17489,7 @@ const parking_futex = struct { | ... | @@ -17432,7 +17489,7 @@ const parking_futex = struct { |
| 17432 | const Waiter = struct { | 17489 | const Waiter = struct { |
| 17433 | node: std.DoublyLinkedList.Node, | 17490 | node: std.DoublyLinkedList.Node, |
| 17434 | address: usize, | 17491 | address: usize, |
| 17435 | tid: std.Thread.Id, | 17492 | tid: ParkTid, |
| 17436 | /// `thread_status.cancelation` is `.parked` while the thread is waiting. The single thread | 17493 | /// `thread_status.cancelation` is `.parked` while the thread is waiting. The single thread |
| 17437 | /// which atomically updates it (to `.none` or `.canceling`) is responsible for: | 17494 | /// which atomically updates it (to `.none` or `.canceling`) is responsible for: |
| 17438 | /// | 17495 | /// |
| ... | @@ -17473,7 +17530,7 @@ const parking_futex = struct { | ... | @@ -17473,7 +17530,7 @@ const parking_futex = struct { |
| 17473 | 17530 | ||
| 17474 | // Put the threadlocal access outside of the critical section. | 17531 | // Put the threadlocal access outside of the critical section. |
| 17475 | const opt_thread = Thread.current; | 17532 | const opt_thread = Thread.current; |
| 17476 | const self_tid = if (opt_thread) |thread| thread.id else std.Thread.getCurrentId(); | 17533 | const self_tid = getParkTid(); |
| 17477 | 17534 | ||
| 17478 | var waiter: Waiter = .{ | 17535 | var waiter: Waiter = .{ |
| 17479 | .node = undefined, // populated by list append | 17536 | .node = undefined, // populated by list append |
| ... | @@ -17721,7 +17778,12 @@ const parking_sleep = struct { | ... | @@ -17721,7 +17778,12 @@ const parking_sleep = struct { |
| 17721 | }, | 17778 | }, |
| 17722 | } | 17779 | } |
| 17723 | } | 17780 | } |
| 17781 | |||
| 17724 | // Uncancelable sleep; we expect not to be manually unparked. | 17782 | // Uncancelable sleep; we expect not to be manually unparked. |
| 17783 | |||
| 17784 | // On systems where parking the thread requires a one-time setup operation (e.g. creating a | ||
| 17785 | // semaphore), we need to ensure that setup is done before we call `park`. | ||
| 17786 | _ = getParkTid(); | ||
| 17725 | var dummy_flag: UnparkFlag = unpark_flag_init; | 17787 | var dummy_flag: UnparkFlag = unpark_flag_init; |
| 17726 | if (park(timeout, null, if (need_unpark_flag) &dummy_flag)) { | 17788 | if (park(timeout, null, if (need_unpark_flag) &dummy_flag)) { |
| 17727 | unreachable; // unexpected unpark | 17789 | unreachable; // unexpected unpark |
| ... | @@ -17760,7 +17822,7 @@ const ParkingMutex = struct { | ... | @@ -17760,7 +17822,7 @@ const ParkingMutex = struct { |
| 17760 | /// Never modified once the `Waiter` is in the linked list. | 17822 | /// Never modified once the `Waiter` is in the linked list. |
| 17761 | next: ?*Waiter, | 17823 | next: ?*Waiter, |
| 17762 | /// Never modified once the `Waiter` is in the linked list. | 17824 | /// Never modified once the `Waiter` is in the linked list. |
| 17763 | tid: std.Thread.Id, | 17825 | tid: ParkTid, |
| 17764 | }; | 17826 | }; |
| 17765 | fn lock(m: *ParkingMutex) void { | 17827 | fn lock(m: *ParkingMutex) void { |
| 17766 | state: switch (State.unlocked) { // assume 'unlocked' to optimize for uncontended case | 17828 | state: switch (State.unlocked) { // assume 'unlocked' to optimize for uncontended case |
| ... | @@ -17776,7 +17838,7 @@ const ParkingMutex = struct { | ... | @@ -17776,7 +17838,7 @@ const ParkingMutex = struct { |
| 17776 | 17838 | ||
| 17777 | .locked_once, _ => |last_state| { | 17839 | .locked_once, _ => |last_state| { |
| 17778 | const old_waiter = last_state.waiter(); | 17840 | const old_waiter = last_state.waiter(); |
| 17779 | const self_tid = if (Thread.current) |t| t.id else std.Thread.getCurrentId(); | 17841 | const self_tid = getParkTid(); |
| 17780 | var waiter: Waiter = .{ | 17842 | var waiter: Waiter = .{ |
| 17781 | .next = old_waiter, | 17843 | .next = old_waiter, |
| 17782 | .unpark_flag = unpark_flag_init, | 17844 | .unpark_flag = unpark_flag_init, |
| ... | @@ -17904,9 +17966,36 @@ fn setUnparkFlag(f: *UnparkFlag) void { | ... | @@ -17904,9 +17966,36 @@ fn setUnparkFlag(f: *UnparkFlag) void { |
| 17904 | /// but it seems that someone at Microsoft forgot how big their TIDs are supposed to be. | 17966 | /// but it seems that someone at Microsoft forgot how big their TIDs are supposed to be. |
| 17905 | const UnparkTid = switch (native_os) { | 17967 | const UnparkTid = switch (native_os) { |
| 17906 | .windows => usize, | 17968 | .windows => usize, |
| 17969 | else => ParkTid, | ||
| 17970 | }; | ||
| 17971 | |||
| 17972 | const ParkTid = switch (native_os) { | ||
| 17973 | .haiku => std.c.sem_id, | ||
| 17907 | else => std.Thread.Id, | 17974 | else => std.Thread.Id, |
| 17908 | }; | 17975 | }; |
| 17909 | 17976 | ||
| 17977 | threadlocal var park_sem: std.c.sem_id = -1; | ||
| 17978 | |||
| 17979 | fn getParkTid() ParkTid { | ||
| 17980 | switch (native_os) { | ||
| 17981 | .haiku => { | ||
| 17982 | if (park_sem == -1) { | ||
| 17983 | park_sem = std.c._kern_create_sem(0, null); | ||
| 17984 | if (park_sem < 0) @panic("_kern_create_sem failed"); | ||
| 17985 | _ = std.c.on_exit_thread(destroyParkSem, null); | ||
| 17986 | } | ||
| 17987 | return park_sem; | ||
| 17988 | }, | ||
| 17989 | else => { | ||
| 17990 | return if (Thread.current) |thread| thread.id else std.Thread.getCurrentId(); | ||
| 17991 | }, | ||
| 17992 | } | ||
| 17993 | } | ||
| 17994 | |||
| 17995 | fn destroyParkSem(_: ?*anyopaque) callconv(.c) void { | ||
| 17996 | _ = std.c._kern_delete_sem(park_sem); | ||
| 17997 | } | ||
| 17998 | |||
| 17910 | fn park( | 17999 | fn park( |
| 17911 | timeout: Io.Timeout, | 18000 | timeout: Io.Timeout, |
| 17912 | /// This value has no semantic effect, but may allow the OS to optimize the operation. | 18001 | /// This value has no semantic effect, but may allow the OS to optimize the operation. |
| ... | @@ -17972,6 +18061,27 @@ fn park( | ... | @@ -17972,6 +18061,27 @@ fn park( |
| 17972 | } | 18061 | } |
| 17973 | }, | 18062 | }, |
| 17974 | .illumos => @panic("TODO: illumos lwp_park"), | 18063 | .illumos => @panic("TODO: illumos lwp_park"), |
| 18064 | .haiku => { | ||
| 18065 | const timeout_flags: u32, const timeout_us = switch (timeout) { | ||
| 18066 | .none => .{ 0, 0 }, | ||
| 18067 | .deadline => |deadline| .{ | ||
| 18068 | if (deadline.clock == .real) std.c.B_ABSOLUTE_TIMEOUT | std.c.B_TIMEOUT_REAL_TIME_BASE else std.c.B_ABSOLUTE_TIMEOUT, | ||
| 18069 | deadline.raw.toMicroseconds(), | ||
| 18070 | }, | ||
| 18071 | .duration => |duration| .{ | ||
| 18072 | if (duration.clock == .real) std.c.B_ABSOLUTE_TIMEOUT | std.c.B_TIMEOUT_REAL_TIME_BASE else std.c.B_ABSOLUTE_TIMEOUT, | ||
| 18073 | nowPosix(duration.clock).addDuration(duration.raw).toMicroseconds(), | ||
| 18074 | }, | ||
| 18075 | }; | ||
| 18076 | while (true) { | ||
| 18077 | switch (std.c._kern_acquire_sem_etc(park_sem, 1, timeout_flags, timeout_us)) { | ||
| 18078 | 0 => return, | ||
| 18079 | std.c.E.B_TIMED_OUT => return error.Timeout, | ||
| 18080 | std.c.E.B_INTERRUPTED => {}, | ||
| 18081 | else => unreachable, | ||
| 18082 | } | ||
| 18083 | } | ||
| 18084 | }, | ||
| 17975 | else => comptime unreachable, | 18085 | else => comptime unreachable, |
| 17976 | } | 18086 | } |
| 17977 | } | 18087 | } |
| ... | @@ -18014,6 +18124,14 @@ fn unpark(tids: []const UnparkTid, addr_hint: ?*const anyopaque) void { | ... | @@ -18014,6 +18124,14 @@ fn unpark(tids: []const UnparkTid, addr_hint: ?*const anyopaque) void { |
| 18014 | } | 18124 | } |
| 18015 | }, | 18125 | }, |
| 18016 | .illumos => @panic("TODO: illumos lwp_unpark"), | 18126 | .illumos => @panic("TODO: illumos lwp_unpark"), |
| 18127 | .haiku => { | ||
| 18128 | for (tids) |tid| { | ||
| 18129 | switch (std.c._kern_release_sem_etc(tid, 1, 0)) { | ||
| 18130 | 0 => {}, | ||
| 18131 | else => recoverableOsBugDetected(), | ||
| 18132 | } | ||
| 18133 | } | ||
| 18134 | }, | ||
| 18017 | else => comptime unreachable, | 18135 | else => comptime unreachable, |
| 18018 | } | 18136 | } |
| 18019 | } | 18137 | } |
| ... | @@ -18171,7 +18289,7 @@ fn fileMemoryMapCreate( | ... | @@ -18171,7 +18289,7 @@ fn fileMemoryMapCreate( |
| 18171 | error.Unseekable, error.Canceled, error.AccessDenied => |e| return e, | 18289 | error.Unseekable, error.Canceled, error.AccessDenied => |e| return e, |
| 18172 | error.OperationUnsupported => {}, | 18290 | error.OperationUnsupported => {}, |
| 18173 | else => { | 18291 | else => { |
| 18174 | if (builtin.mode == .Debug) | 18292 | if (builtin.mode == .debug) |
| 18175 | std.log.warn("memory mapping failed with {t}, falling back to file operations", .{err}); | 18293 | std.log.warn("memory mapping failed with {t}, falling back to file operations", .{err}); |
| 18176 | }, | 18294 | }, |
| 18177 | } | 18295 | } |
| ... | @@ -18278,7 +18396,7 @@ fn createFileMap( | ... | @@ -18278,7 +18396,7 @@ fn createFileMap( |
| 18278 | .INVALID_VIEW_SIZE => |status| return windows.statusBug(status), | 18396 | .INVALID_VIEW_SIZE => |status| return windows.statusBug(status), |
| 18279 | else => |status| return windows.unexpectedStatus(status), | 18397 | else => |status| return windows.unexpectedStatus(status), |
| 18280 | } | 18398 | } |
| 18281 | if (builtin.mode == .Debug) { | 18399 | if (builtin.mode == .debug) { |
| 18282 | const page_size = std.heap.pageSize(); | 18400 | const page_size = std.heap.pageSize(); |
| 18283 | const alignment: Alignment = .fromByteUnits(page_size); | 18401 | const alignment: Alignment = .fromByteUnits(page_size); |
| 18284 | assert(contents_len == alignment.forward(len)); | 18402 | assert(contents_len == alignment.forward(len)); |
| ... | @@ -18369,7 +18487,7 @@ fn fileMemoryMapDestroy(userdata: ?*anyopaque, mm: *File.MemoryMap) void { | ... | @@ -18369,7 +18487,7 @@ fn fileMemoryMapDestroy(userdata: ?*anyopaque, mm: *File.MemoryMap) void { |
| 18369 | switch (posix.errno(posix.system.munmap(memory.ptr, memory.len))) { | 18487 | switch (posix.errno(posix.system.munmap(memory.ptr, memory.len))) { |
| 18370 | .SUCCESS => {}, | 18488 | .SUCCESS => {}, |
| 18371 | else => |e| { | 18489 | else => |e| { |
| 18372 | if (builtin.mode == .Debug) | 18490 | if (builtin.mode == .debug) |
| 18373 | std.log.err("failed to unmap {d} bytes at {*}: {t}", .{ memory.len, memory.ptr, e }); | 18491 | std.log.err("failed to unmap {d} bytes at {*}: {t}", .{ memory.len, memory.ptr, e }); |
| 18374 | }, | 18492 | }, |
| 18375 | } | 18493 | } |
| ... | @@ -18969,7 +19087,7 @@ fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!windows | ... | @@ -18969,7 +19087,7 @@ fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!windows |
| 18969 | .{ | 19087 | .{ |
| 18970 | .DIRECTORY_FILE = options.filter == .dir_only, | 19088 | .DIRECTORY_FILE = options.filter == .dir_only, |
| 18971 | .NON_DIRECTORY_FILE = options.filter == .non_directory_only, | 19089 | .NON_DIRECTORY_FILE = options.filter == .non_directory_only, |
| 18972 | .IO = if (options.follow_symlinks) .SYNCHRONOUS_NONALERT else .ASYNCHRONOUS, | 19090 | .IO = .SYNCHRONOUS_NONALERT, |
| 18973 | .OPEN_REPARSE_POINT = !options.follow_symlinks, | 19091 | .OPEN_REPARSE_POINT = !options.follow_symlinks, |
| 18974 | }, | 19092 | }, |
| 18975 | null, | 19093 | null, |
lib/std/Io/Threaded/test.zig-2| ... | @@ -149,8 +149,6 @@ test "async with array return type" { | ... | @@ -149,8 +149,6 @@ test "async with array return type" { |
| 149 | } | 149 | } |
| 150 | 150 | ||
| 151 | test "cancel blocked read from pipe" { | 151 | test "cancel blocked read from pipe" { |
| 152 | if (builtin.cpu.arch.isSPARC() and builtin.os.tag == .linux) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/35347 | ||
| 153 | |||
| 154 | const global = struct { | 152 | const global = struct { |
| 155 | fn readFromPipe(io: Io, pipe: Io.File) !void { | 153 | fn readFromPipe(io: Io, pipe: Io.File) !void { |
| 156 | var buf: [1]u8 = undefined; | 154 | var buf: [1]u8 = undefined; |
lib/std/Io/Uring.zig+14-8| ... | @@ -1135,8 +1135,9 @@ fn mainIdleEntry() callconv(.naked) void { | ... | @@ -1135,8 +1135,9 @@ fn mainIdleEntry() callconv(.naked) void { |
| 1135 | 1135 | ||
| 1136 | fn mainIdle( | 1136 | fn mainIdle( |
| 1137 | ev: *Evented, | 1137 | ev: *Evented, |
| 1138 | message: *const SwitchMessage, | 1138 | contexts: *const Io.fiber.Switch, |
| 1139 | ) callconv(.withStackAlign(.c, @max(@alignOf(Thread), @alignOf(Io.fiber.Context)))) noreturn { | 1139 | ) callconv(.withStackAlign(.c, @max(@alignOf(Thread), @alignOf(Io.fiber.Context)))) noreturn { |
| 1140 | const message: *const SwitchMessage = @fieldParentPtr("contexts", contexts); | ||
| 1140 | message.handle(ev); | 1141 | message.handle(ev); |
| 1141 | ev.idle(&ev.threads.allocated[0]); | 1142 | ev.idle(&ev.threads.allocated[0]); |
| 1142 | ev.yield(@ptrCast(&ev.main_fiber_buffer), .nothing); | 1143 | ev.yield(@ptrCast(&ev.main_fiber_buffer), .nothing); |
| ... | @@ -1414,8 +1415,9 @@ const AsyncClosure = struct { | ... | @@ -1414,8 +1415,9 @@ const AsyncClosure = struct { |
| 1414 | 1415 | ||
| 1415 | fn call( | 1416 | fn call( |
| 1416 | closure: *AsyncClosure, | 1417 | closure: *AsyncClosure, |
| 1417 | message: *const SwitchMessage, | 1418 | contexts: *const Io.fiber.Switch, |
| 1418 | ) callconv(.withStackAlign(.c, @alignOf(AsyncClosure))) noreturn { | 1419 | ) callconv(.withStackAlign(.c, @alignOf(AsyncClosure))) noreturn { |
| 1420 | const message: *const SwitchMessage = @fieldParentPtr("contexts", contexts); | ||
| 1419 | const ev = closure.evented; | 1421 | const ev = closure.evented; |
| 1420 | const fiber = closure.fiber; | 1422 | const fiber = closure.fiber; |
| 1421 | message.handle(ev); | 1423 | message.handle(ev); |
| ... | @@ -1779,8 +1781,9 @@ const Group = struct { | ... | @@ -1779,8 +1781,9 @@ const Group = struct { |
| 1779 | 1781 | ||
| 1780 | fn call( | 1782 | fn call( |
| 1781 | closure: *Group.AsyncClosure, | 1783 | closure: *Group.AsyncClosure, |
| 1782 | message: *const SwitchMessage, | 1784 | contexts: *const Io.fiber.Switch, |
| 1783 | ) callconv(.withStackAlign(.c, @alignOf(Group.AsyncClosure))) noreturn { | 1785 | ) callconv(.withStackAlign(.c, @alignOf(Group.AsyncClosure))) noreturn { |
| 1786 | const message: *const SwitchMessage = @fieldParentPtr("contexts", contexts); | ||
| 1784 | const ev = closure.evented; | 1787 | const ev = closure.evented; |
| 1785 | const fiber = closure.fiber; | 1788 | const fiber = closure.fiber; |
| 1786 | message.handle(ev); | 1789 | message.handle(ev); |
| ... | @@ -3558,7 +3561,7 @@ fn dirHardLink( | ... | @@ -3558,7 +3561,7 @@ fn dirHardLink( |
| 3558 | old_sub_path_posix, | 3561 | old_sub_path_posix, |
| 3559 | new_dir.handle, | 3562 | new_dir.handle, |
| 3560 | new_sub_path_posix, | 3563 | new_sub_path_posix, |
| 3561 | if (options.follow_symlinks) 0 else linux.AT.SYMLINK_NOFOLLOW, | 3564 | if (options.follow_symlinks) linux.AT.SYMLINK_FOLLOW else 0, |
| 3562 | ); | 3565 | ); |
| 3563 | } | 3566 | } |
| 3564 | 3567 | ||
| ... | @@ -3990,7 +3993,7 @@ fn fileHardLink( | ... | @@ -3990,7 +3993,7 @@ fn fileHardLink( |
| 3990 | "", | 3993 | "", |
| 3991 | new_dir.handle, | 3994 | new_dir.handle, |
| 3992 | new_sub_path_posix, | 3995 | new_sub_path_posix, |
| 3993 | linux.AT.EMPTY_PATH | @as(u32, if (options.follow_symlinks) 0 else linux.AT.SYMLINK_NOFOLLOW), | 3996 | linux.AT.EMPTY_PATH | @as(u32, if (options.follow_symlinks) linux.AT.SYMLINK_FOLLOW else 0), |
| 3994 | ); | 3997 | ); |
| 3995 | } | 3998 | } |
| 3996 | 3999 | ||
| ... | @@ -4050,7 +4053,7 @@ fn fileMemoryMapDestroy(userdata: ?*anyopaque, mm: *File.MemoryMap) void { | ... | @@ -4050,7 +4053,7 @@ fn fileMemoryMapDestroy(userdata: ?*anyopaque, mm: *File.MemoryMap) void { |
| 4050 | if (memory.len == 0) return; | 4053 | if (memory.len == 0) return; |
| 4051 | switch (linux.errno(linux.munmap(memory.ptr, memory.len))) { | 4054 | switch (linux.errno(linux.munmap(memory.ptr, memory.len))) { |
| 4052 | .SUCCESS => {}, | 4055 | .SUCCESS => {}, |
| 4053 | else => |err| if (builtin.mode == .Debug) | 4056 | else => |err| if (builtin.mode == .debug) |
| 4054 | std.log.err("failed to unmap {d} bytes at {*}: {t}", .{ memory.len, memory.ptr, err }), | 4057 | std.log.err("failed to unmap {d} bytes at {*}: {t}", .{ memory.len, memory.ptr, err }), |
| 4055 | } | 4058 | } |
| 4056 | mm.* = undefined; | 4059 | mm.* = undefined; |
| ... | @@ -5186,9 +5189,9 @@ fn netWriteFileUnavailable( | ... | @@ -5186,9 +5189,9 @@ fn netWriteFileUnavailable( |
| 5186 | return error.Unimplemented; | 5189 | return error.Unimplemented; |
| 5187 | } | 5190 | } |
| 5188 | 5191 | ||
| 5189 | fn netClose(userdata: ?*anyopaque, handles: []const net.Socket.Handle) void { | 5192 | fn netClose(userdata: ?*anyopaque, sockets: []const net.Socket) void { |
| 5190 | const ev: *Evented = @ptrCast(@alignCast(userdata)); | 5193 | const ev: *Evented = @ptrCast(@alignCast(userdata)); |
| 5191 | for (handles) |handle| ev.close(handle); | 5194 | for (sockets) |sock| ev.close(sock.handle); |
| 5192 | } | 5195 | } |
| 5193 | 5196 | ||
| 5194 | fn netShutdown( | 5197 | fn netShutdown( |
| ... | @@ -5295,6 +5298,7 @@ fn bind( | ... | @@ -5295,6 +5298,7 @@ fn bind( |
| 5295 | switch (cancel_region.errno()) { | 5298 | switch (cancel_region.errno()) { |
| 5296 | .SUCCESS => return, | 5299 | .SUCCESS => return, |
| 5297 | .INTR, .CANCELED => {}, | 5300 | .INTR, .CANCELED => {}, |
| 5301 | .ACCES => return error.AccessDenied, | ||
| 5298 | .ADDRINUSE => return error.AddressInUse, | 5302 | .ADDRINUSE => return error.AddressInUse, |
| 5299 | .BADF => |err| return errnoBug(err), // File descriptor used after closed. | 5303 | .BADF => |err| return errnoBug(err), // File descriptor used after closed. |
| 5300 | .INVAL => |err| return errnoBug(err), // invalid parameters | 5304 | .INVAL => |err| return errnoBug(err), // invalid parameters |
| ... | @@ -5542,6 +5546,8 @@ fn linkat( | ... | @@ -5542,6 +5546,8 @@ fn linkat( |
| 5542 | new_path: [*:0]const u8, | 5546 | new_path: [*:0]const u8, |
| 5543 | flags: u32, | 5547 | flags: u32, |
| 5544 | ) File.HardLinkError!void { | 5548 | ) File.HardLinkError!void { |
| 5549 | // allowed flags: https://man7.org/linux/man-pages/man2/linkat.2.html | ||
| 5550 | assert(flags & ~(@as(u32, linux.AT.SYMLINK_FOLLOW | linux.AT.EMPTY_PATH)) == 0); | ||
| 5545 | while (true) { | 5551 | while (true) { |
| 5546 | const thread = try cancel_region.awaitIoUring(); | 5552 | const thread = try cancel_region.awaitIoUring(); |
| 5547 | thread.enqueue().* = .{ | 5553 | thread.enqueue().* = .{ |
lib/std/Io/Writer.zig+21-21| ... | @@ -874,7 +874,7 @@ pub fn splatBytes(w: *Writer, bytes: []const u8, n: usize) Error!usize { | ... | @@ -874,7 +874,7 @@ pub fn splatBytes(w: *Writer, bytes: []const u8, n: usize) Error!usize { |
| 874 | } | 874 | } |
| 875 | 875 | ||
| 876 | /// Asserts the `buffer` was initialized with a capacity of at least `@sizeOf(T)` bytes. | 876 | /// Asserts the `buffer` was initialized with a capacity of at least `@sizeOf(T)` bytes. |
| 877 | pub inline fn writeInt(w: *Writer, comptime T: type, value: T, endian: std.builtin.Endian) Error!void { | 877 | pub inline fn writeInt(w: *Writer, comptime T: type, value: T, endian: std.lang.Endian) Error!void { |
| 878 | var bytes: [@divExact(@typeInfo(T).int.bits, 8)]u8 = undefined; | 878 | var bytes: [@divExact(@typeInfo(T).int.bits, 8)]u8 = undefined; |
| 879 | std.mem.writeInt(std.math.ByteAlignedInt(@TypeOf(value)), &bytes, value, endian); | 879 | std.mem.writeInt(std.math.ByteAlignedInt(@TypeOf(value)), &bytes, value, endian); |
| 880 | return w.writeAll(&bytes); | 880 | return w.writeAll(&bytes); |
| ... | @@ -882,7 +882,7 @@ pub inline fn writeInt(w: *Writer, comptime T: type, value: T, endian: std.built | ... | @@ -882,7 +882,7 @@ pub inline fn writeInt(w: *Writer, comptime T: type, value: T, endian: std.built |
| 882 | 882 | ||
| 883 | /// The function is inline to avoid the dead code in case `endian` is | 883 | /// The function is inline to avoid the dead code in case `endian` is |
| 884 | /// comptime-known and matches host endianness. | 884 | /// comptime-known and matches host endianness. |
| 885 | pub inline fn writeStruct(w: *Writer, value: anytype, endian: std.builtin.Endian) Error!void { | 885 | pub inline fn writeStruct(w: *Writer, value: anytype, endian: std.lang.Endian) Error!void { |
| 886 | switch (@typeInfo(@TypeOf(value))) { | 886 | switch (@typeInfo(@TypeOf(value))) { |
| 887 | .@"struct" => |info| switch (info.layout) { | 887 | .@"struct" => |info| switch (info.layout) { |
| 888 | .auto => @compileError("ill-defined memory layout"), | 888 | .auto => @compileError("ill-defined memory layout"), |
| ... | @@ -907,7 +907,7 @@ pub inline fn writeSliceEndian( | ... | @@ -907,7 +907,7 @@ pub inline fn writeSliceEndian( |
| 907 | w: *Writer, | 907 | w: *Writer, |
| 908 | Elem: type, | 908 | Elem: type, |
| 909 | slice: []const Elem, | 909 | slice: []const Elem, |
| 910 | endian: std.builtin.Endian, | 910 | endian: std.lang.Endian, |
| 911 | ) Error!void { | 911 | ) Error!void { |
| 912 | switch (@typeInfo(Elem)) { | 912 | switch (@typeInfo(Elem)) { |
| 913 | .@"struct" => |info| comptime assert(info.layout != .auto), | 913 | .@"struct" => |info| comptime assert(info.layout != .auto), |
| ... | @@ -2387,6 +2387,7 @@ pub fn unreachableRebase(w: *Writer, preserve: usize, capacity: usize) Error!voi | ... | @@ -2387,6 +2387,7 @@ pub fn unreachableRebase(w: *Writer, preserve: usize, capacity: usize) Error!voi |
| 2387 | 2387 | ||
| 2388 | pub fn fromArrayList(array_list: *ArrayList(u8)) Writer { | 2388 | pub fn fromArrayList(array_list: *ArrayList(u8)) Writer { |
| 2389 | defer array_list.* = .empty; | 2389 | defer array_list.* = .empty; |
| 2390 | array_list.pointer_stability.assertUnlocked(); | ||
| 2390 | return .{ | 2391 | return .{ |
| 2391 | .vtable = &.{ | 2392 | .vtable = &.{ |
| 2392 | .drain = fixedDrain, | 2393 | .drain = fixedDrain, |
| ... | @@ -2402,6 +2403,7 @@ pub fn toArrayList(w: *Writer) ArrayList(u8) { | ... | @@ -2402,6 +2403,7 @@ pub fn toArrayList(w: *Writer) ArrayList(u8) { |
| 2402 | const result: ArrayList(u8) = .{ | 2403 | const result: ArrayList(u8) = .{ |
| 2403 | .items = w.buffer[0..w.end], | 2404 | .items = w.buffer[0..w.end], |
| 2404 | .capacity = w.buffer.len, | 2405 | .capacity = w.buffer.len, |
| 2406 | .pointer_stability = .{}, | ||
| 2405 | }; | 2407 | }; |
| 2406 | w.buffer = &.{}; | 2408 | w.buffer = &.{}; |
| 2407 | w.end = 0; | 2409 | w.end = 0; |
| ... | @@ -2651,6 +2653,7 @@ pub const Allocating = struct { | ... | @@ -2651,6 +2653,7 @@ pub const Allocating = struct { |
| 2651 | const result: std.array_list.Aligned(u8, alignment) = .{ | 2653 | const result: std.array_list.Aligned(u8, alignment) = .{ |
| 2652 | .items = @alignCast(w.buffer[0..w.end]), | 2654 | .items = @alignCast(w.buffer[0..w.end]), |
| 2653 | .capacity = w.buffer.len, | 2655 | .capacity = w.buffer.len, |
| 2656 | .pointer_stability = .{}, | ||
| 2654 | }; | 2657 | }; |
| 2655 | w.buffer = &.{}; | 2658 | w.buffer = &.{}; |
| 2656 | w.end = 0; | 2659 | w.end = 0; |
| ... | @@ -2742,29 +2745,26 @@ pub const Allocating = struct { | ... | @@ -2742,29 +2745,26 @@ pub const Allocating = struct { |
| 2742 | 2745 | ||
| 2743 | fn drain(w: *Writer, data: []const []const u8, splat: usize) Error!usize { | 2746 | fn drain(w: *Writer, data: []const []const u8, splat: usize) Error!usize { |
| 2744 | const a: *Allocating = @fieldParentPtr("writer", w); | 2747 | const a: *Allocating = @fieldParentPtr("writer", w); |
| 2745 | const pattern = data[data.len - 1]; | ||
| 2746 | const splat_len = pattern.len * splat; | ||
| 2747 | const start_len = a.writer.end; | ||
| 2748 | assert(data.len != 0); | 2748 | assert(data.len != 0); |
| 2749 | for (data) |bytes| { | 2749 | const count = countSplat(data, splat); |
| 2750 | a.ensureUnusedCapacity(bytes.len + splat_len + 1) catch return error.WriteFailed; | 2750 | a.ensureUnusedCapacity(count + 1) catch return error.WriteFailed; |
| 2751 | for (data[0 .. data.len - 1]) |bytes| { | ||
| 2751 | @memcpy(a.writer.buffer[a.writer.end..][0..bytes.len], bytes); | 2752 | @memcpy(a.writer.buffer[a.writer.end..][0..bytes.len], bytes); |
| 2752 | a.writer.end += bytes.len; | 2753 | a.writer.end += bytes.len; |
| 2753 | } | 2754 | } |
| 2754 | if (splat == 0) { | 2755 | const pattern = data[data.len - 1]; |
| 2755 | a.writer.end -= pattern.len; | 2756 | switch (pattern.len) { |
| 2756 | } else switch (pattern.len) { | ||
| 2757 | 0 => {}, | 2757 | 0 => {}, |
| 2758 | 1 => { | 2758 | 1 => { |
| 2759 | @memset(a.writer.buffer[a.writer.end..][0 .. splat - 1], pattern[0]); | 2759 | @memset(a.writer.buffer[a.writer.end..][0..splat], pattern[0]); |
| 2760 | a.writer.end += splat - 1; | 2760 | a.writer.end += splat; |
| 2761 | }, | 2761 | }, |
| 2762 | else => for (0..splat - 1) |_| { | 2762 | else => for (0..splat) |_| { |
| 2763 | @memcpy(a.writer.buffer[a.writer.end..][0..pattern.len], pattern); | 2763 | @memcpy(a.writer.buffer[a.writer.end..][0..pattern.len], pattern); |
| 2764 | a.writer.end += pattern.len; | 2764 | a.writer.end += pattern.len; |
| 2765 | }, | 2765 | }, |
| 2766 | } | 2766 | } |
| 2767 | return a.writer.end - start_len; | 2767 | return count; |
| 2768 | } | 2768 | } |
| 2769 | 2769 | ||
| 2770 | fn sendFile(w: *Writer, file_reader: *File.Reader, limit: Limit) FileError!usize { | 2770 | fn sendFile(w: *Writer, file_reader: *File.Reader, limit: Limit) FileError!usize { |
| ... | @@ -2817,12 +2817,12 @@ pub const Allocating = struct { | ... | @@ -2817,12 +2817,12 @@ pub const Allocating = struct { |
| 2817 | } | 2817 | } |
| 2818 | 2818 | ||
| 2819 | test Allocating { | 2819 | test Allocating { |
| 2820 | try testAllocating(.fromByteUnits(1)); | 2820 | try testAllocating(.@"1"); |
| 2821 | try testAllocating(.fromByteUnits(4)); | 2821 | try testAllocating(.@"4"); |
| 2822 | try testAllocating(.fromByteUnits(8)); | 2822 | try testAllocating(.@"8"); |
| 2823 | try testAllocating(.fromByteUnits(16)); | 2823 | try testAllocating(.@"16"); |
| 2824 | try testAllocating(.fromByteUnits(32)); | 2824 | try testAllocating(.@"32"); |
| 2825 | try testAllocating(.fromByteUnits(64)); | 2825 | try testAllocating(.@"64"); |
| 2826 | } | 2826 | } |
| 2827 | }; | 2827 | }; |
| 2828 | 2828 |
lib/std/Io/net.zig+7-2| ... | @@ -198,6 +198,8 @@ pub const IpAddress = union(enum) { | ... | @@ -198,6 +198,8 @@ pub const IpAddress = union(enum) { |
| 198 | } | 198 | } |
| 199 | 199 | ||
| 200 | pub const ListenError = error{ | 200 | pub const ListenError = error{ |
| 201 | /// The address is protected and the current user does not have permission to bind it. | ||
| 202 | AccessDenied, | ||
| 201 | /// The address is already taken. Can occur when bound port is 0 but | 203 | /// The address is already taken. Can occur when bound port is 0 but |
| 202 | /// all ephemeral ports are already in use. | 204 | /// all ephemeral ports are already in use. |
| 203 | AddressInUse, | 205 | AddressInUse, |
| ... | @@ -254,6 +256,8 @@ pub const IpAddress = union(enum) { | ... | @@ -254,6 +256,8 @@ pub const IpAddress = union(enum) { |
| 254 | } | 256 | } |
| 255 | 257 | ||
| 256 | pub const BindError = error{ | 258 | pub const BindError = error{ |
| 259 | /// The address is protected and the current user does not have permission to bind it. | ||
| 260 | AccessDenied, | ||
| 257 | /// The address is already taken. Can occur when bound port is 0 but | 261 | /// The address is already taken. Can occur when bound port is 0 but |
| 258 | /// all ephemeral ports are already in use. | 262 | /// all ephemeral ports are already in use. |
| 259 | AddressInUse, | 263 | AddressInUse, |
| ... | @@ -901,6 +905,7 @@ pub const UnixAddress = struct { | ... | @@ -901,6 +905,7 @@ pub const UnixAddress = struct { |
| 901 | ReadOnlyFileSystem, | 905 | ReadOnlyFileSystem, |
| 902 | WouldBlock, | 906 | WouldBlock, |
| 903 | NetworkDown, | 907 | NetworkDown, |
| 908 | ConnectionRefused, | ||
| 904 | } || Io.Cancelable || Io.UnexpectedError; | 909 | } || Io.Cancelable || Io.UnexpectedError; |
| 905 | 910 | ||
| 906 | pub fn connect(ua: *const UnixAddress, io: Io) ConnectError!Stream { | 911 | pub fn connect(ua: *const UnixAddress, io: Io) ConnectError!Stream { |
| ... | @@ -1076,7 +1081,7 @@ pub const Socket = struct { | ... | @@ -1076,7 +1081,7 @@ pub const Socket = struct { |
| 1076 | 1081 | ||
| 1077 | /// Leaves `address` in a valid state. | 1082 | /// Leaves `address` in a valid state. |
| 1078 | pub fn close(s: *const Socket, io: Io) void { | 1083 | pub fn close(s: *const Socket, io: Io) void { |
| 1079 | io.vtable.netClose(io.userdata, (&s.handle)[0..1]); | 1084 | io.vtable.netClose(io.userdata, s[0..1]); |
| 1080 | } | 1085 | } |
| 1081 | 1086 | ||
| 1082 | pub fn closeMany(io: Io, sockets: []const Socket) void { | 1087 | pub fn closeMany(io: Io, sockets: []const Socket) void { |
| ... | @@ -1253,7 +1258,7 @@ pub const Stream = struct { | ... | @@ -1253,7 +1258,7 @@ pub const Stream = struct { |
| 1253 | } | 1258 | } |
| 1254 | 1259 | ||
| 1255 | pub fn close(s: *const Stream, io: Io) void { | 1260 | pub fn close(s: *const Stream, io: Io) void { |
| 1256 | io.vtable.netClose(io.userdata, (&s.socket.handle)[0..1]); | 1261 | io.vtable.netClose(io.userdata, (&s.socket)[0..1]); |
| 1257 | } | 1262 | } |
| 1258 | 1263 | ||
| 1259 | pub fn shutdown(s: *const Stream, io: Io, how: ShutdownHow) ShutdownError!void { | 1264 | pub fn shutdown(s: *const Stream, io: Io, how: ShutdownHow) ShutdownError!void { |
lib/std/Io/net/test.zig-2| ... | @@ -356,8 +356,6 @@ test "decompress compressed DNS name" { | ... | @@ -356,8 +356,6 @@ test "decompress compressed DNS name" { |
| 356 | } | 356 | } |
| 357 | 357 | ||
| 358 | test "cancel accept" { | 358 | test "cancel accept" { |
| 359 | if (builtin.cpu.arch.isSPARC() and builtin.os.tag == .linux) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/35347 | ||
| 360 | |||
| 361 | const io = testing.io; | 359 | const io = testing.io; |
| 362 | const localhost: net.IpAddress = .{ .ip4 = .loopback(0) }; | 360 | const localhost: net.IpAddress = .{ .ip4 = .loopback(0) }; |
| 363 | 361 |
lib/std/Io/test.zig-4| ... | @@ -232,8 +232,6 @@ fn count(a: usize, b: usize, result: *usize) void { | ... | @@ -232,8 +232,6 @@ fn count(a: usize, b: usize, result: *usize) void { |
| 232 | } | 232 | } |
| 233 | 233 | ||
| 234 | test "Group.cancel" { | 234 | test "Group.cancel" { |
| 235 | if (builtin.cpu.arch.isSPARC() and builtin.os.tag == .linux) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/35347 | ||
| 236 | |||
| 237 | const global = struct { | 235 | const global = struct { |
| 238 | fn sleep(io: Io, result: *usize) Io.Cancelable!void { | 236 | fn sleep(io: Io, result: *usize) Io.Cancelable!void { |
| 239 | defer result.* = 1; | 237 | defer result.* = 1; |
| ... | @@ -326,8 +324,6 @@ test "Group materializes error.Cancel" { | ... | @@ -326,8 +324,6 @@ test "Group materializes error.Cancel" { |
| 326 | } | 324 | } |
| 327 | 325 | ||
| 328 | test "Group task receives cancelation unknowingly" { | 326 | test "Group task receives cancelation unknowingly" { |
| 329 | if (builtin.cpu.arch.isSPARC() and builtin.os.tag == .linux) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/35347 | ||
| 330 | |||
| 331 | const S = struct { | 327 | const S = struct { |
| 332 | io: Io, | 328 | io: Io, |
| 333 | err: ?Io.Cancelable!void, | 329 | err: ?Io.Cancelable!void, |
lib/std/Progress.zig+14-2| ... | @@ -442,7 +442,15 @@ pub const Node = struct { | ... | @@ -442,7 +442,15 @@ pub const Node = struct { |
| 442 | global_progress.ipc_files[slot] = file; | 442 | global_progress.ipc_files[slot] = file; |
| 443 | storageByIndex(index).setIpcIndex(.{ .slot = slot, .generation = generation }); | 443 | storageByIndex(index).setIpcIndex(.{ .slot = slot, .generation = generation }); |
| 444 | break; | 444 | break; |
| 445 | } else file.close(io); | 445 | } else { |
| 446 | // There was no IPC slot available, so we'll drop this node's IPC info and just close | ||
| 447 | // the fd. To avoid an old `estimated_total_items` or `completed_count` value still | ||
| 448 | // being rendered for the node, we'll zero that field out (and the user is not allowed | ||
| 449 | // to change it because they think we're doing IPC). | ||
| 450 | file.close(io); | ||
| 451 | @atomicStore(u32, &storageByIndex(index).completed_count, 0, .monotonic); | ||
| 452 | @atomicStore(u32, &storageByIndex(index).estimated_total_count, 0, .monotonic); | ||
| 453 | } | ||
| 446 | } | 454 | } |
| 447 | 455 | ||
| 448 | pub fn setIpcIndex(node: Node, ipc_index: Ipc.Index) void { | 456 | pub fn setIpcIndex(node: Node, ipc_index: Ipc.Index) void { |
| ... | @@ -452,7 +460,11 @@ pub const Node = struct { | ... | @@ -452,7 +460,11 @@ pub const Node = struct { |
| 452 | /// Not thread-safe. | 460 | /// Not thread-safe. |
| 453 | pub fn takeIpcIndex(node: Node) ?Ipc.Index { | 461 | pub fn takeIpcIndex(node: Node) ?Ipc.Index { |
| 454 | const storage = storageByIndex(node.index.unwrap() orelse return null); | 462 | const storage = storageByIndex(node.index.unwrap() orelse return null); |
| 455 | assert(storage.estimated_total_count == std.math.maxInt(u32)); | 463 | switch (storage.estimated_total_count) { |
| 464 | std.math.maxInt(u32) => {}, // indicates that there is an IPC index in `completed_count` | ||
| 465 | 0 => return null, // `setIpcFile` failed so we don't have an IPC index for this node | ||
| 466 | else => unreachable, // not an IPC node | ||
| 467 | } | ||
| 456 | @atomicStore(u32, &storage.estimated_total_count, 0, .monotonic); | 468 | @atomicStore(u32, &storage.estimated_total_count, 0, .monotonic); |
| 457 | return @bitCast(storage.completed_count); | 469 | return @bitCast(storage.completed_count); |
| 458 | } | 470 | } |
lib/std/Random/RomuTrio.zig-1| ... | @@ -122,7 +122,6 @@ test fill { | ... | @@ -122,7 +122,6 @@ test fill { |
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | test "buf seeding test" { | 124 | test "buf seeding test" { |
| 125 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 126 | const buf0: [24]u8 = @bitCast([3]u64{ 16294208416658607535, 13964609475759908645, 4703697494102998476 }); | 125 | const buf0: [24]u8 = @bitCast([3]u64{ 16294208416658607535, 13964609475759908645, 4703697494102998476 }); |
| 127 | const resulting_state = .{ .x = 16294208416658607535, .y = 13964609475759908645, .z = 4703697494102998476 }; | 126 | const resulting_state = .{ .x = 16294208416658607535, .y = 13964609475759908645, .z = 4703697494102998476 }; |
| 128 | var r = RomuTrio.init(0); | 127 | var r = RomuTrio.init(0); |
lib/std/Random/Xoshiro256.zig-2| ... | @@ -89,8 +89,6 @@ pub fn fill(self: *Xoshiro256, buf: []u8) void { | ... | @@ -89,8 +89,6 @@ pub fn fill(self: *Xoshiro256, buf: []u8) void { |
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | test "sequence" { | 91 | test "sequence" { |
| 92 | if (@import("builtin").zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 93 | |||
| 94 | var r = Xoshiro256.init(0); | 92 | var r = Xoshiro256.init(0); |
| 95 | 93 | ||
| 96 | const seq1 = [_]u64{ | 94 | const seq1 = [_]u64{ |
lib/std/Random/benchmark.zig+1-1| ... | @@ -122,7 +122,7 @@ fn usage() void { | ... | @@ -122,7 +122,7 @@ fn usage() void { |
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | fn mode(comptime x: comptime_int) comptime_int { | 124 | fn mode(comptime x: comptime_int) comptime_int { |
| 125 | return if (builtin.mode == .Debug) x / 64 else x; | 125 | return if (builtin.mode == .debug) x / 64 else x; |
| 126 | } | 126 | } |
| 127 | 127 | ||
| 128 | pub fn main(init: std.process.Init) !void { | 128 | pub fn main(init: std.process.Init) !void { |
lib/std/Target.zig+49-140| ... | @@ -1194,9 +1194,6 @@ pub fn toCoffMachine(target: *const Target) std.coff.IMAGE.FILE.MACHINE { | ... | @@ -1194,9 +1194,6 @@ pub fn toCoffMachine(target: *const Target) std.coff.IMAGE.FILE.MACHINE { |
| 1194 | }; | 1194 | }; |
| 1195 | } | 1195 | } |
| 1196 | 1196 | ||
| 1197 | /// Deprecated; use 'std.zig.Subsystem' instead. To be removed after 0.16.0 is tagged. | ||
| 1198 | pub const SubSystem = std.zig.Subsystem; | ||
| 1199 | |||
| 1200 | pub const Cpu = struct { | 1197 | pub const Cpu = struct { |
| 1201 | /// Architecture | 1198 | /// Architecture |
| 1202 | arch: Arch, | 1199 | arch: Arch, |
| ... | @@ -1796,10 +1793,12 @@ pub const Cpu = struct { | ... | @@ -1796,10 +1793,12 @@ pub const Cpu = struct { |
| 1796 | .x86_64_regcall_v4_win, | 1793 | .x86_64_regcall_v4_win, |
| 1797 | .x86_64_vectorcall, | 1794 | .x86_64_vectorcall, |
| 1798 | .x86_64_interrupt, | 1795 | .x86_64_interrupt, |
| 1796 | .x86_64_preserve_none, | ||
| 1799 | => &.{.x86_64}, | 1797 | => &.{.x86_64}, |
| 1800 | 1798 | ||
| 1801 | .x86_sysv, | 1799 | .x86_sysv, |
| 1802 | .x86_win, | 1800 | .x86_win, |
| 1801 | .x86_mingw, | ||
| 1803 | .x86_stdcall, | 1802 | .x86_stdcall, |
| 1804 | .x86_fastcall, | 1803 | .x86_fastcall, |
| 1805 | .x86_thiscall, | 1804 | .x86_thiscall, |
| ... | @@ -1821,6 +1820,7 @@ pub const Cpu = struct { | ... | @@ -1821,6 +1820,7 @@ pub const Cpu = struct { |
| 1821 | .aarch64_aapcs_win, | 1820 | .aarch64_aapcs_win, |
| 1822 | .aarch64_vfabi, | 1821 | .aarch64_vfabi, |
| 1823 | .aarch64_vfabi_sve, | 1822 | .aarch64_vfabi_sve, |
| 1823 | .aarch64_preserve_none, | ||
| 1824 | => &.{ .aarch64, .aarch64_be }, | 1824 | => &.{ .aarch64, .aarch64_be }, |
| 1825 | 1825 | ||
| 1826 | .alpha_osf, | 1826 | .alpha_osf, |
| ... | @@ -2081,6 +2081,7 @@ pub const Cpu = struct { | ... | @@ -2081,6 +2081,7 @@ pub const Cpu = struct { |
| 2081 | else => generic(arch), | 2081 | else => generic(arch), |
| 2082 | }, | 2082 | }, |
| 2083 | .powerpc64 => switch (os.tag) { | 2083 | .powerpc64 => switch (os.tag) { |
| 2084 | .linux, .freebsd => &powerpc.cpu.pwr8, | ||
| 2084 | .openbsd => &powerpc.cpu.pwr9, | 2085 | .openbsd => &powerpc.cpu.pwr9, |
| 2085 | else => generic(arch), | 2086 | else => generic(arch), |
| 2086 | }, | 2087 | }, |
| ... | @@ -2660,12 +2661,26 @@ pub const DynamicLinker = struct { | ... | @@ -2660,12 +2661,26 @@ pub const DynamicLinker = struct { |
| 2660 | else => return none, | 2661 | else => return none, |
| 2661 | }}), | 2662 | }}), |
| 2662 | 2663 | ||
| 2663 | .loongarch64 => initFmt("/lib64/ld-linux-loongarch-{s}.so.1", .{switch (abi) { | 2664 | .loongarch32, |
| 2664 | .gnu => "lp64d", | 2665 | .loongarch64, |
| 2665 | .gnuf32 => "lp64f", | 2666 | => |arch| initFmt("/lib{s}/ld-linux-{s}{s}.so.1", .{ |
| 2666 | .gnusf => "lp64s", | 2667 | switch (arch) { |
| 2667 | else => return none, | 2668 | .loongarch32 => "32", |
| 2668 | }}), | 2669 | .loongarch64 => "64", |
| 2670 | else => unreachable, | ||
| 2671 | }, | ||
| 2672 | switch (arch) { | ||
| 2673 | .loongarch32 => "loongarch-ilp32", | ||
| 2674 | .loongarch64 => "loongarch-lp64", | ||
| 2675 | else => unreachable, | ||
| 2676 | }, | ||
| 2677 | switch (abi) { | ||
| 2678 | .gnu => "d", | ||
| 2679 | .gnuf32 => "f", | ||
| 2680 | .gnusf => "s", | ||
| 2681 | else => return none, | ||
| 2682 | }, | ||
| 2683 | }), | ||
| 2669 | 2684 | ||
| 2670 | .hppa, | 2685 | .hppa, |
| 2671 | .m68k, | 2686 | .m68k, |
| ... | @@ -3069,9 +3084,13 @@ pub fn stackGrowth(target: *const Target) StackGrowth { | ... | @@ -3069,9 +3084,13 @@ pub fn stackGrowth(target: *const Target) StackGrowth { |
| 3069 | /// Default signedness of `char` for the native C compiler for this target | 3084 | /// Default signedness of `char` for the native C compiler for this target |
| 3070 | /// Note that char signedness is implementation-defined and many compilers provide | 3085 | /// Note that char signedness is implementation-defined and many compilers provide |
| 3071 | /// an option to override the default signedness e.g. GCC's -funsigned-char / -fsigned-char | 3086 | /// an option to override the default signedness e.g. GCC's -funsigned-char / -fsigned-char |
| 3072 | pub fn cCharSignedness(target: *const Target) std.builtin.Signedness { | 3087 | /// Returns `null` if no C ABI is defined for this target. |
| 3088 | pub fn cCharSignedness(target: *const Target) ?std.builtin.Signedness { | ||
| 3089 | switch (target.os.tag) { | ||
| 3090 | .opengl => return null, | ||
| 3091 | else => {}, | ||
| 3092 | } | ||
| 3073 | if (target.os.tag.isDarwin() or target.os.tag == .windows or target.os.tag == .uefi) return .signed; | 3093 | if (target.os.tag.isDarwin() or target.os.tag == .windows or target.os.tag == .uefi) return .signed; |
| 3074 | |||
| 3075 | return switch (target.cpu.arch) { | 3094 | return switch (target.cpu.arch) { |
| 3076 | .aarch64, | 3095 | .aarch64, |
| 3077 | .aarch64_be, | 3096 | .aarch64_be, |
| ... | @@ -3117,7 +3136,8 @@ pub const CType = enum { | ... | @@ -3117,7 +3136,8 @@ pub const CType = enum { |
| 3117 | longdouble, | 3136 | longdouble, |
| 3118 | }; | 3137 | }; |
| 3119 | 3138 | ||
| 3120 | pub fn cTypeByteSize(t: *const Target, c_type: CType) u16 { | 3139 | /// Returns `null` if no C ABI is defined for this target. |
| 3140 | pub fn cTypeByteSize(t: *const Target, c_type: CType) ?u16 { | ||
| 3121 | return switch (c_type) { | 3141 | return switch (c_type) { |
| 3122 | .char, | 3142 | .char, |
| 3123 | .short, | 3143 | .short, |
| ... | @@ -3130,18 +3150,19 @@ pub fn cTypeByteSize(t: *const Target, c_type: CType) u16 { | ... | @@ -3130,18 +3150,19 @@ pub fn cTypeByteSize(t: *const Target, c_type: CType) u16 { |
| 3130 | .ulonglong, | 3150 | .ulonglong, |
| 3131 | .float, | 3151 | .float, |
| 3132 | .double, | 3152 | .double, |
| 3133 | => @divExact(cTypeBitSize(t, c_type), 8), | 3153 | => @divExact(cTypeBitSize(t, c_type) orelse return null, 8), |
| 3134 | 3154 | ||
| 3135 | .longdouble => switch (cTypeBitSize(t, c_type)) { | 3155 | .longdouble => switch (cTypeBitSize(t, c_type) orelse return null) { |
| 3136 | 64 => 8, | 3156 | 64 => 8, |
| 3137 | 80 => @intCast(std.mem.alignForward(usize, 10, cTypeAlignment(t, .longdouble))), | 3157 | 80 => @intCast(std.mem.alignForward(usize, 10, cTypeAlignment(t, c_type).?)), |
| 3138 | 128 => 16, | 3158 | 128 => 16, |
| 3139 | else => unreachable, | 3159 | else => unreachable, |
| 3140 | }, | 3160 | }, |
| 3141 | }; | 3161 | }; |
| 3142 | } | 3162 | } |
| 3143 | 3163 | ||
| 3144 | pub fn cTypeBitSize(target: *const Target, c_type: CType) u16 { | 3164 | /// Returns `null` if no C ABI is defined for this target. |
| 3165 | pub fn cTypeBitSize(target: *const Target, c_type: CType) ?u16 { | ||
| 3145 | switch (target.os.tag) { | 3166 | switch (target.os.tag) { |
| 3146 | .freestanding, | 3167 | .freestanding, |
| 3147 | .other, | 3168 | .other, |
| ... | @@ -3462,15 +3483,17 @@ pub fn cTypeBitSize(target: *const Target, c_type: CType) u16 { | ... | @@ -3462,15 +3483,17 @@ pub fn cTypeBitSize(target: *const Target, c_type: CType) u16 { |
| 3462 | .longlong, .ulonglong, .longdouble => return 64, | 3483 | .longlong, .ulonglong, .longdouble => return 64, |
| 3463 | }, | 3484 | }, |
| 3464 | 3485 | ||
| 3486 | .opengl => return null, | ||
| 3487 | |||
| 3465 | .ps3, | 3488 | .ps3, |
| 3466 | .contiki, | 3489 | .contiki, |
| 3467 | .managarm, | 3490 | .managarm, |
| 3468 | .opengl, | ||
| 3469 | => @panic("specify the C integer and float type sizes for this OS"), | 3491 | => @panic("specify the C integer and float type sizes for this OS"), |
| 3470 | } | 3492 | } |
| 3471 | } | 3493 | } |
| 3472 | 3494 | ||
| 3473 | pub fn cTypeAlignment(target: *const Target, c_type: CType) u16 { | 3495 | /// Returns `null` if no C ABI is defined for this target. |
| 3496 | pub fn cTypeAlignment(target: *const Target, c_type: CType) ?u16 { | ||
| 3474 | // Overrides for unusual alignments | 3497 | // Overrides for unusual alignments |
| 3475 | switch (target.cpu.arch) { | 3498 | switch (target.cpu.arch) { |
| 3476 | .avr, | 3499 | .avr, |
| ... | @@ -3503,7 +3526,7 @@ pub fn cTypeAlignment(target: *const Target, c_type: CType) u16 { | ... | @@ -3503,7 +3526,7 @@ pub fn cTypeAlignment(target: *const Target, c_type: CType) u16 { |
| 3503 | 3526 | ||
| 3504 | // Next-power-of-two-aligned, up to a maximum. | 3527 | // Next-power-of-two-aligned, up to a maximum. |
| 3505 | return @min( | 3528 | return @min( |
| 3506 | std.math.ceilPowerOfTwoAssert(u16, (cTypeBitSize(target, c_type) + 7) / 8), | 3529 | std.math.ceilPowerOfTwoAssert(u16, ((cTypeBitSize(target, c_type) orelse return null) + 7) / 8), |
| 3507 | @as(u16, switch (target.cpu.arch) { | 3530 | @as(u16, switch (target.cpu.arch) { |
| 3508 | .msp430, | 3531 | .msp430, |
| 3509 | .x86_16, | 3532 | .x86_16, |
| ... | @@ -3578,120 +3601,6 @@ pub fn cTypeAlignment(target: *const Target, c_type: CType) u16 { | ... | @@ -3578,120 +3601,6 @@ pub fn cTypeAlignment(target: *const Target, c_type: CType) u16 { |
| 3578 | ); | 3601 | ); |
| 3579 | } | 3602 | } |
| 3580 | 3603 | ||
| 3581 | pub fn cTypePreferredAlignment(target: *const Target, c_type: CType) u16 { | ||
| 3582 | // Overrides for unusual alignments | ||
| 3583 | switch (target.cpu.arch) { | ||
| 3584 | .arc, .arceb => switch (c_type) { | ||
| 3585 | .longdouble => return 4, | ||
| 3586 | else => {}, | ||
| 3587 | }, | ||
| 3588 | .avr, | ||
| 3589 | .ez80, | ||
| 3590 | => return 1, | ||
| 3591 | .x86 => switch (target.os.tag) { | ||
| 3592 | .windows, .uefi => switch (c_type) { | ||
| 3593 | .longdouble => switch (target.abi) { | ||
| 3594 | .gnu => return 4, | ||
| 3595 | else => return 8, | ||
| 3596 | }, | ||
| 3597 | else => {}, | ||
| 3598 | }, | ||
| 3599 | else => switch (c_type) { | ||
| 3600 | .longdouble => return 4, | ||
| 3601 | else => {}, | ||
| 3602 | }, | ||
| 3603 | }, | ||
| 3604 | .m68k => switch (c_type) { | ||
| 3605 | .int, .uint, .long, .ulong => return 2, | ||
| 3606 | else => {}, | ||
| 3607 | }, | ||
| 3608 | .wasm32, .wasm64 => switch (target.os.tag) { | ||
| 3609 | .emscripten => switch (c_type) { | ||
| 3610 | .longdouble => return 8, | ||
| 3611 | else => {}, | ||
| 3612 | }, | ||
| 3613 | else => {}, | ||
| 3614 | }, | ||
| 3615 | else => {}, | ||
| 3616 | } | ||
| 3617 | |||
| 3618 | // Next-power-of-two-aligned, up to a maximum. | ||
| 3619 | return @min( | ||
| 3620 | std.math.ceilPowerOfTwoAssert(u16, (cTypeBitSize(target, c_type) + 7) / 8), | ||
| 3621 | @as(u16, switch (target.cpu.arch) { | ||
| 3622 | .x86_16, | ||
| 3623 | .msp430, | ||
| 3624 | => 2, | ||
| 3625 | |||
| 3626 | .arc, | ||
| 3627 | .arceb, | ||
| 3628 | .csky, | ||
| 3629 | .kalimba, | ||
| 3630 | .microblaze, | ||
| 3631 | .microblazeel, | ||
| 3632 | .or1k, | ||
| 3633 | .propeller, | ||
| 3634 | .sh, | ||
| 3635 | .sheb, | ||
| 3636 | .xcore, | ||
| 3637 | .xtensa, | ||
| 3638 | .xtensaeb, | ||
| 3639 | => 4, | ||
| 3640 | |||
| 3641 | .amdgcn, | ||
| 3642 | .arm, | ||
| 3643 | .armeb, | ||
| 3644 | .bpfeb, | ||
| 3645 | .bpfel, | ||
| 3646 | .hexagon, | ||
| 3647 | .hppa, | ||
| 3648 | .lanai, | ||
| 3649 | .m68k, | ||
| 3650 | .m88k, | ||
| 3651 | .mips, | ||
| 3652 | .mipsel, | ||
| 3653 | .nvptx, | ||
| 3654 | .nvptx64, | ||
| 3655 | .s390x, | ||
| 3656 | .sparc, | ||
| 3657 | .thumb, | ||
| 3658 | .thumbeb, | ||
| 3659 | .x86, | ||
| 3660 | => 8, | ||
| 3661 | |||
| 3662 | .aarch64, | ||
| 3663 | .aarch64_be, | ||
| 3664 | .alpha, | ||
| 3665 | .hppa64, | ||
| 3666 | .kvx, | ||
| 3667 | .loongarch32, | ||
| 3668 | .loongarch64, | ||
| 3669 | .mips64, | ||
| 3670 | .mips64el, | ||
| 3671 | .powerpc, | ||
| 3672 | .powerpcle, | ||
| 3673 | .powerpc64, | ||
| 3674 | .powerpc64le, | ||
| 3675 | .riscv32, | ||
| 3676 | .riscv32be, | ||
| 3677 | .riscv64, | ||
| 3678 | .riscv64be, | ||
| 3679 | .sparc64, | ||
| 3680 | .spirv32, | ||
| 3681 | .spirv64, | ||
| 3682 | .ve, | ||
| 3683 | .wasm32, | ||
| 3684 | .wasm64, | ||
| 3685 | .x86_64, | ||
| 3686 | => 16, | ||
| 3687 | |||
| 3688 | .avr, | ||
| 3689 | .ez80, | ||
| 3690 | => unreachable, // Handled above. | ||
| 3691 | }), | ||
| 3692 | ); | ||
| 3693 | } | ||
| 3694 | |||
| 3695 | pub fn cMaxIntAlignment(target: *const Target) u16 { | 3604 | pub fn cMaxIntAlignment(target: *const Target) u16 { |
| 3696 | return switch (target.cpu.arch) { | 3605 | return switch (target.cpu.arch) { |
| 3697 | .avr, | 3606 | .avr, |
| ... | @@ -3715,6 +3624,11 @@ pub fn cMaxIntAlignment(target: *const Target) u16 { | ... | @@ -3715,6 +3624,11 @@ pub fn cMaxIntAlignment(target: *const Target) u16 { |
| 3715 | .xcore, | 3624 | .xcore, |
| 3716 | => 4, | 3625 | => 4, |
| 3717 | 3626 | ||
| 3627 | .x86 => switch (target.os.tag) { | ||
| 3628 | else => 4, | ||
| 3629 | .uefi, .windows => 8, | ||
| 3630 | }, | ||
| 3631 | |||
| 3718 | .arm, | 3632 | .arm, |
| 3719 | .armeb, | 3633 | .armeb, |
| 3720 | .hexagon, | 3634 | .hexagon, |
| ... | @@ -3733,7 +3647,6 @@ pub fn cMaxIntAlignment(target: *const Target) u16 { | ... | @@ -3733,7 +3647,6 @@ pub fn cMaxIntAlignment(target: *const Target) u16 { |
| 3733 | .sparc, | 3647 | .sparc, |
| 3734 | .thumb, | 3648 | .thumb, |
| 3735 | .thumbeb, | 3649 | .thumbeb, |
| 3736 | .x86, | ||
| 3737 | .xtensa, | 3650 | .xtensa, |
| 3738 | .xtensaeb, | 3651 | .xtensaeb, |
| 3739 | => 8, | 3652 | => 8, |
| ... | @@ -3769,18 +3682,14 @@ pub fn cMaxIntAlignment(target: *const Target) u16 { | ... | @@ -3769,18 +3682,14 @@ pub fn cMaxIntAlignment(target: *const Target) u16 { |
| 3769 | pub fn cCallingConvention(target: *const Target) ?std.builtin.CallingConvention { | 3682 | pub fn cCallingConvention(target: *const Target) ?std.builtin.CallingConvention { |
| 3770 | return switch (target.cpu.arch) { | 3683 | return switch (target.cpu.arch) { |
| 3771 | .x86_64 => switch (target.os.tag) { | 3684 | .x86_64 => switch (target.os.tag) { |
| 3772 | .windows, | 3685 | .windows, .uefi => .{ .x86_64_win = .{} }, |
| 3773 | .uefi, | ||
| 3774 | => .{ .x86_64_win = .{} }, | ||
| 3775 | else => switch (target.abi) { | 3686 | else => switch (target.abi) { |
| 3776 | .gnux32, .muslx32, .x32 => .{ .x86_64_x32 = .{} }, | 3687 | .gnux32, .muslx32, .x32 => .{ .x86_64_x32 = .{} }, |
| 3777 | else => .{ .x86_64_sysv = .{} }, | 3688 | else => .{ .x86_64_sysv = .{} }, |
| 3778 | }, | 3689 | }, |
| 3779 | }, | 3690 | }, |
| 3780 | .x86 => switch (target.os.tag) { | 3691 | .x86 => switch (target.os.tag) { |
| 3781 | .windows, | 3692 | .windows, .uefi => if (target.isMinGW()) .{ .x86_mingw = .{} } else .{ .x86_win = .{} }, |
| 3782 | .uefi, | ||
| 3783 | => .{ .x86_win = .{} }, | ||
| 3784 | else => .{ .x86_sysv = .{} }, | 3693 | else => .{ .x86_sysv = .{} }, |
| 3785 | }, | 3694 | }, |
| 3786 | .x86_16 => .{ .x86_16_cdecl = .{} }, | 3695 | .x86_16 => .{ .x86_16_cdecl = .{} }, |
lib/std/Thread.zig+36-43| ... | @@ -639,8 +639,7 @@ const WindowsThreadImpl = struct { | ... | @@ -639,8 +639,7 @@ const WindowsThreadImpl = struct { |
| 639 | } | 639 | } |
| 640 | 640 | ||
| 641 | fn join(self: Impl) void { | 641 | fn join(self: Impl) void { |
| 642 | const infinite_timeout: windows.LARGE_INTEGER = std.math.minInt(windows.LARGE_INTEGER); | 642 | switch (windows.ntdll.NtWaitForSingleObject(self.thread.thread_handle, .FALSE, null)) { |
| 643 | switch (windows.ntdll.NtWaitForSingleObject(self.thread.thread_handle, .FALSE, &infinite_timeout)) { | ||
| 644 | windows.NTSTATUS.WAIT_0 => {}, | 643 | windows.NTSTATUS.WAIT_0 => {}, |
| 645 | else => |status| windows.unexpectedStatus(status) catch unreachable, | 644 | else => |status| windows.unexpectedStatus(status) catch unreachable, |
| 646 | } | 645 | } |
| ... | @@ -720,10 +719,9 @@ const PosixThreadImpl = struct { | ... | @@ -720,10 +719,9 @@ const PosixThreadImpl = struct { |
| 720 | }, | 719 | }, |
| 721 | .haiku => { | 720 | .haiku => { |
| 722 | var system_info: std.c.system_info = undefined; | 721 | var system_info: std.c.system_info = undefined; |
| 723 | const rc = std.c.get_system_info(&system_info); // always returns B_OK | 722 | return switch (std.c.get_system_info(&system_info)) { |
| 724 | return switch (posix.errno(rc)) { | 723 | 0 => @as(usize, @intCast(system_info.cpu_count)), |
| 725 | .SUCCESS => @as(usize, @intCast(system_info.cpu_count)), | 724 | else => error.Unexpected, |
| 726 | else => |err| posix.unexpectedErrno(err), | ||
| 727 | }; | 725 | }; |
| 728 | }, | 726 | }, |
| 729 | else => { | 727 | else => { |
| ... | @@ -1146,6 +1144,13 @@ const LinuxThreadImpl = struct { | ... | @@ -1146,6 +1144,13 @@ const LinuxThreadImpl = struct { |
| 1146 | parent_tid: i32 = undefined, | 1144 | parent_tid: i32 = undefined, |
| 1147 | mapped: []align(std.heap.page_size_min) u8, | 1145 | mapped: []align(std.heap.page_size_min) u8, |
| 1148 | 1146 | ||
| 1147 | // On SPARC, the kernel needs to be able to restore the current register window from the | ||
| 1148 | // stack when returning from a syscall. That presents a bit of a problem in `freeAndExit` | ||
| 1149 | // since we're deallocating the stack! The good news is that, since we do not care about | ||
| 1150 | // the contents of the incoming and local registers at that point, we can just tell the | ||
| 1151 | // kernel that our stack is this undefined global buffer. | ||
| 1152 | var sparc_exit_stack: [192]u8 align(16) = undefined; | ||
| 1153 | |||
| 1149 | /// Calls `munmap(mapped.ptr, mapped.len)` then `exit(1)` without touching the stack (which lives in `mapped.ptr`). | 1154 | /// Calls `munmap(mapped.ptr, mapped.len)` then `exit(1)` without touching the stack (which lives in `mapped.ptr`). |
| 1150 | /// Ported over from musl libc's pthread detached implementation: | 1155 | /// Ported over from musl libc's pthread detached implementation: |
| 1151 | /// https://github.com/ifduyue/musl/search?q=__unmapself | 1156 | /// https://github.com/ifduyue/musl/search?q=__unmapself |
| ... | @@ -1365,51 +1370,39 @@ const LinuxThreadImpl = struct { | ... | @@ -1365,51 +1370,39 @@ const LinuxThreadImpl = struct { |
| 1365 | [len] "{r5}" (self.mapped.len), | 1370 | [len] "{r5}" (self.mapped.len), |
| 1366 | ), | 1371 | ), |
| 1367 | .sparc => asm volatile ( | 1372 | .sparc => asm volatile ( |
| 1368 | \\ # See sparc64 comments below. | 1373 | \\ // See sparc64 comments below. |
| 1369 | \\ 1: | 1374 | \\ t 0x3 // ST_FLUSH_WINDOWS |
| 1370 | \\ cmp %%fp, 0 | 1375 | \\ mov %%g3, %%sp |
| 1371 | \\ beq 2f | 1376 | \\ mov %%g1, %%o0 |
| 1372 | \\ nop | 1377 | \\ mov %%g2, %%o1 |
| 1373 | \\ ba 1b | 1378 | \\ mov 73, %%g1 // SYS_munmap |
| 1374 | \\ restore | 1379 | \\ t 0x10 |
| 1375 | \\ 2: | 1380 | \\ mov 1, %%g1 // SYS_exit |
| 1376 | \\ mov %%g1, %%o0 // ptr | 1381 | \\ mov 0, %%o0 |
| 1377 | \\ mov %%g2, %%o1 // len | 1382 | \\ t 0x10 |
| 1378 | \\ mov 73, %%g1 // SYS_munmap | ||
| 1379 | \\ t 0x3 // ST_FLUSH_WINDOWS | ||
| 1380 | \\ t 0x10 | ||
| 1381 | \\ mov 1, %%g1 // SYS_exit | ||
| 1382 | \\ mov 0, %%o0 | ||
| 1383 | \\ t 0x10 | ||
| 1384 | : | 1383 | : |
| 1385 | : [ptr] "{g1}" (@intFromPtr(self.mapped.ptr)), | 1384 | : [ptr] "{g1}" (@intFromPtr(self.mapped.ptr)), |
| 1386 | [len] "{g2}" (self.mapped.len), | 1385 | [len] "{g2}" (self.mapped.len), |
| 1386 | [stack] "{g3}" (&sparc_exit_stack), | ||
| 1387 | : .{ .memory = true }), | 1387 | : .{ .memory = true }), |
| 1388 | .sparc64 => asm volatile ( | 1388 | .sparc64 => asm volatile ( |
| 1389 | \\ # SPARCs really don't like it when active stack frames | 1389 | \\ // Ensure that the kernel only has to flush the current register window. |
| 1390 | \\ # is unmapped (it will result in a segfault), so we | 1390 | \\ flushw |
| 1391 | \\ # force-deactivate it by running `restore` until | 1391 | \\ // Set up a fake stack for the syscall to restore l/i registers from. Local |
| 1392 | \\ # all frames are cleared. | 1392 | \\ // and incoming registers must be treated as effectively garbage past this |
| 1393 | \\ 1: | 1393 | \\ // instruction! |
| 1394 | \\ cmp %%fp, 0 | 1394 | \\ sub %%g3, 2047, %%sp |
| 1395 | \\ beq 2f | 1395 | \\ mov %%g1, %%o0 |
| 1396 | \\ nop | 1396 | \\ mov %%g2, %%o1 |
| 1397 | \\ ba 1b | 1397 | \\ mov 73, %%g1 // SYS_munmap |
| 1398 | \\ restore | 1398 | \\ t 0x6d |
| 1399 | \\ 2: | 1399 | \\ mov 1, %%g1 // SYS_exit |
| 1400 | \\ mov %%g1, %%o0 // ptr | 1400 | \\ mov 0, %%o0 |
| 1401 | \\ mov %%g2, %%o1 // len | 1401 | \\ t 0x6d |
| 1402 | \\ mov 73, %%g1 // SYS_munmap | ||
| 1403 | \\ # Flush register window contents to prevent background | ||
| 1404 | \\ # memory access before unmapping the stack. | ||
| 1405 | \\ flushw | ||
| 1406 | \\ t 0x6d | ||
| 1407 | \\ mov 1, %%g1 // SYS_exit | ||
| 1408 | \\ mov 0, %%o0 | ||
| 1409 | \\ t 0x6d | ||
| 1410 | : | 1402 | : |
| 1411 | : [ptr] "{g1}" (@intFromPtr(self.mapped.ptr)), | 1403 | : [ptr] "{g1}" (@intFromPtr(self.mapped.ptr)), |
| 1412 | [len] "{g2}" (self.mapped.len), | 1404 | [len] "{g2}" (self.mapped.len), |
| 1405 | [stack] "{g3}" (&sparc_exit_stack), | ||
| 1413 | : .{ .memory = true }), | 1406 | : .{ .memory = true }), |
| 1414 | .loongarch32, .loongarch64 => asm volatile ( | 1407 | .loongarch32, .loongarch64 => asm volatile ( |
| 1415 | \\ ori $a7, $zero, 215 # SYS_munmap | 1408 | \\ ori $a7, $zero, 215 # SYS_munmap |
lib/std/Uri.zig+4-4| ... | @@ -221,16 +221,16 @@ pub fn parseAfterScheme(scheme: []const u8, text: []const u8) ParseError!Uri { | ... | @@ -221,16 +221,16 @@ pub fn parseAfterScheme(scheme: []const u8, text: []const u8) ParseError!Uri { |
| 221 | } | 221 | } |
| 222 | 222 | ||
| 223 | if (authority.len > start_of_host and authority[start_of_host] == '[') { // IPv6 | 223 | if (authority.len > start_of_host and authority[start_of_host] == '[') { // IPv6 |
| 224 | end_of_host = std.mem.lastIndexOf(u8, authority, "]") orelse return error.InvalidFormat; | 224 | end_of_host = std.mem.findLast(u8, authority, "]") orelse return error.InvalidFormat; |
| 225 | end_of_host += 1; | 225 | end_of_host += 1; |
| 226 | 226 | ||
| 227 | if (std.mem.lastIndexOf(u8, authority, ":")) |index| { | 227 | if (std.mem.findLast(u8, authority, ":")) |index| { |
| 228 | if (index >= end_of_host) { // if not part of the V6 address field | 228 | if (index >= end_of_host) { // if not part of the V6 address field |
| 229 | end_of_host = @min(end_of_host, index); | 229 | end_of_host = @min(end_of_host, index); |
| 230 | uri.port = std.fmt.parseInt(u16, authority[index + 1 ..], 10) catch return error.InvalidPort; | 230 | uri.port = std.fmt.parseInt(u16, authority[index + 1 ..], 10) catch return error.InvalidPort; |
| 231 | } | 231 | } |
| 232 | } | 232 | } |
| 233 | } else if (std.mem.lastIndexOf(u8, authority, ":")) |index| { | 233 | } else if (std.mem.findLast(u8, authority, ":")) |index| { |
| 234 | if (index >= start_of_host) { // if not part of the userinfo field | 234 | if (index >= start_of_host) { // if not part of the userinfo field |
| 235 | end_of_host = @min(end_of_host, index); | 235 | end_of_host = @min(end_of_host, index); |
| 236 | uri.port = std.fmt.parseInt(u16, authority[index + 1 ..], 10) catch return error.InvalidPort; | 236 | uri.port = std.fmt.parseInt(u16, authority[index + 1 ..], 10) catch return error.InvalidPort; |
| ... | @@ -475,7 +475,7 @@ fn merge_paths(base: Component, new: []u8, aux_buf: *[]u8) error{NoSpaceLeft}!Co | ... | @@ -475,7 +475,7 @@ fn merge_paths(base: Component, new: []u8, aux_buf: *[]u8) error{NoSpaceLeft}!Co |
| 475 | var aux: Writer = .fixed(aux_buf.*); | 475 | var aux: Writer = .fixed(aux_buf.*); |
| 476 | if (!base.isEmpty()) { | 476 | if (!base.isEmpty()) { |
| 477 | base.formatPath(&aux) catch return error.NoSpaceLeft; | 477 | base.formatPath(&aux) catch return error.NoSpaceLeft; |
| 478 | aux.end = std.mem.lastIndexOfScalar(u8, aux.buffered(), '/') orelse return remove_dot_segments(new); | 478 | aux.end = std.mem.findScalarLast(u8, aux.buffered(), '/') orelse return remove_dot_segments(new); |
| 479 | } | 479 | } |
| 480 | aux.print("/{s}", .{new}) catch return error.NoSpaceLeft; | 480 | aux.print("/{s}", .{new}) catch return error.NoSpaceLeft; |
| 481 | const merged_path = remove_dot_segments(aux.buffered()); | 481 | const merged_path = remove_dot_segments(aux.buffered()); |
lib/std/array_hash_map.zig+7-7| ... | @@ -13,12 +13,12 @@ const hash_map = @This(); | ... | @@ -13,12 +13,12 @@ const hash_map = @This(); |
| 13 | /// | 13 | /// |
| 14 | /// See `AutoContext` for a description of the hash and equal implementations. | 14 | /// See `AutoContext` for a description of the hash and equal implementations. |
| 15 | pub fn Auto(comptime K: type, comptime V: type) type { | 15 | pub fn Auto(comptime K: type, comptime V: type) type { |
| 16 | return ArrayHashMap(K, V, AutoContext(K), !autoEqlIsCheap(K)); | 16 | return Custom(K, V, AutoContext(K), !autoEqlIsCheap(K)); |
| 17 | } | 17 | } |
| 18 | 18 | ||
| 19 | /// An `ArrayHashMap` with strings as keys. | 19 | /// An `ArrayHashMap` with strings as keys. |
| 20 | pub fn String(comptime V: type) type { | 20 | pub fn String(comptime V: type) type { |
| 21 | return ArrayHashMap([]const u8, V, StringContext, true); | 21 | return Custom([]const u8, V, StringContext, true); |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | pub const StringContext = struct { | 24 | pub const StringContext = struct { |
| ... | @@ -2130,7 +2130,7 @@ test "0 sized key and 0 sized value" { | ... | @@ -2130,7 +2130,7 @@ test "0 sized key and 0 sized value" { |
| 2130 | test "setKey storehash true" { | 2130 | test "setKey storehash true" { |
| 2131 | const gpa = std.testing.allocator; | 2131 | const gpa = std.testing.allocator; |
| 2132 | 2132 | ||
| 2133 | var map: ArrayHashMap(i32, i32, AutoContext(i32), true) = .empty; | 2133 | var map: Custom(i32, i32, AutoContext(i32), true) = .empty; |
| 2134 | defer map.deinit(gpa); | 2134 | defer map.deinit(gpa); |
| 2135 | 2135 | ||
| 2136 | try map.put(gpa, 12, 34); | 2136 | try map.put(gpa, 12, 34); |
| ... | @@ -2146,7 +2146,7 @@ test "setKey storehash true" { | ... | @@ -2146,7 +2146,7 @@ test "setKey storehash true" { |
| 2146 | test "setKey storehash false" { | 2146 | test "setKey storehash false" { |
| 2147 | const gpa = std.testing.allocator; | 2147 | const gpa = std.testing.allocator; |
| 2148 | 2148 | ||
| 2149 | var map: ArrayHashMap(i32, i32, AutoContext(i32), false) = .empty; | 2149 | var map: Custom(i32, i32, AutoContext(i32), false) = .empty; |
| 2150 | defer map.deinit(gpa); | 2150 | defer map.deinit(gpa); |
| 2151 | 2151 | ||
| 2152 | try map.put(gpa, 12, 34); | 2152 | try map.put(gpa, 12, 34); |
| ... | @@ -2162,7 +2162,7 @@ test "setKey storehash false" { | ... | @@ -2162,7 +2162,7 @@ test "setKey storehash false" { |
| 2162 | test "setKey storehash false with index" { | 2162 | test "setKey storehash false with index" { |
| 2163 | const gpa = std.testing.allocator; | 2163 | const gpa = std.testing.allocator; |
| 2164 | 2164 | ||
| 2165 | const T = ArrayHashMap(usize, usize, AutoContext(usize), false); | 2165 | const T = Custom(usize, usize, AutoContext(usize), false); |
| 2166 | 2166 | ||
| 2167 | var map: T = .empty; | 2167 | var map: T = .empty; |
| 2168 | defer map.deinit(gpa); | 2168 | defer map.deinit(gpa); |
| ... | @@ -2180,9 +2180,9 @@ test "setKey storehash false with index" { | ... | @@ -2180,9 +2180,9 @@ test "setKey storehash false with index" { |
| 2180 | test "setKey storehash true with index" { | 2180 | test "setKey storehash true with index" { |
| 2181 | const gpa = std.testing.allocator; | 2181 | const gpa = std.testing.allocator; |
| 2182 | 2182 | ||
| 2183 | const T = ArrayHashMap(usize, usize, AutoContext(usize), false); | 2183 | const T = Custom(usize, usize, AutoContext(usize), false); |
| 2184 | 2184 | ||
| 2185 | var map: ArrayHashMap(usize, usize, AutoContext(usize), true) = .empty; | 2185 | var map: Custom(usize, usize, AutoContext(usize), true) = .empty; |
| 2186 | defer map.deinit(gpa); | 2186 | defer map.deinit(gpa); |
| 2187 | 2187 | ||
| 2188 | for (0..T.linear_scan_max + 1) |i| try map.put(gpa, i, i); | 2188 | for (0..T.linear_scan_max + 1) |i| try map.put(gpa, i, i); |
lib/std/array_list.zig+201-145| ... | @@ -26,8 +26,8 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type | ... | @@ -26,8 +26,8 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type |
| 26 | /// | 26 | /// |
| 27 | /// Pointers to elements in this slice are invalidated by various | 27 | /// Pointers to elements in this slice are invalidated by various |
| 28 | /// functions of this ArrayList in accordance with the respective | 28 | /// functions of this ArrayList in accordance with the respective |
| 29 | /// documentation. In all cases, "invalidated" means that the memory | 29 | /// documentation. |
| 30 | /// has been passed to this allocator's resize or free function. | 30 | /// An invalidated pointer may point either to valid or freed memory. |
| 31 | items: Slice, | 31 | items: Slice, |
| 32 | /// How many T values this list can hold without allocating | 32 | /// How many T values this list can hold without allocating |
| 33 | /// additional memory. | 33 | /// additional memory. |
| ... | @@ -35,7 +35,7 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type | ... | @@ -35,7 +35,7 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type |
| 35 | allocator: Allocator, | 35 | allocator: Allocator, |
| 36 | 36 | ||
| 37 | /// Used to detect memory safety violations. | 37 | /// Used to detect memory safety violations. |
| 38 | pointer_stability: debug.SafetyLock = .{}, | 38 | pointer_stability: debug.SafetyLock, |
| 39 | 39 | ||
| 40 | pub const Slice = if (alignment) |a| ([]align(a.toByteUnits()) T) else []T; | 40 | pub const Slice = if (alignment) |a| ([]align(a.toByteUnits()) T) else []T; |
| 41 | 41 | ||
| ... | @@ -49,6 +49,7 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type | ... | @@ -49,6 +49,7 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type |
| 49 | .items = &[_]T{}, | 49 | .items = &[_]T{}, |
| 50 | .capacity = 0, | 50 | .capacity = 0, |
| 51 | .allocator = gpa, | 51 | .allocator = gpa, |
| 52 | .pointer_stability = .{}, | ||
| 52 | }; | 53 | }; |
| 53 | } | 54 | } |
| 54 | 55 | ||
| ... | @@ -94,6 +95,7 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type | ... | @@ -94,6 +95,7 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type |
| 94 | .items = slice, | 95 | .items = slice, |
| 95 | .capacity = slice.len, | 96 | .capacity = slice.len, |
| 96 | .allocator = gpa, | 97 | .allocator = gpa, |
| 98 | .pointer_stability = .{}, | ||
| 97 | }; | 99 | }; |
| 98 | } | 100 | } |
| 99 | 101 | ||
| ... | @@ -105,22 +107,28 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type | ... | @@ -105,22 +107,28 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type |
| 105 | .items = slice, | 107 | .items = slice, |
| 106 | .capacity = slice.len + 1, | 108 | .capacity = slice.len + 1, |
| 107 | .allocator = gpa, | 109 | .allocator = gpa, |
| 110 | .pointer_stability = .{}, | ||
| 108 | }; | 111 | }; |
| 109 | } | 112 | } |
| 110 | 113 | ||
| 111 | /// Initializes an ArrayList with the `items` and `capacity` fields | 114 | /// Initializes an ArrayList with the `items` and `capacity` fields |
| 112 | /// of this ArrayList. Empties this ArrayList. | 115 | /// of this ArrayList. Empties this ArrayList. |
| 113 | pub fn moveToUnmanaged(self: *Self) Aligned(T, alignment) { | 116 | pub fn moveToUnmanaged(self: *Self) Aligned(T, alignment) { |
| 114 | self.pointer_stability.assertUnlocked(); | ||
| 115 | const allocator = self.allocator; | 117 | const allocator = self.allocator; |
| 116 | const result: Aligned(T, alignment) = .{ .items = self.items, .capacity = self.capacity }; | 118 | const result: Aligned(T, alignment) = .{ |
| 119 | .items = self.items, | ||
| 120 | .capacity = self.capacity, | ||
| 121 | .pointer_stability = self.pointer_stability, | ||
| 122 | }; | ||
| 117 | self.* = init(allocator); | 123 | self.* = init(allocator); |
| 118 | return result; | 124 | return result; |
| 119 | } | 125 | } |
| 120 | 126 | ||
| 121 | /// The caller owns the returned memory. Empties this ArrayList. | 127 | /// The caller owns the returned memory. Empties this ArrayList. |
| 122 | /// Its capacity is cleared, making `deinit` safe but unnecessary to call. | 128 | /// Its capacity is cleared, making `deinit` safe but unnecessary to call. |
| 129 | /// May invalidate element pointers if remapping memory cannot be done in place. | ||
| 123 | pub fn toOwnedSlice(self: *Self) Allocator.Error!Slice { | 130 | pub fn toOwnedSlice(self: *Self) Allocator.Error!Slice { |
| 131 | self.pointer_stability.assertUnlocked(); | ||
| 124 | const allocator = self.allocator; | 132 | const allocator = self.allocator; |
| 125 | 133 | ||
| 126 | const old_memory = self.allocatedSlice(); | 134 | const old_memory = self.allocatedSlice(); |
| ... | @@ -136,6 +144,7 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type | ... | @@ -136,6 +144,7 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type |
| 136 | } | 144 | } |
| 137 | 145 | ||
| 138 | /// The caller owns the returned memory. Empties this ArrayList. | 146 | /// The caller owns the returned memory. Empties this ArrayList. |
| 147 | /// May invalidate element pointers if remapping memory cannot be done in place. | ||
| 139 | pub fn toOwnedSliceSentinel(self: *Self, comptime sentinel: T) Allocator.Error!SentinelSlice(sentinel) { | 148 | pub fn toOwnedSliceSentinel(self: *Self, comptime sentinel: T) Allocator.Error!SentinelSlice(sentinel) { |
| 140 | // This addition can never overflow because `self.items` can never occupy the whole address space | 149 | // This addition can never overflow because `self.items` can never occupy the whole address space |
| 141 | try self.ensureTotalCapacityPrecise(self.items.len + 1); | 150 | try self.ensureTotalCapacityPrecise(self.items.len + 1); |
| ... | @@ -151,31 +160,31 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type | ... | @@ -151,31 +160,31 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type |
| 151 | return cloned; | 160 | return cloned; |
| 152 | } | 161 | } |
| 153 | 162 | ||
| 154 | /// Insert `item` at index `i`. Moves `list[i .. list.len]` to higher indices to make room. | 163 | /// Insert `item` at index `index`. Moves `list[index .. list.len]` to higher indices to make room. |
| 155 | /// If `i` is equal to the length of the list this operation is equivalent to append. | 164 | /// If `index` is equal to the length of the list this operation is equivalent to append. |
| 156 | /// This operation is O(N). | 165 | /// This operation is O(N). |
| 157 | /// Invalidates element pointers if additional memory is needed. | 166 | /// Invalidates element pointers if additional memory is needed. |
| 167 | /// Invalidates pre-existing pointers to elements at and after `index`. | ||
| 158 | /// Asserts that the index is in bounds or equal to the length. | 168 | /// Asserts that the index is in bounds or equal to the length. |
| 159 | pub fn insert(self: *Self, i: usize, item: T) Allocator.Error!void { | 169 | pub fn insert(self: *Self, index: usize, item: T) Allocator.Error!void { |
| 160 | const dst = try self.addManyAt(i, 1); | 170 | self.pointer_stability.assertUnlocked(); |
| 171 | const dst = try self.addManyAt(index, 1); | ||
| 161 | dst[0] = item; | 172 | dst[0] = item; |
| 162 | } | 173 | } |
| 163 | 174 | ||
| 164 | /// Insert `item` at index `i`. Moves `list[i .. list.len]` to higher indices to make room. | 175 | /// Insert `item` at index `index`. Moves `list[index .. list.len]` to higher indices to make room. |
| 165 | /// If `i` is equal to the length of the list this operation is | 176 | /// If `index` is equal to the length of the list this operation is |
| 166 | /// equivalent to appendAssumeCapacity. | 177 | /// equivalent to appendAssumeCapacity. |
| 167 | /// This operation is O(N). | 178 | /// This operation is O(N). |
| 179 | /// Invalidates pre-existing pointers to elements at and after `index`. | ||
| 168 | /// Asserts that there is enough capacity for the new item. | 180 | /// Asserts that there is enough capacity for the new item. |
| 169 | /// Asserts that the index is in bounds or equal to the length. | 181 | /// Asserts that the index is in bounds or equal to the length. |
| 170 | pub fn insertAssumeCapacity(self: *Self, i: usize, item: T) void { | 182 | pub fn insertAssumeCapacity(self: *Self, index: usize, item: T) void { |
| 171 | self.pointer_stability.lock(); | 183 | self.pointer_stability.assertUnlocked(); |
| 172 | defer self.pointer_stability.unlock(); | ||
| 173 | |||
| 174 | assert(self.items.len < self.capacity); | 184 | assert(self.items.len < self.capacity); |
| 175 | self.items.len += 1; | 185 | self.items.len += 1; |
| 176 | 186 | @memmove(self.items[index + 1 .. self.items.len], self.items[index .. self.items.len - 1]); | |
| 177 | @memmove(self.items[i + 1 .. self.items.len], self.items[i .. self.items.len - 1]); | 187 | self.items[index] = item; |
| 178 | self.items[i] = item; | ||
| 179 | } | 188 | } |
| 180 | 189 | ||
| 181 | /// Add `count` new elements at position `index`, which have | 190 | /// Add `count` new elements at position `index`, which have |
| ... | @@ -188,12 +197,11 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type | ... | @@ -188,12 +197,11 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type |
| 188 | /// Asserts that the index is in bounds or equal to the length. | 197 | /// Asserts that the index is in bounds or equal to the length. |
| 189 | pub fn addManyAt(self: *Self, index: usize, count: usize) Allocator.Error![]T { | 198 | pub fn addManyAt(self: *Self, index: usize, count: usize) Allocator.Error![]T { |
| 190 | const new_len = try addOrOom(self.items.len, count); | 199 | const new_len = try addOrOom(self.items.len, count); |
| 200 | self.pointer_stability.assertUnlocked(); | ||
| 191 | 201 | ||
| 192 | if (self.capacity >= new_len) | 202 | if (self.capacity >= new_len) |
| 193 | return addManyAtAssumeCapacity(self, index, count); | 203 | return addManyAtAssumeCapacity(self, index, count); |
| 194 | 204 | ||
| 195 | self.pointer_stability.lock(); | ||
| 196 | defer self.pointer_stability.unlock(); | ||
| 197 | // Here we avoid copying allocated but unused bytes by | 205 | // Here we avoid copying allocated but unused bytes by |
| 198 | // attempting a resize in place, and falling back to allocating | 206 | // attempting a resize in place, and falling back to allocating |
| 199 | // a new buffer and doing our own copy. With a realloc() call, | 207 | // a new buffer and doing our own copy. With a realloc() call, |
| ... | @@ -225,9 +233,11 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type | ... | @@ -225,9 +233,11 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type |
| 225 | /// `undefined` values. Returns a slice pointing to the newly allocated | 233 | /// `undefined` values. Returns a slice pointing to the newly allocated |
| 226 | /// elements, which becomes invalid after various `ArrayList` | 234 | /// elements, which becomes invalid after various `ArrayList` |
| 227 | /// operations. | 235 | /// operations. |
| 236 | /// Invalidates pre-existing pointers to elements at and after `index`. | ||
| 228 | /// Asserts that there is enough capacity for the new elements. | 237 | /// Asserts that there is enough capacity for the new elements. |
| 229 | /// Asserts that the index is in bounds or equal to the length. | 238 | /// Asserts that the index is in bounds or equal to the length. |
| 230 | pub fn addManyAtAssumeCapacity(self: *Self, index: usize, count: usize) []T { | 239 | pub fn addManyAtAssumeCapacity(self: *Self, index: usize, count: usize) []T { |
| 240 | self.pointer_stability.assertUnlocked(); | ||
| 231 | const new_len = self.items.len + count; | 241 | const new_len = self.items.len + count; |
| 232 | assert(self.capacity >= new_len); | 242 | assert(self.capacity >= new_len); |
| 233 | const to_move = self.items[index..]; | 243 | const to_move = self.items[index..]; |
| ... | @@ -238,7 +248,7 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type | ... | @@ -238,7 +248,7 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type |
| 238 | return result; | 248 | return result; |
| 239 | } | 249 | } |
| 240 | 250 | ||
| 241 | /// Insert slice `items` at index `i` by moving `list[i .. list.len]` to make room. | 251 | /// Insert slice `items` at index `index` by moving `list[index .. list.len]` to make room. |
| 242 | /// This operation is O(N). | 252 | /// This operation is O(N). |
| 243 | /// Invalidates pre-existing pointers to elements at and after `index`. | 253 | /// Invalidates pre-existing pointers to elements at and after `index`. |
| 244 | /// Invalidates all pre-existing element pointers if capacity must be | 254 | /// Invalidates all pre-existing element pointers if capacity must be |
| ... | @@ -254,7 +264,9 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type | ... | @@ -254,7 +264,9 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type |
| 254 | } | 264 | } |
| 255 | 265 | ||
| 256 | /// Grows or shrinks the list as necessary. | 266 | /// Grows or shrinks the list as necessary. |
| 257 | /// Invalidates element pointers if additional capacity is allocated. | 267 | /// Invalidates element pointers if additional capacity is allocated, |
| 268 | /// Invalidates pointers to elements at and above index `start + len` | ||
| 269 | /// when `len` and `new_items.len` are unequal. | ||
| 258 | /// Asserts that the range is in bounds. | 270 | /// Asserts that the range is in bounds. |
| 259 | pub fn replaceRange(self: *Self, start: usize, len: usize, new_items: []const T) Allocator.Error!void { | 271 | pub fn replaceRange(self: *Self, start: usize, len: usize, new_items: []const T) Allocator.Error!void { |
| 260 | var unmanaged = self.moveToUnmanaged(); | 272 | var unmanaged = self.moveToUnmanaged(); |
| ... | @@ -263,7 +275,8 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type | ... | @@ -263,7 +275,8 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type |
| 263 | } | 275 | } |
| 264 | 276 | ||
| 265 | /// Grows or shrinks the list as necessary. | 277 | /// Grows or shrinks the list as necessary. |
| 266 | /// Never invalidates element pointers. | 278 | /// Invalidates pointers to elements at and above index `start + len` |
| 279 | /// when `len` and `new_items.len` are unequal. | ||
| 267 | /// Asserts the capacity is enough for additional items. | 280 | /// Asserts the capacity is enough for additional items. |
| 268 | pub fn replaceRangeAssumeCapacity(self: *Self, start: usize, len: usize, new_items: []const T) void { | 281 | pub fn replaceRangeAssumeCapacity(self: *Self, start: usize, len: usize, new_items: []const T) void { |
| 269 | var unmanaged = self.moveToUnmanaged(); | 282 | var unmanaged = self.moveToUnmanaged(); |
| ... | @@ -300,10 +313,12 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type | ... | @@ -300,10 +313,12 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type |
| 300 | 313 | ||
| 301 | /// Removes the element at the specified index and returns it. | 314 | /// Removes the element at the specified index and returns it. |
| 302 | /// The empty slot is filled from the end of the list. | 315 | /// The empty slot is filled from the end of the list. |
| 316 | /// Invalidates pointers to the end of the list. | ||
| 303 | /// This operation is O(1). | 317 | /// This operation is O(1). |
| 304 | /// This may not preserve item order. Use `orderedRemove` if you need to preserve order. | 318 | /// This may not preserve item order. Use `orderedRemove` if you need to preserve order. |
| 305 | /// Asserts that the index is in bounds. | 319 | /// Asserts that the index is in bounds. |
| 306 | pub fn swapRemove(self: *Self, i: usize) T { | 320 | pub fn swapRemove(self: *Self, i: usize) T { |
| 321 | self.pointer_stability.assertUnlocked(); | ||
| 307 | const val = self.items[i]; | 322 | const val = self.items[i]; |
| 308 | self.items[i] = self.items[self.items.len - 1]; | 323 | self.items[i] = self.items[self.items.len - 1]; |
| 309 | self.items[self.items.len - 1] = undefined; | 324 | self.items[self.items.len - 1] = undefined; |
| ... | @@ -353,6 +368,8 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type | ... | @@ -353,6 +368,8 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type |
| 353 | @memcpy(self.items[old_len..][0..items.len], items); | 368 | @memcpy(self.items[old_len..][0..items.len], items); |
| 354 | } | 369 | } |
| 355 | 370 | ||
| 371 | /// Prints a formatted string into this list. | ||
| 372 | /// Invalidates element pointers if additional memory is needed. | ||
| 356 | pub fn print(self: *Self, comptime fmt: []const u8, args: anytype) error{OutOfMemory}!void { | 373 | pub fn print(self: *Self, comptime fmt: []const u8, args: anytype) error{OutOfMemory}!void { |
| 357 | const gpa = self.allocator; | 374 | const gpa = self.allocator; |
| 358 | var unmanaged = self.moveToUnmanaged(); | 375 | var unmanaged = self.moveToUnmanaged(); |
| ... | @@ -404,9 +421,7 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type | ... | @@ -404,9 +421,7 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type |
| 404 | /// Invalidates element pointers for the elements `items[new_len..]`. | 421 | /// Invalidates element pointers for the elements `items[new_len..]`. |
| 405 | /// Asserts that the new length is less than or equal to the previous length. | 422 | /// Asserts that the new length is less than or equal to the previous length. |
| 406 | pub fn shrinkRetainingCapacity(self: *Self, new_len: usize) void { | 423 | pub fn shrinkRetainingCapacity(self: *Self, new_len: usize) void { |
| 407 | self.pointer_stability.lock(); | 424 | self.pointer_stability.assertUnlocked(); |
| 408 | defer self.pointer_stability.unlock(); | ||
| 409 | |||
| 410 | assert(new_len <= self.items.len); | 425 | assert(new_len <= self.items.len); |
| 411 | @memset(self.items[new_len..], undefined); | 426 | @memset(self.items[new_len..], undefined); |
| 412 | self.items.len = new_len; | 427 | self.items.len = new_len; |
| ... | @@ -415,8 +430,7 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type | ... | @@ -415,8 +430,7 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type |
| 415 | /// Reduce length to 0. | 430 | /// Reduce length to 0. |
| 416 | /// Invalidates all element pointers. | 431 | /// Invalidates all element pointers. |
| 417 | pub fn clearRetainingCapacity(self: *Self) void { | 432 | pub fn clearRetainingCapacity(self: *Self) void { |
| 418 | self.pointer_stability.lock(); | 433 | self.pointer_stability.assertUnlocked(); |
| 419 | defer self.pointer_stability.unlock(); | ||
| 420 | @memset(self.items, undefined); | 434 | @memset(self.items, undefined); |
| 421 | self.items.len = 0; | 435 | self.items.len = 0; |
| 422 | } | 436 | } |
| ... | @@ -449,18 +463,15 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type | ... | @@ -449,18 +463,15 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type |
| 449 | /// modify the array so that it can hold exactly `new_capacity` items. | 463 | /// modify the array so that it can hold exactly `new_capacity` items. |
| 450 | /// Invalidates element pointers if additional memory is needed. | 464 | /// Invalidates element pointers if additional memory is needed. |
| 451 | pub fn ensureTotalCapacityPrecise(self: *Self, new_capacity: usize) Allocator.Error!void { | 465 | pub fn ensureTotalCapacityPrecise(self: *Self, new_capacity: usize) Allocator.Error!void { |
| 452 | self.pointer_stability.lock(); | ||
| 453 | defer self.pointer_stability.unlock(); | ||
| 454 | |||
| 455 | if (@sizeOf(T) == 0) { | 466 | if (@sizeOf(T) == 0) { |
| 456 | self.capacity = math.maxInt(usize); | 467 | self.capacity = math.maxInt(usize); |
| 457 | return; | 468 | return; |
| 458 | } | 469 | } |
| 459 | 470 | ||
| 460 | if (self.capacity >= new_capacity) return; | 471 | if (self.capacity >= new_capacity) return; |
| 461 | 472 | self.pointer_stability.assertUnlocked(); | |
| 462 | // Here we avoid copying allocated but unused bytes by | 473 | // Here we avoid copying allocated but unused bytes by |
| 463 | // attempting a resize in place, and falling back to allocating | 474 | // attempting a remap, and falling back to allocating |
| 464 | // a new buffer and doing our own copy. With a realloc() call, | 475 | // a new buffer and doing our own copy. With a realloc() call, |
| 465 | // the allocator implementation would pointlessly copy our | 476 | // the allocator implementation would pointlessly copy our |
| 466 | // extra capacity. | 477 | // extra capacity. |
| ... | @@ -491,7 +502,8 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type | ... | @@ -491,7 +502,8 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type |
| 491 | } | 502 | } |
| 492 | 503 | ||
| 493 | /// Increase length by 1, returning pointer to the new item. | 504 | /// Increase length by 1, returning pointer to the new item. |
| 494 | /// The returned pointer becomes invalid when the list resized. | 505 | /// Invalidates element pointers if additional memory is needed. |
| 506 | /// The returned pointer may be invalidated by further operations to this list. | ||
| 495 | pub fn addOne(self: *Self) Allocator.Error!*T { | 507 | pub fn addOne(self: *Self) Allocator.Error!*T { |
| 496 | // This can never overflow because `self.items` can never occupy the whole address space | 508 | // This can never overflow because `self.items` can never occupy the whole address space |
| 497 | const newlen = self.items.len + 1; | 509 | const newlen = self.items.len + 1; |
| ... | @@ -500,7 +512,7 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type | ... | @@ -500,7 +512,7 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type |
| 500 | } | 512 | } |
| 501 | 513 | ||
| 502 | /// Increase length by 1, returning pointer to the new item. | 514 | /// Increase length by 1, returning pointer to the new item. |
| 503 | /// The returned pointer becomes invalid when the list is resized. | 515 | /// The returned pointer may be invalidated by further operations to this list. |
| 504 | /// Never invalidates element pointers. | 516 | /// Never invalidates element pointers. |
| 505 | /// Asserts that the list can hold one additional item. | 517 | /// Asserts that the list can hold one additional item. |
| 506 | pub fn addOneAssumeCapacity(self: *Self) *T { | 518 | pub fn addOneAssumeCapacity(self: *Self) *T { |
| ... | @@ -511,8 +523,9 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type | ... | @@ -511,8 +523,9 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type |
| 511 | 523 | ||
| 512 | /// Resize the array, adding `n` new elements, which have `undefined` values. | 524 | /// Resize the array, adding `n` new elements, which have `undefined` values. |
| 513 | /// The return value is an array pointing to the newly allocated elements. | 525 | /// The return value is an array pointing to the newly allocated elements. |
| 514 | /// The returned pointer becomes invalid when the list is resized. | 526 | /// The returned pointer may be invalidated by further operations to this list. |
| 515 | /// Resizes list if `self.capacity` is not large enough. | 527 | /// Resizes list if `self.capacity` is not large enough. |
| 528 | /// Invalidates element pointers if additional memory is needed. | ||
| 516 | pub fn addManyAsArray(self: *Self, comptime n: usize) Allocator.Error!*[n]T { | 529 | pub fn addManyAsArray(self: *Self, comptime n: usize) Allocator.Error!*[n]T { |
| 517 | const prev_len = self.items.len; | 530 | const prev_len = self.items.len; |
| 518 | try self.resize(try addOrOom(self.items.len, n)); | 531 | try self.resize(try addOrOom(self.items.len, n)); |
| ... | @@ -522,7 +535,7 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type | ... | @@ -522,7 +535,7 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type |
| 522 | /// Resize the array, adding `n` new elements, which have `undefined` values. | 535 | /// Resize the array, adding `n` new elements, which have `undefined` values. |
| 523 | /// The return value is an array pointing to the newly allocated elements. | 536 | /// The return value is an array pointing to the newly allocated elements. |
| 524 | /// Never invalidates element pointers. | 537 | /// Never invalidates element pointers. |
| 525 | /// The returned pointer becomes invalid when the list is resized. | 538 | /// The returned pointer may be invalidated by further operations to this list. |
| 526 | /// Asserts that the list can hold the additional items. | 539 | /// Asserts that the list can hold the additional items. |
| 527 | pub fn addManyAsArrayAssumeCapacity(self: *Self, comptime n: usize) *[n]T { | 540 | pub fn addManyAsArrayAssumeCapacity(self: *Self, comptime n: usize) *[n]T { |
| 528 | assert(self.items.len + n <= self.capacity); | 541 | assert(self.items.len + n <= self.capacity); |
| ... | @@ -533,8 +546,9 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type | ... | @@ -533,8 +546,9 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type |
| 533 | 546 | ||
| 534 | /// Resize the array, adding `n` new elements, which have `undefined` values. | 547 | /// Resize the array, adding `n` new elements, which have `undefined` values. |
| 535 | /// The return value is a slice pointing to the newly allocated elements. | 548 | /// The return value is a slice pointing to the newly allocated elements. |
| 536 | /// The returned pointer becomes invalid when the list is resized. | 549 | /// The returned pointer may be invalidated by further operations to this list. |
| 537 | /// Resizes list if `self.capacity` is not large enough. | 550 | /// Resizes list if `self.capacity` is not large enough. |
| 551 | /// Invalidates element pointers if additional memory is needed. | ||
| 538 | pub fn addManyAsSlice(self: *Self, n: usize) Allocator.Error![]T { | 552 | pub fn addManyAsSlice(self: *Self, n: usize) Allocator.Error![]T { |
| 539 | const prev_len = self.items.len; | 553 | const prev_len = self.items.len; |
| 540 | try self.resize(try addOrOom(self.items.len, n)); | 554 | try self.resize(try addOrOom(self.items.len, n)); |
| ... | @@ -544,7 +558,7 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type | ... | @@ -544,7 +558,7 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type |
| 544 | /// Resize the array, adding `n` new elements, which have `undefined` values. | 558 | /// Resize the array, adding `n` new elements, which have `undefined` values. |
| 545 | /// The return value is a slice pointing to the newly allocated elements. | 559 | /// The return value is a slice pointing to the newly allocated elements. |
| 546 | /// Never invalidates element pointers. | 560 | /// Never invalidates element pointers. |
| 547 | /// The returned pointer becomes invalid when the list is resized. | 561 | /// The returned pointer may be invalidated by further operations to this list. |
| 548 | /// Asserts that the list can hold the additional items. | 562 | /// Asserts that the list can hold the additional items. |
| 549 | pub fn addManyAsSliceAssumeCapacity(self: *Self, n: usize) []T { | 563 | pub fn addManyAsSliceAssumeCapacity(self: *Self, n: usize) []T { |
| 550 | assert(self.items.len + n <= self.capacity); | 564 | assert(self.items.len + n <= self.capacity); |
| ... | @@ -554,11 +568,10 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type | ... | @@ -554,11 +568,10 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type |
| 554 | } | 568 | } |
| 555 | 569 | ||
| 556 | /// Remove and return the last element from the list, or return `null` if list is empty. | 570 | /// Remove and return the last element from the list, or return `null` if list is empty. |
| 557 | /// Invalidates element pointers to the removed element, if any. | 571 | /// Invalidates element pointers to the removed element. |
| 558 | pub fn pop(self: *Self) ?T { | 572 | pub fn pop(self: *Self) ?T { |
| 559 | if (self.items.len == 0) return null; | 573 | if (self.items.len == 0) return null; |
| 560 | self.pointer_stability.lock(); | 574 | self.pointer_stability.assertUnlocked(); |
| 561 | defer self.pointer_stability.unlock(); | ||
| 562 | const val = self.items[self.items.len - 1]; | 575 | const val = self.items[self.items.len - 1]; |
| 563 | self.items[self.items.len - 1] = undefined; | 576 | self.items[self.items.len - 1] = undefined; |
| 564 | self.items.len -= 1; | 577 | self.items.len -= 1; |
| ... | @@ -567,6 +580,7 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type | ... | @@ -567,6 +580,7 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type |
| 567 | 580 | ||
| 568 | /// Returns a slice of all the items plus the extra capacity, whose memory | 581 | /// Returns a slice of all the items plus the extra capacity, whose memory |
| 569 | /// contents are `undefined`. | 582 | /// contents are `undefined`. |
| 583 | /// The returned pointer may be invalidated by further operations to this list. | ||
| 570 | pub fn allocatedSlice(self: Self) Slice { | 584 | pub fn allocatedSlice(self: Self) Slice { |
| 571 | // `items.len` is the length, not the capacity. | 585 | // `items.len` is the length, not the capacity. |
| 572 | return self.items.ptr[0..self.capacity]; | 586 | return self.items.ptr[0..self.capacity]; |
| ... | @@ -576,18 +590,29 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type | ... | @@ -576,18 +590,29 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type |
| 576 | /// This can be useful for writing directly into an ArrayList. | 590 | /// This can be useful for writing directly into an ArrayList. |
| 577 | /// Note that such an operation must be followed up with a direct | 591 | /// Note that such an operation must be followed up with a direct |
| 578 | /// modification of `self.items.len`. | 592 | /// modification of `self.items.len`. |
| 593 | /// The returned pointer may be invalidated by further operations to this list. | ||
| 579 | pub fn unusedCapacitySlice(self: Self) []T { | 594 | pub fn unusedCapacitySlice(self: Self) []T { |
| 580 | return self.allocatedSlice()[self.items.len..]; | 595 | return self.allocatedSlice()[self.items.len..]; |
| 581 | } | 596 | } |
| 582 | 597 | ||
| 583 | /// Deprecated in favor of `getLast` | 598 | /// Deprecated in favor of `last` |
| 584 | pub const getLastOrNull = getLast; | 599 | pub const getLastOrNull = last; |
| 585 | 600 | ||
| 586 | /// Returns the last element from the list, or `null` if the list is empty. | 601 | /// Returns the last element from the list, or `null` if the list is |
| 587 | pub fn getLast(self: Self) ?T { | 602 | /// empty. |
| 603 | /// Never invalidates element pointers. | ||
| 604 | pub fn last(self: Self) ?T { | ||
| 588 | if (self.items.len == 0) return null; | 605 | if (self.items.len == 0) return null; |
| 589 | return self.items[self.items.len - 1]; | 606 | return self.items[self.items.len - 1]; |
| 590 | } | 607 | } |
| 608 | |||
| 609 | /// Returns a pointer to the last element from the list, or `null` if | ||
| 610 | /// the list is empty. | ||
| 611 | /// The returned pointer may be invalidated by further operations to this list. | ||
| 612 | pub fn lastPtr(self: Self) ?*T { | ||
| 613 | if (self.items.len == 0) return null; | ||
| 614 | return &self.items[self.items.len - 1]; | ||
| 615 | } | ||
| 591 | }; | 616 | }; |
| 592 | } | 617 | } |
| 593 | 618 | ||
| ... | @@ -613,20 +638,21 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { | ... | @@ -613,20 +638,21 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { |
| 613 | /// | 638 | /// |
| 614 | /// Pointers to elements in this slice are invalidated by various | 639 | /// Pointers to elements in this slice are invalidated by various |
| 615 | /// functions of this ArrayList in accordance with the respective | 640 | /// functions of this ArrayList in accordance with the respective |
| 616 | /// documentation. In all cases, "invalidated" means that the memory | 641 | /// documentation. |
| 617 | /// has been passed to an allocator's resize or free function. | 642 | /// An invalidated pointer may point either to valid or freed memory. |
| 618 | items: Slice, | 643 | items: Slice, |
| 619 | /// How many T values this list can hold without allocating | 644 | /// How many T values this list can hold without allocating |
| 620 | /// additional memory. | 645 | /// additional memory. |
| 621 | capacity: usize, | 646 | capacity: usize, |
| 622 | 647 | ||
| 623 | /// Used to detect memory safety violations. | 648 | /// Used to detect memory safety violations. |
| 624 | pointer_stability: debug.SafetyLock = .{}, | 649 | pointer_stability: debug.SafetyLock, |
| 625 | 650 | ||
| 626 | /// An ArrayList containing no elements. | 651 | /// An ArrayList containing no elements. |
| 627 | pub const empty: Self = .{ | 652 | pub const empty: Self = .{ |
| 628 | .items = &.{}, | 653 | .items = &.{}, |
| 629 | .capacity = 0, | 654 | .capacity = 0, |
| 655 | .pointer_stability = .{}, | ||
| 630 | }; | 656 | }; |
| 631 | 657 | ||
| 632 | pub const Slice = if (alignment) |a| ([]align(a.toByteUnits()) T) else []T; | 658 | pub const Slice = if (alignment) |a| ([]align(a.toByteUnits()) T) else []T; |
| ... | @@ -652,6 +678,7 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { | ... | @@ -652,6 +678,7 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { |
| 652 | return .{ | 678 | return .{ |
| 653 | .items = buffer[0..0], | 679 | .items = buffer[0..0], |
| 654 | .capacity = buffer.len, | 680 | .capacity = buffer.len, |
| 681 | .pointer_stability = .{}, | ||
| 655 | }; | 682 | }; |
| 656 | } | 683 | } |
| 657 | 684 | ||
| ... | @@ -682,7 +709,12 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { | ... | @@ -682,7 +709,12 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { |
| 682 | /// Convert this list into an analogous memory-managed one. | 709 | /// Convert this list into an analogous memory-managed one. |
| 683 | /// The returned list has ownership of the underlying memory. | 710 | /// The returned list has ownership of the underlying memory. |
| 684 | pub fn toManaged(self: *Self, gpa: Allocator) AlignedManaged(T, alignment) { | 711 | pub fn toManaged(self: *Self, gpa: Allocator) AlignedManaged(T, alignment) { |
| 685 | return .{ .items = self.items, .capacity = self.capacity, .allocator = gpa }; | 712 | return .{ |
| 713 | .items = self.items, | ||
| 714 | .capacity = self.capacity, | ||
| 715 | .allocator = gpa, | ||
| 716 | .pointer_stability = self.pointer_stability, | ||
| 717 | }; | ||
| 686 | } | 718 | } |
| 687 | 719 | ||
| 688 | /// ArrayList takes ownership of the passed in slice. | 720 | /// ArrayList takes ownership of the passed in slice. |
| ... | @@ -691,6 +723,7 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { | ... | @@ -691,6 +723,7 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { |
| 691 | return Self{ | 723 | return Self{ |
| 692 | .items = slice, | 724 | .items = slice, |
| 693 | .capacity = slice.len, | 725 | .capacity = slice.len, |
| 726 | .pointer_stability = .{}, | ||
| 694 | }; | 727 | }; |
| 695 | } | 728 | } |
| 696 | 729 | ||
| ... | @@ -700,13 +733,16 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { | ... | @@ -700,13 +733,16 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { |
| 700 | return Self{ | 733 | return Self{ |
| 701 | .items = slice, | 734 | .items = slice, |
| 702 | .capacity = slice.len + 1, | 735 | .capacity = slice.len + 1, |
| 736 | .pointer_stability = .{}, | ||
| 703 | }; | 737 | }; |
| 704 | } | 738 | } |
| 705 | 739 | ||
| 706 | /// The caller owns the returned memory. Empties this ArrayList. | 740 | /// The caller owns the returned memory. Empties this ArrayList. |
| 707 | /// Its capacity is cleared, making deinit() safe but unnecessary to call. | 741 | /// Its capacity is cleared, making deinit() safe but unnecessary to call. |
| 742 | /// May invalidate element pointers. | ||
| 708 | pub fn toOwnedSlice(self: *Self, gpa: Allocator) Allocator.Error!Slice { | 743 | pub fn toOwnedSlice(self: *Self, gpa: Allocator) Allocator.Error!Slice { |
| 709 | const old_memory = self.allocatedSlice(); | 744 | const old_memory = self.allocatedSlice(); |
| 745 | self.pointer_stability.assertUnlocked(); | ||
| 710 | if (gpa.remap(old_memory, self.items.len)) |new_items| { | 746 | if (gpa.remap(old_memory, self.items.len)) |new_items| { |
| 711 | self.* = .empty; | 747 | self.* = .empty; |
| 712 | return new_items; | 748 | return new_items; |
| ... | @@ -719,7 +755,9 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { | ... | @@ -719,7 +755,9 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { |
| 719 | } | 755 | } |
| 720 | 756 | ||
| 721 | /// The caller owns the returned memory. ArrayList becomes empty. | 757 | /// The caller owns the returned memory. ArrayList becomes empty. |
| 758 | /// May invalidate element pointers. | ||
| 722 | pub fn toOwnedSliceSentinel(self: *Self, gpa: Allocator, comptime sentinel: T) Allocator.Error!SentinelSlice(sentinel) { | 759 | pub fn toOwnedSliceSentinel(self: *Self, gpa: Allocator, comptime sentinel: T) Allocator.Error!SentinelSlice(sentinel) { |
| 760 | self.pointer_stability.assertUnlocked(); | ||
| 723 | // This addition can never overflow because `self.items` can never occupy the whole address space. | 761 | // This addition can never overflow because `self.items` can never occupy the whole address space. |
| 724 | try self.ensureTotalCapacityPrecise(gpa, self.items.len + 1); | 762 | try self.ensureTotalCapacityPrecise(gpa, self.items.len + 1); |
| 725 | self.appendAssumeCapacity(sentinel); | 763 | self.appendAssumeCapacity(sentinel); |
| ... | @@ -732,6 +770,7 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { | ... | @@ -732,6 +770,7 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { |
| 732 | /// Its capacity is cleared, making deinit() safe but unnecessary to call. | 770 | /// Its capacity is cleared, making deinit() safe but unnecessary to call. |
| 733 | /// | 771 | /// |
| 734 | /// Asserts what the capacity is equal to the length. | 772 | /// Asserts what the capacity is equal to the length. |
| 773 | /// Never invalidates element pointers. | ||
| 735 | pub fn toOwnedSliceAssert(self: *Self) Slice { | 774 | pub fn toOwnedSliceAssert(self: *Self) Slice { |
| 736 | assert(self.items.len == self.capacity); | 775 | assert(self.items.len == self.capacity); |
| 737 | const items = self.items; | 776 | const items = self.items; |
| ... | @@ -741,6 +780,7 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { | ... | @@ -741,6 +780,7 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { |
| 741 | 780 | ||
| 742 | /// The caller owns the returned memory. ArrayList becomes empty. | 781 | /// The caller owns the returned memory. ArrayList becomes empty. |
| 743 | /// Asserts what the capacity is equal to the length + 1. | 782 | /// Asserts what the capacity is equal to the length + 1. |
| 783 | /// Never invalidates element pointers. | ||
| 744 | pub fn toOwnedSliceSentinelAssert(self: *Self, comptime sentinel: T) SentinelSlice(sentinel) { | 784 | pub fn toOwnedSliceSentinelAssert(self: *Self, comptime sentinel: T) SentinelSlice(sentinel) { |
| 745 | std.debug.assert(self.items.len + 1 == self.capacity); | 785 | std.debug.assert(self.items.len + 1 == self.capacity); |
| 746 | self.appendAssumeCapacity(sentinel); | 786 | self.appendAssumeCapacity(sentinel); |
| ... | @@ -755,46 +795,41 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { | ... | @@ -755,46 +795,41 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { |
| 755 | return cloned; | 795 | return cloned; |
| 756 | } | 796 | } |
| 757 | 797 | ||
| 758 | /// Insert `item` at index `i`. Moves `list[i .. list.len]` to higher indices to make room. | 798 | /// Insert `item` at index `index`. Moves `list[index .. list.len]` to higher indices to make room. |
| 759 | /// If `i` is equal to the length of the list this operation is equivalent to append. | 799 | /// If `index` is equal to the length of the list this operation is equivalent to append. |
| 760 | /// This operation is O(N). | 800 | /// This operation is O(N). |
| 761 | /// Invalidates element pointers if additional memory is needed. | 801 | /// Invalidates element pointers if additional memory is needed. |
| 802 | /// Invalidates pre-existing pointers to elements at and after `index`. | ||
| 762 | /// Asserts that the index is in bounds or equal to the length. | 803 | /// Asserts that the index is in bounds or equal to the length. |
| 763 | pub fn insert(self: *Self, gpa: Allocator, i: usize, item: T) Allocator.Error!void { | 804 | pub fn insert(self: *Self, gpa: Allocator, index: usize, item: T) Allocator.Error!void { |
| 764 | const dst = try self.addManyAt(gpa, i, 1); | 805 | self.pointer_stability.assertUnlocked(); |
| 806 | const dst = try self.addManyAt(gpa, index, 1); | ||
| 765 | dst[0] = item; | 807 | dst[0] = item; |
| 766 | } | 808 | } |
| 767 | 809 | ||
| 768 | /// Insert `item` at index `i`. Moves `list[i .. list.len]` to higher indices to make room. | 810 | /// Insert `item` at index `index`. Moves `list[index .. list.len]` to higher indices to make room. |
| 769 | /// | 811 | /// If `index` is equal to the length of the list this operation is |
| 770 | /// If `i` is equal to the length of the list this operation is equivalent to append. | 812 | /// equivalent to appendAssumeCapacity. |
| 771 | /// | ||
| 772 | /// This operation is O(N). | 813 | /// This operation is O(N). |
| 773 | /// | 814 | /// Invalidates pre-existing pointers to elements at and after `index`. |
| 774 | /// Asserts that the list has capacity for one additional item. | 815 | /// Asserts that the list has capacity for one additional item. |
| 775 | /// | ||
| 776 | /// Asserts that the index is in bounds or equal to the length. | 816 | /// Asserts that the index is in bounds or equal to the length. |
| 777 | pub fn insertAssumeCapacity(self: *Self, i: usize, item: T) void { | 817 | pub fn insertAssumeCapacity(self: *Self, index: usize, item: T) void { |
| 778 | self.pointer_stability.lock(); | 818 | self.pointer_stability.assertUnlocked(); |
| 779 | defer self.pointer_stability.unlock(); | ||
| 780 | |||
| 781 | assert(self.items.len < self.capacity); | 819 | assert(self.items.len < self.capacity); |
| 782 | self.items.len += 1; | 820 | self.items.len += 1; |
| 783 | 821 | @memmove(self.items[index + 1 .. self.items.len], self.items[index .. self.items.len - 1]); | |
| 784 | @memmove(self.items[i + 1 .. self.items.len], self.items[i .. self.items.len - 1]); | 822 | self.items[index] = item; |
| 785 | self.items[i] = item; | ||
| 786 | } | 823 | } |
| 787 | 824 | ||
| 788 | /// Insert `item` at index `i`, moving `list[i .. list.len]` to higher indices to make room. | 825 | /// Insert `item` at index `index`. Moves `list[index .. list.len]` to higher indices to make room. |
| 789 | /// | 826 | /// If `index` is equal to the length of the list this operation is |
| 790 | /// If `i` is equal to the length of the list this operation is equivalent to append. | 827 | /// equivalent to appendAssumeCapacity. |
| 791 | /// | ||
| 792 | /// This operation is O(N). | 828 | /// This operation is O(N). |
| 793 | /// | 829 | /// Invalidates pre-existing pointers to elements at and after `index`. |
| 830 | /// Asserts that the index is in bounds or equal to the length. | ||
| 794 | /// If the list lacks unused capacity for the additional item, returns | 831 | /// If the list lacks unused capacity for the additional item, returns |
| 795 | /// `error.OutOfMemory`. | 832 | /// `error.OutOfMemory`. |
| 796 | /// | ||
| 797 | /// Asserts that the index is in bounds or equal to the length. | ||
| 798 | pub fn insertBounded(self: *Self, i: usize, item: T) error{OutOfMemory}!void { | 833 | pub fn insertBounded(self: *Self, i: usize, item: T) error{OutOfMemory}!void { |
| 799 | if (self.capacity - self.items.len == 0) return error.OutOfMemory; | 834 | if (self.capacity - self.items.len == 0) return error.OutOfMemory; |
| 800 | return insertAssumeCapacity(self, i, item); | 835 | return insertAssumeCapacity(self, i, item); |
| ... | @@ -814,21 +849,48 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { | ... | @@ -814,21 +849,48 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { |
| 814 | index: usize, | 849 | index: usize, |
| 815 | count: usize, | 850 | count: usize, |
| 816 | ) Allocator.Error![]T { | 851 | ) Allocator.Error![]T { |
| 817 | var managed = self.toManaged(gpa); | 852 | const new_len = try addOrOom(self.items.len, count); |
| 818 | defer self.* = managed.moveToUnmanaged(); | 853 | self.pointer_stability.assertUnlocked(); |
| 819 | return managed.addManyAt(index, count); | 854 | |
| 855 | if (self.capacity >= new_len) | ||
| 856 | return addManyAtAssumeCapacity(self, index, count); | ||
| 857 | |||
| 858 | // Here we avoid copying allocated but unused bytes by | ||
| 859 | // attempting a resize in place, and falling back to allocating | ||
| 860 | // a new buffer and doing our own copy. With a realloc() call, | ||
| 861 | // the allocator implementation would pointlessly copy our | ||
| 862 | // extra capacity. | ||
| 863 | const new_capacity = Aligned(T, alignment).growCapacity(new_len); | ||
| 864 | const old_memory = self.allocatedSlice(); | ||
| 865 | if (gpa.remap(old_memory, new_capacity)) |new_memory| { | ||
| 866 | self.items.ptr = new_memory.ptr; | ||
| 867 | self.capacity = new_memory.len; | ||
| 868 | return addManyAtAssumeCapacity(self, index, count); | ||
| 869 | } | ||
| 870 | |||
| 871 | // Make a new allocation, avoiding `ensureTotalCapacity` in order | ||
| 872 | // to avoid extra memory copies. | ||
| 873 | const new_memory = try gpa.alignedAlloc(T, alignment, new_capacity); | ||
| 874 | const to_move = self.items[index..]; | ||
| 875 | @memcpy(new_memory[0..index], self.items[0..index]); | ||
| 876 | @memcpy(new_memory[index + count ..][0..to_move.len], to_move); | ||
| 877 | gpa.free(old_memory); | ||
| 878 | self.items = new_memory[0..new_len]; | ||
| 879 | self.capacity = new_memory.len; | ||
| 880 | // The inserted elements at `new_memory[index..][0..count]` have | ||
| 881 | // already been set to `undefined` by memory allocation. | ||
| 882 | return new_memory[index..][0..count]; | ||
| 820 | } | 883 | } |
| 821 | 884 | ||
| 822 | /// Add `count` new elements at position `index`, which have | 885 | /// Add `count` new elements at position `index`, which have |
| 823 | /// `undefined` values. Returns a slice pointing to the newly allocated | 886 | /// `undefined` values. Returns a slice pointing to the newly allocated |
| 824 | /// elements, which becomes invalid after various `ArrayList` | 887 | /// elements, which becomes invalid after various `ArrayList` |
| 825 | /// operations. | 888 | /// operations. |
| 889 | /// Invalidates pre-existing pointers to elements at and after `index`. | ||
| 826 | /// Asserts that the list has capacity for the additional items. | 890 | /// Asserts that the list has capacity for the additional items. |
| 827 | /// Asserts that the index is in bounds or equal to the length. | 891 | /// Asserts that the index is in bounds or equal to the length. |
| 828 | pub fn addManyAtAssumeCapacity(self: *Self, index: usize, count: usize) []T { | 892 | pub fn addManyAtAssumeCapacity(self: *Self, index: usize, count: usize) []T { |
| 829 | self.pointer_stability.lock(); | 893 | self.pointer_stability.assertUnlocked(); |
| 830 | defer self.pointer_stability.unlock(); | ||
| 831 | |||
| 832 | const new_len = self.items.len + count; | 894 | const new_len = self.items.len + count; |
| 833 | assert(self.capacity >= new_len); | 895 | assert(self.capacity >= new_len); |
| 834 | const to_move = self.items[index..]; | 896 | const to_move = self.items[index..]; |
| ... | @@ -843,17 +905,16 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { | ... | @@ -843,17 +905,16 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { |
| 843 | /// `undefined` values, returning a slice pointing to the newly | 905 | /// `undefined` values, returning a slice pointing to the newly |
| 844 | /// allocated elements, which becomes invalid after various `ArrayList` | 906 | /// allocated elements, which becomes invalid after various `ArrayList` |
| 845 | /// operations. | 907 | /// operations. |
| 846 | /// | 908 | /// Invalidates pre-existing pointers to elements at and after `index`. |
| 847 | /// If the list lacks unused capacity for the additional items, returns | 909 | /// If the list lacks unused capacity for the additional items, returns |
| 848 | /// `error.OutOfMemory`. | 910 | /// `error.OutOfMemory`. |
| 849 | /// | ||
| 850 | /// Asserts that the index is in bounds or equal to the length. | 911 | /// Asserts that the index is in bounds or equal to the length. |
| 851 | pub fn addManyAtBounded(self: *Self, index: usize, count: usize) error{OutOfMemory}![]T { | 912 | pub fn addManyAtBounded(self: *Self, index: usize, count: usize) error{OutOfMemory}![]T { |
| 852 | if (self.capacity - self.items.len < count) return error.OutOfMemory; | 913 | if (self.capacity - self.items.len < count) return error.OutOfMemory; |
| 853 | return addManyAtAssumeCapacity(self, index, count); | 914 | return addManyAtAssumeCapacity(self, index, count); |
| 854 | } | 915 | } |
| 855 | 916 | ||
| 856 | /// Insert slice `items` at index `i` by moving `list[i .. list.len]` to make room. | 917 | /// Insert slice `items` at index `index` by moving `list[index .. list.len]` to make room. |
| 857 | /// This operation is O(N). | 918 | /// This operation is O(N). |
| 858 | /// Invalidates pre-existing pointers to elements at and after `index`. | 919 | /// Invalidates pre-existing pointers to elements at and after `index`. |
| 859 | /// Invalidates all pre-existing element pointers if capacity must be | 920 | /// Invalidates all pre-existing element pointers if capacity must be |
| ... | @@ -873,7 +934,7 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { | ... | @@ -873,7 +934,7 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { |
| 873 | @memcpy(dst, items); | 934 | @memcpy(dst, items); |
| 874 | } | 935 | } |
| 875 | 936 | ||
| 876 | /// Insert slice `items` at index `i` by moving `list[i .. list.len]` to make room. | 937 | /// Insert slice `items` at index `index` by moving `list[index .. list.len]` to make room. |
| 877 | /// This operation is O(N). | 938 | /// This operation is O(N). |
| 878 | /// Invalidates pre-existing pointers to elements at and after `index`. | 939 | /// Invalidates pre-existing pointers to elements at and after `index`. |
| 879 | /// Asserts that the list has capacity for the additional items. | 940 | /// Asserts that the list has capacity for the additional items. |
| ... | @@ -887,7 +948,7 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { | ... | @@ -887,7 +948,7 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { |
| 887 | @memcpy(dst, items); | 948 | @memcpy(dst, items); |
| 888 | } | 949 | } |
| 889 | 950 | ||
| 890 | /// Insert slice `items` at index `i` by moving `list[i .. list.len]` to make room. | 951 | /// Insert slice `items` at index `index` by moving `list[index .. list.len]` to make room. |
| 891 | /// This operation is O(N). | 952 | /// This operation is O(N). |
| 892 | /// Invalidates pre-existing pointers to elements at and after `index`. | 953 | /// Invalidates pre-existing pointers to elements at and after `index`. |
| 893 | /// If the list lacks unused capacity for the additional items, returns | 954 | /// If the list lacks unused capacity for the additional items, returns |
| ... | @@ -903,7 +964,9 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { | ... | @@ -903,7 +964,9 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { |
| 903 | } | 964 | } |
| 904 | 965 | ||
| 905 | /// Grows or shrinks the list as necessary. | 966 | /// Grows or shrinks the list as necessary. |
| 906 | /// Invalidates element pointers if additional capacity is allocated. | 967 | /// Invalidates element pointers if additional capacity is allocated, |
| 968 | /// Invalidates pointers to elements at and above index `start + len` | ||
| 969 | /// when `len` and `new_items.len` are unequal. | ||
| 907 | /// Asserts that the range is in bounds. | 970 | /// Asserts that the range is in bounds. |
| 908 | pub fn replaceRange( | 971 | pub fn replaceRange( |
| 909 | self: *Self, | 972 | self: *Self, |
| ... | @@ -917,9 +980,8 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { | ... | @@ -917,9 +980,8 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { |
| 917 | } | 980 | } |
| 918 | 981 | ||
| 919 | /// Grows or shrinks the list as necessary. | 982 | /// Grows or shrinks the list as necessary. |
| 920 | /// | 983 | /// Invalidates pointers to elements at and above index `start + len` |
| 921 | /// Never invalidates element pointers. | 984 | /// when `len` and `new_items.len` are unequal. |
| 922 | /// | ||
| 923 | /// Asserts the capacity is enough for additional items. | 985 | /// Asserts the capacity is enough for additional items. |
| 924 | pub fn replaceRangeAssumeCapacity( | 986 | pub fn replaceRangeAssumeCapacity( |
| 925 | self: *Self, | 987 | self: *Self, |
| ... | @@ -928,7 +990,7 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { | ... | @@ -928,7 +990,7 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { |
| 928 | new_items: []const T, | 990 | new_items: []const T, |
| 929 | ) void { | 991 | ) void { |
| 930 | std.debug.assert(self.capacity - self.items.len >= new_items.len -| len); | 992 | std.debug.assert(self.capacity - self.items.len >= new_items.len -| len); |
| 931 | 993 | self.pointer_stability.assertUnlocked(); | |
| 932 | const tail = self.items[start + len ..]; | 994 | const tail = self.items[start + len ..]; |
| 933 | const vacated = self.items[self.items.len - (len -| new_items.len) ..]; | 995 | const vacated = self.items[self.items.len - (len -| new_items.len) ..]; |
| 934 | self.items.len = self.items.len - len + new_items.len; | 996 | self.items.len = self.items.len - len + new_items.len; |
| ... | @@ -937,10 +999,8 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { | ... | @@ -937,10 +999,8 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { |
| 937 | @memset(vacated, undefined); | 999 | @memset(vacated, undefined); |
| 938 | } | 1000 | } |
| 939 | 1001 | ||
| 940 | /// Grows or shrinks the list as necessary. | 1002 | /// Invalidates pointers to elements at and above index `start + len` |
| 941 | /// | 1003 | /// when `len` and `new_items.len` are unequal. |
| 942 | /// Never invalidates element pointers. | ||
| 943 | /// | ||
| 944 | /// If the unused capacity is insufficient for additional items, | 1004 | /// If the unused capacity is insufficient for additional items, |
| 945 | /// returns `error.OutOfMemory`. | 1005 | /// returns `error.OutOfMemory`. |
| 946 | pub fn replaceRangeBounded( | 1006 | pub fn replaceRangeBounded( |
| ... | @@ -1003,6 +1063,7 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { | ... | @@ -1003,6 +1063,7 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { |
| 1003 | /// | 1063 | /// |
| 1004 | /// Invalidates element pointers beyond the first deleted index. | 1064 | /// Invalidates element pointers beyond the first deleted index. |
| 1005 | pub fn orderedRemoveMany(self: *Self, sorted_indexes: []const usize) void { | 1065 | pub fn orderedRemoveMany(self: *Self, sorted_indexes: []const usize) void { |
| 1066 | self.pointer_stability.assertUnlocked(); | ||
| 1006 | if (sorted_indexes.len == 0) return; | 1067 | if (sorted_indexes.len == 0) return; |
| 1007 | var shift: usize = 1; | 1068 | var shift: usize = 1; |
| 1008 | for (sorted_indexes[0 .. sorted_indexes.len - 1], sorted_indexes[1..]) |removed, end| { | 1069 | for (sorted_indexes[0 .. sorted_indexes.len - 1], sorted_indexes[1..]) |removed, end| { |
| ... | @@ -1025,8 +1086,7 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { | ... | @@ -1025,8 +1086,7 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { |
| 1025 | /// This operation is O(1). | 1086 | /// This operation is O(1). |
| 1026 | /// Asserts that the index is in bounds. | 1087 | /// Asserts that the index is in bounds. |
| 1027 | pub fn swapRemove(self: *Self, i: usize) T { | 1088 | pub fn swapRemove(self: *Self, i: usize) T { |
| 1028 | self.pointer_stability.lock(); | 1089 | self.pointer_stability.assertUnlocked(); |
| 1029 | defer self.pointer_stability.unlock(); | ||
| 1030 | const val = self.items[i]; | 1090 | const val = self.items[i]; |
| 1031 | self.items[i] = self.items[self.items.len - 1]; | 1091 | self.items[i] = self.items[self.items.len - 1]; |
| 1032 | self.items[self.items.len - 1] = undefined; | 1092 | self.items[self.items.len - 1] = undefined; |
| ... | @@ -1043,7 +1103,7 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { | ... | @@ -1043,7 +1103,7 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { |
| 1043 | } | 1103 | } |
| 1044 | 1104 | ||
| 1045 | /// Append the slice of items to the list. | 1105 | /// Append the slice of items to the list. |
| 1046 | /// | 1106 | /// Never invalidates element pointers. |
| 1047 | /// Asserts that the list can hold the additional items. | 1107 | /// Asserts that the list can hold the additional items. |
| 1048 | pub fn appendSliceAssumeCapacity(self: *Self, items: []const T) void { | 1108 | pub fn appendSliceAssumeCapacity(self: *Self, items: []const T) void { |
| 1049 | const old_len = self.items.len; | 1109 | const old_len = self.items.len; |
| ... | @@ -1054,7 +1114,7 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { | ... | @@ -1054,7 +1114,7 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { |
| 1054 | } | 1114 | } |
| 1055 | 1115 | ||
| 1056 | /// Append the slice of items to the list. | 1116 | /// Append the slice of items to the list. |
| 1057 | /// | 1117 | /// Never invalidates element pointers. |
| 1058 | /// If the list lacks unused capacity for the additional items, returns `error.OutOfMemory`. | 1118 | /// If the list lacks unused capacity for the additional items, returns `error.OutOfMemory`. |
| 1059 | pub fn appendSliceBounded(self: *Self, items: []const T) error{OutOfMemory}!void { | 1119 | pub fn appendSliceBounded(self: *Self, items: []const T) error{OutOfMemory}!void { |
| 1060 | if (self.capacity - self.items.len < items.len) return error.OutOfMemory; | 1120 | if (self.capacity - self.items.len < items.len) return error.OutOfMemory; |
| ... | @@ -1074,7 +1134,7 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { | ... | @@ -1074,7 +1134,7 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { |
| 1074 | /// | 1134 | /// |
| 1075 | /// Intended to be used only when `appendSliceAssumeCapacity` would be | 1135 | /// Intended to be used only when `appendSliceAssumeCapacity` would be |
| 1076 | /// a compile error. | 1136 | /// a compile error. |
| 1077 | /// | 1137 | /// Never invalidates element pointers. |
| 1078 | /// Asserts that the list can hold the additional items. | 1138 | /// Asserts that the list can hold the additional items. |
| 1079 | pub fn appendUnalignedSliceAssumeCapacity(self: *Self, items: []align(1) const T) void { | 1139 | pub fn appendUnalignedSliceAssumeCapacity(self: *Self, items: []align(1) const T) void { |
| 1080 | const old_len = self.items.len; | 1140 | const old_len = self.items.len; |
| ... | @@ -1088,7 +1148,7 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { | ... | @@ -1088,7 +1148,7 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { |
| 1088 | /// | 1148 | /// |
| 1089 | /// Intended to be used only when `appendSliceAssumeCapacity` would be | 1149 | /// Intended to be used only when `appendSliceAssumeCapacity` would be |
| 1090 | /// a compile error. | 1150 | /// a compile error. |
| 1091 | /// | 1151 | /// Never invalidates element pointers. |
| 1092 | /// If the list lacks unused capacity for the additional items, returns | 1152 | /// If the list lacks unused capacity for the additional items, returns |
| 1093 | /// `error.OutOfMemory`. | 1153 | /// `error.OutOfMemory`. |
| 1094 | pub fn appendUnalignedSliceBounded(self: *Self, items: []align(1) const T) error{OutOfMemory}!void { | 1154 | pub fn appendUnalignedSliceBounded(self: *Self, items: []align(1) const T) error{OutOfMemory}!void { |
| ... | @@ -1096,6 +1156,8 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { | ... | @@ -1096,6 +1156,8 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { |
| 1096 | return appendUnalignedSliceAssumeCapacity(self, items); | 1156 | return appendUnalignedSliceAssumeCapacity(self, items); |
| 1097 | } | 1157 | } |
| 1098 | 1158 | ||
| 1159 | /// Prints a formatted string into this list. | ||
| 1160 | /// Invalidates element pointers if additional memory is needed. | ||
| 1099 | pub fn print(self: *Self, gpa: Allocator, comptime fmt: []const u8, args: anytype) error{OutOfMemory}!void { | 1161 | pub fn print(self: *Self, gpa: Allocator, comptime fmt: []const u8, args: anytype) error{OutOfMemory}!void { |
| 1100 | comptime assert(T == u8); | 1162 | comptime assert(T == u8); |
| 1101 | try self.ensureUnusedCapacity(gpa, fmt.len); | 1163 | try self.ensureUnusedCapacity(gpa, fmt.len); |
| ... | @@ -1106,6 +1168,9 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { | ... | @@ -1106,6 +1168,9 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { |
| 1106 | }; | 1168 | }; |
| 1107 | } | 1169 | } |
| 1108 | 1170 | ||
| 1171 | /// Prints a formatted string into this list. | ||
| 1172 | /// Asserts that there is enough capacity for the write. | ||
| 1173 | /// Never invalidates element pointers. | ||
| 1109 | pub fn printAssumeCapacity(self: *Self, comptime fmt: []const u8, args: anytype) void { | 1174 | pub fn printAssumeCapacity(self: *Self, comptime fmt: []const u8, args: anytype) void { |
| 1110 | comptime assert(T == u8); | 1175 | comptime assert(T == u8); |
| 1111 | var w: std.Io.Writer = .fixed(self.unusedCapacitySlice()); | 1176 | var w: std.Io.Writer = .fixed(self.unusedCapacitySlice()); |
| ... | @@ -1113,6 +1178,9 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { | ... | @@ -1113,6 +1178,9 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { |
| 1113 | self.items.len += w.end; | 1178 | self.items.len += w.end; |
| 1114 | } | 1179 | } |
| 1115 | 1180 | ||
| 1181 | /// Prints a formatted string into this list. | ||
| 1182 | /// Returns error.OutOfMemory if additional capacity is needed for the write. | ||
| 1183 | /// Never invalidates element pointers. | ||
| 1116 | pub fn printBounded(self: *Self, comptime fmt: []const u8, args: anytype) error{OutOfMemory}!void { | 1184 | pub fn printBounded(self: *Self, comptime fmt: []const u8, args: anytype) error{OutOfMemory}!void { |
| 1117 | comptime assert(T == u8); | 1185 | comptime assert(T == u8); |
| 1118 | var w: std.Io.Writer = .fixed(self.unusedCapacitySlice()); | 1186 | var w: std.Io.Writer = .fixed(self.unusedCapacitySlice()); |
| ... | @@ -1188,8 +1256,7 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { | ... | @@ -1188,8 +1256,7 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { |
| 1188 | /// Asserts that the new length is less than or equal to the previous length. | 1256 | /// Asserts that the new length is less than or equal to the previous length. |
| 1189 | /// If succeds capacity is guaranteed to be equal to the length. | 1257 | /// If succeds capacity is guaranteed to be equal to the length. |
| 1190 | pub fn shrinkAndFreePrecise(self: *Self, gpa: Allocator, new_len: usize) Allocator.Error!void { | 1258 | pub fn shrinkAndFreePrecise(self: *Self, gpa: Allocator, new_len: usize) Allocator.Error!void { |
| 1191 | self.pointer_stability.lock(); | 1259 | self.pointer_stability.assertUnlocked(); |
| 1192 | defer self.pointer_stability.unlock(); | ||
| 1193 | assert(new_len <= self.items.len); | 1260 | assert(new_len <= self.items.len); |
| 1194 | 1261 | ||
| 1195 | if (@sizeOf(T) == 0) { | 1262 | if (@sizeOf(T) == 0) { |
| ... | @@ -1243,8 +1310,7 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { | ... | @@ -1243,8 +1310,7 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { |
| 1243 | /// Keeps capacity the same. | 1310 | /// Keeps capacity the same. |
| 1244 | /// Asserts that the new length is less than or equal to the previous length. | 1311 | /// Asserts that the new length is less than or equal to the previous length. |
| 1245 | pub fn shrinkRetainingCapacity(self: *Self, new_len: usize) void { | 1312 | pub fn shrinkRetainingCapacity(self: *Self, new_len: usize) void { |
| 1246 | self.pointer_stability.lock(); | 1313 | self.pointer_stability.assertUnlocked(); |
| 1247 | defer self.pointer_stability.unlock(); | ||
| 1248 | 1314 | ||
| 1249 | assert(new_len <= self.items.len); | 1315 | assert(new_len <= self.items.len); |
| 1250 | @memset(self.items[new_len..], undefined); | 1316 | @memset(self.items[new_len..], undefined); |
| ... | @@ -1254,16 +1320,14 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { | ... | @@ -1254,16 +1320,14 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { |
| 1254 | /// Reduce length to 0. | 1320 | /// Reduce length to 0. |
| 1255 | /// Invalidates all element pointers. | 1321 | /// Invalidates all element pointers. |
| 1256 | pub fn clearRetainingCapacity(self: *Self) void { | 1322 | pub fn clearRetainingCapacity(self: *Self) void { |
| 1257 | self.pointer_stability.lock(); | 1323 | self.pointer_stability.assertUnlocked(); |
| 1258 | defer self.pointer_stability.unlock(); | ||
| 1259 | @memset(self.items, undefined); | 1324 | @memset(self.items, undefined); |
| 1260 | self.items.len = 0; | 1325 | self.items.len = 0; |
| 1261 | } | 1326 | } |
| 1262 | 1327 | ||
| 1263 | /// Invalidates all element pointers. | 1328 | /// Invalidates all element pointers. |
| 1264 | pub fn clearAndFree(self: *Self, gpa: Allocator) void { | 1329 | pub fn clearAndFree(self: *Self, gpa: Allocator) void { |
| 1265 | self.pointer_stability.lock(); | 1330 | self.pointer_stability.assertUnlocked(); |
| 1266 | defer self.pointer_stability.unlock(); | ||
| 1267 | gpa.free(self.allocatedSlice()); | 1331 | gpa.free(self.allocatedSlice()); |
| 1268 | self.items.len = 0; | 1332 | self.items.len = 0; |
| 1269 | self.capacity = 0; | 1333 | self.capacity = 0; |
| ... | @@ -1281,8 +1345,7 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { | ... | @@ -1281,8 +1345,7 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { |
| 1281 | /// modify the array so that it can hold exactly `new_capacity` items. | 1345 | /// modify the array so that it can hold exactly `new_capacity` items. |
| 1282 | /// Invalidates element pointers if additional memory is needed. | 1346 | /// Invalidates element pointers if additional memory is needed. |
| 1283 | pub fn ensureTotalCapacityPrecise(self: *Self, gpa: Allocator, new_capacity: usize) Allocator.Error!void { | 1347 | pub fn ensureTotalCapacityPrecise(self: *Self, gpa: Allocator, new_capacity: usize) Allocator.Error!void { |
| 1284 | self.pointer_stability.lock(); | 1348 | self.pointer_stability.assertUnlocked(); |
| 1285 | defer self.pointer_stability.unlock(); | ||
| 1286 | 1349 | ||
| 1287 | if (@sizeOf(T) == 0) { | 1350 | if (@sizeOf(T) == 0) { |
| 1288 | self.capacity = math.maxInt(usize); | 1351 | self.capacity = math.maxInt(usize); |
| ... | @@ -1327,7 +1390,8 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { | ... | @@ -1327,7 +1390,8 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { |
| 1327 | } | 1390 | } |
| 1328 | 1391 | ||
| 1329 | /// Increase length by 1, returning pointer to the new item. | 1392 | /// Increase length by 1, returning pointer to the new item. |
| 1330 | /// The returned element pointer becomes invalid when the list is resized. | 1393 | /// Invalidates element pointers if additional memory is needed. |
| 1394 | /// The returned pointer may be invalidated by further operations to this list. | ||
| 1331 | pub fn addOne(self: *Self, gpa: Allocator) Allocator.Error!*T { | 1395 | pub fn addOne(self: *Self, gpa: Allocator) Allocator.Error!*T { |
| 1332 | // This can never overflow because `self.items` can never occupy the whole address space | 1396 | // This can never overflow because `self.items` can never occupy the whole address space |
| 1333 | const newlen = self.items.len + 1; | 1397 | const newlen = self.items.len + 1; |
| ... | @@ -1336,11 +1400,8 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { | ... | @@ -1336,11 +1400,8 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { |
| 1336 | } | 1400 | } |
| 1337 | 1401 | ||
| 1338 | /// Increase length by 1, returning pointer to the new item. | 1402 | /// Increase length by 1, returning pointer to the new item. |
| 1339 | /// | ||
| 1340 | /// Never invalidates element pointers. | 1403 | /// Never invalidates element pointers. |
| 1341 | /// | 1404 | /// The returned pointer may be invalidated by further operations to this list. |
| 1342 | /// The returned element pointer becomes invalid when the list is resized. | ||
| 1343 | /// | ||
| 1344 | /// Asserts that the list can hold one additional item. | 1405 | /// Asserts that the list can hold one additional item. |
| 1345 | pub fn addOneAssumeCapacity(self: *Self) *T { | 1406 | pub fn addOneAssumeCapacity(self: *Self) *T { |
| 1346 | assert(self.items.len < self.capacity); | 1407 | assert(self.items.len < self.capacity); |
| ... | @@ -1350,11 +1411,8 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { | ... | @@ -1350,11 +1411,8 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { |
| 1350 | } | 1411 | } |
| 1351 | 1412 | ||
| 1352 | /// Increase length by 1, returning pointer to the new item. | 1413 | /// Increase length by 1, returning pointer to the new item. |
| 1353 | /// | ||
| 1354 | /// Never invalidates element pointers. | 1414 | /// Never invalidates element pointers. |
| 1355 | /// | 1415 | /// The returned pointer may be invalidated by further operations to this list. |
| 1356 | /// The returned element pointer becomes invalid when the list is resized. | ||
| 1357 | /// | ||
| 1358 | /// If the list lacks unused capacity for the additional item, returns `error.OutOfMemory`. | 1416 | /// If the list lacks unused capacity for the additional item, returns `error.OutOfMemory`. |
| 1359 | pub fn addOneBounded(self: *Self) error{OutOfMemory}!*T { | 1417 | pub fn addOneBounded(self: *Self) error{OutOfMemory}!*T { |
| 1360 | if (self.capacity - self.items.len < 1) return error.OutOfMemory; | 1418 | if (self.capacity - self.items.len < 1) return error.OutOfMemory; |
| ... | @@ -1362,8 +1420,9 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { | ... | @@ -1362,8 +1420,9 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { |
| 1362 | } | 1420 | } |
| 1363 | 1421 | ||
| 1364 | /// Resize the array, adding `n` new elements, which have `undefined` values. | 1422 | /// Resize the array, adding `n` new elements, which have `undefined` values. |
| 1423 | /// Invalidates element pointers if additional memory is required. | ||
| 1365 | /// The return value is an array pointing to the newly allocated elements. | 1424 | /// The return value is an array pointing to the newly allocated elements. |
| 1366 | /// The returned pointer becomes invalid when the list is resized. | 1425 | /// The returned pointer may be invalidated by further operations to this list. |
| 1367 | pub fn addManyAsArray(self: *Self, gpa: Allocator, comptime n: usize) Allocator.Error!*[n]T { | 1426 | pub fn addManyAsArray(self: *Self, gpa: Allocator, comptime n: usize) Allocator.Error!*[n]T { |
| 1368 | const prev_len = self.items.len; | 1427 | const prev_len = self.items.len; |
| 1369 | try self.resize(gpa, try addOrOom(self.items.len, n)); | 1428 | try self.resize(gpa, try addOrOom(self.items.len, n)); |
| ... | @@ -1371,13 +1430,9 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { | ... | @@ -1371,13 +1430,9 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { |
| 1371 | } | 1430 | } |
| 1372 | 1431 | ||
| 1373 | /// Resize the array, adding `n` new elements, which have `undefined` values. | 1432 | /// Resize the array, adding `n` new elements, which have `undefined` values. |
| 1374 | /// | ||
| 1375 | /// The return value is an array pointing to the newly allocated elements. | 1433 | /// The return value is an array pointing to the newly allocated elements. |
| 1376 | /// | ||
| 1377 | /// Never invalidates element pointers. | 1434 | /// Never invalidates element pointers. |
| 1378 | /// | 1435 | /// The returned pointer may be invalidated by further operations to this list. |
| 1379 | /// The returned pointer becomes invalid when the list is resized. | ||
| 1380 | /// | ||
| 1381 | /// Asserts that the list can hold the additional items. | 1436 | /// Asserts that the list can hold the additional items. |
| 1382 | pub fn addManyAsArrayAssumeCapacity(self: *Self, comptime n: usize) *[n]T { | 1437 | pub fn addManyAsArrayAssumeCapacity(self: *Self, comptime n: usize) *[n]T { |
| 1383 | assert(self.items.len + n <= self.capacity); | 1438 | assert(self.items.len + n <= self.capacity); |
| ... | @@ -1387,13 +1442,9 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { | ... | @@ -1387,13 +1442,9 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { |
| 1387 | } | 1442 | } |
| 1388 | 1443 | ||
| 1389 | /// Resize the array, adding `n` new elements, which have `undefined` values. | 1444 | /// Resize the array, adding `n` new elements, which have `undefined` values. |
| 1390 | /// | ||
| 1391 | /// The return value is an array pointing to the newly allocated elements. | 1445 | /// The return value is an array pointing to the newly allocated elements. |
| 1392 | /// | ||
| 1393 | /// Never invalidates element pointers. | 1446 | /// Never invalidates element pointers. |
| 1394 | /// | 1447 | /// The returned pointer may be invalidated by further operations to this list. |
| 1395 | /// The returned pointer becomes invalid when the list is resized. | ||
| 1396 | /// | ||
| 1397 | /// If the list lacks unused capacity for the additional items, returns | 1448 | /// If the list lacks unused capacity for the additional items, returns |
| 1398 | /// `error.OutOfMemory`. | 1449 | /// `error.OutOfMemory`. |
| 1399 | pub fn addManyAsArrayBounded(self: *Self, comptime n: usize) error{OutOfMemory}!*[n]T { | 1450 | pub fn addManyAsArrayBounded(self: *Self, comptime n: usize) error{OutOfMemory}!*[n]T { |
| ... | @@ -1403,7 +1454,7 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { | ... | @@ -1403,7 +1454,7 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { |
| 1403 | 1454 | ||
| 1404 | /// Resize the array, adding `n` new elements, which have `undefined` values. | 1455 | /// Resize the array, adding `n` new elements, which have `undefined` values. |
| 1405 | /// The return value is a slice pointing to the newly allocated elements. | 1456 | /// The return value is a slice pointing to the newly allocated elements. |
| 1406 | /// The returned pointer becomes invalid when the list is resized. | 1457 | /// The returned pointer may be invalidated by further operations to this list. |
| 1407 | /// Resizes list if `self.capacity` is not large enough. | 1458 | /// Resizes list if `self.capacity` is not large enough. |
| 1408 | pub fn addManyAsSlice(self: *Self, gpa: Allocator, n: usize) Allocator.Error![]T { | 1459 | pub fn addManyAsSlice(self: *Self, gpa: Allocator, n: usize) Allocator.Error![]T { |
| 1409 | const prev_len = self.items.len; | 1460 | const prev_len = self.items.len; |
| ... | @@ -1413,10 +1464,8 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { | ... | @@ -1413,10 +1464,8 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { |
| 1413 | 1464 | ||
| 1414 | /// Resizes the array, adding `n` new elements, which have `undefined` | 1465 | /// Resizes the array, adding `n` new elements, which have `undefined` |
| 1415 | /// values, returning a slice pointing to the newly allocated elements. | 1466 | /// values, returning a slice pointing to the newly allocated elements. |
| 1416 | /// | 1467 | /// Never invalidates element pointers. |
| 1417 | /// Never invalidates element pointers. The returned pointer becomes | 1468 | /// The returned pointer may be invalidated by further operations to this list. |
| 1418 | /// invalid when the list is resized. | ||
| 1419 | /// | ||
| 1420 | /// Asserts that the list can hold the additional items. | 1469 | /// Asserts that the list can hold the additional items. |
| 1421 | pub fn addManyAsSliceAssumeCapacity(self: *Self, n: usize) []T { | 1470 | pub fn addManyAsSliceAssumeCapacity(self: *Self, n: usize) []T { |
| 1422 | assert(self.items.len + n <= self.capacity); | 1471 | assert(self.items.len + n <= self.capacity); |
| ... | @@ -1427,10 +1476,8 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { | ... | @@ -1427,10 +1476,8 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { |
| 1427 | 1476 | ||
| 1428 | /// Resizes the array, adding `n` new elements, which have `undefined` | 1477 | /// Resizes the array, adding `n` new elements, which have `undefined` |
| 1429 | /// values, returning a slice pointing to the newly allocated elements. | 1478 | /// values, returning a slice pointing to the newly allocated elements. |
| 1430 | /// | 1479 | /// Never invalidates element pointers. |
| 1431 | /// Never invalidates element pointers. The returned pointer becomes | 1480 | /// The returned pointer may be invalidated by further operations to this list. |
| 1432 | /// invalid when the list is resized. | ||
| 1433 | /// | ||
| 1434 | /// If the list lacks unused capacity for the additional items, returns | 1481 | /// If the list lacks unused capacity for the additional items, returns |
| 1435 | /// `error.OutOfMemory`. | 1482 | /// `error.OutOfMemory`. |
| 1436 | pub fn addManyAsSliceBounded(self: *Self, n: usize) error{OutOfMemory}![]T { | 1483 | pub fn addManyAsSliceBounded(self: *Self, n: usize) error{OutOfMemory}![]T { |
| ... | @@ -1443,8 +1490,7 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { | ... | @@ -1443,8 +1490,7 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { |
| 1443 | /// Invalidates pointers to last element. | 1490 | /// Invalidates pointers to last element. |
| 1444 | pub fn pop(self: *Self) ?T { | 1491 | pub fn pop(self: *Self) ?T { |
| 1445 | if (self.items.len == 0) return null; | 1492 | if (self.items.len == 0) return null; |
| 1446 | self.pointer_stability.lock(); | 1493 | self.pointer_stability.assertUnlocked(); |
| 1447 | defer self.pointer_stability.unlock(); | ||
| 1448 | 1494 | ||
| 1449 | const val = self.items[self.items.len - 1]; | 1495 | const val = self.items[self.items.len - 1]; |
| 1450 | self.items[self.items.len - 1] = undefined; | 1496 | self.items[self.items.len - 1] = undefined; |
| ... | @@ -1454,6 +1500,7 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { | ... | @@ -1454,6 +1500,7 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { |
| 1454 | 1500 | ||
| 1455 | /// Returns a slice of all the items plus the extra capacity, whose memory | 1501 | /// Returns a slice of all the items plus the extra capacity, whose memory |
| 1456 | /// contents are `undefined`. | 1502 | /// contents are `undefined`. |
| 1503 | /// The returned pointer may be invalidated by further operations to this list. | ||
| 1457 | pub fn allocatedSlice(self: Self) Slice { | 1504 | pub fn allocatedSlice(self: Self) Slice { |
| 1458 | return self.items.ptr[0..self.capacity]; | 1505 | return self.items.ptr[0..self.capacity]; |
| 1459 | } | 1506 | } |
| ... | @@ -1462,19 +1509,22 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { | ... | @@ -1462,19 +1509,22 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type { |
| 1462 | /// This can be useful for writing directly into an ArrayList. | 1509 | /// This can be useful for writing directly into an ArrayList. |
| 1463 | /// Note that such an operation must be followed up with a direct | 1510 | /// Note that such an operation must be followed up with a direct |
| 1464 | /// modification of `self.items.len`. | 1511 | /// modification of `self.items.len`. |
| 1512 | /// The returned pointer may be invalidated by further operations to this list. | ||
| 1465 | pub fn unusedCapacitySlice(self: Self) []T { | 1513 | pub fn unusedCapacitySlice(self: Self) []T { |
| 1466 | return self.allocatedSlice()[self.items.len..]; | 1514 | return self.allocatedSlice()[self.items.len..]; |
| 1467 | } | 1515 | } |
| 1468 | 1516 | ||
| 1469 | /// Deprecated in favor of `last`. | 1517 | /// Returns the last element from the list, or `null` if the list is |
| 1470 | pub fn getLast(self: Self) ?T { | 1518 | /// empty. |
| 1519 | pub fn last(self: Self) ?T { | ||
| 1471 | if (self.items.len == 0) return null; | 1520 | if (self.items.len == 0) return null; |
| 1472 | return self.items[self.items.len - 1]; | 1521 | return self.items[self.items.len - 1]; |
| 1473 | } | 1522 | } |
| 1474 | 1523 | ||
| 1475 | /// Returns a pointer to the last element from the list, or `null` if | 1524 | /// Returns a pointer to the last element from the list, or `null` if |
| 1476 | /// the list is empty. | 1525 | /// the list is empty. |
| 1477 | pub fn last(self: Self) ?*T { | 1526 | /// The returned pointer may be invalidated by further operations to this list. |
| 1527 | pub fn lastPtr(self: Self) ?*T { | ||
| 1478 | if (self.items.len == 0) return null; | 1528 | if (self.items.len == 0) return null; |
| 1479 | return &self.items[self.items.len - 1]; | 1529 | return &self.items[self.items.len - 1]; |
| 1480 | } | 1530 | } |
| ... | @@ -2441,6 +2491,10 @@ test "Managed(u0)" { | ... | @@ -2441,6 +2491,10 @@ test "Managed(u0)" { |
| 2441 | count += 1; | 2491 | count += 1; |
| 2442 | } | 2492 | } |
| 2443 | try testing.expectEqual(count, 3); | 2493 | try testing.expectEqual(count, 3); |
| 2494 | |||
| 2495 | const ownedSlice = try list.toOwnedSlice(); | ||
| 2496 | defer a.free(ownedSlice); | ||
| 2497 | try testing.expectEqualSlices(u0, ownedSlice, &.{ 0, 0, 0 }); | ||
| 2444 | } | 2498 | } |
| 2445 | 2499 | ||
| 2446 | test "Managed(?u32).pop()" { | 2500 | test "Managed(?u32).pop()" { |
| ... | @@ -2469,7 +2523,7 @@ test "last" { | ... | @@ -2469,7 +2523,7 @@ test "last" { |
| 2469 | try testing.expectEqual(list.last(), null); | 2523 | try testing.expectEqual(list.last(), null); |
| 2470 | 2524 | ||
| 2471 | try list.append(a, 2); | 2525 | try list.append(a, 2); |
| 2472 | try testing.expectEqual(list.last().?.*, 2); | 2526 | try testing.expectEqual(list.last().?, 2); |
| 2473 | } | 2527 | } |
| 2474 | 2528 | ||
| 2475 | test "return OutOfMemory when capacity would exceed maximum usize integer value" { | 2529 | test "return OutOfMemory when capacity would exceed maximum usize integer value" { |
| ... | @@ -2481,6 +2535,7 @@ test "return OutOfMemory when capacity would exceed maximum usize integer value" | ... | @@ -2481,6 +2535,7 @@ test "return OutOfMemory when capacity would exceed maximum usize integer value" |
| 2481 | var list: ArrayList(u32) = .{ | 2535 | var list: ArrayList(u32) = .{ |
| 2482 | .items = undefined, | 2536 | .items = undefined, |
| 2483 | .capacity = math.maxInt(usize) - 1, | 2537 | .capacity = math.maxInt(usize) - 1, |
| 2538 | .pointer_stability = .{}, | ||
| 2484 | }; | 2539 | }; |
| 2485 | list.items.len = math.maxInt(usize) - 1; | 2540 | list.items.len = math.maxInt(usize) - 1; |
| 2486 | 2541 | ||
| ... | @@ -2499,6 +2554,7 @@ test "return OutOfMemory when capacity would exceed maximum usize integer value" | ... | @@ -2499,6 +2554,7 @@ test "return OutOfMemory when capacity would exceed maximum usize integer value" |
| 2499 | .items = undefined, | 2554 | .items = undefined, |
| 2500 | .capacity = math.maxInt(usize) - 1, | 2555 | .capacity = math.maxInt(usize) - 1, |
| 2501 | .allocator = a, | 2556 | .allocator = a, |
| 2557 | .pointer_stability = .{}, | ||
| 2502 | }; | 2558 | }; |
| 2503 | list.items.len = math.maxInt(usize) - 1; | 2559 | list.items.len = math.maxInt(usize) - 1; |
| 2504 | 2560 |
lib/std/ascii.zig+3-3| ... | @@ -511,11 +511,11 @@ pub const HexEscape = struct { | ... | @@ -511,11 +511,11 @@ pub const HexEscape = struct { |
| 511 | }; | 511 | }; |
| 512 | 512 | ||
| 513 | /// Replaces non-ASCII bytes with hex escapes. | 513 | /// Replaces non-ASCII bytes with hex escapes. |
| 514 | pub fn hexEscape(bytes: []const u8, case: std.fmt.Case) std.fmt.Alt(HexEscape, HexEscape.format) { | 514 | pub fn hexEscape(bytes: []const u8, case: std.fmt.Case) HexEscape { |
| 515 | return .{ .data = .{ .bytes = bytes, .charset = switch (case) { | 515 | return .{ .bytes = bytes, .charset = switch (case) { |
| 516 | .lower => HexEscape.lower_charset, | 516 | .lower => HexEscape.lower_charset, |
| 517 | .upper => HexEscape.upper_charset, | 517 | .upper => HexEscape.upper_charset, |
| 518 | } } }; | 518 | } }; |
| 519 | } | 519 | } |
| 520 | 520 | ||
| 521 | test hexEscape { | 521 | test hexEscape { |
lib/std/bit_set.zig-2| ... | @@ -1707,8 +1707,6 @@ fn testStaticBitSet(comptime Set: type) !void { | ... | @@ -1707,8 +1707,6 @@ fn testStaticBitSet(comptime Set: type) !void { |
| 1707 | } | 1707 | } |
| 1708 | 1708 | ||
| 1709 | test Integer { | 1709 | test Integer { |
| 1710 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 1711 | |||
| 1712 | try testStaticBitSet(Integer(0)); | 1710 | try testStaticBitSet(Integer(0)); |
| 1713 | try testStaticBitSet(Integer(1)); | 1711 | try testStaticBitSet(Integer(1)); |
| 1714 | try testStaticBitSet(Integer(2)); | 1712 | try testStaticBitSet(Integer(2)); |
lib/std/c.zig+52-22| ... | @@ -2821,13 +2821,14 @@ pub const SIG = switch (native_os) { | ... | @@ -2821,13 +2821,14 @@ pub const SIG = switch (native_os) { |
| 2821 | } | 2821 | } |
| 2822 | 2822 | ||
| 2823 | pub const POLL: SIG = .IO; | 2823 | pub const POLL: SIG = .IO; |
| 2824 | pub const IOT: SIG = .ABRT; | ||
| 2825 | pub const CLD: SIG = .CHLD; | ||
| 2824 | 2826 | ||
| 2825 | HUP = 1, | 2827 | HUP = 1, |
| 2826 | INT = 2, | 2828 | INT = 2, |
| 2827 | QUIT = 3, | 2829 | QUIT = 3, |
| 2828 | ILL = 4, | 2830 | ILL = 4, |
| 2829 | TRAP = 5, | 2831 | TRAP = 5, |
| 2830 | IOT = 6, | ||
| 2831 | ABRT = 6, | 2832 | ABRT = 6, |
| 2832 | EMT = 7, | 2833 | EMT = 7, |
| 2833 | FPE = 8, | 2834 | FPE = 8, |
| ... | @@ -2840,7 +2841,6 @@ pub const SIG = switch (native_os) { | ... | @@ -2840,7 +2841,6 @@ pub const SIG = switch (native_os) { |
| 2840 | TERM = 15, | 2841 | TERM = 15, |
| 2841 | USR1 = 16, | 2842 | USR1 = 16, |
| 2842 | USR2 = 17, | 2843 | USR2 = 17, |
| 2843 | CLD = 18, | ||
| 2844 | CHLD = 18, | 2844 | CHLD = 18, |
| 2845 | PWR = 19, | 2845 | PWR = 19, |
| 2846 | WINCH = 20, | 2846 | WINCH = 20, |
| ... | @@ -2991,6 +2991,7 @@ pub const SIG = switch (native_os) { | ... | @@ -2991,6 +2991,7 @@ pub const SIG = switch (native_os) { |
| 2991 | pub const UNBLOCK = 2; | 2991 | pub const UNBLOCK = 2; |
| 2992 | pub const SETMASK = 3; | 2992 | pub const SETMASK = 3; |
| 2993 | 2993 | ||
| 2994 | pub const IO: SIG = .POLL; | ||
| 2994 | pub const IOT: SIG = .ABRT; | 2995 | pub const IOT: SIG = .ABRT; |
| 2995 | 2996 | ||
| 2996 | HUP = 1, | 2997 | HUP = 1, |
| ... | @@ -9736,6 +9737,7 @@ pub const SS = switch (native_os) { | ... | @@ -9736,6 +9737,7 @@ pub const SS = switch (native_os) { |
| 9736 | 9737 | ||
| 9737 | pub const EV = switch (native_os) { | 9738 | pub const EV = switch (native_os) { |
| 9738 | .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => struct { | 9739 | .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => struct { |
| 9740 | // https://github.com/apple-oss-distributions/xnu/blob/main/bsd/sys/event.h | ||
| 9739 | /// add event to kq (implies enable) | 9741 | /// add event to kq (implies enable) |
| 9740 | pub const ADD = 0x0001; | 9742 | pub const ADD = 0x0001; |
| 9741 | /// delete event from kq | 9743 | /// delete event from kq |
| ... | @@ -9771,11 +9773,14 @@ pub const EV = switch (native_os) { | ... | @@ -9771,11 +9773,14 @@ pub const EV = switch (native_os) { |
| 9771 | pub const FLAG0 = 0x1000; | 9773 | pub const FLAG0 = 0x1000; |
| 9772 | /// filter-specific flag | 9774 | /// filter-specific flag |
| 9773 | pub const FLAG1 = 0x2000; | 9775 | pub const FLAG1 = 0x2000; |
| 9774 | /// EOF detected | 9776 | /// EOF detected (return value) |
| 9775 | pub const EOF = 0x8000; | 9777 | pub const EOF = 0x8000; |
| 9776 | /// error, data contains errno | 9778 | /// error, data contains errno (return value) |
| 9777 | pub const ERROR = 0x4000; | 9779 | pub const ERROR = 0x4000; |
| 9780 | /// use poll(2) semantics for EVFILT.READ | ||
| 9778 | pub const POLL = FLAG0; | 9781 | pub const POLL = FLAG0; |
| 9782 | /// on input, filter should actively return in the presence of OOB on the descriptor | ||
| 9783 | /// on output, indicates the presence of OOB data on the descriptor | ||
| 9779 | pub const OOBAND = FLAG1; | 9784 | pub const OOBAND = FLAG1; |
| 9780 | }, | 9785 | }, |
| 9781 | .dragonfly => struct { | 9786 | .dragonfly => struct { |
| ... | @@ -9818,6 +9823,7 @@ pub const EV = switch (native_os) { | ... | @@ -9818,6 +9823,7 @@ pub const EV = switch (native_os) { |
| 9818 | pub const EOF = 0x8000; | 9823 | pub const EOF = 0x8000; |
| 9819 | }, | 9824 | }, |
| 9820 | .freebsd => struct { | 9825 | .freebsd => struct { |
| 9826 | // https://cgit.freebsd.org/src/tree/sys/sys/event.h | ||
| 9821 | /// add event to kq (implies enable) | 9827 | /// add event to kq (implies enable) |
| 9822 | pub const ADD = 0x0001; | 9828 | pub const ADD = 0x0001; |
| 9823 | /// delete event from kq | 9829 | /// delete event from kq |
| ... | @@ -9826,12 +9832,14 @@ pub const EV = switch (native_os) { | ... | @@ -9826,12 +9832,14 @@ pub const EV = switch (native_os) { |
| 9826 | pub const ENABLE = 0x0004; | 9832 | pub const ENABLE = 0x0004; |
| 9827 | /// disable event (not reported) | 9833 | /// disable event (not reported) |
| 9828 | pub const DISABLE = 0x0008; | 9834 | pub const DISABLE = 0x0008; |
| 9835 | /// enable _ONESHOT and force trigger | ||
| 9836 | pub const FORCEONESHOT = 0x0100; | ||
| 9837 | /// do not update the udata field | ||
| 9838 | pub const KEEPUDATA = 0x0200; | ||
| 9829 | /// only report one occurrence | 9839 | /// only report one occurrence |
| 9830 | pub const ONESHOT = 0x0010; | 9840 | pub const ONESHOT = 0x0010; |
| 9831 | /// clear event state after reporting | 9841 | /// clear event state after reporting |
| 9832 | pub const CLEAR = 0x0020; | 9842 | pub const CLEAR = 0x0020; |
| 9833 | /// error, event data contains errno | ||
| 9834 | pub const ERROR = 0x4000; | ||
| 9835 | /// force immediate event output | 9843 | /// force immediate event output |
| 9836 | /// ... with or without ERROR | 9844 | /// ... with or without ERROR |
| 9837 | /// ... use KEVENT_FLAG_ERROR_EVENTS | 9845 | /// ... use KEVENT_FLAG_ERROR_EVENTS |
| ... | @@ -9839,6 +9847,18 @@ pub const EV = switch (native_os) { | ... | @@ -9839,6 +9847,18 @@ pub const EV = switch (native_os) { |
| 9839 | pub const RECEIPT = 0x0040; | 9847 | pub const RECEIPT = 0x0040; |
| 9840 | /// disable event after reporting | 9848 | /// disable event after reporting |
| 9841 | pub const DISPATCH = 0x0080; | 9849 | pub const DISPATCH = 0x0080; |
| 9850 | /// reserved by system | ||
| 9851 | pub const SYSFLAGS = 0xF000; | ||
| 9852 | /// note should be dropped | ||
| 9853 | pub const DROP = 0x1000; | ||
| 9854 | /// filter-specific flag 1 | ||
| 9855 | pub const FLAG1 = 0x2000; | ||
| 9856 | /// filter-specific flag 2 | ||
| 9857 | pub const FLAG2 = 0x4000; | ||
| 9858 | /// EOF detected (return value) | ||
| 9859 | pub const EOF = 0x8000; | ||
| 9860 | /// error, event data contains errno (return value) | ||
| 9861 | pub const ERROR = 0x4000; | ||
| 9842 | }, | 9862 | }, |
| 9843 | .openbsd => struct { | 9863 | .openbsd => struct { |
| 9844 | pub const ADD = 0x0001; | 9864 | pub const ADD = 0x0001; |
| ... | @@ -9962,6 +9982,7 @@ pub const EVFILT = switch (native_os) { | ... | @@ -9962,6 +9982,7 @@ pub const EVFILT = switch (native_os) { |
| 9962 | pub const EMPTY = 9; | 9982 | pub const EMPTY = 9; |
| 9963 | }, | 9983 | }, |
| 9964 | .freebsd => struct { | 9984 | .freebsd => struct { |
| 9985 | // https://cgit.freebsd.org/src/tree/sys/sys/event.h | ||
| 9965 | pub const READ = -1; | 9986 | pub const READ = -1; |
| 9966 | pub const WRITE = -2; | 9987 | pub const WRITE = -2; |
| 9967 | /// attached to aio requests | 9988 | /// attached to aio requests |
| ... | @@ -9978,12 +9999,18 @@ pub const EVFILT = switch (native_os) { | ... | @@ -9978,12 +9999,18 @@ pub const EVFILT = switch (native_os) { |
| 9978 | pub const PROCDESC = -8; | 9999 | pub const PROCDESC = -8; |
| 9979 | /// Filesystem events | 10000 | /// Filesystem events |
| 9980 | pub const FS = -9; | 10001 | pub const FS = -9; |
| 10002 | /// attached to lio requests | ||
| 9981 | pub const LIO = -10; | 10003 | pub const LIO = -10; |
| 9982 | /// User events | 10004 | /// User events |
| 9983 | pub const USER = -11; | 10005 | pub const USER = -11; |
| 9984 | /// Sendfile events | 10006 | /// Sendfile events |
| 9985 | pub const SENDFILE = -12; | 10007 | pub const SENDFILE = -12; |
| 10008 | /// empty send socket buf | ||
| 9986 | pub const EMPTY = -13; | 10009 | pub const EMPTY = -13; |
| 10010 | /// attached to struct prison | ||
| 10011 | pub const JAIL = -14; | ||
| 10012 | /// attached to jail descriptors | ||
| 10013 | pub const JAILDESC = -15; | ||
| 9987 | }, | 10014 | }, |
| 9988 | .openbsd => struct { | 10015 | .openbsd => struct { |
| 9989 | pub const READ = -1; | 10016 | pub const READ = -1; |
| ... | @@ -10002,6 +10029,7 @@ pub const EVFILT = switch (native_os) { | ... | @@ -10002,6 +10029,7 @@ pub const EVFILT = switch (native_os) { |
| 10002 | 10029 | ||
| 10003 | pub const NOTE = switch (native_os) { | 10030 | pub const NOTE = switch (native_os) { |
| 10004 | .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => struct { | 10031 | .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => struct { |
| 10032 | // https://github.com/apple-oss-distributions/xnu/blob/main/bsd/sys/event.h | ||
| 10005 | /// On input, TRIGGER causes the event to be triggered for output. | 10033 | /// On input, TRIGGER causes the event to be triggered for output. |
| 10006 | pub const TRIGGER = 0x01000000; | 10034 | pub const TRIGGER = 0x01000000; |
| 10007 | /// ignore input fflags | 10035 | /// ignore input fflags |
| ... | @@ -10033,7 +10061,7 @@ pub const NOTE = switch (native_os) { | ... | @@ -10033,7 +10061,7 @@ pub const NOTE = switch (native_os) { |
| 10033 | pub const RENAME = 0x00000020; | 10061 | pub const RENAME = 0x00000020; |
| 10034 | /// vnode access was revoked | 10062 | /// vnode access was revoked |
| 10035 | pub const REVOKE = 0x00000040; | 10063 | pub const REVOKE = 0x00000040; |
| 10036 | /// No specific vnode event: to test for EVFILT_READ activation | 10064 | /// No specific vnode event: to test for EVFILT_READ activation |
| 10037 | pub const NONE = 0x00000080; | 10065 | pub const NONE = 0x00000080; |
| 10038 | /// vnode was unlocked by flock(2) | 10066 | /// vnode was unlocked by flock(2) |
| 10039 | pub const FUNLOCK = 0x00000100; | 10067 | pub const FUNLOCK = 0x00000100; |
| ... | @@ -10045,7 +10073,7 @@ pub const NOTE = switch (native_os) { | ... | @@ -10045,7 +10073,7 @@ pub const NOTE = switch (native_os) { |
| 10045 | pub const EXEC = 0x20000000; | 10073 | pub const EXEC = 0x20000000; |
| 10046 | /// shared with EVFILT_SIGNAL | 10074 | /// shared with EVFILT_SIGNAL |
| 10047 | pub const SIGNAL = 0x08000000; | 10075 | pub const SIGNAL = 0x08000000; |
| 10048 | /// exit status to be returned, valid for child process only | 10076 | /// exit status to be returned, valid for child process only |
| 10049 | pub const EXITSTATUS = 0x04000000; | 10077 | pub const EXITSTATUS = 0x04000000; |
| 10050 | /// provide details on reasons for exit | 10078 | /// provide details on reasons for exit |
| 10051 | pub const EXIT_DETAIL = 0x02000000; | 10079 | pub const EXIT_DETAIL = 0x02000000; |
| ... | @@ -10056,11 +10084,11 @@ pub const NOTE = switch (native_os) { | ... | @@ -10056,11 +10084,11 @@ pub const NOTE = switch (native_os) { |
| 10056 | pub const EXIT_DECRYPTFAIL = 0x00010000; | 10084 | pub const EXIT_DECRYPTFAIL = 0x00010000; |
| 10057 | pub const EXIT_MEMORY = 0x00020000; | 10085 | pub const EXIT_MEMORY = 0x00020000; |
| 10058 | pub const EXIT_CSERROR = 0x00040000; | 10086 | pub const EXIT_CSERROR = 0x00040000; |
| 10059 | /// will react on memory pressure | 10087 | /// will react on memory pressure |
| 10060 | pub const VM_PRESSURE = 0x80000000; | 10088 | pub const VM_PRESSURE = 0x80000000; |
| 10061 | /// will quit on memory pressure, possibly after cleaning up dirty state | 10089 | /// will quit on memory pressure, possibly after cleaning up dirty state |
| 10062 | pub const VM_PRESSURE_TERMINATE = 0x40000000; | 10090 | pub const VM_PRESSURE_TERMINATE = 0x40000000; |
| 10063 | /// will quit immediately on memory pressure | 10091 | /// will quit immediately on memory pressure |
| 10064 | pub const VM_PRESSURE_SUDDEN_TERMINATE = 0x20000000; | 10092 | pub const VM_PRESSURE_SUDDEN_TERMINATE = 0x20000000; |
| 10065 | /// there was an error | 10093 | /// there was an error |
| 10066 | pub const VM_ERROR = 0x10000000; | 10094 | pub const VM_ERROR = 0x10000000; |
| ... | @@ -10078,6 +10106,9 @@ pub const NOTE = switch (native_os) { | ... | @@ -10078,6 +10106,9 @@ pub const NOTE = switch (native_os) { |
| 10078 | pub const CRITICAL = 0x00000020; | 10106 | pub const CRITICAL = 0x00000020; |
| 10079 | /// system does maximum timer coalescing | 10107 | /// system does maximum timer coalescing |
| 10080 | pub const BACKGROUND = 0x00000040; | 10108 | pub const BACKGROUND = 0x00000040; |
| 10109 | /// with ABSOLUTE: causes the timer to continue to tick across sleep, still uses gettimeofday epoch | ||
| 10110 | /// with MACHTIME and ABSOLUTE: uses mach continuous time epoch | ||
| 10111 | /// without ABSOLUTE: continues to tick across sleep | ||
| 10081 | pub const MACH_CONTINUOUS_TIME = 0x00000080; | 10112 | pub const MACH_CONTINUOUS_TIME = 0x00000080; |
| 10082 | /// data is mach absolute time units | 10113 | /// data is mach absolute time units |
| 10083 | pub const MACHTIME = 0x00000100; | 10114 | pub const MACHTIME = 0x00000100; |
| ... | @@ -11237,31 +11268,30 @@ pub const signalfd_siginfo = illumos.signalfd_siginfo; | ... | @@ -11237,31 +11268,30 @@ pub const signalfd_siginfo = illumos.signalfd_siginfo; |
| 11237 | pub const taskid_t = illumos.taskid_t; | 11268 | pub const taskid_t = illumos.taskid_t; |
| 11238 | pub const zoneid_t = illumos.zoneid_t; | 11269 | pub const zoneid_t = illumos.zoneid_t; |
| 11239 | 11270 | ||
| 11271 | pub const B_ABSOLUTE_TIMEOUT = haiku.B_ABSOLUTE_TIMEOUT; | ||
| 11272 | pub const B_OS_NAME_LENGTH = haiku.B_OS_NAME_LENGTH; | ||
| 11273 | pub const B_TIMEOUT_REAL_TIME_BASE = haiku.B_TIMEOUT_REAL_TIME_BASE; | ||
| 11240 | pub const DirEnt = haiku.DirEnt; | 11274 | pub const DirEnt = haiku.DirEnt; |
| 11241 | pub const _get_next_area_info = haiku._get_next_area_info; | 11275 | pub const _kern_acquire_sem_etc = haiku._kern_acquire_sem_etc; |
| 11242 | pub const _get_next_image_info = haiku._get_next_image_info; | 11276 | pub const _kern_create_sem = haiku._kern_create_sem; |
| 11243 | pub const _get_team_info = haiku._get_team_info; | 11277 | pub const _kern_delete_sem = haiku._kern_delete_sem; |
| 11244 | pub const _kern_get_current_team = haiku._kern_get_current_team; | ||
| 11245 | pub const _kern_open_dir = haiku._kern_open_dir; | 11278 | pub const _kern_open_dir = haiku._kern_open_dir; |
| 11246 | pub const _kern_read_dir = haiku._kern_read_dir; | 11279 | pub const _kern_read_dir = haiku._kern_read_dir; |
| 11247 | pub const _kern_read_stat = haiku._kern_read_stat; | 11280 | pub const _kern_read_stat = haiku._kern_read_stat; |
| 11281 | pub const _kern_release_sem_etc = haiku._kern_release_sem_etc; | ||
| 11248 | pub const _kern_rewind_dir = haiku._kern_rewind_dir; | 11282 | pub const _kern_rewind_dir = haiku._kern_rewind_dir; |
| 11249 | pub const readv_pos = haiku.readv_pos; | ||
| 11250 | pub const writev_pos = haiku.writev_pos; | ||
| 11251 | pub const area_id = haiku.area_id; | 11283 | pub const area_id = haiku.area_id; |
| 11252 | pub const area_info = haiku.area_info; | ||
| 11253 | pub const directory_which = haiku.directory_which; | ||
| 11254 | pub const find_directory = haiku.find_directory; | ||
| 11255 | pub const find_thread = haiku.find_thread; | 11284 | pub const find_thread = haiku.find_thread; |
| 11256 | pub const get_system_info = haiku.get_system_info; | 11285 | pub const get_system_info = haiku.get_system_info; |
| 11257 | pub const image_info = haiku.image_info; | 11286 | pub const on_exit_thread = haiku.on_exit_thread; |
| 11258 | pub const port_id = haiku.port_id; | 11287 | pub const port_id = haiku.port_id; |
| 11288 | pub const readv_pos = haiku.readv_pos; | ||
| 11259 | pub const sem_id = haiku.sem_id; | 11289 | pub const sem_id = haiku.sem_id; |
| 11260 | pub const status_t = haiku.status_t; | 11290 | pub const status_t = haiku.status_t; |
| 11261 | pub const system_info = haiku.system_info; | 11291 | pub const system_info = haiku.system_info; |
| 11262 | pub const team_id = haiku.team_id; | 11292 | pub const team_id = haiku.team_id; |
| 11263 | pub const team_info = haiku.team_info; | ||
| 11264 | pub const thread_id = haiku.thread_id; | 11293 | pub const thread_id = haiku.thread_id; |
| 11294 | pub const writev_pos = haiku.writev_pos; | ||
| 11265 | 11295 | ||
| 11266 | pub const AUTH = openbsd.AUTH; | 11296 | pub const AUTH = openbsd.AUTH; |
| 11267 | pub const BI = openbsd.BI; | 11297 | pub const BI = openbsd.BI; |
lib/std/c/darwin/dispatch.zig+2-2| ... | @@ -44,8 +44,8 @@ pub const once_t = enum(isize) { | ... | @@ -44,8 +44,8 @@ pub const once_t = enum(isize) { |
| 44 | once_f(predicate, context, function); | 44 | once_f(predicate, context, function); |
| 45 | } else asm volatile ("" ::: .{ .memory = true }); | 45 | } else asm volatile ("" ::: .{ .memory = true }); |
| 46 | switch (builtin.mode) { | 46 | switch (builtin.mode) { |
| 47 | .Debug, .ReleaseSafe => {}, | 47 | .debug, .safe => {}, |
| 48 | .ReleaseFast, .ReleaseSmall => if (predicate.* != .done) unreachable, | 48 | .fast, .small => if (predicate.* != .done) unreachable, |
| 49 | } | 49 | } |
| 50 | } | 50 | } |
| 51 | }; | 51 | }; |
lib/std/c/haiku.zig+18-69| ... | @@ -1,15 +1,8 @@ | ... | @@ -1,15 +1,8 @@ |
| 1 | const std = @import("../std.zig"); | 1 | const std = @import("../std.zig"); |
| 2 | const assert = std.debug.assert; | ||
| 3 | const builtin = @import("builtin"); | 2 | const builtin = @import("builtin"); |
| 4 | const maxInt = std.math.maxInt; | 3 | const assert = std.debug.assert; |
| 5 | const iovec = std.posix.iovec; | ||
| 6 | const iovec_const = std.posix.iovec_const; | ||
| 7 | const socklen_t = std.c.socklen_t; | ||
| 8 | const fd_t = std.c.fd_t; | 4 | const fd_t = std.c.fd_t; |
| 9 | const off_t = std.c.off_t; | 5 | const off_t = std.c.off_t; |
| 10 | const PATH_MAX = std.c.PATH_MAX; | ||
| 11 | const uid_t = std.c.uid_t; | ||
| 12 | const gid_t = std.c.gid_t; | ||
| 13 | const dev_t = std.c.dev_t; | 6 | const dev_t = std.c.dev_t; |
| 14 | const ino_t = std.c.ino_t; | 7 | const ino_t = std.c.ino_t; |
| 15 | 8 | ||
| ... | @@ -17,52 +10,27 @@ comptime { | ... | @@ -17,52 +10,27 @@ comptime { |
| 17 | assert(builtin.os.tag == .haiku); // Prevent access of std.c symbols on wrong OS. | 10 | assert(builtin.os.tag == .haiku); // Prevent access of std.c symbols on wrong OS. |
| 18 | } | 11 | } |
| 19 | 12 | ||
| 20 | pub extern "root" fn _errnop() *i32; | 13 | pub const B_OS_NAME_LENGTH = 32; |
| 21 | pub extern "root" fn find_directory(which: directory_which, volume: i32, createIt: bool, path_ptr: [*]u8, length: i32) u64; | 14 | pub const B_ABSOLUTE_TIMEOUT = 0x10; |
| 22 | pub extern "root" fn find_thread(thread_name: ?*anyopaque) i32; | 15 | pub const B_TIMEOUT_REAL_TIME_BASE = 0x40; |
| 23 | pub extern "root" fn get_system_info(system_info: *system_info) usize; | 16 | |
| 24 | pub extern "root" fn _get_team_info(team: i32, team_info: *team_info, size: usize) i32; | 17 | pub extern "root" fn _kern_create_sem(count: c_int, name: ?[*:0]const u8) sem_id; |
| 25 | pub extern "root" fn _get_next_area_info(team: i32, cookie: *i64, area_info: *area_info, size: usize) i32; | 18 | pub extern "root" fn _kern_delete_sem(id: sem_id) status_t; |
| 26 | pub extern "root" fn _get_next_image_info(team: i32, cookie: *i32, image_info: *image_info, size: usize) i32; | 19 | pub extern "root" fn _kern_acquire_sem_etc(id: sem_id, count: u32, flags: u32, timeout: i64) status_t; |
| 27 | pub extern "root" fn _kern_get_current_team() team_id; | 20 | pub extern "root" fn _kern_release_sem_etc(id: sem_id, count: u32, flags: u32) status_t; |
| 28 | pub extern "root" fn _kern_open_dir(fd: fd_t, path: [*:0]const u8) fd_t; | 21 | pub extern "root" fn _kern_open_dir(fd: fd_t, path: [*:0]const u8) fd_t; |
| 29 | pub extern "root" fn _kern_read_dir(fd: fd_t, buffer: [*]u8, bufferSize: usize, maxCount: u32) isize; | 22 | pub extern "root" fn _kern_read_dir(fd: fd_t, buffer: [*]u8, bufferSize: usize, maxCount: u32) isize; |
| 30 | pub extern "root" fn _kern_rewind_dir(fd: fd_t) status_t; | 23 | pub extern "root" fn _kern_rewind_dir(fd: fd_t) status_t; |
| 31 | pub extern "root" fn _kern_read_stat(fd: fd_t, path: [*:0]const u8, traverseLink: bool, stat: *std.c.Stat, statSize: usize) status_t; | 24 | pub extern "root" fn _kern_read_stat(fd: fd_t, path: [*:0]const u8, traverseLink: bool, stat: *std.c.Stat, statSize: usize) status_t; |
| 32 | pub extern "root" fn readv_pos(fd: fd_t, pos: off_t, vec: [*]const std.c.iovec, count: i32) isize; | ||
| 33 | pub extern "root" fn writev_pos(fd: fd_t, pos: off_t, vec: [*]const std.c.iovec_const, count: i32) isize; | ||
| 34 | 25 | ||
| 35 | pub const area_info = extern struct { | 26 | pub extern "root" fn on_exit_thread(callback: *const fn (?*anyopaque) callconv(.c) void, data: ?*anyopaque) status_t; |
| 36 | area: u32, | 27 | pub extern "root" fn find_thread(name: ?[*:0]const u8) thread_id; |
| 37 | name: [32]u8, | 28 | pub extern "root" fn get_system_info(info: *system_info) status_t; |
| 38 | size: usize, | ||
| 39 | lock: u32, | ||
| 40 | protection: u32, | ||
| 41 | team_id: i32, | ||
| 42 | ram_size: u32, | ||
| 43 | copy_count: u32, | ||
| 44 | in_count: u32, | ||
| 45 | out_count: u32, | ||
| 46 | address: *anyopaque, | ||
| 47 | }; | ||
| 48 | 29 | ||
| 49 | pub const image_info = extern struct { | 30 | pub extern "root" fn _errnop() *i32; |
| 50 | id: u32, | 31 | |
| 51 | image_type: u32, | 32 | pub extern "root" fn readv_pos(fd: fd_t, pos: off_t, vec: [*]const std.c.iovec, count: i32) isize; |
| 52 | sequence: i32, | 33 | pub extern "root" fn writev_pos(fd: fd_t, pos: off_t, vec: [*]const std.c.iovec_const, count: i32) isize; |
| 53 | init_order: i32, | ||
| 54 | init_routine: *anyopaque, | ||
| 55 | term_routine: *anyopaque, | ||
| 56 | device: i32, | ||
| 57 | node: i64, | ||
| 58 | name: [PATH_MAX]u8, | ||
| 59 | text: *anyopaque, | ||
| 60 | data: *anyopaque, | ||
| 61 | text_size: i32, | ||
| 62 | data_size: i32, | ||
| 63 | api_version: i32, | ||
| 64 | abi: i32, | ||
| 65 | }; | ||
| 66 | 34 | ||
| 67 | pub const system_info = extern struct { | 35 | pub const system_info = extern struct { |
| 68 | boot_time: i64, | 36 | boot_time: i64, |
| ... | @@ -86,31 +54,12 @@ pub const system_info = extern struct { | ... | @@ -86,31 +54,12 @@ pub const system_info = extern struct { |
| 86 | max_teams: u32, | 54 | max_teams: u32, |
| 87 | used_teams: u32, | 55 | used_teams: u32, |
| 88 | kernel_name: [256]u8, | 56 | kernel_name: [256]u8, |
| 89 | kernel_build_date: [32]u8, | 57 | kernel_build_date: [B_OS_NAME_LENGTH]u8, |
| 90 | kernel_build_time: [32]u8, | 58 | kernel_build_time: [B_OS_NAME_LENGTH]u8, |
| 91 | kernel_version: i64, | 59 | kernel_version: i64, |
| 92 | abi: u32, | 60 | abi: u32, |
| 93 | }; | 61 | }; |
| 94 | 62 | ||
| 95 | pub const team_info = extern struct { | ||
| 96 | team_id: i32, | ||
| 97 | thread_count: i32, | ||
| 98 | image_count: i32, | ||
| 99 | area_count: i32, | ||
| 100 | debugger_nub_thread: i32, | ||
| 101 | debugger_nub_port: i32, | ||
| 102 | argc: i32, | ||
| 103 | args: [64]u8, | ||
| 104 | uid: uid_t, | ||
| 105 | gid: gid_t, | ||
| 106 | }; | ||
| 107 | |||
| 108 | pub const directory_which = enum(i32) { | ||
| 109 | B_USER_SETTINGS_DIRECTORY = 0xbbe, | ||
| 110 | |||
| 111 | _, | ||
| 112 | }; | ||
| 113 | |||
| 114 | pub const area_id = i32; | 63 | pub const area_id = i32; |
| 115 | pub const port_id = i32; | 64 | pub const port_id = i32; |
| 116 | pub const sem_id = i32; | 65 | pub const sem_id = i32; |
lib/std/compress/flate/Compress.zig+1-1| ... | @@ -738,7 +738,7 @@ fn matchAndAddHash(c: *Compress, i: usize, h: Hash, gt: u16, max_chain: u16, goo | ... | @@ -738,7 +738,7 @@ fn matchAndAddHash(c: *Compress, i: usize, h: Hash, gt: u16, max_chain: u16, goo |
| 738 | 738 | ||
| 739 | fn clenHlen(freqs: [19]u16) u4 { | 739 | fn clenHlen(freqs: [19]u16) u4 { |
| 740 | // Note that the first four codes (16, 17, 18, and 0) are always present. | 740 | // Note that the first four codes (16, 17, 18, and 0) are always present. |
| 741 | if (builtin.mode != .ReleaseSmall and (std.simd.suggestVectorLength(u16) orelse 1) >= 8) { | 741 | if (builtin.mode != .small and (std.simd.suggestVectorLength(u16) orelse 1) >= 8) { |
| 742 | const V = @Vector(16, u16); | 742 | const V = @Vector(16, u16); |
| 743 | const hlen_mul: V = comptime m: { | 743 | const hlen_mul: V = comptime m: { |
| 744 | var hlen_mul: [16]u16 = undefined; | 744 | var hlen_mul: [16]u16 = undefined; |
lib/std/compress/flate/token.zig+3-3| ... | @@ -57,9 +57,9 @@ const fixed_dist = blk: { | ... | @@ -57,9 +57,9 @@ const fixed_dist = blk: { |
| 57 | }; | 57 | }; |
| 58 | 58 | ||
| 59 | // All paramters of codes can be derived matchematically, however some are faster to | 59 | // All paramters of codes can be derived matchematically, however some are faster to |
| 60 | // do via lookup table. For ReleaseSmall, we do all mathematically to save space. | 60 | // do via lookup table. For -Osmall, we do all mathematically to save space. |
| 61 | pub const LenCode = if (builtin.mode != .ReleaseSmall) LookupLenCode else ShortLenCode; | 61 | pub const LenCode = if (builtin.mode != .small) LookupLenCode else ShortLenCode; |
| 62 | pub const DistCode = if (builtin.mode != .ReleaseSmall) LookupDistCode else ShortDistCode; | 62 | pub const DistCode = if (builtin.mode != .small) LookupDistCode else ShortDistCode; |
| 63 | const ShortLenCode = ShortCode(u8, u2, u3, true); | 63 | const ShortLenCode = ShortCode(u8, u2, u3, true); |
| 64 | const ShortDistCode = ShortCode(u15, u1, u4, false); | 64 | const ShortDistCode = ShortCode(u15, u1, u4, false); |
| 65 | /// For length and distance codes, they having this format. | 65 | /// For length and distance codes, they having this format. |
lib/std/crypto/25519/field.zig+2-2| ... | @@ -7,8 +7,8 @@ const NotSquareError = crypto.errors.NotSquareError; | ... | @@ -7,8 +7,8 @@ const NotSquareError = crypto.errors.NotSquareError; |
| 7 | 7 | ||
| 8 | // Inline conditionally, when it can result in large code generation. | 8 | // Inline conditionally, when it can result in large code generation. |
| 9 | const bloaty_inline: std.builtin.CallingConvention = switch (builtin.mode) { | 9 | const bloaty_inline: std.builtin.CallingConvention = switch (builtin.mode) { |
| 10 | .ReleaseSafe, .ReleaseFast => .@"inline", | 10 | .safe, .fast => .@"inline", |
| 11 | .Debug, .ReleaseSmall => .auto, | 11 | .debug, .small => .auto, |
| 12 | }; | 12 | }; |
| 13 | 13 | ||
| 14 | pub const Fe = struct { | 14 | pub const Fe = struct { |
lib/std/crypto/Certificate.zig+81-10| ... | @@ -175,6 +175,8 @@ pub const GeneralNameTag = enum(u5) { | ... | @@ -175,6 +175,8 @@ pub const GeneralNameTag = enum(u5) { |
| 175 | _, | 175 | _, |
| 176 | }; | 176 | }; |
| 177 | 177 | ||
| 178 | const net = @import("../Io/net.zig"); | ||
| 179 | |||
| 178 | pub const Parsed = struct { | 180 | pub const Parsed = struct { |
| 179 | certificate: Certificate, | 181 | certificate: Certificate, |
| 180 | issuer_slice: Slice, | 182 | issuer_slice: Slice, |
| ... | @@ -315,6 +317,7 @@ pub const Parsed = struct { | ... | @@ -315,6 +317,7 @@ pub const Parsed = struct { |
| 315 | // what to check. Otherwise, only the common name is checked. | 317 | // what to check. Otherwise, only the common name is checked. |
| 316 | const subject_alt_name = parsed_subject.subjectAltName(); | 318 | const subject_alt_name = parsed_subject.subjectAltName(); |
| 317 | if (subject_alt_name.len == 0) { | 319 | if (subject_alt_name.len == 0) { |
| 320 | // note: checkIpAddress is intentionally omitted, as it is not permitted in the common name field anyway. | ||
| 318 | if (checkHostName(host_name, parsed_subject.commonName())) { | 321 | if (checkHostName(host_name, parsed_subject.commonName())) { |
| 319 | return; | 322 | return; |
| 320 | } else { | 323 | } else { |
| ... | @@ -332,6 +335,10 @@ pub const Parsed = struct { | ... | @@ -332,6 +335,10 @@ pub const Parsed = struct { |
| 332 | const dns_name = subject_alt_name[general_name.slice.start..general_name.slice.end]; | 335 | const dns_name = subject_alt_name[general_name.slice.start..general_name.slice.end]; |
| 333 | if (checkHostName(host_name, dns_name)) return; | 336 | if (checkHostName(host_name, dns_name)) return; |
| 334 | }, | 337 | }, |
| 338 | .iPAddress => { | ||
| 339 | const ip_address = subject_alt_name[general_name.slice.start..general_name.slice.end]; | ||
| 340 | if (checkIpAddress(host_name, ip_address)) return; | ||
| 341 | }, | ||
| 335 | else => {}, | 342 | else => {}, |
| 336 | } | 343 | } |
| 337 | } | 344 | } |
| ... | @@ -376,6 +383,22 @@ pub const Parsed = struct { | ... | @@ -376,6 +383,22 @@ pub const Parsed = struct { |
| 376 | 383 | ||
| 377 | return false; | 384 | return false; |
| 378 | } | 385 | } |
| 386 | |||
| 387 | // Check IP address according to RFC 5280 §4.2.1.6. | ||
| 388 | fn checkIpAddress(host_name: []const u8, ip_address: []const u8) bool { | ||
| 389 | switch (ip_address.len) { | ||
| 390 | 4 => { | ||
| 391 | // port is irrelevant to SAN matching, so 0 is a harmless placeholder. | ||
| 392 | const address = net.Ip4Address.parse(host_name, 0) catch return false; | ||
| 393 | return mem.eql(u8, &address.bytes, ip_address); | ||
| 394 | }, | ||
| 395 | 16 => { | ||
| 396 | const address = net.Ip6Address.parse(host_name, 0) catch return false; | ||
| 397 | return mem.eql(u8, &address.bytes, ip_address); | ||
| 398 | }, | ||
| 399 | else => return false, // a malformed certificate, neither 4 nor 16 octets | ||
| 400 | } | ||
| 401 | } | ||
| 379 | }; | 402 | }; |
| 380 | 403 | ||
| 381 | test "Parsed.checkHostName RFC 6125 compliance" { | 404 | test "Parsed.checkHostName RFC 6125 compliance" { |
| ... | @@ -417,6 +440,39 @@ test "Parsed.checkHostName RFC 6125 compliance" { | ... | @@ -417,6 +440,39 @@ test "Parsed.checkHostName RFC 6125 compliance" { |
| 417 | try expectEqual(false, Parsed.checkHostName("example.com", "*.")); | 440 | try expectEqual(false, Parsed.checkHostName("example.com", "*.")); |
| 418 | } | 441 | } |
| 419 | 442 | ||
| 443 | test "Parsed.checkIpAddress RFC 5280 4.2.1.6 compliance" { | ||
| 444 | const expectEqual = std.testing.expectEqual; | ||
| 445 | |||
| 446 | // Exact match positive tests | ||
| 447 | try expectEqual(true, Parsed.checkIpAddress("127.0.0.1", &[4]u8{ 127, 0, 0, 1 })); | ||
| 448 | try expectEqual(true, Parsed.checkIpAddress("0:0:0:0:0:0:0:1", &[16]u8{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 })); | ||
| 449 | |||
| 450 | // Mismatches should not pass | ||
| 451 | try expectEqual(false, Parsed.checkIpAddress("1.2.3.4", &[4]u8{ 5, 6, 7, 8 })); | ||
| 452 | try expectEqual(false, Parsed.checkIpAddress("0:0:0:0:0:0:0:1", &[16]u8{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 })); | ||
| 453 | |||
| 454 | // IPv6: the hostname may be in short-form and should match the exact 16 octets specified in the SAN | ||
| 455 | try expectEqual(true, Parsed.checkIpAddress("::1", &[16]u8{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 })); | ||
| 456 | |||
| 457 | // IPv6: do not match when using DNS64 / NAT64 (i.e. 64:ff9b::/96) | ||
| 458 | // the RFC requires exact octet matches, so this is likely surprising and wrong. The decision here is to fail-safe out of an abundance of caution. | ||
| 459 | // The test assertions are included not to harden on this behavior, but to show that this use-case was considered. | ||
| 460 | // This check may become more lenient in the future if a valid use-case is found. | ||
| 461 | try expectEqual(false, Parsed.checkIpAddress("64:ff9b::192.0.2.10", &[4]u8{ 192, 0, 2, 10 })); | ||
| 462 | try expectEqual(false, Parsed.checkIpAddress("::ffff:127.0.0.1", &[4]u8{ 127, 0, 0, 1 })); | ||
| 463 | |||
| 464 | // Malformed SAN lengths (not 4 or 16 octets) never match. | ||
| 465 | try expectEqual(false, Parsed.checkIpAddress("127.0.0", &[_]u8{ 127, 0, 0 })); | ||
| 466 | try expectEqual(false, Parsed.checkIpAddress("127.0.0.1.0", &[_]u8{ 127, 0, 0, 1, 0 })); | ||
| 467 | |||
| 468 | // A non-parseable host_name never matches. | ||
| 469 | try expectEqual(false, Parsed.checkIpAddress("not-an-ip", &[4]u8{ 127, 0, 0, 1 })); | ||
| 470 | |||
| 471 | // Edge cases - empty strings | ||
| 472 | try expectEqual(false, Parsed.checkIpAddress("", "")); | ||
| 473 | try expectEqual(false, Parsed.checkIpAddress("127.0.0.1", "")); | ||
| 474 | } | ||
| 475 | |||
| 420 | pub const ParseError = der.Element.ParseError || ParseVersionError || ParseTimeError || ParseEnumError || ParseBitStringError; | 476 | pub const ParseError = der.Element.ParseError || ParseVersionError || ParseTimeError || ParseEnumError || ParseBitStringError; |
| 421 | 477 | ||
| 422 | pub fn parse(cert: Certificate) ParseError!Parsed { | 478 | pub fn parse(cert: Certificate) ParseError!Parsed { |
| ... | @@ -793,7 +849,7 @@ fn verifyRsa( | ... | @@ -793,7 +849,7 @@ fn verifyRsa( |
| 793 | inline 128, 256, 384, 512 => |modulus_len| { | 849 | inline 128, 256, 384, 512 => |modulus_len| { |
| 794 | const public_key = rsa.PublicKey.fromBytes(exponent, modulus) catch | 850 | const public_key = rsa.PublicKey.fromBytes(exponent, modulus) catch |
| 795 | return error.CertificateSignatureInvalid; | 851 | return error.CertificateSignatureInvalid; |
| 796 | rsa.PKCS1v1_5Signature.verify(modulus_len, sig[0..modulus_len].*, msg, public_key, Hash) catch | 852 | rsa.PKCS1v1_5Signature.verify(modulus_len, sig[0..modulus_len], msg, public_key, Hash) catch |
| 797 | return error.CertificateSignatureInvalid; | 853 | return error.CertificateSignatureInvalid; |
| 798 | }, | 854 | }, |
| 799 | else => return error.CertificateSignatureUnsupportedBitCount, | 855 | else => return error.CertificateSignatureUnsupportedBitCount, |
| ... | @@ -983,7 +1039,7 @@ pub const rsa = struct { | ... | @@ -983,7 +1039,7 @@ pub const rsa = struct { |
| 983 | 1039 | ||
| 984 | pub fn concatVerify( | 1040 | pub fn concatVerify( |
| 985 | comptime modulus_len: usize, | 1041 | comptime modulus_len: usize, |
| 986 | sig: [modulus_len]u8, | 1042 | sig: *const [modulus_len]u8, |
| 987 | msg: []const []const u8, | 1043 | msg: []const []const u8, |
| 988 | public_key: PublicKey, | 1044 | public_key: PublicKey, |
| 989 | comptime Hash: type, | 1045 | comptime Hash: type, |
| ... | @@ -1092,9 +1148,9 @@ pub const rsa = struct { | ... | @@ -1092,9 +1148,9 @@ pub const rsa = struct { |
| 1092 | } | 1148 | } |
| 1093 | var m_p_buf: [8 + Hash.digest_length + Hash.digest_length]u8 = undefined; | 1149 | var m_p_buf: [8 + Hash.digest_length + Hash.digest_length]u8 = undefined; |
| 1094 | var m_p = m_p_buf[0 .. 8 + Hash.digest_length + sLen]; | 1150 | var m_p = m_p_buf[0 .. 8 + Hash.digest_length + sLen]; |
| 1095 | std.mem.copyForwards(u8, m_p, @as(*const [8]u8, &@splat(0))); | 1151 | @memmove(m_p[0..8], @as(*const [8]u8, &@splat(0))); |
| 1096 | std.mem.copyForwards(u8, m_p[8..], &mHash); | 1152 | @memmove(m_p[8..][0..Hash.digest_length], &mHash); |
| 1097 | std.mem.copyForwards(u8, m_p[(8 + Hash.digest_length)..], salt); | 1153 | @memmove(m_p[(8 + Hash.digest_length)..], salt); |
| 1098 | 1154 | ||
| 1099 | // 13. Let H' = Hash(M'), an octet string of length hLen. | 1155 | // 13. Let H' = Hash(M'), an octet string of length hLen. |
| 1100 | var h_p: [Hash.digest_length]u8 = undefined; | 1156 | var h_p: [Hash.digest_length]u8 = undefined; |
| ... | @@ -1136,7 +1192,7 @@ pub const rsa = struct { | ... | @@ -1136,7 +1192,7 @@ pub const rsa = struct { |
| 1136 | 1192 | ||
| 1137 | pub fn verify( | 1193 | pub fn verify( |
| 1138 | comptime modulus_len: usize, | 1194 | comptime modulus_len: usize, |
| 1139 | sig: [modulus_len]u8, | 1195 | sig: *const [modulus_len]u8, |
| 1140 | msg: []const u8, | 1196 | msg: []const u8, |
| 1141 | public_key: PublicKey, | 1197 | public_key: PublicKey, |
| 1142 | comptime Hash: type, | 1198 | comptime Hash: type, |
| ... | @@ -1146,7 +1202,7 @@ pub const rsa = struct { | ... | @@ -1146,7 +1202,7 @@ pub const rsa = struct { |
| 1146 | 1202 | ||
| 1147 | pub fn concatVerify( | 1203 | pub fn concatVerify( |
| 1148 | comptime modulus_len: usize, | 1204 | comptime modulus_len: usize, |
| 1149 | sig: [modulus_len]u8, | 1205 | sig: *const [modulus_len]u8, |
| 1150 | msg: []const []const u8, | 1206 | msg: []const []const u8, |
| 1151 | public_key: PublicKey, | 1207 | public_key: PublicKey, |
| 1152 | comptime Hash: type, | 1208 | comptime Hash: type, |
| ... | @@ -1187,6 +1243,11 @@ pub const rsa = struct { | ... | @@ -1187,6 +1243,11 @@ pub const rsa = struct { |
| 1187 | // DigestInfo value (see the notes below) and let tLen be the length | 1243 | // DigestInfo value (see the notes below) and let tLen be the length |
| 1188 | // in octets of T. | 1244 | // in octets of T. |
| 1189 | const hash_der: []const u8 = &switch (Hash) { | 1245 | const hash_der: []const u8 = &switch (Hash) { |
| 1246 | crypto.hash.Md5 => .{ | ||
| 1247 | 0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, | ||
| 1248 | 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00, | ||
| 1249 | 0x04, 0x10, | ||
| 1250 | }, | ||
| 1190 | crypto.hash.Sha1 => .{ | 1251 | crypto.hash.Sha1 => .{ |
| 1191 | 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, | 1252 | 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, |
| 1192 | 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, | 1253 | 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, |
| ... | @@ -1211,7 +1272,17 @@ pub const rsa = struct { | ... | @@ -1211,7 +1272,17 @@ pub const rsa = struct { |
| 1211 | 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, | 1272 | 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, |
| 1212 | 0x00, 0x04, 0x40, | 1273 | 0x00, 0x04, 0x40, |
| 1213 | }, | 1274 | }, |
| 1214 | else => @compileError("unreachable"), | 1275 | crypto.hash.sha3.Sha3_256 => .{ |
| 1276 | 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, | ||
| 1277 | 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x08, 0x05, | ||
| 1278 | 0x00, 0x04, 0x20, | ||
| 1279 | }, | ||
| 1280 | crypto.hash.sha3.Sha3_512 => .{ | ||
| 1281 | 0x30, 0x51, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, | ||
| 1282 | 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x0a, 0x05, | ||
| 1283 | 0x00, 0x04, 0x40, | ||
| 1284 | }, | ||
| 1285 | else => comptime unreachable, | ||
| 1215 | }; | 1286 | }; |
| 1216 | em_index -= hash_der.len; | 1287 | em_index -= hash_der.len; |
| 1217 | @memcpy(em[em_index..][0..hash_der.len], hash_der); | 1288 | @memcpy(em[em_index..][0..hash_der.len], hash_der); |
| ... | @@ -1292,8 +1363,8 @@ pub const rsa = struct { | ... | @@ -1292,8 +1363,8 @@ pub const rsa = struct { |
| 1292 | 1363 | ||
| 1293 | const EncryptError = error{MessageTooLong}; | 1364 | const EncryptError = error{MessageTooLong}; |
| 1294 | 1365 | ||
| 1295 | fn encrypt(comptime modulus_len: usize, msg: [modulus_len]u8, public_key: PublicKey) EncryptError![modulus_len]u8 { | 1366 | fn encrypt(comptime modulus_len: usize, msg: *const [modulus_len]u8, public_key: PublicKey) EncryptError![modulus_len]u8 { |
| 1296 | const m = Fe.fromBytes(public_key.n, &msg, .big) catch return error.MessageTooLong; | 1367 | const m = Fe.fromBytes(public_key.n, msg, .big) catch return error.MessageTooLong; |
| 1297 | const e = public_key.n.powPublic(m, public_key.e) catch unreachable; | 1368 | const e = public_key.n.powPublic(m, public_key.e) catch unreachable; |
| 1298 | var res: [modulus_len]u8 = undefined; | 1369 | var res: [modulus_len]u8 = undefined; |
| 1299 | e.toBytes(&res, .big) catch unreachable; | 1370 | e.toBytes(&res, .big) catch unreachable; |
lib/std/crypto/aes.zig+2-2| ... | @@ -6,9 +6,9 @@ const has_aesni = builtin.cpu.has(.x86, .aes); | ... | @@ -6,9 +6,9 @@ const has_aesni = builtin.cpu.has(.x86, .aes); |
| 6 | const has_avx = builtin.cpu.has(.x86, .avx); | 6 | const has_avx = builtin.cpu.has(.x86, .avx); |
| 7 | const has_armaes = builtin.cpu.has(.aarch64, .aes); | 7 | const has_armaes = builtin.cpu.has(.aarch64, .aes); |
| 8 | // C backend doesn't currently support passing vectors to inline asm. | 8 | // C backend doesn't currently support passing vectors to inline asm. |
| 9 | const impl = if (builtin.cpu.arch == .x86_64 and builtin.zig_backend != .stage2_c and has_aesni and has_avx) impl: { | 9 | const impl = if (builtin.cpu.arch == .x86_64 and has_aesni and has_avx) impl: { |
| 10 | break :impl @import("aes/aesni.zig"); | 10 | break :impl @import("aes/aesni.zig"); |
| 11 | } else if (builtin.cpu.arch == .aarch64 and builtin.zig_backend != .stage2_c and has_armaes) impl: { | 11 | } else if (builtin.cpu.arch == .aarch64 and (builtin.zig_backend != .stage2_c or !builtin.os.tag.isDarwin()) and has_armaes) impl: { |
| 12 | break :impl @import("aes/armcrypto.zig"); | 12 | break :impl @import("aes/armcrypto.zig"); |
| 13 | } else impl: { | 13 | } else impl: { |
| 14 | break :impl @import("aes/soft.zig"); | 14 | break :impl @import("aes/soft.zig"); |
lib/std/crypto/aes_ocb.zig-10| ... | @@ -262,8 +262,6 @@ const hexToBytes = std.fmt.hexToBytes; | ... | @@ -262,8 +262,6 @@ const hexToBytes = std.fmt.hexToBytes; |
| 262 | const testing = std.testing; | 262 | const testing = std.testing; |
| 263 | 263 | ||
| 264 | test "AesOcb test vector 1" { | 264 | test "AesOcb test vector 1" { |
| 265 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 266 | |||
| 267 | var k: [Aes128Ocb.key_length]u8 = undefined; | 265 | var k: [Aes128Ocb.key_length]u8 = undefined; |
| 268 | var nonce: [Aes128Ocb.nonce_length]u8 = undefined; | 266 | var nonce: [Aes128Ocb.nonce_length]u8 = undefined; |
| 269 | var tag: [Aes128Ocb.tag_length]u8 = undefined; | 267 | var tag: [Aes128Ocb.tag_length]u8 = undefined; |
| ... | @@ -281,8 +279,6 @@ test "AesOcb test vector 1" { | ... | @@ -281,8 +279,6 @@ test "AesOcb test vector 1" { |
| 281 | } | 279 | } |
| 282 | 280 | ||
| 283 | test "AesOcb test vector 2" { | 281 | test "AesOcb test vector 2" { |
| 284 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 285 | |||
| 286 | var k: [Aes128Ocb.key_length]u8 = undefined; | 282 | var k: [Aes128Ocb.key_length]u8 = undefined; |
| 287 | var nonce: [Aes128Ocb.nonce_length]u8 = undefined; | 283 | var nonce: [Aes128Ocb.nonce_length]u8 = undefined; |
| 288 | var tag: [Aes128Ocb.tag_length]u8 = undefined; | 284 | var tag: [Aes128Ocb.tag_length]u8 = undefined; |
| ... | @@ -303,8 +299,6 @@ test "AesOcb test vector 2" { | ... | @@ -303,8 +299,6 @@ test "AesOcb test vector 2" { |
| 303 | } | 299 | } |
| 304 | 300 | ||
| 305 | test "AesOcb test vector 3" { | 301 | test "AesOcb test vector 3" { |
| 306 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 307 | |||
| 308 | var k: [Aes128Ocb.key_length]u8 = undefined; | 302 | var k: [Aes128Ocb.key_length]u8 = undefined; |
| 309 | var nonce: [Aes128Ocb.nonce_length]u8 = undefined; | 303 | var nonce: [Aes128Ocb.nonce_length]u8 = undefined; |
| 310 | var tag: [Aes128Ocb.tag_length]u8 = undefined; | 304 | var tag: [Aes128Ocb.tag_length]u8 = undefined; |
| ... | @@ -329,8 +323,6 @@ test "AesOcb test vector 3" { | ... | @@ -329,8 +323,6 @@ test "AesOcb test vector 3" { |
| 329 | } | 323 | } |
| 330 | 324 | ||
| 331 | test "AesOcb test vector 4" { | 325 | test "AesOcb test vector 4" { |
| 332 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 333 | |||
| 334 | var k: [Aes128Ocb.key_length]u8 = undefined; | 326 | var k: [Aes128Ocb.key_length]u8 = undefined; |
| 335 | var nonce: [Aes128Ocb.nonce_length]u8 = undefined; | 327 | var nonce: [Aes128Ocb.nonce_length]u8 = undefined; |
| 336 | var tag: [Aes128Ocb.tag_length]u8 = undefined; | 328 | var tag: [Aes128Ocb.tag_length]u8 = undefined; |
| ... | @@ -356,8 +348,6 @@ test "AesOcb test vector 4" { | ... | @@ -356,8 +348,6 @@ test "AesOcb test vector 4" { |
| 356 | } | 348 | } |
| 357 | 349 | ||
| 358 | test "AesOcb in-place encryption-decryption" { | 350 | test "AesOcb in-place encryption-decryption" { |
| 359 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 360 | |||
| 361 | var k: [Aes128Ocb.key_length]u8 = undefined; | 351 | var k: [Aes128Ocb.key_length]u8 = undefined; |
| 362 | var nonce: [Aes128Ocb.nonce_length]u8 = undefined; | 352 | var nonce: [Aes128Ocb.nonce_length]u8 = undefined; |
| 363 | var tag: [Aes128Ocb.tag_length]u8 = undefined; | 353 | var tag: [Aes128Ocb.tag_length]u8 = undefined; |
lib/std/crypto/benchmark.zig+3-3| ... | @@ -454,8 +454,8 @@ fn benchmarkPwhash( | ... | @@ -454,8 +454,8 @@ fn benchmarkPwhash( |
| 454 | 454 | ||
| 455 | const strHash = ty.strHash; | 455 | const strHash = ty.strHash; |
| 456 | const strHashFnInfo = @typeInfo(@TypeOf(strHash)).@"fn"; | 456 | const strHashFnInfo = @typeInfo(@TypeOf(strHash)).@"fn"; |
| 457 | const needs_io = strHashFnInfo.params.len == 4 and strHashFnInfo.params[3].type == std.Io; | 457 | const needs_io = strHashFnInfo.param_types.len == 4 and strHashFnInfo.param_types[3].? == std.Io; |
| 458 | const needs_salt = strHashFnInfo.params.len == 4 and strHashFnInfo.params[3].type != std.Io; | 458 | const needs_salt = strHashFnInfo.param_types.len == 4 and strHashFnInfo.param_types[3].? != std.Io; |
| 459 | const salt: [16]u8 = @splat(0); | 459 | const salt: [16]u8 = @splat(0); |
| 460 | 460 | ||
| 461 | const start = benchTime(io); | 461 | const start = benchTime(io); |
| ... | @@ -493,7 +493,7 @@ fn usage() void { | ... | @@ -493,7 +493,7 @@ fn usage() void { |
| 493 | } | 493 | } |
| 494 | 494 | ||
| 495 | fn mode(comptime x: comptime_int) comptime_int { | 495 | fn mode(comptime x: comptime_int) comptime_int { |
| 496 | return if (builtin.mode == .Debug) x / 64 else x; | 496 | return if (builtin.mode == .debug) x / 64 else x; |
| 497 | } | 497 | } |
| 498 | 498 | ||
| 499 | pub fn main(init: std.process.Init) !void { | 499 | pub fn main(init: std.process.Init) !void { |
lib/std/crypto/ecdsa.zig+6-24| ... | @@ -1,4 +1,3 @@ | ... | @@ -1,4 +1,3 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 2 | const std = @import("std"); | 1 | const std = @import("std"); |
| 3 | const crypto = std.crypto; | 2 | const crypto = std.crypto; |
| 4 | const fmt = std.fmt; | 3 | const fmt = std.fmt; |
| ... | @@ -25,14 +24,17 @@ pub const EcdsaSecp256k1Sha256 = Ecdsa(crypto.ecc.Secp256k1, crypto.hash.sha2.Sh | ... | @@ -25,14 +24,17 @@ pub const EcdsaSecp256k1Sha256 = Ecdsa(crypto.ecc.Secp256k1, crypto.hash.sha2.Sh |
| 25 | pub const EcdsaSecp256k1Sha256oSha256 = Ecdsa(crypto.ecc.Secp256k1, crypto.hash.composition.Sha256oSha256); | 24 | pub const EcdsaSecp256k1Sha256oSha256 = Ecdsa(crypto.ecc.Secp256k1, crypto.hash.composition.Sha256oSha256); |
| 26 | 25 | ||
| 27 | /// Elliptic Curve Digital Signature Algorithm (ECDSA). | 26 | /// Elliptic Curve Digital Signature Algorithm (ECDSA). |
| 28 | pub fn Ecdsa(comptime Curve: type, comptime Hash: type) type { | 27 | pub fn Ecdsa(comptime C: type, comptime H: type) type { |
| 29 | const Prf = switch (Hash) { | 28 | const Prf = switch (H) { |
| 30 | sha3.Shake128 => sha3.KMac128, | 29 | sha3.Shake128 => sha3.KMac128, |
| 31 | sha3.Shake256 => sha3.KMac256, | 30 | sha3.Shake256 => sha3.KMac256, |
| 32 | else => crypto.auth.hmac.Hmac(Hash), | 31 | else => crypto.auth.hmac.Hmac(H), |
| 33 | }; | 32 | }; |
| 34 | 33 | ||
| 35 | return struct { | 34 | return struct { |
| 35 | pub const Curve = C; | ||
| 36 | pub const Hash = H; | ||
| 37 | |||
| 36 | /// Length (in bytes) of optional random bytes, for non-deterministic signatures. | 38 | /// Length (in bytes) of optional random bytes, for non-deterministic signatures. |
| 37 | pub const noise_length = Curve.scalar.encoded_length; | 39 | pub const noise_length = Curve.scalar.encoded_length; |
| 38 | 40 | ||
| ... | @@ -415,8 +417,6 @@ pub fn Ecdsa(comptime Curve: type, comptime Hash: type) type { | ... | @@ -415,8 +417,6 @@ pub fn Ecdsa(comptime Curve: type, comptime Hash: type) type { |
| 415 | } | 417 | } |
| 416 | 418 | ||
| 417 | test "Basic operations over EcdsaP384Sha384" { | 419 | test "Basic operations over EcdsaP384Sha384" { |
| 418 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 419 | |||
| 420 | const io = testing.io; | 420 | const io = testing.io; |
| 421 | const Scheme = EcdsaP384Sha384; | 421 | const Scheme = EcdsaP384Sha384; |
| 422 | const kp = Scheme.KeyPair.generate(io); | 422 | const kp = Scheme.KeyPair.generate(io); |
| ... | @@ -432,8 +432,6 @@ test "Basic operations over EcdsaP384Sha384" { | ... | @@ -432,8 +432,6 @@ test "Basic operations over EcdsaP384Sha384" { |
| 432 | } | 432 | } |
| 433 | 433 | ||
| 434 | test "Basic operations over Secp256k1" { | 434 | test "Basic operations over Secp256k1" { |
| 435 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 436 | |||
| 437 | const io = testing.io; | 435 | const io = testing.io; |
| 438 | const Scheme = EcdsaSecp256k1Sha256oSha256; | 436 | const Scheme = EcdsaSecp256k1Sha256oSha256; |
| 439 | const kp = Scheme.KeyPair.generate(io); | 437 | const kp = Scheme.KeyPair.generate(io); |
| ... | @@ -449,8 +447,6 @@ test "Basic operations over Secp256k1" { | ... | @@ -449,8 +447,6 @@ test "Basic operations over Secp256k1" { |
| 449 | } | 447 | } |
| 450 | 448 | ||
| 451 | test "Basic operations over EcdsaP384Sha256" { | 449 | test "Basic operations over EcdsaP384Sha256" { |
| 452 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 453 | |||
| 454 | const io = testing.io; | 450 | const io = testing.io; |
| 455 | const Scheme = Ecdsa(crypto.ecc.P384, crypto.hash.sha2.Sha256); | 451 | const Scheme = Ecdsa(crypto.ecc.P384, crypto.hash.sha2.Sha256); |
| 456 | const kp = Scheme.KeyPair.generate(io); | 452 | const kp = Scheme.KeyPair.generate(io); |
| ... | @@ -466,8 +462,6 @@ test "Basic operations over EcdsaP384Sha256" { | ... | @@ -466,8 +462,6 @@ test "Basic operations over EcdsaP384Sha256" { |
| 466 | } | 462 | } |
| 467 | 463 | ||
| 468 | test "Verifying a existing signature with EcdsaP384Sha256" { | 464 | test "Verifying a existing signature with EcdsaP384Sha256" { |
| 469 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 470 | |||
| 471 | const Scheme = Ecdsa(crypto.ecc.P384, crypto.hash.sha2.Sha256); | 465 | const Scheme = Ecdsa(crypto.ecc.P384, crypto.hash.sha2.Sha256); |
| 472 | // zig fmt: off | 466 | // zig fmt: off |
| 473 | const sk_bytes = [_]u8{ | 467 | const sk_bytes = [_]u8{ |
| ... | @@ -503,8 +497,6 @@ test "Verifying a existing signature with EcdsaP384Sha256" { | ... | @@ -503,8 +497,6 @@ test "Verifying a existing signature with EcdsaP384Sha256" { |
| 503 | } | 497 | } |
| 504 | 498 | ||
| 505 | test "Prehashed message operations" { | 499 | test "Prehashed message operations" { |
| 506 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 507 | |||
| 508 | const io = testing.io; | 500 | const io = testing.io; |
| 509 | 501 | ||
| 510 | const Scheme = EcdsaP256Sha256; | 502 | const Scheme = EcdsaP256Sha256; |
| ... | @@ -539,8 +531,6 @@ const TestVector = struct { | ... | @@ -539,8 +531,6 @@ const TestVector = struct { |
| 539 | }; | 531 | }; |
| 540 | 532 | ||
| 541 | test "Test vectors from Project Wycheproof - EcdsaP256Sha256 valid" { | 533 | test "Test vectors from Project Wycheproof - EcdsaP256Sha256 valid" { |
| 542 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 543 | |||
| 544 | const vectors: []const TestVector = &.{ | 534 | const vectors: []const TestVector = &.{ |
| 545 | // well-formed DER encoding -> expected valid | 535 | // well-formed DER encoding -> expected valid |
| 546 | .{ .key = "042927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", .msg = "313233343030", .sig = "304402202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e1802204cd60b855d442f5b3c7b11eb6c4e0ae7525fe710fab9aa7c77a67f79e6fadd76" }, | 536 | .{ .key = "042927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", .msg = "313233343030", .sig = "304402202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e1802204cd60b855d442f5b3c7b11eb6c4e0ae7525fe710fab9aa7c77a67f79e6fadd76" }, |
| ... | @@ -711,8 +701,6 @@ test "Test vectors from Project Wycheproof - EcdsaP256Sha256 valid" { | ... | @@ -711,8 +701,6 @@ test "Test vectors from Project Wycheproof - EcdsaP256Sha256 valid" { |
| 711 | } | 701 | } |
| 712 | 702 | ||
| 713 | test "Test vectors from Project Wycheproof - EcdsaP256Sha256 invalid" { | 703 | test "Test vectors from Project Wycheproof - EcdsaP256Sha256 invalid" { |
| 714 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 715 | |||
| 716 | const vectors: []const TestVector = &.{ | 704 | const vectors: []const TestVector = &.{ |
| 717 | // S encoded with negative sign -> expected invalid | 705 | // S encoded with negative sign -> expected invalid |
| 718 | .{ .key = "042927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", .msg = "313233343030", .sig = "304402202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180220b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db" }, | 706 | .{ .key = "042927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", .msg = "313233343030", .sig = "304402202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180220b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db" }, |
| ... | @@ -1026,8 +1014,6 @@ test "Test vectors from Project Wycheproof - EcdsaP256Sha256 invalid" { | ... | @@ -1026,8 +1014,6 @@ test "Test vectors from Project Wycheproof - EcdsaP256Sha256 invalid" { |
| 1026 | } | 1014 | } |
| 1027 | 1015 | ||
| 1028 | test "Test vectors from Project Wycheproof - EcdsaP384Sha384 valid" { | 1016 | test "Test vectors from Project Wycheproof - EcdsaP384Sha384 valid" { |
| 1029 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 1030 | |||
| 1031 | const vectors: []const TestVector = &.{ | 1017 | const vectors: []const TestVector = &.{ |
| 1032 | // canonical sign-bit padding on R; canonical sign-bit padding on S -> expected valid | 1018 | // canonical sign-bit padding on R; canonical sign-bit padding on S -> expected valid |
| 1033 | .{ .key = "0429bdb76d5fa741bfd70233cb3a66cc7d44beb3b0663d92a8136650478bcefb61ef182e155a54345a5e8e5e88f064e5bc9a525ab7f764dad3dae1468c2b419f3b62b9ba917d5e8c4fb1ec47404a3fc76474b2713081be9db4c00e043ada9fc4a3", .msg = "4d7367", .sig = "3066023100d7143a836608b25599a7f28dec6635494c2992ad1e2bbeecb7ef601a9c01746e710ce0d9c48accb38a79ede5b9638f3402310080f9e165e8c61035bf8aa7b5533960e46dd0e211c904a064edb6de41f797c0eae4e327612ee3f816f4157272bb4fabc9" }, | 1019 | .{ .key = "0429bdb76d5fa741bfd70233cb3a66cc7d44beb3b0663d92a8136650478bcefb61ef182e155a54345a5e8e5e88f064e5bc9a525ab7f764dad3dae1468c2b419f3b62b9ba917d5e8c4fb1ec47404a3fc76474b2713081be9db4c00e043ada9fc4a3", .msg = "4d7367", .sig = "3066023100d7143a836608b25599a7f28dec6635494c2992ad1e2bbeecb7ef601a9c01746e710ce0d9c48accb38a79ede5b9638f3402310080f9e165e8c61035bf8aa7b5533960e46dd0e211c904a064edb6de41f797c0eae4e327612ee3f816f4157272bb4fabc9" }, |
| ... | @@ -1243,8 +1229,6 @@ test "Test vectors from Project Wycheproof - EcdsaP384Sha384 valid" { | ... | @@ -1243,8 +1229,6 @@ test "Test vectors from Project Wycheproof - EcdsaP384Sha384 valid" { |
| 1243 | } | 1229 | } |
| 1244 | 1230 | ||
| 1245 | test "Test vectors from Project Wycheproof - EcdsaP384Sha384 invalid" { | 1231 | test "Test vectors from Project Wycheproof - EcdsaP384Sha384 invalid" { |
| 1246 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 1247 | |||
| 1248 | const vectors: []const TestVector = &.{ | 1232 | const vectors: []const TestVector = &.{ |
| 1249 | // S encoded with negative sign -> expected invalid | 1233 | // S encoded with negative sign -> expected invalid |
| 1250 | .{ .key = "042da57dda1089276a543f9ffdac0bff0d976cad71eb7280e7d9bfd9fee4bdb2f20f47ff888274389772d98cc5752138aa4b6d054d69dcf3e25ec49df870715e34883b1836197d76f8ad962e78f6571bbc7407b0d6091f9e4d88f014274406174f", .msg = "313233343030", .sig = "3064023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d70230e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82" }, | 1234 | .{ .key = "042da57dda1089276a543f9ffdac0bff0d976cad71eb7280e7d9bfd9fee4bdb2f20f47ff888274389772d98cc5752138aa4b6d054d69dcf3e25ec49df870715e34883b1836197d76f8ad962e78f6571bbc7407b0d6091f9e4d88f014274406174f", .msg = "313233343030", .sig = "3064023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d70230e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82" }, |
| ... | @@ -1631,8 +1615,6 @@ fn tvTry(comptime Scheme: type, vector: TestVector) !void { | ... | @@ -1631,8 +1615,6 @@ fn tvTry(comptime Scheme: type, vector: TestVector) !void { |
| 1631 | } | 1615 | } |
| 1632 | 1616 | ||
| 1633 | test "Sec1 encoding/decoding" { | 1617 | test "Sec1 encoding/decoding" { |
| 1634 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 1635 | |||
| 1636 | const io = testing.io; | 1618 | const io = testing.io; |
| 1637 | const Scheme = EcdsaP384Sha384; | 1619 | const Scheme = EcdsaP384Sha384; |
| 1638 | const kp = Scheme.KeyPair.generate(io); | 1620 | const kp = Scheme.KeyPair.generate(io); |
lib/std/crypto/ff.zig-4| ... | @@ -966,8 +966,6 @@ const ct_unprotected = struct { | ... | @@ -966,8 +966,6 @@ const ct_unprotected = struct { |
| 966 | }; | 966 | }; |
| 967 | 967 | ||
| 968 | test "finite field arithmetic" { | 968 | test "finite field arithmetic" { |
| 969 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 970 | |||
| 971 | const M = Modulus(256); | 969 | const M = Modulus(256); |
| 972 | const m = try M.fromPrimitive(u256, 3429938563481314093726330772853735541133072814650493833233); | 970 | const m = try M.fromPrimitive(u256, 3429938563481314093726330772853735541133072814650493833233); |
| 973 | var x = try M.Fe.fromPrimitive(u256, m, 80169837251094269539116136208111827396136208141182357733); | 971 | var x = try M.Fe.fromPrimitive(u256, m, 80169837251094269539116136208111827396136208141182357733); |
| ... | @@ -1066,8 +1064,6 @@ test "finite field arithmetic" { | ... | @@ -1066,8 +1064,6 @@ test "finite field arithmetic" { |
| 1066 | } | 1064 | } |
| 1067 | 1065 | ||
| 1068 | fn testCt(ct_: anytype) !void { | 1066 | fn testCt(ct_: anytype) !void { |
| 1069 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 1070 | |||
| 1071 | const l0: Limb = 0; | 1067 | const l0: Limb = 0; |
| 1072 | const l1: Limb = 1; | 1068 | const l1: Limb = 1; |
| 1073 | try testing.expectEqual(l1, ct_.select(true, l1, l0)); | 1069 | try testing.expectEqual(l1, ct_.select(true, l1, l0)); |
lib/std/crypto/ghash_polyval.zig+5-5| ... | @@ -30,7 +30,7 @@ fn Hash(comptime endian: std.builtin.Endian, comptime shift_key: bool) type { | ... | @@ -30,7 +30,7 @@ fn Hash(comptime endian: std.builtin.Endian, comptime shift_key: bool) type { |
| 30 | pub const mac_length = 16; | 30 | pub const mac_length = 16; |
| 31 | pub const key_length = 16; | 31 | pub const key_length = 16; |
| 32 | 32 | ||
| 33 | const pc_count = if (builtin.mode != .ReleaseSmall) 16 else 2; | 33 | const pc_count = if (builtin.mode != .small) 16 else 2; |
| 34 | const agg_4_threshold = 22; | 34 | const agg_4_threshold = 22; |
| 35 | const agg_8_threshold = 84; | 35 | const agg_8_threshold = 84; |
| 36 | const agg_16_threshold = 328; | 36 | const agg_16_threshold = 328; |
| ... | @@ -61,7 +61,7 @@ fn Hash(comptime endian: std.builtin.Endian, comptime shift_key: bool) type { | ... | @@ -61,7 +61,7 @@ fn Hash(comptime endian: std.builtin.Endian, comptime shift_key: bool) type { |
| 61 | hx[0] = h; | 61 | hx[0] = h; |
| 62 | hx[1] = reduce(clsq128(hx[0])); // h^2 | 62 | hx[1] = reduce(clsq128(hx[0])); // h^2 |
| 63 | 63 | ||
| 64 | if (builtin.mode != .ReleaseSmall) { | 64 | if (builtin.mode != .small) { |
| 65 | hx[2] = reduce(clmul128(hx[1], h)); // h^3 | 65 | hx[2] = reduce(clmul128(hx[1], h)); // h^3 |
| 66 | hx[3] = reduce(clsq128(hx[1])); // h^4 = h^2^2 | 66 | hx[3] = reduce(clsq128(hx[1])); // h^4 = h^2^2 |
| 67 | if (block_count >= agg_8_threshold) { | 67 | if (block_count >= agg_8_threshold) { |
| ... | @@ -303,7 +303,7 @@ fn Hash(comptime endian: std.builtin.Endian, comptime shift_key: bool) type { | ... | @@ -303,7 +303,7 @@ fn Hash(comptime endian: std.builtin.Endian, comptime shift_key: bool) type { |
| 303 | 303 | ||
| 304 | var i: usize = 0; | 304 | var i: usize = 0; |
| 305 | 305 | ||
| 306 | if (builtin.mode != .ReleaseSmall and msg.len >= agg_16_threshold * block_length) { | 306 | if (builtin.mode != .small and msg.len >= agg_16_threshold * block_length) { |
| 307 | // 16-blocks aggregated reduction | 307 | // 16-blocks aggregated reduction |
| 308 | while (i + 256 <= msg.len) : (i += 256) { | 308 | while (i + 256 <= msg.len) : (i += 256) { |
| 309 | var u = clmul128(acc ^ mem.readInt(u128, msg[i..][0..16], endian), st.hx[15 - 0]); | 309 | var u = clmul128(acc ^ mem.readInt(u128, msg[i..][0..16], endian), st.hx[15 - 0]); |
| ... | @@ -313,7 +313,7 @@ fn Hash(comptime endian: std.builtin.Endian, comptime shift_key: bool) type { | ... | @@ -313,7 +313,7 @@ fn Hash(comptime endian: std.builtin.Endian, comptime shift_key: bool) type { |
| 313 | } | 313 | } |
| 314 | acc = reduce(u); | 314 | acc = reduce(u); |
| 315 | } | 315 | } |
| 316 | } else if (builtin.mode != .ReleaseSmall and msg.len >= agg_8_threshold * block_length) { | 316 | } else if (builtin.mode != .small and msg.len >= agg_8_threshold * block_length) { |
| 317 | // 8-blocks aggregated reduction | 317 | // 8-blocks aggregated reduction |
| 318 | while (i + 128 <= msg.len) : (i += 128) { | 318 | while (i + 128 <= msg.len) : (i += 128) { |
| 319 | var u = clmul128(acc ^ mem.readInt(u128, msg[i..][0..16], endian), st.hx[7 - 0]); | 319 | var u = clmul128(acc ^ mem.readInt(u128, msg[i..][0..16], endian), st.hx[7 - 0]); |
| ... | @@ -323,7 +323,7 @@ fn Hash(comptime endian: std.builtin.Endian, comptime shift_key: bool) type { | ... | @@ -323,7 +323,7 @@ fn Hash(comptime endian: std.builtin.Endian, comptime shift_key: bool) type { |
| 323 | } | 323 | } |
| 324 | acc = reduce(u); | 324 | acc = reduce(u); |
| 325 | } | 325 | } |
| 326 | } else if (builtin.mode != .ReleaseSmall and msg.len >= agg_4_threshold * block_length) { | 326 | } else if (builtin.mode != .small and msg.len >= agg_4_threshold * block_length) { |
| 327 | // 4-blocks aggregated reduction | 327 | // 4-blocks aggregated reduction |
| 328 | while (i + 64 <= msg.len) : (i += 64) { | 328 | while (i + 64 <= msg.len) : (i += 64) { |
| 329 | var u = clmul128(acc ^ mem.readInt(u128, msg[i..][0..16], endian), st.hx[3 - 0]); | 329 | var u = clmul128(acc ^ mem.readInt(u128, msg[i..][0..16], endian), st.hx[3 - 0]); |
lib/std/crypto/kangarootwelve.zig+2-2| ... | @@ -885,7 +885,7 @@ fn ktMultiThreaded( | ... | @@ -885,7 +885,7 @@ fn ktMultiThreaded( |
| 885 | 885 | ||
| 886 | var select_outstanding: usize = 0; | 886 | var select_outstanding: usize = 0; |
| 887 | var select: Select = .init(io, select_buf); | 887 | var select: Select = .init(io, select_buf); |
| 888 | defer select.cancel(); | 888 | defer select.cancelDiscard(); |
| 889 | var batches_spawned: usize = 0; | 889 | var batches_spawned: usize = 0; |
| 890 | var next_to_process: usize = 0; | 890 | var next_to_process: usize = 0; |
| 891 | 891 | ||
| ... | @@ -1398,7 +1398,7 @@ test "KT128 sequential and parallel produce same output for many random lengths" | ... | @@ -1398,7 +1398,7 @@ test "KT128 sequential and parallel produce same output for many random lengths" |
| 1398 | var prng = std.Random.DefaultPrng.init(std.testing.random_seed); | 1398 | var prng = std.Random.DefaultPrng.init(std.testing.random_seed); |
| 1399 | const random = prng.random(); | 1399 | const random = prng.random(); |
| 1400 | 1400 | ||
| 1401 | const num_tests = if (builtin.mode == .Debug) 10 else 1000; | 1401 | const num_tests = if (builtin.mode == .debug) 10 else 1000; |
| 1402 | const max_length = 250000; | 1402 | const max_length = 250000; |
| 1403 | 1403 | ||
| 1404 | for (0..num_tests) |_| { | 1404 | for (0..num_tests) |_| { |
lib/std/crypto/keccak_p.zig+2-2| ... | @@ -202,7 +202,7 @@ pub fn State(comptime f: u11, comptime capacity: u11, comptime rounds: u5) type | ... | @@ -202,7 +202,7 @@ pub fn State(comptime f: u11, comptime capacity: u11, comptime rounds: u5) type |
| 202 | 202 | ||
| 203 | // In debug mode, track transitions to prevent insecure ones. | 203 | // In debug mode, track transitions to prevent insecure ones. |
| 204 | const Op = enum { uninitialized, initialized, updated, absorb, squeeze }; | 204 | const Op = enum { uninitialized, initialized, updated, absorb, squeeze }; |
| 205 | const TransitionTracker = if (mode == .Debug) struct { | 205 | const TransitionTracker = if (mode == .debug) struct { |
| 206 | op: Op = .uninitialized, | 206 | op: Op = .uninitialized, |
| 207 | 207 | ||
| 208 | fn to(tracker: *@This(), next_op: Op) void { | 208 | fn to(tracker: *@This(), next_op: Op) void { |
| ... | @@ -294,7 +294,7 @@ pub fn State(comptime f: u11, comptime capacity: u11, comptime rounds: u5) type | ... | @@ -294,7 +294,7 @@ pub fn State(comptime f: u11, comptime capacity: u11, comptime rounds: u5) type |
| 294 | 294 | ||
| 295 | /// Permute the state | 295 | /// Permute the state |
| 296 | pub fn permute(self: *Self) void { | 296 | pub fn permute(self: *Self) void { |
| 297 | if (mode == .Debug) { | 297 | if (mode == .debug) { |
| 298 | if (self.transition.op == .absorb and self.offset > 0) { | 298 | if (self.transition.op == .absorb and self.offset > 0) { |
| 299 | @panic("cannot permute with pending input - call fillBlock() or pad() instead"); | 299 | @panic("cannot permute with pending input - call fillBlock() or pad() instead"); |
| 300 | } | 300 | } |
lib/std/crypto/pcurves/p256/p256_64.zig+17-17| ... | @@ -110,7 +110,7 @@ fn subborrowxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) void { | ... | @@ -110,7 +110,7 @@ fn subborrowxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) void { |
| 110 | /// out1: [0x0 ~> 0xffffffffffffffff] | 110 | /// out1: [0x0 ~> 0xffffffffffffffff] |
| 111 | /// out2: [0x0 ~> 0xffffffffffffffff] | 111 | /// out2: [0x0 ~> 0xffffffffffffffff] |
| 112 | fn mulxU64(out1: *u64, out2: *u64, arg1: u64, arg2: u64) void { | 112 | fn mulxU64(out1: *u64, out2: *u64, arg1: u64, arg2: u64) void { |
| 113 | @setRuntimeSafety(mode == .Debug); | 113 | @setRuntimeSafety(mode == .debug); |
| 114 | 114 | ||
| 115 | const x = @as(u128, arg1) * @as(u128, arg2); | 115 | const x = @as(u128, arg1) * @as(u128, arg2); |
| 116 | out1.* = @as(u64, @truncate(x)); | 116 | out1.* = @as(u64, @truncate(x)); |
| ... | @@ -129,7 +129,7 @@ fn mulxU64(out1: *u64, out2: *u64, arg1: u64, arg2: u64) void { | ... | @@ -129,7 +129,7 @@ fn mulxU64(out1: *u64, out2: *u64, arg1: u64, arg2: u64) void { |
| 129 | /// Output Bounds: | 129 | /// Output Bounds: |
| 130 | /// out1: [0x0 ~> 0xffffffffffffffff] | 130 | /// out1: [0x0 ~> 0xffffffffffffffff] |
| 131 | fn cmovznzU64(out1: *u64, arg1: u1, arg2: u64, arg3: u64) void { | 131 | fn cmovznzU64(out1: *u64, arg1: u1, arg2: u64, arg3: u64) void { |
| 132 | @setRuntimeSafety(mode == .Debug); | 132 | @setRuntimeSafety(mode == .debug); |
| 133 | 133 | ||
| 134 | const mask = 0 -% @as(u64, arg1); | 134 | const mask = 0 -% @as(u64, arg1); |
| 135 | out1.* = (mask & arg3) | ((~mask) & arg2); | 135 | out1.* = (mask & arg3) | ((~mask) & arg2); |
| ... | @@ -145,7 +145,7 @@ fn cmovznzU64(out1: *u64, arg1: u1, arg2: u64, arg3: u64) void { | ... | @@ -145,7 +145,7 @@ fn cmovznzU64(out1: *u64, arg1: u1, arg2: u64, arg3: u64) void { |
| 145 | /// 0 ≤ eval out1 < m | 145 | /// 0 ≤ eval out1 < m |
| 146 | /// | 146 | /// |
| 147 | pub fn mul(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement, arg2: MontgomeryDomainFieldElement) void { | 147 | pub fn mul(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement, arg2: MontgomeryDomainFieldElement) void { |
| 148 | @setRuntimeSafety(mode == .Debug); | 148 | @setRuntimeSafety(mode == .debug); |
| 149 | 149 | ||
| 150 | const x1 = (arg1[1]); | 150 | const x1 = (arg1[1]); |
| 151 | const x2 = (arg1[2]); | 151 | const x2 = (arg1[2]); |
| ... | @@ -437,7 +437,7 @@ pub fn mul(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme | ... | @@ -437,7 +437,7 @@ pub fn mul(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme |
| 437 | /// 0 ≤ eval out1 < m | 437 | /// 0 ≤ eval out1 < m |
| 438 | /// | 438 | /// |
| 439 | pub fn square(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement) void { | 439 | pub fn square(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement) void { |
| 440 | @setRuntimeSafety(mode == .Debug); | 440 | @setRuntimeSafety(mode == .debug); |
| 441 | 441 | ||
| 442 | const x1 = (arg1[1]); | 442 | const x1 = (arg1[1]); |
| 443 | const x2 = (arg1[2]); | 443 | const x2 = (arg1[2]); |
| ... | @@ -730,7 +730,7 @@ pub fn square(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEl | ... | @@ -730,7 +730,7 @@ pub fn square(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEl |
| 730 | /// 0 ≤ eval out1 < m | 730 | /// 0 ≤ eval out1 < m |
| 731 | /// | 731 | /// |
| 732 | pub fn add(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement, arg2: MontgomeryDomainFieldElement) void { | 732 | pub fn add(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement, arg2: MontgomeryDomainFieldElement) void { |
| 733 | @setRuntimeSafety(mode == .Debug); | 733 | @setRuntimeSafety(mode == .debug); |
| 734 | 734 | ||
| 735 | var x1: u64 = undefined; | 735 | var x1: u64 = undefined; |
| 736 | var x2: u1 = undefined; | 736 | var x2: u1 = undefined; |
| ... | @@ -783,7 +783,7 @@ pub fn add(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme | ... | @@ -783,7 +783,7 @@ pub fn add(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme |
| 783 | /// 0 ≤ eval out1 < m | 783 | /// 0 ≤ eval out1 < m |
| 784 | /// | 784 | /// |
| 785 | pub fn sub(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement, arg2: MontgomeryDomainFieldElement) void { | 785 | pub fn sub(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement, arg2: MontgomeryDomainFieldElement) void { |
| 786 | @setRuntimeSafety(mode == .Debug); | 786 | @setRuntimeSafety(mode == .debug); |
| 787 | 787 | ||
| 788 | var x1: u64 = undefined; | 788 | var x1: u64 = undefined; |
| 789 | var x2: u1 = undefined; | 789 | var x2: u1 = undefined; |
| ... | @@ -826,7 +826,7 @@ pub fn sub(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme | ... | @@ -826,7 +826,7 @@ pub fn sub(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme |
| 826 | /// 0 ≤ eval out1 < m | 826 | /// 0 ≤ eval out1 < m |
| 827 | /// | 827 | /// |
| 828 | pub fn opp(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement) void { | 828 | pub fn opp(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement) void { |
| 829 | @setRuntimeSafety(mode == .Debug); | 829 | @setRuntimeSafety(mode == .debug); |
| 830 | 830 | ||
| 831 | var x1: u64 = undefined; | 831 | var x1: u64 = undefined; |
| 832 | var x2: u1 = undefined; | 832 | var x2: u1 = undefined; |
| ... | @@ -869,7 +869,7 @@ pub fn opp(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme | ... | @@ -869,7 +869,7 @@ pub fn opp(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme |
| 869 | /// 0 ≤ eval out1 < m | 869 | /// 0 ≤ eval out1 < m |
| 870 | /// | 870 | /// |
| 871 | pub fn fromMontgomery(out1: *NonMontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement) void { | 871 | pub fn fromMontgomery(out1: *NonMontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement) void { |
| 872 | @setRuntimeSafety(mode == .Debug); | 872 | @setRuntimeSafety(mode == .debug); |
| 873 | 873 | ||
| 874 | const x1 = (arg1[0]); | 874 | const x1 = (arg1[0]); |
| 875 | var x2: u64 = undefined; | 875 | var x2: u64 = undefined; |
| ... | @@ -1022,7 +1022,7 @@ pub fn fromMontgomery(out1: *NonMontgomeryDomainFieldElement, arg1: MontgomeryDo | ... | @@ -1022,7 +1022,7 @@ pub fn fromMontgomery(out1: *NonMontgomeryDomainFieldElement, arg1: MontgomeryDo |
| 1022 | /// 0 ≤ eval out1 < m | 1022 | /// 0 ≤ eval out1 < m |
| 1023 | /// | 1023 | /// |
| 1024 | pub fn toMontgomery(out1: *MontgomeryDomainFieldElement, arg1: NonMontgomeryDomainFieldElement) void { | 1024 | pub fn toMontgomery(out1: *MontgomeryDomainFieldElement, arg1: NonMontgomeryDomainFieldElement) void { |
| 1025 | @setRuntimeSafety(mode == .Debug); | 1025 | @setRuntimeSafety(mode == .debug); |
| 1026 | 1026 | ||
| 1027 | const x1 = (arg1[1]); | 1027 | const x1 = (arg1[1]); |
| 1028 | const x2 = (arg1[2]); | 1028 | const x2 = (arg1[2]); |
| ... | @@ -1297,7 +1297,7 @@ pub fn toMontgomery(out1: *MontgomeryDomainFieldElement, arg1: NonMontgomeryDoma | ... | @@ -1297,7 +1297,7 @@ pub fn toMontgomery(out1: *MontgomeryDomainFieldElement, arg1: NonMontgomeryDoma |
| 1297 | /// Output Bounds: | 1297 | /// Output Bounds: |
| 1298 | /// out1: [0x0 ~> 0xffffffffffffffff] | 1298 | /// out1: [0x0 ~> 0xffffffffffffffff] |
| 1299 | pub fn nonzero(out1: *u64, arg1: [4]u64) void { | 1299 | pub fn nonzero(out1: *u64, arg1: [4]u64) void { |
| 1300 | @setRuntimeSafety(mode == .Debug); | 1300 | @setRuntimeSafety(mode == .debug); |
| 1301 | 1301 | ||
| 1302 | const x1 = ((arg1[0]) | ((arg1[1]) | ((arg1[2]) | (arg1[3])))); | 1302 | const x1 = ((arg1[0]) | ((arg1[1]) | ((arg1[2]) | (arg1[3])))); |
| 1303 | out1.* = x1; | 1303 | out1.* = x1; |
| ... | @@ -1315,7 +1315,7 @@ pub fn nonzero(out1: *u64, arg1: [4]u64) void { | ... | @@ -1315,7 +1315,7 @@ pub fn nonzero(out1: *u64, arg1: [4]u64) void { |
| 1315 | /// Output Bounds: | 1315 | /// Output Bounds: |
| 1316 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] | 1316 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] |
| 1317 | pub fn selectznz(out1: *[4]u64, arg1: u1, arg2: [4]u64, arg3: [4]u64) void { | 1317 | pub fn selectznz(out1: *[4]u64, arg1: u1, arg2: [4]u64, arg3: [4]u64) void { |
| 1318 | @setRuntimeSafety(mode == .Debug); | 1318 | @setRuntimeSafety(mode == .debug); |
| 1319 | 1319 | ||
| 1320 | var x1: u64 = undefined; | 1320 | var x1: u64 = undefined; |
| 1321 | cmovznzU64(&x1, arg1, (arg2[0]), (arg3[0])); | 1321 | cmovznzU64(&x1, arg1, (arg2[0]), (arg3[0])); |
| ... | @@ -1343,7 +1343,7 @@ pub fn selectznz(out1: *[4]u64, arg1: u1, arg2: [4]u64, arg3: [4]u64) void { | ... | @@ -1343,7 +1343,7 @@ pub fn selectznz(out1: *[4]u64, arg1: u1, arg2: [4]u64, arg3: [4]u64) void { |
| 1343 | /// Output Bounds: | 1343 | /// Output Bounds: |
| 1344 | /// out1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff]] | 1344 | /// out1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff]] |
| 1345 | pub fn toBytes(out1: *[32]u8, arg1: [4]u64) void { | 1345 | pub fn toBytes(out1: *[32]u8, arg1: [4]u64) void { |
| 1346 | @setRuntimeSafety(mode == .Debug); | 1346 | @setRuntimeSafety(mode == .debug); |
| 1347 | 1347 | ||
| 1348 | const x1 = (arg1[3]); | 1348 | const x1 = (arg1[3]); |
| 1349 | const x2 = (arg1[2]); | 1349 | const x2 = (arg1[2]); |
| ... | @@ -1452,7 +1452,7 @@ pub fn toBytes(out1: *[32]u8, arg1: [4]u64) void { | ... | @@ -1452,7 +1452,7 @@ pub fn toBytes(out1: *[32]u8, arg1: [4]u64) void { |
| 1452 | /// Output Bounds: | 1452 | /// Output Bounds: |
| 1453 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] | 1453 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] |
| 1454 | pub fn fromBytes(out1: *[4]u64, arg1: [32]u8) void { | 1454 | pub fn fromBytes(out1: *[4]u64, arg1: [32]u8) void { |
| 1455 | @setRuntimeSafety(mode == .Debug); | 1455 | @setRuntimeSafety(mode == .debug); |
| 1456 | 1456 | ||
| 1457 | const x1 = (@as(u64, (arg1[31])) << 56); | 1457 | const x1 = (@as(u64, (arg1[31])) << 56); |
| 1458 | const x2 = (@as(u64, (arg1[30])) << 48); | 1458 | const x2 = (@as(u64, (arg1[30])) << 48); |
| ... | @@ -1527,7 +1527,7 @@ pub fn fromBytes(out1: *[4]u64, arg1: [32]u8) void { | ... | @@ -1527,7 +1527,7 @@ pub fn fromBytes(out1: *[4]u64, arg1: [32]u8) void { |
| 1527 | /// 0 ≤ eval out1 < m | 1527 | /// 0 ≤ eval out1 < m |
| 1528 | /// | 1528 | /// |
| 1529 | pub fn setOne(out1: *MontgomeryDomainFieldElement) void { | 1529 | pub fn setOne(out1: *MontgomeryDomainFieldElement) void { |
| 1530 | @setRuntimeSafety(mode == .Debug); | 1530 | @setRuntimeSafety(mode == .debug); |
| 1531 | 1531 | ||
| 1532 | out1[0] = @as(u64, 0x1); | 1532 | out1[0] = @as(u64, 0x1); |
| 1533 | out1[1] = 0xffffffff00000000; | 1533 | out1[1] = 0xffffffff00000000; |
| ... | @@ -1544,7 +1544,7 @@ pub fn setOne(out1: *MontgomeryDomainFieldElement) void { | ... | @@ -1544,7 +1544,7 @@ pub fn setOne(out1: *MontgomeryDomainFieldElement) void { |
| 1544 | /// Output Bounds: | 1544 | /// Output Bounds: |
| 1545 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] | 1545 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] |
| 1546 | pub fn msat(out1: *[5]u64) void { | 1546 | pub fn msat(out1: *[5]u64) void { |
| 1547 | @setRuntimeSafety(mode == .Debug); | 1547 | @setRuntimeSafety(mode == .debug); |
| 1548 | 1548 | ||
| 1549 | out1[0] = 0xffffffffffffffff; | 1549 | out1[0] = 0xffffffffffffffff; |
| 1550 | out1[1] = 0xffffffff; | 1550 | out1[1] = 0xffffffff; |
| ... | @@ -1582,7 +1582,7 @@ pub fn msat(out1: *[5]u64) void { | ... | @@ -1582,7 +1582,7 @@ pub fn msat(out1: *[5]u64) void { |
| 1582 | /// out4: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] | 1582 | /// out4: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] |
| 1583 | /// out5: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] | 1583 | /// out5: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] |
| 1584 | pub fn divstep(out1: *u64, out2: *[5]u64, out3: *[5]u64, out4: *[4]u64, out5: *[4]u64, arg1: u64, arg2: [5]u64, arg3: [5]u64, arg4: [4]u64, arg5: [4]u64) void { | 1584 | pub fn divstep(out1: *u64, out2: *[5]u64, out3: *[5]u64, out4: *[4]u64, out5: *[4]u64, arg1: u64, arg2: [5]u64, arg3: [5]u64, arg4: [4]u64, arg5: [4]u64) void { |
| 1585 | @setRuntimeSafety(mode == .Debug); | 1585 | @setRuntimeSafety(mode == .debug); |
| 1586 | 1586 | ||
| 1587 | var x1: u64 = undefined; | 1587 | var x1: u64 = undefined; |
| 1588 | var x2: u1 = undefined; | 1588 | var x2: u1 = undefined; |
| ... | @@ -1816,7 +1816,7 @@ pub fn divstep(out1: *u64, out2: *[5]u64, out3: *[5]u64, out4: *[4]u64, out5: *[ | ... | @@ -1816,7 +1816,7 @@ pub fn divstep(out1: *u64, out2: *[5]u64, out3: *[5]u64, out4: *[4]u64, out5: *[ |
| 1816 | /// Output Bounds: | 1816 | /// Output Bounds: |
| 1817 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] | 1817 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] |
| 1818 | pub fn divstepPrecomp(out1: *[4]u64) void { | 1818 | pub fn divstepPrecomp(out1: *[4]u64) void { |
| 1819 | @setRuntimeSafety(mode == .Debug); | 1819 | @setRuntimeSafety(mode == .debug); |
| 1820 | 1820 | ||
| 1821 | out1[0] = 0x67ffffffb8000000; | 1821 | out1[0] = 0x67ffffffb8000000; |
| 1822 | out1[1] = 0xc000000038000000; | 1822 | out1[1] = 0xc000000038000000; |
lib/std/crypto/pcurves/p256/p256_scalar_64.zig+17-17| ... | @@ -110,7 +110,7 @@ fn subborrowxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) void { | ... | @@ -110,7 +110,7 @@ fn subborrowxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) void { |
| 110 | /// out1: [0x0 ~> 0xffffffffffffffff] | 110 | /// out1: [0x0 ~> 0xffffffffffffffff] |
| 111 | /// out2: [0x0 ~> 0xffffffffffffffff] | 111 | /// out2: [0x0 ~> 0xffffffffffffffff] |
| 112 | fn mulxU64(out1: *u64, out2: *u64, arg1: u64, arg2: u64) void { | 112 | fn mulxU64(out1: *u64, out2: *u64, arg1: u64, arg2: u64) void { |
| 113 | @setRuntimeSafety(mode == .Debug); | 113 | @setRuntimeSafety(mode == .debug); |
| 114 | 114 | ||
| 115 | const x = @as(u128, arg1) * @as(u128, arg2); | 115 | const x = @as(u128, arg1) * @as(u128, arg2); |
| 116 | out1.* = @as(u64, @truncate(x)); | 116 | out1.* = @as(u64, @truncate(x)); |
| ... | @@ -129,7 +129,7 @@ fn mulxU64(out1: *u64, out2: *u64, arg1: u64, arg2: u64) void { | ... | @@ -129,7 +129,7 @@ fn mulxU64(out1: *u64, out2: *u64, arg1: u64, arg2: u64) void { |
| 129 | /// Output Bounds: | 129 | /// Output Bounds: |
| 130 | /// out1: [0x0 ~> 0xffffffffffffffff] | 130 | /// out1: [0x0 ~> 0xffffffffffffffff] |
| 131 | fn cmovznzU64(out1: *u64, arg1: u1, arg2: u64, arg3: u64) void { | 131 | fn cmovznzU64(out1: *u64, arg1: u1, arg2: u64, arg3: u64) void { |
| 132 | @setRuntimeSafety(mode == .Debug); | 132 | @setRuntimeSafety(mode == .debug); |
| 133 | 133 | ||
| 134 | const mask = 0 -% @as(u64, arg1); | 134 | const mask = 0 -% @as(u64, arg1); |
| 135 | out1.* = (mask & arg3) | ((~mask) & arg2); | 135 | out1.* = (mask & arg3) | ((~mask) & arg2); |
| ... | @@ -145,7 +145,7 @@ fn cmovznzU64(out1: *u64, arg1: u1, arg2: u64, arg3: u64) void { | ... | @@ -145,7 +145,7 @@ fn cmovznzU64(out1: *u64, arg1: u1, arg2: u64, arg3: u64) void { |
| 145 | /// 0 ≤ eval out1 < m | 145 | /// 0 ≤ eval out1 < m |
| 146 | /// | 146 | /// |
| 147 | pub fn mul(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement, arg2: MontgomeryDomainFieldElement) void { | 147 | pub fn mul(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement, arg2: MontgomeryDomainFieldElement) void { |
| 148 | @setRuntimeSafety(mode == .Debug); | 148 | @setRuntimeSafety(mode == .debug); |
| 149 | 149 | ||
| 150 | const x1 = (arg1[1]); | 150 | const x1 = (arg1[1]); |
| 151 | const x2 = (arg1[2]); | 151 | const x2 = (arg1[2]); |
| ... | @@ -485,7 +485,7 @@ pub fn mul(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme | ... | @@ -485,7 +485,7 @@ pub fn mul(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme |
| 485 | /// 0 ≤ eval out1 < m | 485 | /// 0 ≤ eval out1 < m |
| 486 | /// | 486 | /// |
| 487 | pub fn square(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement) void { | 487 | pub fn square(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement) void { |
| 488 | @setRuntimeSafety(mode == .Debug); | 488 | @setRuntimeSafety(mode == .debug); |
| 489 | 489 | ||
| 490 | const x1 = (arg1[1]); | 490 | const x1 = (arg1[1]); |
| 491 | const x2 = (arg1[2]); | 491 | const x2 = (arg1[2]); |
| ... | @@ -826,7 +826,7 @@ pub fn square(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEl | ... | @@ -826,7 +826,7 @@ pub fn square(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEl |
| 826 | /// 0 ≤ eval out1 < m | 826 | /// 0 ≤ eval out1 < m |
| 827 | /// | 827 | /// |
| 828 | pub fn add(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement, arg2: MontgomeryDomainFieldElement) void { | 828 | pub fn add(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement, arg2: MontgomeryDomainFieldElement) void { |
| 829 | @setRuntimeSafety(mode == .Debug); | 829 | @setRuntimeSafety(mode == .debug); |
| 830 | 830 | ||
| 831 | var x1: u64 = undefined; | 831 | var x1: u64 = undefined; |
| 832 | var x2: u1 = undefined; | 832 | var x2: u1 = undefined; |
| ... | @@ -879,7 +879,7 @@ pub fn add(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme | ... | @@ -879,7 +879,7 @@ pub fn add(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme |
| 879 | /// 0 ≤ eval out1 < m | 879 | /// 0 ≤ eval out1 < m |
| 880 | /// | 880 | /// |
| 881 | pub fn sub(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement, arg2: MontgomeryDomainFieldElement) void { | 881 | pub fn sub(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement, arg2: MontgomeryDomainFieldElement) void { |
| 882 | @setRuntimeSafety(mode == .Debug); | 882 | @setRuntimeSafety(mode == .debug); |
| 883 | 883 | ||
| 884 | var x1: u64 = undefined; | 884 | var x1: u64 = undefined; |
| 885 | var x2: u1 = undefined; | 885 | var x2: u1 = undefined; |
| ... | @@ -922,7 +922,7 @@ pub fn sub(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme | ... | @@ -922,7 +922,7 @@ pub fn sub(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme |
| 922 | /// 0 ≤ eval out1 < m | 922 | /// 0 ≤ eval out1 < m |
| 923 | /// | 923 | /// |
| 924 | pub fn opp(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement) void { | 924 | pub fn opp(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement) void { |
| 925 | @setRuntimeSafety(mode == .Debug); | 925 | @setRuntimeSafety(mode == .debug); |
| 926 | 926 | ||
| 927 | var x1: u64 = undefined; | 927 | var x1: u64 = undefined; |
| 928 | var x2: u1 = undefined; | 928 | var x2: u1 = undefined; |
| ... | @@ -965,7 +965,7 @@ pub fn opp(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme | ... | @@ -965,7 +965,7 @@ pub fn opp(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme |
| 965 | /// 0 ≤ eval out1 < m | 965 | /// 0 ≤ eval out1 < m |
| 966 | /// | 966 | /// |
| 967 | pub fn fromMontgomery(out1: *NonMontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement) void { | 967 | pub fn fromMontgomery(out1: *NonMontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement) void { |
| 968 | @setRuntimeSafety(mode == .Debug); | 968 | @setRuntimeSafety(mode == .debug); |
| 969 | 969 | ||
| 970 | const x1 = (arg1[0]); | 970 | const x1 = (arg1[0]); |
| 971 | var x2: u64 = undefined; | 971 | var x2: u64 = undefined; |
| ... | @@ -1178,7 +1178,7 @@ pub fn fromMontgomery(out1: *NonMontgomeryDomainFieldElement, arg1: MontgomeryDo | ... | @@ -1178,7 +1178,7 @@ pub fn fromMontgomery(out1: *NonMontgomeryDomainFieldElement, arg1: MontgomeryDo |
| 1178 | /// 0 ≤ eval out1 < m | 1178 | /// 0 ≤ eval out1 < m |
| 1179 | /// | 1179 | /// |
| 1180 | pub fn toMontgomery(out1: *MontgomeryDomainFieldElement, arg1: NonMontgomeryDomainFieldElement) void { | 1180 | pub fn toMontgomery(out1: *MontgomeryDomainFieldElement, arg1: NonMontgomeryDomainFieldElement) void { |
| 1181 | @setRuntimeSafety(mode == .Debug); | 1181 | @setRuntimeSafety(mode == .debug); |
| 1182 | 1182 | ||
| 1183 | const x1 = (arg1[1]); | 1183 | const x1 = (arg1[1]); |
| 1184 | const x2 = (arg1[2]); | 1184 | const x2 = (arg1[2]); |
| ... | @@ -1501,7 +1501,7 @@ pub fn toMontgomery(out1: *MontgomeryDomainFieldElement, arg1: NonMontgomeryDoma | ... | @@ -1501,7 +1501,7 @@ pub fn toMontgomery(out1: *MontgomeryDomainFieldElement, arg1: NonMontgomeryDoma |
| 1501 | /// Output Bounds: | 1501 | /// Output Bounds: |
| 1502 | /// out1: [0x0 ~> 0xffffffffffffffff] | 1502 | /// out1: [0x0 ~> 0xffffffffffffffff] |
| 1503 | pub fn nonzero(out1: *u64, arg1: [4]u64) void { | 1503 | pub fn nonzero(out1: *u64, arg1: [4]u64) void { |
| 1504 | @setRuntimeSafety(mode == .Debug); | 1504 | @setRuntimeSafety(mode == .debug); |
| 1505 | 1505 | ||
| 1506 | const x1 = ((arg1[0]) | ((arg1[1]) | ((arg1[2]) | (arg1[3])))); | 1506 | const x1 = ((arg1[0]) | ((arg1[1]) | ((arg1[2]) | (arg1[3])))); |
| 1507 | out1.* = x1; | 1507 | out1.* = x1; |
| ... | @@ -1519,7 +1519,7 @@ pub fn nonzero(out1: *u64, arg1: [4]u64) void { | ... | @@ -1519,7 +1519,7 @@ pub fn nonzero(out1: *u64, arg1: [4]u64) void { |
| 1519 | /// Output Bounds: | 1519 | /// Output Bounds: |
| 1520 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] | 1520 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] |
| 1521 | pub fn selectznz(out1: *[4]u64, arg1: u1, arg2: [4]u64, arg3: [4]u64) void { | 1521 | pub fn selectznz(out1: *[4]u64, arg1: u1, arg2: [4]u64, arg3: [4]u64) void { |
| 1522 | @setRuntimeSafety(mode == .Debug); | 1522 | @setRuntimeSafety(mode == .debug); |
| 1523 | 1523 | ||
| 1524 | var x1: u64 = undefined; | 1524 | var x1: u64 = undefined; |
| 1525 | cmovznzU64(&x1, arg1, (arg2[0]), (arg3[0])); | 1525 | cmovznzU64(&x1, arg1, (arg2[0]), (arg3[0])); |
| ... | @@ -1547,7 +1547,7 @@ pub fn selectznz(out1: *[4]u64, arg1: u1, arg2: [4]u64, arg3: [4]u64) void { | ... | @@ -1547,7 +1547,7 @@ pub fn selectznz(out1: *[4]u64, arg1: u1, arg2: [4]u64, arg3: [4]u64) void { |
| 1547 | /// Output Bounds: | 1547 | /// Output Bounds: |
| 1548 | /// out1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff]] | 1548 | /// out1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff]] |
| 1549 | pub fn toBytes(out1: *[32]u8, arg1: [4]u64) void { | 1549 | pub fn toBytes(out1: *[32]u8, arg1: [4]u64) void { |
| 1550 | @setRuntimeSafety(mode == .Debug); | 1550 | @setRuntimeSafety(mode == .debug); |
| 1551 | 1551 | ||
| 1552 | const x1 = (arg1[3]); | 1552 | const x1 = (arg1[3]); |
| 1553 | const x2 = (arg1[2]); | 1553 | const x2 = (arg1[2]); |
| ... | @@ -1656,7 +1656,7 @@ pub fn toBytes(out1: *[32]u8, arg1: [4]u64) void { | ... | @@ -1656,7 +1656,7 @@ pub fn toBytes(out1: *[32]u8, arg1: [4]u64) void { |
| 1656 | /// Output Bounds: | 1656 | /// Output Bounds: |
| 1657 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] | 1657 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] |
| 1658 | pub fn fromBytes(out1: *[4]u64, arg1: [32]u8) void { | 1658 | pub fn fromBytes(out1: *[4]u64, arg1: [32]u8) void { |
| 1659 | @setRuntimeSafety(mode == .Debug); | 1659 | @setRuntimeSafety(mode == .debug); |
| 1660 | 1660 | ||
| 1661 | const x1 = (@as(u64, (arg1[31])) << 56); | 1661 | const x1 = (@as(u64, (arg1[31])) << 56); |
| 1662 | const x2 = (@as(u64, (arg1[30])) << 48); | 1662 | const x2 = (@as(u64, (arg1[30])) << 48); |
| ... | @@ -1731,7 +1731,7 @@ pub fn fromBytes(out1: *[4]u64, arg1: [32]u8) void { | ... | @@ -1731,7 +1731,7 @@ pub fn fromBytes(out1: *[4]u64, arg1: [32]u8) void { |
| 1731 | /// 0 ≤ eval out1 < m | 1731 | /// 0 ≤ eval out1 < m |
| 1732 | /// | 1732 | /// |
| 1733 | pub fn setOne(out1: *MontgomeryDomainFieldElement) void { | 1733 | pub fn setOne(out1: *MontgomeryDomainFieldElement) void { |
| 1734 | @setRuntimeSafety(mode == .Debug); | 1734 | @setRuntimeSafety(mode == .debug); |
| 1735 | 1735 | ||
| 1736 | out1[0] = 0xc46353d039cdaaf; | 1736 | out1[0] = 0xc46353d039cdaaf; |
| 1737 | out1[1] = 0x4319055258e8617b; | 1737 | out1[1] = 0x4319055258e8617b; |
| ... | @@ -1748,7 +1748,7 @@ pub fn setOne(out1: *MontgomeryDomainFieldElement) void { | ... | @@ -1748,7 +1748,7 @@ pub fn setOne(out1: *MontgomeryDomainFieldElement) void { |
| 1748 | /// Output Bounds: | 1748 | /// Output Bounds: |
| 1749 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] | 1749 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] |
| 1750 | pub fn msat(out1: *[5]u64) void { | 1750 | pub fn msat(out1: *[5]u64) void { |
| 1751 | @setRuntimeSafety(mode == .Debug); | 1751 | @setRuntimeSafety(mode == .debug); |
| 1752 | 1752 | ||
| 1753 | out1[0] = 0xf3b9cac2fc632551; | 1753 | out1[0] = 0xf3b9cac2fc632551; |
| 1754 | out1[1] = 0xbce6faada7179e84; | 1754 | out1[1] = 0xbce6faada7179e84; |
| ... | @@ -1786,7 +1786,7 @@ pub fn msat(out1: *[5]u64) void { | ... | @@ -1786,7 +1786,7 @@ pub fn msat(out1: *[5]u64) void { |
| 1786 | /// out4: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] | 1786 | /// out4: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] |
| 1787 | /// out5: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] | 1787 | /// out5: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] |
| 1788 | pub fn divstep(out1: *u64, out2: *[5]u64, out3: *[5]u64, out4: *[4]u64, out5: *[4]u64, arg1: u64, arg2: [5]u64, arg3: [5]u64, arg4: [4]u64, arg5: [4]u64) void { | 1788 | pub fn divstep(out1: *u64, out2: *[5]u64, out3: *[5]u64, out4: *[4]u64, out5: *[4]u64, arg1: u64, arg2: [5]u64, arg3: [5]u64, arg4: [4]u64, arg5: [4]u64) void { |
| 1789 | @setRuntimeSafety(mode == .Debug); | 1789 | @setRuntimeSafety(mode == .debug); |
| 1790 | 1790 | ||
| 1791 | var x1: u64 = undefined; | 1791 | var x1: u64 = undefined; |
| 1792 | var x2: u1 = undefined; | 1792 | var x2: u1 = undefined; |
| ... | @@ -2020,7 +2020,7 @@ pub fn divstep(out1: *u64, out2: *[5]u64, out3: *[5]u64, out4: *[4]u64, out5: *[ | ... | @@ -2020,7 +2020,7 @@ pub fn divstep(out1: *u64, out2: *[5]u64, out3: *[5]u64, out4: *[4]u64, out5: *[ |
| 2020 | /// Output Bounds: | 2020 | /// Output Bounds: |
| 2021 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] | 2021 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] |
| 2022 | pub fn divstepPrecomp(out1: *[4]u64) void { | 2022 | pub fn divstepPrecomp(out1: *[4]u64) void { |
| 2023 | @setRuntimeSafety(mode == .Debug); | 2023 | @setRuntimeSafety(mode == .debug); |
| 2024 | 2024 | ||
| 2025 | out1[0] = 0xd739262fb7fcfbb5; | 2025 | out1[0] = 0xd739262fb7fcfbb5; |
| 2026 | out1[1] = 0x8ac6f75d20074414; | 2026 | out1[1] = 0x8ac6f75d20074414; |
lib/std/crypto/pcurves/p384.zig+4-6| ... | @@ -56,7 +56,7 @@ pub const P384 = struct { | ... | @@ -56,7 +56,7 @@ pub const P384 = struct { |
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | /// Create a point from serialized affine coordinates. | 58 | /// Create a point from serialized affine coordinates. |
| 59 | pub fn fromSerializedAffineCoordinates(xs: [48]u8, ys: [48]u8, endian: std.builtin.Endian) (NonCanonicalError || EncodingError)!P384 { | 59 | pub fn fromSerializedAffineCoordinates(xs: [48]u8, ys: [48]u8, endian: std.lang.Endian) (NonCanonicalError || EncodingError)!P384 { |
| 60 | const x = try Fe.fromBytes(xs, endian); | 60 | const x = try Fe.fromBytes(xs, endian); |
| 61 | const y = try Fe.fromBytes(ys, endian); | 61 | const y = try Fe.fromBytes(ys, endian); |
| 62 | return fromAffineCoordinates(.{ .x = x, .y = y }); | 62 | return fromAffineCoordinates(.{ .x = x, .y = y }); |
| ... | @@ -395,7 +395,7 @@ pub const P384 = struct { | ... | @@ -395,7 +395,7 @@ pub const P384 = struct { |
| 395 | 395 | ||
| 396 | /// Multiply an elliptic curve point by a scalar. | 396 | /// Multiply an elliptic curve point by a scalar. |
| 397 | /// Return error.IdentityElement if the result is the identity element. | 397 | /// Return error.IdentityElement if the result is the identity element. |
| 398 | pub fn mul(p: P384, s_: [48]u8, endian: std.builtin.Endian) IdentityElementError!P384 { | 398 | pub fn mul(p: P384, s_: [48]u8, endian: std.lang.Endian) IdentityElementError!P384 { |
| 399 | const s = if (endian == .little) s_ else Fe.orderSwap(s_); | 399 | const s = if (endian == .little) s_ else Fe.orderSwap(s_); |
| 400 | if (p.is_base) { | 400 | if (p.is_base) { |
| 401 | return pcMul16(&basePointPc, s, false); | 401 | return pcMul16(&basePointPc, s, false); |
| ... | @@ -407,7 +407,7 @@ pub const P384 = struct { | ... | @@ -407,7 +407,7 @@ pub const P384 = struct { |
| 407 | 407 | ||
| 408 | /// Multiply an elliptic curve point by a *PUBLIC* scalar *IN VARIABLE TIME* | 408 | /// Multiply an elliptic curve point by a *PUBLIC* scalar *IN VARIABLE TIME* |
| 409 | /// This can be used for signature verification. | 409 | /// This can be used for signature verification. |
| 410 | pub fn mulPublic(p: P384, s_: [48]u8, endian: std.builtin.Endian) IdentityElementError!P384 { | 410 | pub fn mulPublic(p: P384, s_: [48]u8, endian: std.lang.Endian) IdentityElementError!P384 { |
| 411 | const s = if (endian == .little) s_ else Fe.orderSwap(s_); | 411 | const s = if (endian == .little) s_ else Fe.orderSwap(s_); |
| 412 | if (p.is_base) { | 412 | if (p.is_base) { |
| 413 | return pcMul16(&basePointPc, s, true); | 413 | return pcMul16(&basePointPc, s, true); |
| ... | @@ -419,7 +419,7 @@ pub const P384 = struct { | ... | @@ -419,7 +419,7 @@ pub const P384 = struct { |
| 419 | 419 | ||
| 420 | /// Double-base multiplication of public parameters - Compute (p1*s1)+(p2*s2) *IN VARIABLE TIME* | 420 | /// Double-base multiplication of public parameters - Compute (p1*s1)+(p2*s2) *IN VARIABLE TIME* |
| 421 | /// This can be used for signature verification. | 421 | /// This can be used for signature verification. |
| 422 | pub fn mulDoubleBasePublic(p1: P384, s1_: [48]u8, p2: P384, s2_: [48]u8, endian: std.builtin.Endian) IdentityElementError!P384 { | 422 | pub fn mulDoubleBasePublic(p1: P384, s1_: [48]u8, p2: P384, s2_: [48]u8, endian: std.lang.Endian) IdentityElementError!P384 { |
| 423 | const s1 = if (endian == .little) s1_ else Fe.orderSwap(s1_); | 423 | const s1 = if (endian == .little) s1_ else Fe.orderSwap(s1_); |
| 424 | const s2 = if (endian == .little) s2_ else Fe.orderSwap(s2_); | 424 | const s2 = if (endian == .little) s2_ else Fe.orderSwap(s2_); |
| 425 | try p1.rejectIdentity(); | 425 | try p1.rejectIdentity(); |
| ... | @@ -478,7 +478,5 @@ pub const AffineCoordinates = struct { | ... | @@ -478,7 +478,5 @@ pub const AffineCoordinates = struct { |
| 478 | }; | 478 | }; |
| 479 | 479 | ||
| 480 | test { | 480 | test { |
| 481 | if (@import("builtin").zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 482 | |||
| 483 | _ = @import("tests/p384.zig"); | 481 | _ = @import("tests/p384.zig"); |
| 484 | } | 482 | } |
lib/std/crypto/pcurves/p384/p384_64.zig+17-17| ... | @@ -79,7 +79,7 @@ fn subborrowxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) void { | ... | @@ -79,7 +79,7 @@ fn subborrowxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) void { |
| 79 | /// out1: [0x0 ~> 0xffffffffffffffff] | 79 | /// out1: [0x0 ~> 0xffffffffffffffff] |
| 80 | /// out2: [0x0 ~> 0xffffffffffffffff] | 80 | /// out2: [0x0 ~> 0xffffffffffffffff] |
| 81 | fn mulxU64(out1: *u64, out2: *u64, arg1: u64, arg2: u64) void { | 81 | fn mulxU64(out1: *u64, out2: *u64, arg1: u64, arg2: u64) void { |
| 82 | @setRuntimeSafety(mode == .Debug); | 82 | @setRuntimeSafety(mode == .debug); |
| 83 | 83 | ||
| 84 | const x = @as(u128, arg1) * @as(u128, arg2); | 84 | const x = @as(u128, arg1) * @as(u128, arg2); |
| 85 | out1.* = @as(u64, @truncate(x)); | 85 | out1.* = @as(u64, @truncate(x)); |
| ... | @@ -98,7 +98,7 @@ fn mulxU64(out1: *u64, out2: *u64, arg1: u64, arg2: u64) void { | ... | @@ -98,7 +98,7 @@ fn mulxU64(out1: *u64, out2: *u64, arg1: u64, arg2: u64) void { |
| 98 | /// Output Bounds: | 98 | /// Output Bounds: |
| 99 | /// out1: [0x0 ~> 0xffffffffffffffff] | 99 | /// out1: [0x0 ~> 0xffffffffffffffff] |
| 100 | fn cmovznzU64(out1: *u64, arg1: u1, arg2: u64, arg3: u64) void { | 100 | fn cmovznzU64(out1: *u64, arg1: u1, arg2: u64, arg3: u64) void { |
| 101 | @setRuntimeSafety(mode == .Debug); | 101 | @setRuntimeSafety(mode == .debug); |
| 102 | 102 | ||
| 103 | const mask = 0 -% @as(u64, arg1); | 103 | const mask = 0 -% @as(u64, arg1); |
| 104 | out1.* = (mask & arg3) | ((~mask) & arg2); | 104 | out1.* = (mask & arg3) | ((~mask) & arg2); |
| ... | @@ -114,7 +114,7 @@ fn cmovznzU64(out1: *u64, arg1: u1, arg2: u64, arg3: u64) void { | ... | @@ -114,7 +114,7 @@ fn cmovznzU64(out1: *u64, arg1: u1, arg2: u64, arg3: u64) void { |
| 114 | /// 0 ≤ eval out1 < m | 114 | /// 0 ≤ eval out1 < m |
| 115 | /// | 115 | /// |
| 116 | pub fn mul(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement, arg2: MontgomeryDomainFieldElement) void { | 116 | pub fn mul(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement, arg2: MontgomeryDomainFieldElement) void { |
| 117 | @setRuntimeSafety(mode == .Debug); | 117 | @setRuntimeSafety(mode == .debug); |
| 118 | 118 | ||
| 119 | const x1 = (arg1[1]); | 119 | const x1 = (arg1[1]); |
| 120 | const x2 = (arg1[2]); | 120 | const x2 = (arg1[2]); |
| ... | @@ -834,7 +834,7 @@ pub fn mul(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme | ... | @@ -834,7 +834,7 @@ pub fn mul(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme |
| 834 | /// 0 ≤ eval out1 < m | 834 | /// 0 ≤ eval out1 < m |
| 835 | /// | 835 | /// |
| 836 | pub fn square(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement) void { | 836 | pub fn square(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement) void { |
| 837 | @setRuntimeSafety(mode == .Debug); | 837 | @setRuntimeSafety(mode == .debug); |
| 838 | 838 | ||
| 839 | const x1 = (arg1[1]); | 839 | const x1 = (arg1[1]); |
| 840 | const x2 = (arg1[2]); | 840 | const x2 = (arg1[2]); |
| ... | @@ -1555,7 +1555,7 @@ pub fn square(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEl | ... | @@ -1555,7 +1555,7 @@ pub fn square(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEl |
| 1555 | /// 0 ≤ eval out1 < m | 1555 | /// 0 ≤ eval out1 < m |
| 1556 | /// | 1556 | /// |
| 1557 | pub fn add(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement, arg2: MontgomeryDomainFieldElement) void { | 1557 | pub fn add(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement, arg2: MontgomeryDomainFieldElement) void { |
| 1558 | @setRuntimeSafety(mode == .Debug); | 1558 | @setRuntimeSafety(mode == .debug); |
| 1559 | 1559 | ||
| 1560 | var x1: u64 = undefined; | 1560 | var x1: u64 = undefined; |
| 1561 | var x2: u1 = undefined; | 1561 | var x2: u1 = undefined; |
| ... | @@ -1626,7 +1626,7 @@ pub fn add(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme | ... | @@ -1626,7 +1626,7 @@ pub fn add(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme |
| 1626 | /// 0 ≤ eval out1 < m | 1626 | /// 0 ≤ eval out1 < m |
| 1627 | /// | 1627 | /// |
| 1628 | pub fn sub(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement, arg2: MontgomeryDomainFieldElement) void { | 1628 | pub fn sub(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement, arg2: MontgomeryDomainFieldElement) void { |
| 1629 | @setRuntimeSafety(mode == .Debug); | 1629 | @setRuntimeSafety(mode == .debug); |
| 1630 | 1630 | ||
| 1631 | var x1: u64 = undefined; | 1631 | var x1: u64 = undefined; |
| 1632 | var x2: u1 = undefined; | 1632 | var x2: u1 = undefined; |
| ... | @@ -1683,7 +1683,7 @@ pub fn sub(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme | ... | @@ -1683,7 +1683,7 @@ pub fn sub(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme |
| 1683 | /// 0 ≤ eval out1 < m | 1683 | /// 0 ≤ eval out1 < m |
| 1684 | /// | 1684 | /// |
| 1685 | pub fn opp(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement) void { | 1685 | pub fn opp(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement) void { |
| 1686 | @setRuntimeSafety(mode == .Debug); | 1686 | @setRuntimeSafety(mode == .debug); |
| 1687 | 1687 | ||
| 1688 | var x1: u64 = undefined; | 1688 | var x1: u64 = undefined; |
| 1689 | var x2: u1 = undefined; | 1689 | var x2: u1 = undefined; |
| ... | @@ -1740,7 +1740,7 @@ pub fn opp(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme | ... | @@ -1740,7 +1740,7 @@ pub fn opp(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme |
| 1740 | /// 0 ≤ eval out1 < m | 1740 | /// 0 ≤ eval out1 < m |
| 1741 | /// | 1741 | /// |
| 1742 | pub fn fromMontgomery(out1: *NonMontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement) void { | 1742 | pub fn fromMontgomery(out1: *NonMontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement) void { |
| 1743 | @setRuntimeSafety(mode == .Debug); | 1743 | @setRuntimeSafety(mode == .debug); |
| 1744 | 1744 | ||
| 1745 | const x1 = (arg1[0]); | 1745 | const x1 = (arg1[0]); |
| 1746 | var x2: u64 = undefined; | 1746 | var x2: u64 = undefined; |
| ... | @@ -2225,7 +2225,7 @@ pub fn fromMontgomery(out1: *NonMontgomeryDomainFieldElement, arg1: MontgomeryDo | ... | @@ -2225,7 +2225,7 @@ pub fn fromMontgomery(out1: *NonMontgomeryDomainFieldElement, arg1: MontgomeryDo |
| 2225 | /// 0 ≤ eval out1 < m | 2225 | /// 0 ≤ eval out1 < m |
| 2226 | /// | 2226 | /// |
| 2227 | pub fn toMontgomery(out1: *MontgomeryDomainFieldElement, arg1: NonMontgomeryDomainFieldElement) void { | 2227 | pub fn toMontgomery(out1: *MontgomeryDomainFieldElement, arg1: NonMontgomeryDomainFieldElement) void { |
| 2228 | @setRuntimeSafety(mode == .Debug); | 2228 | @setRuntimeSafety(mode == .debug); |
| 2229 | 2229 | ||
| 2230 | const x1 = (arg1[1]); | 2230 | const x1 = (arg1[1]); |
| 2231 | const x2 = (arg1[2]); | 2231 | const x2 = (arg1[2]); |
| ... | @@ -2862,7 +2862,7 @@ pub fn toMontgomery(out1: *MontgomeryDomainFieldElement, arg1: NonMontgomeryDoma | ... | @@ -2862,7 +2862,7 @@ pub fn toMontgomery(out1: *MontgomeryDomainFieldElement, arg1: NonMontgomeryDoma |
| 2862 | /// Output Bounds: | 2862 | /// Output Bounds: |
| 2863 | /// out1: [0x0 ~> 0xffffffffffffffff] | 2863 | /// out1: [0x0 ~> 0xffffffffffffffff] |
| 2864 | pub fn nonzero(out1: *u64, arg1: [6]u64) void { | 2864 | pub fn nonzero(out1: *u64, arg1: [6]u64) void { |
| 2865 | @setRuntimeSafety(mode == .Debug); | 2865 | @setRuntimeSafety(mode == .debug); |
| 2866 | 2866 | ||
| 2867 | const x1 = ((arg1[0]) | ((arg1[1]) | ((arg1[2]) | ((arg1[3]) | ((arg1[4]) | (arg1[5])))))); | 2867 | const x1 = ((arg1[0]) | ((arg1[1]) | ((arg1[2]) | ((arg1[3]) | ((arg1[4]) | (arg1[5])))))); |
| 2868 | out1.* = x1; | 2868 | out1.* = x1; |
| ... | @@ -2880,7 +2880,7 @@ pub fn nonzero(out1: *u64, arg1: [6]u64) void { | ... | @@ -2880,7 +2880,7 @@ pub fn nonzero(out1: *u64, arg1: [6]u64) void { |
| 2880 | /// Output Bounds: | 2880 | /// Output Bounds: |
| 2881 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] | 2881 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] |
| 2882 | pub fn selectznz(out1: *[6]u64, arg1: u1, arg2: [6]u64, arg3: [6]u64) void { | 2882 | pub fn selectznz(out1: *[6]u64, arg1: u1, arg2: [6]u64, arg3: [6]u64) void { |
| 2883 | @setRuntimeSafety(mode == .Debug); | 2883 | @setRuntimeSafety(mode == .debug); |
| 2884 | 2884 | ||
| 2885 | var x1: u64 = undefined; | 2885 | var x1: u64 = undefined; |
| 2886 | cmovznzU64(&x1, arg1, (arg2[0]), (arg3[0])); | 2886 | cmovznzU64(&x1, arg1, (arg2[0]), (arg3[0])); |
| ... | @@ -2914,7 +2914,7 @@ pub fn selectznz(out1: *[6]u64, arg1: u1, arg2: [6]u64, arg3: [6]u64) void { | ... | @@ -2914,7 +2914,7 @@ pub fn selectznz(out1: *[6]u64, arg1: u1, arg2: [6]u64, arg3: [6]u64) void { |
| 2914 | /// Output Bounds: | 2914 | /// Output Bounds: |
| 2915 | /// out1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff]] | 2915 | /// out1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff]] |
| 2916 | pub fn toBytes(out1: *[48]u8, arg1: [6]u64) void { | 2916 | pub fn toBytes(out1: *[48]u8, arg1: [6]u64) void { |
| 2917 | @setRuntimeSafety(mode == .Debug); | 2917 | @setRuntimeSafety(mode == .debug); |
| 2918 | 2918 | ||
| 2919 | const x1 = (arg1[5]); | 2919 | const x1 = (arg1[5]); |
| 2920 | const x2 = (arg1[4]); | 2920 | const x2 = (arg1[4]); |
| ... | @@ -3069,7 +3069,7 @@ pub fn toBytes(out1: *[48]u8, arg1: [6]u64) void { | ... | @@ -3069,7 +3069,7 @@ pub fn toBytes(out1: *[48]u8, arg1: [6]u64) void { |
| 3069 | /// Output Bounds: | 3069 | /// Output Bounds: |
| 3070 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] | 3070 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] |
| 3071 | pub fn fromBytes(out1: *[6]u64, arg1: [48]u8) void { | 3071 | pub fn fromBytes(out1: *[6]u64, arg1: [48]u8) void { |
| 3072 | @setRuntimeSafety(mode == .Debug); | 3072 | @setRuntimeSafety(mode == .debug); |
| 3073 | 3073 | ||
| 3074 | const x1 = (@as(u64, (arg1[47])) << 56); | 3074 | const x1 = (@as(u64, (arg1[47])) << 56); |
| 3075 | const x2 = (@as(u64, (arg1[46])) << 48); | 3075 | const x2 = (@as(u64, (arg1[46])) << 48); |
| ... | @@ -3176,7 +3176,7 @@ pub fn fromBytes(out1: *[6]u64, arg1: [48]u8) void { | ... | @@ -3176,7 +3176,7 @@ pub fn fromBytes(out1: *[6]u64, arg1: [48]u8) void { |
| 3176 | /// 0 ≤ eval out1 < m | 3176 | /// 0 ≤ eval out1 < m |
| 3177 | /// | 3177 | /// |
| 3178 | pub fn setOne(out1: *MontgomeryDomainFieldElement) void { | 3178 | pub fn setOne(out1: *MontgomeryDomainFieldElement) void { |
| 3179 | @setRuntimeSafety(mode == .Debug); | 3179 | @setRuntimeSafety(mode == .debug); |
| 3180 | 3180 | ||
| 3181 | out1[0] = 0xffffffff00000001; | 3181 | out1[0] = 0xffffffff00000001; |
| 3182 | out1[1] = 0xffffffff; | 3182 | out1[1] = 0xffffffff; |
| ... | @@ -3195,7 +3195,7 @@ pub fn setOne(out1: *MontgomeryDomainFieldElement) void { | ... | @@ -3195,7 +3195,7 @@ pub fn setOne(out1: *MontgomeryDomainFieldElement) void { |
| 3195 | /// Output Bounds: | 3195 | /// Output Bounds: |
| 3196 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] | 3196 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] |
| 3197 | pub fn msat(out1: *[7]u64) void { | 3197 | pub fn msat(out1: *[7]u64) void { |
| 3198 | @setRuntimeSafety(mode == .Debug); | 3198 | @setRuntimeSafety(mode == .debug); |
| 3199 | 3199 | ||
| 3200 | out1[0] = 0xffffffff; | 3200 | out1[0] = 0xffffffff; |
| 3201 | out1[1] = 0xffffffff00000000; | 3201 | out1[1] = 0xffffffff00000000; |
| ... | @@ -3235,7 +3235,7 @@ pub fn msat(out1: *[7]u64) void { | ... | @@ -3235,7 +3235,7 @@ pub fn msat(out1: *[7]u64) void { |
| 3235 | /// out4: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] | 3235 | /// out4: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] |
| 3236 | /// out5: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] | 3236 | /// out5: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] |
| 3237 | pub fn divstep(out1: *u64, out2: *[7]u64, out3: *[7]u64, out4: *[6]u64, out5: *[6]u64, arg1: u64, arg2: [7]u64, arg3: [7]u64, arg4: [6]u64, arg5: [6]u64) void { | 3237 | pub fn divstep(out1: *u64, out2: *[7]u64, out3: *[7]u64, out4: *[6]u64, out5: *[6]u64, arg1: u64, arg2: [7]u64, arg3: [7]u64, arg4: [6]u64, arg5: [6]u64) void { |
| 3238 | @setRuntimeSafety(mode == .Debug); | 3238 | @setRuntimeSafety(mode == .debug); |
| 3239 | 3239 | ||
| 3240 | var x1: u64 = undefined; | 3240 | var x1: u64 = undefined; |
| 3241 | var x2: u1 = undefined; | 3241 | var x2: u1 = undefined; |
| ... | @@ -3561,7 +3561,7 @@ pub fn divstep(out1: *u64, out2: *[7]u64, out3: *[7]u64, out4: *[6]u64, out5: *[ | ... | @@ -3561,7 +3561,7 @@ pub fn divstep(out1: *u64, out2: *[7]u64, out3: *[7]u64, out4: *[6]u64, out5: *[ |
| 3561 | /// Output Bounds: | 3561 | /// Output Bounds: |
| 3562 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] | 3562 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] |
| 3563 | pub fn divstepPrecomp(out1: *[6]u64) void { | 3563 | pub fn divstepPrecomp(out1: *[6]u64) void { |
| 3564 | @setRuntimeSafety(mode == .Debug); | 3564 | @setRuntimeSafety(mode == .debug); |
| 3565 | 3565 | ||
| 3566 | out1[0] = 0xfff69400fff18fff; | 3566 | out1[0] = 0xfff69400fff18fff; |
| 3567 | out1[1] = 0x2b7feffffd3ff; | 3567 | out1[1] = 0x2b7feffffd3ff; |
lib/std/crypto/pcurves/p384/p384_scalar_64.zig+17-17| ... | @@ -79,7 +79,7 @@ fn subborrowxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) void { | ... | @@ -79,7 +79,7 @@ fn subborrowxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) void { |
| 79 | /// out1: [0x0 ~> 0xffffffffffffffff] | 79 | /// out1: [0x0 ~> 0xffffffffffffffff] |
| 80 | /// out2: [0x0 ~> 0xffffffffffffffff] | 80 | /// out2: [0x0 ~> 0xffffffffffffffff] |
| 81 | fn mulxU64(out1: *u64, out2: *u64, arg1: u64, arg2: u64) void { | 81 | fn mulxU64(out1: *u64, out2: *u64, arg1: u64, arg2: u64) void { |
| 82 | @setRuntimeSafety(mode == .Debug); | 82 | @setRuntimeSafety(mode == .debug); |
| 83 | 83 | ||
| 84 | const x = @as(u128, arg1) * @as(u128, arg2); | 84 | const x = @as(u128, arg1) * @as(u128, arg2); |
| 85 | out1.* = @as(u64, @truncate(x)); | 85 | out1.* = @as(u64, @truncate(x)); |
| ... | @@ -98,7 +98,7 @@ fn mulxU64(out1: *u64, out2: *u64, arg1: u64, arg2: u64) void { | ... | @@ -98,7 +98,7 @@ fn mulxU64(out1: *u64, out2: *u64, arg1: u64, arg2: u64) void { |
| 98 | /// Output Bounds: | 98 | /// Output Bounds: |
| 99 | /// out1: [0x0 ~> 0xffffffffffffffff] | 99 | /// out1: [0x0 ~> 0xffffffffffffffff] |
| 100 | fn cmovznzU64(out1: *u64, arg1: u1, arg2: u64, arg3: u64) void { | 100 | fn cmovznzU64(out1: *u64, arg1: u1, arg2: u64, arg3: u64) void { |
| 101 | @setRuntimeSafety(mode == .Debug); | 101 | @setRuntimeSafety(mode == .debug); |
| 102 | 102 | ||
| 103 | const mask = 0 -% @as(u64, arg1); | 103 | const mask = 0 -% @as(u64, arg1); |
| 104 | out1.* = (mask & arg3) | ((~mask) & arg2); | 104 | out1.* = (mask & arg3) | ((~mask) & arg2); |
| ... | @@ -114,7 +114,7 @@ fn cmovznzU64(out1: *u64, arg1: u1, arg2: u64, arg3: u64) void { | ... | @@ -114,7 +114,7 @@ fn cmovznzU64(out1: *u64, arg1: u1, arg2: u64, arg3: u64) void { |
| 114 | /// 0 ≤ eval out1 < m | 114 | /// 0 ≤ eval out1 < m |
| 115 | /// | 115 | /// |
| 116 | pub fn mul(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement, arg2: MontgomeryDomainFieldElement) void { | 116 | pub fn mul(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement, arg2: MontgomeryDomainFieldElement) void { |
| 117 | @setRuntimeSafety(mode == .Debug); | 117 | @setRuntimeSafety(mode == .debug); |
| 118 | 118 | ||
| 119 | const x1 = (arg1[1]); | 119 | const x1 = (arg1[1]); |
| 120 | const x2 = (arg1[2]); | 120 | const x2 = (arg1[2]); |
| ... | @@ -834,7 +834,7 @@ pub fn mul(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme | ... | @@ -834,7 +834,7 @@ pub fn mul(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme |
| 834 | /// 0 ≤ eval out1 < m | 834 | /// 0 ≤ eval out1 < m |
| 835 | /// | 835 | /// |
| 836 | pub fn square(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement) void { | 836 | pub fn square(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement) void { |
| 837 | @setRuntimeSafety(mode == .Debug); | 837 | @setRuntimeSafety(mode == .debug); |
| 838 | 838 | ||
| 839 | const x1 = (arg1[1]); | 839 | const x1 = (arg1[1]); |
| 840 | const x2 = (arg1[2]); | 840 | const x2 = (arg1[2]); |
| ... | @@ -1555,7 +1555,7 @@ pub fn square(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEl | ... | @@ -1555,7 +1555,7 @@ pub fn square(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEl |
| 1555 | /// 0 ≤ eval out1 < m | 1555 | /// 0 ≤ eval out1 < m |
| 1556 | /// | 1556 | /// |
| 1557 | pub fn add(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement, arg2: MontgomeryDomainFieldElement) void { | 1557 | pub fn add(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement, arg2: MontgomeryDomainFieldElement) void { |
| 1558 | @setRuntimeSafety(mode == .Debug); | 1558 | @setRuntimeSafety(mode == .debug); |
| 1559 | 1559 | ||
| 1560 | var x1: u64 = undefined; | 1560 | var x1: u64 = undefined; |
| 1561 | var x2: u1 = undefined; | 1561 | var x2: u1 = undefined; |
| ... | @@ -1626,7 +1626,7 @@ pub fn add(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme | ... | @@ -1626,7 +1626,7 @@ pub fn add(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme |
| 1626 | /// 0 ≤ eval out1 < m | 1626 | /// 0 ≤ eval out1 < m |
| 1627 | /// | 1627 | /// |
| 1628 | pub fn sub(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement, arg2: MontgomeryDomainFieldElement) void { | 1628 | pub fn sub(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement, arg2: MontgomeryDomainFieldElement) void { |
| 1629 | @setRuntimeSafety(mode == .Debug); | 1629 | @setRuntimeSafety(mode == .debug); |
| 1630 | 1630 | ||
| 1631 | var x1: u64 = undefined; | 1631 | var x1: u64 = undefined; |
| 1632 | var x2: u1 = undefined; | 1632 | var x2: u1 = undefined; |
| ... | @@ -1683,7 +1683,7 @@ pub fn sub(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme | ... | @@ -1683,7 +1683,7 @@ pub fn sub(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme |
| 1683 | /// 0 ≤ eval out1 < m | 1683 | /// 0 ≤ eval out1 < m |
| 1684 | /// | 1684 | /// |
| 1685 | pub fn opp(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement) void { | 1685 | pub fn opp(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement) void { |
| 1686 | @setRuntimeSafety(mode == .Debug); | 1686 | @setRuntimeSafety(mode == .debug); |
| 1687 | 1687 | ||
| 1688 | var x1: u64 = undefined; | 1688 | var x1: u64 = undefined; |
| 1689 | var x2: u1 = undefined; | 1689 | var x2: u1 = undefined; |
| ... | @@ -1740,7 +1740,7 @@ pub fn opp(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme | ... | @@ -1740,7 +1740,7 @@ pub fn opp(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme |
| 1740 | /// 0 ≤ eval out1 < m | 1740 | /// 0 ≤ eval out1 < m |
| 1741 | /// | 1741 | /// |
| 1742 | pub fn fromMontgomery(out1: *NonMontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement) void { | 1742 | pub fn fromMontgomery(out1: *NonMontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement) void { |
| 1743 | @setRuntimeSafety(mode == .Debug); | 1743 | @setRuntimeSafety(mode == .debug); |
| 1744 | 1744 | ||
| 1745 | const x1 = (arg1[0]); | 1745 | const x1 = (arg1[0]); |
| 1746 | var x2: u64 = undefined; | 1746 | var x2: u64 = undefined; |
| ... | @@ -2225,7 +2225,7 @@ pub fn fromMontgomery(out1: *NonMontgomeryDomainFieldElement, arg1: MontgomeryDo | ... | @@ -2225,7 +2225,7 @@ pub fn fromMontgomery(out1: *NonMontgomeryDomainFieldElement, arg1: MontgomeryDo |
| 2225 | /// 0 ≤ eval out1 < m | 2225 | /// 0 ≤ eval out1 < m |
| 2226 | /// | 2226 | /// |
| 2227 | pub fn toMontgomery(out1: *MontgomeryDomainFieldElement, arg1: NonMontgomeryDomainFieldElement) void { | 2227 | pub fn toMontgomery(out1: *MontgomeryDomainFieldElement, arg1: NonMontgomeryDomainFieldElement) void { |
| 2228 | @setRuntimeSafety(mode == .Debug); | 2228 | @setRuntimeSafety(mode == .debug); |
| 2229 | 2229 | ||
| 2230 | const x1 = (arg1[1]); | 2230 | const x1 = (arg1[1]); |
| 2231 | const x2 = (arg1[2]); | 2231 | const x2 = (arg1[2]); |
| ... | @@ -2916,7 +2916,7 @@ pub fn toMontgomery(out1: *MontgomeryDomainFieldElement, arg1: NonMontgomeryDoma | ... | @@ -2916,7 +2916,7 @@ pub fn toMontgomery(out1: *MontgomeryDomainFieldElement, arg1: NonMontgomeryDoma |
| 2916 | /// Output Bounds: | 2916 | /// Output Bounds: |
| 2917 | /// out1: [0x0 ~> 0xffffffffffffffff] | 2917 | /// out1: [0x0 ~> 0xffffffffffffffff] |
| 2918 | pub fn nonzero(out1: *u64, arg1: [6]u64) void { | 2918 | pub fn nonzero(out1: *u64, arg1: [6]u64) void { |
| 2919 | @setRuntimeSafety(mode == .Debug); | 2919 | @setRuntimeSafety(mode == .debug); |
| 2920 | 2920 | ||
| 2921 | const x1 = ((arg1[0]) | ((arg1[1]) | ((arg1[2]) | ((arg1[3]) | ((arg1[4]) | (arg1[5])))))); | 2921 | const x1 = ((arg1[0]) | ((arg1[1]) | ((arg1[2]) | ((arg1[3]) | ((arg1[4]) | (arg1[5])))))); |
| 2922 | out1.* = x1; | 2922 | out1.* = x1; |
| ... | @@ -2934,7 +2934,7 @@ pub fn nonzero(out1: *u64, arg1: [6]u64) void { | ... | @@ -2934,7 +2934,7 @@ pub fn nonzero(out1: *u64, arg1: [6]u64) void { |
| 2934 | /// Output Bounds: | 2934 | /// Output Bounds: |
| 2935 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] | 2935 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] |
| 2936 | pub fn selectznz(out1: *[6]u64, arg1: u1, arg2: [6]u64, arg3: [6]u64) void { | 2936 | pub fn selectznz(out1: *[6]u64, arg1: u1, arg2: [6]u64, arg3: [6]u64) void { |
| 2937 | @setRuntimeSafety(mode == .Debug); | 2937 | @setRuntimeSafety(mode == .debug); |
| 2938 | 2938 | ||
| 2939 | var x1: u64 = undefined; | 2939 | var x1: u64 = undefined; |
| 2940 | cmovznzU64(&x1, arg1, (arg2[0]), (arg3[0])); | 2940 | cmovznzU64(&x1, arg1, (arg2[0]), (arg3[0])); |
| ... | @@ -2968,7 +2968,7 @@ pub fn selectznz(out1: *[6]u64, arg1: u1, arg2: [6]u64, arg3: [6]u64) void { | ... | @@ -2968,7 +2968,7 @@ pub fn selectznz(out1: *[6]u64, arg1: u1, arg2: [6]u64, arg3: [6]u64) void { |
| 2968 | /// Output Bounds: | 2968 | /// Output Bounds: |
| 2969 | /// out1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff]] | 2969 | /// out1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff]] |
| 2970 | pub fn toBytes(out1: *[48]u8, arg1: [6]u64) void { | 2970 | pub fn toBytes(out1: *[48]u8, arg1: [6]u64) void { |
| 2971 | @setRuntimeSafety(mode == .Debug); | 2971 | @setRuntimeSafety(mode == .debug); |
| 2972 | 2972 | ||
| 2973 | const x1 = (arg1[5]); | 2973 | const x1 = (arg1[5]); |
| 2974 | const x2 = (arg1[4]); | 2974 | const x2 = (arg1[4]); |
| ... | @@ -3123,7 +3123,7 @@ pub fn toBytes(out1: *[48]u8, arg1: [6]u64) void { | ... | @@ -3123,7 +3123,7 @@ pub fn toBytes(out1: *[48]u8, arg1: [6]u64) void { |
| 3123 | /// Output Bounds: | 3123 | /// Output Bounds: |
| 3124 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] | 3124 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] |
| 3125 | pub fn fromBytes(out1: *[6]u64, arg1: [48]u8) void { | 3125 | pub fn fromBytes(out1: *[6]u64, arg1: [48]u8) void { |
| 3126 | @setRuntimeSafety(mode == .Debug); | 3126 | @setRuntimeSafety(mode == .debug); |
| 3127 | 3127 | ||
| 3128 | const x1 = (@as(u64, (arg1[47])) << 56); | 3128 | const x1 = (@as(u64, (arg1[47])) << 56); |
| 3129 | const x2 = (@as(u64, (arg1[46])) << 48); | 3129 | const x2 = (@as(u64, (arg1[46])) << 48); |
| ... | @@ -3230,7 +3230,7 @@ pub fn fromBytes(out1: *[6]u64, arg1: [48]u8) void { | ... | @@ -3230,7 +3230,7 @@ pub fn fromBytes(out1: *[6]u64, arg1: [48]u8) void { |
| 3230 | /// 0 ≤ eval out1 < m | 3230 | /// 0 ≤ eval out1 < m |
| 3231 | /// | 3231 | /// |
| 3232 | pub fn setOne(out1: *MontgomeryDomainFieldElement) void { | 3232 | pub fn setOne(out1: *MontgomeryDomainFieldElement) void { |
| 3233 | @setRuntimeSafety(mode == .Debug); | 3233 | @setRuntimeSafety(mode == .debug); |
| 3234 | 3234 | ||
| 3235 | out1[0] = 0x1313e695333ad68d; | 3235 | out1[0] = 0x1313e695333ad68d; |
| 3236 | out1[1] = 0xa7e5f24db74f5885; | 3236 | out1[1] = 0xa7e5f24db74f5885; |
| ... | @@ -3249,7 +3249,7 @@ pub fn setOne(out1: *MontgomeryDomainFieldElement) void { | ... | @@ -3249,7 +3249,7 @@ pub fn setOne(out1: *MontgomeryDomainFieldElement) void { |
| 3249 | /// Output Bounds: | 3249 | /// Output Bounds: |
| 3250 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] | 3250 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] |
| 3251 | pub fn msat(out1: *[7]u64) void { | 3251 | pub fn msat(out1: *[7]u64) void { |
| 3252 | @setRuntimeSafety(mode == .Debug); | 3252 | @setRuntimeSafety(mode == .debug); |
| 3253 | 3253 | ||
| 3254 | out1[0] = 0xecec196accc52973; | 3254 | out1[0] = 0xecec196accc52973; |
| 3255 | out1[1] = 0x581a0db248b0a77a; | 3255 | out1[1] = 0x581a0db248b0a77a; |
| ... | @@ -3289,7 +3289,7 @@ pub fn msat(out1: *[7]u64) void { | ... | @@ -3289,7 +3289,7 @@ pub fn msat(out1: *[7]u64) void { |
| 3289 | /// out4: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] | 3289 | /// out4: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] |
| 3290 | /// out5: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] | 3290 | /// out5: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] |
| 3291 | pub fn divstep(out1: *u64, out2: *[7]u64, out3: *[7]u64, out4: *[6]u64, out5: *[6]u64, arg1: u64, arg2: [7]u64, arg3: [7]u64, arg4: [6]u64, arg5: [6]u64) void { | 3291 | pub fn divstep(out1: *u64, out2: *[7]u64, out3: *[7]u64, out4: *[6]u64, out5: *[6]u64, arg1: u64, arg2: [7]u64, arg3: [7]u64, arg4: [6]u64, arg5: [6]u64) void { |
| 3292 | @setRuntimeSafety(mode == .Debug); | 3292 | @setRuntimeSafety(mode == .debug); |
| 3293 | 3293 | ||
| 3294 | var x1: u64 = undefined; | 3294 | var x1: u64 = undefined; |
| 3295 | var x2: u1 = undefined; | 3295 | var x2: u1 = undefined; |
| ... | @@ -3615,7 +3615,7 @@ pub fn divstep(out1: *u64, out2: *[7]u64, out3: *[7]u64, out4: *[6]u64, out5: *[ | ... | @@ -3615,7 +3615,7 @@ pub fn divstep(out1: *u64, out2: *[7]u64, out3: *[7]u64, out4: *[6]u64, out5: *[ |
| 3615 | /// Output Bounds: | 3615 | /// Output Bounds: |
| 3616 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] | 3616 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] |
| 3617 | pub fn divstepPrecomp(out1: *[6]u64) void { | 3617 | pub fn divstepPrecomp(out1: *[6]u64) void { |
| 3618 | @setRuntimeSafety(mode == .Debug); | 3618 | @setRuntimeSafety(mode == .debug); |
| 3619 | 3619 | ||
| 3620 | out1[0] = 0x49589ae0e6045b6a; | 3620 | out1[0] = 0x49589ae0e6045b6a; |
| 3621 | out1[1] = 0x3c9a5352870040ed; | 3621 | out1[1] = 0x3c9a5352870040ed; |
lib/std/crypto/pcurves/secp256k1.zig+5-7| ... | @@ -51,7 +51,7 @@ pub const Secp256k1 = struct { | ... | @@ -51,7 +51,7 @@ pub const Secp256k1 = struct { |
| 51 | }; | 51 | }; |
| 52 | 52 | ||
| 53 | /// Compute r1 and r2 so that k = r1 + r2*lambda (mod L). | 53 | /// Compute r1 and r2 so that k = r1 + r2*lambda (mod L). |
| 54 | pub fn splitScalar(s: [32]u8, endian: std.builtin.Endian) NonCanonicalError!SplitScalar { | 54 | pub fn splitScalar(s: [32]u8, endian: std.lang.Endian) NonCanonicalError!SplitScalar { |
| 55 | const b1_neg_s = comptime s: { | 55 | const b1_neg_s = comptime s: { |
| 56 | var buf: [32]u8 = undefined; | 56 | var buf: [32]u8 = undefined; |
| 57 | mem.writeInt(u256, &buf, 303414439467246543595250775667605759171, .little); | 57 | mem.writeInt(u256, &buf, 303414439467246543595250775667605759171, .little); |
| ... | @@ -109,7 +109,7 @@ pub const Secp256k1 = struct { | ... | @@ -109,7 +109,7 @@ pub const Secp256k1 = struct { |
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | /// Create a point from serialized affine coordinates. | 111 | /// Create a point from serialized affine coordinates. |
| 112 | pub fn fromSerializedAffineCoordinates(xs: [32]u8, ys: [32]u8, endian: std.builtin.Endian) (NonCanonicalError || EncodingError)!Secp256k1 { | 112 | pub fn fromSerializedAffineCoordinates(xs: [32]u8, ys: [32]u8, endian: std.lang.Endian) (NonCanonicalError || EncodingError)!Secp256k1 { |
| 113 | const x = try Fe.fromBytes(xs, endian); | 113 | const x = try Fe.fromBytes(xs, endian); |
| 114 | const y = try Fe.fromBytes(ys, endian); | 114 | const y = try Fe.fromBytes(ys, endian); |
| 115 | return fromAffineCoordinates(.{ .x = x, .y = y }); | 115 | return fromAffineCoordinates(.{ .x = x, .y = y }); |
| ... | @@ -423,7 +423,7 @@ pub const Secp256k1 = struct { | ... | @@ -423,7 +423,7 @@ pub const Secp256k1 = struct { |
| 423 | 423 | ||
| 424 | /// Multiply an elliptic curve point by a scalar. | 424 | /// Multiply an elliptic curve point by a scalar. |
| 425 | /// Return error.IdentityElement if the result is the identity element. | 425 | /// Return error.IdentityElement if the result is the identity element. |
| 426 | pub fn mul(p: Secp256k1, s_: [32]u8, endian: std.builtin.Endian) IdentityElementError!Secp256k1 { | 426 | pub fn mul(p: Secp256k1, s_: [32]u8, endian: std.lang.Endian) IdentityElementError!Secp256k1 { |
| 427 | const s = if (endian == .little) s_ else Fe.orderSwap(s_); | 427 | const s = if (endian == .little) s_ else Fe.orderSwap(s_); |
| 428 | if (p.is_base) { | 428 | if (p.is_base) { |
| 429 | return pcMul16(&basePointPc, s, false); | 429 | return pcMul16(&basePointPc, s, false); |
| ... | @@ -435,7 +435,7 @@ pub const Secp256k1 = struct { | ... | @@ -435,7 +435,7 @@ pub const Secp256k1 = struct { |
| 435 | 435 | ||
| 436 | /// Multiply an elliptic curve point by a *PUBLIC* scalar *IN VARIABLE TIME* | 436 | /// Multiply an elliptic curve point by a *PUBLIC* scalar *IN VARIABLE TIME* |
| 437 | /// This can be used for signature verification. | 437 | /// This can be used for signature verification. |
| 438 | pub fn mulPublic(p: Secp256k1, s_: [32]u8, endian: std.builtin.Endian) (IdentityElementError || NonCanonicalError)!Secp256k1 { | 438 | pub fn mulPublic(p: Secp256k1, s_: [32]u8, endian: std.lang.Endian) (IdentityElementError || NonCanonicalError)!Secp256k1 { |
| 439 | const s = if (endian == .little) s_ else Fe.orderSwap(s_); | 439 | const s = if (endian == .little) s_ else Fe.orderSwap(s_); |
| 440 | const zero = comptime scalar.Scalar.zero.toBytes(.little); | 440 | const zero = comptime scalar.Scalar.zero.toBytes(.little); |
| 441 | if (mem.eql(u8, &zero, &s)) { | 441 | if (mem.eql(u8, &zero, &s)) { |
| ... | @@ -497,7 +497,7 @@ pub const Secp256k1 = struct { | ... | @@ -497,7 +497,7 @@ pub const Secp256k1 = struct { |
| 497 | 497 | ||
| 498 | /// Double-base multiplication of public parameters - Compute (p1*s1)+(p2*s2) *IN VARIABLE TIME* | 498 | /// Double-base multiplication of public parameters - Compute (p1*s1)+(p2*s2) *IN VARIABLE TIME* |
| 499 | /// This can be used for signature verification. | 499 | /// This can be used for signature verification. |
| 500 | pub fn mulDoubleBasePublic(p1: Secp256k1, s1_: [32]u8, p2: Secp256k1, s2_: [32]u8, endian: std.builtin.Endian) IdentityElementError!Secp256k1 { | 500 | pub fn mulDoubleBasePublic(p1: Secp256k1, s1_: [32]u8, p2: Secp256k1, s2_: [32]u8, endian: std.lang.Endian) IdentityElementError!Secp256k1 { |
| 501 | const s1 = if (endian == .little) s1_ else Fe.orderSwap(s1_); | 501 | const s1 = if (endian == .little) s1_ else Fe.orderSwap(s1_); |
| 502 | const s2 = if (endian == .little) s2_ else Fe.orderSwap(s2_); | 502 | const s2 = if (endian == .little) s2_ else Fe.orderSwap(s2_); |
| 503 | try p1.rejectIdentity(); | 503 | try p1.rejectIdentity(); |
| ... | @@ -556,7 +556,5 @@ pub const AffineCoordinates = struct { | ... | @@ -556,7 +556,5 @@ pub const AffineCoordinates = struct { |
| 556 | }; | 556 | }; |
| 557 | 557 | ||
| 558 | test { | 558 | test { |
| 559 | if (@import("builtin").zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 560 | |||
| 561 | _ = @import("tests/secp256k1.zig"); | 559 | _ = @import("tests/secp256k1.zig"); |
| 562 | } | 560 | } |
lib/std/crypto/pcurves/secp256k1/secp256k1_64.zig+17-17| ... | @@ -79,7 +79,7 @@ fn subborrowxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) void { | ... | @@ -79,7 +79,7 @@ fn subborrowxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) void { |
| 79 | /// out1: [0x0 ~> 0xffffffffffffffff] | 79 | /// out1: [0x0 ~> 0xffffffffffffffff] |
| 80 | /// out2: [0x0 ~> 0xffffffffffffffff] | 80 | /// out2: [0x0 ~> 0xffffffffffffffff] |
| 81 | fn mulxU64(out1: *u64, out2: *u64, arg1: u64, arg2: u64) void { | 81 | fn mulxU64(out1: *u64, out2: *u64, arg1: u64, arg2: u64) void { |
| 82 | @setRuntimeSafety(mode == .Debug); | 82 | @setRuntimeSafety(mode == .debug); |
| 83 | 83 | ||
| 84 | const x = @as(u128, arg1) * @as(u128, arg2); | 84 | const x = @as(u128, arg1) * @as(u128, arg2); |
| 85 | out1.* = @as(u64, @truncate(x)); | 85 | out1.* = @as(u64, @truncate(x)); |
| ... | @@ -98,7 +98,7 @@ fn mulxU64(out1: *u64, out2: *u64, arg1: u64, arg2: u64) void { | ... | @@ -98,7 +98,7 @@ fn mulxU64(out1: *u64, out2: *u64, arg1: u64, arg2: u64) void { |
| 98 | /// Output Bounds: | 98 | /// Output Bounds: |
| 99 | /// out1: [0x0 ~> 0xffffffffffffffff] | 99 | /// out1: [0x0 ~> 0xffffffffffffffff] |
| 100 | fn cmovznzU64(out1: *u64, arg1: u1, arg2: u64, arg3: u64) void { | 100 | fn cmovznzU64(out1: *u64, arg1: u1, arg2: u64, arg3: u64) void { |
| 101 | @setRuntimeSafety(mode == .Debug); | 101 | @setRuntimeSafety(mode == .debug); |
| 102 | 102 | ||
| 103 | const mask = 0 -% @as(u64, arg1); | 103 | const mask = 0 -% @as(u64, arg1); |
| 104 | out1.* = (mask & arg3) | ((~mask) & arg2); | 104 | out1.* = (mask & arg3) | ((~mask) & arg2); |
| ... | @@ -114,7 +114,7 @@ fn cmovznzU64(out1: *u64, arg1: u1, arg2: u64, arg3: u64) void { | ... | @@ -114,7 +114,7 @@ fn cmovznzU64(out1: *u64, arg1: u1, arg2: u64, arg3: u64) void { |
| 114 | /// 0 ≤ eval out1 < m | 114 | /// 0 ≤ eval out1 < m |
| 115 | /// | 115 | /// |
| 116 | pub fn mul(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement, arg2: MontgomeryDomainFieldElement) void { | 116 | pub fn mul(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement, arg2: MontgomeryDomainFieldElement) void { |
| 117 | @setRuntimeSafety(mode == .Debug); | 117 | @setRuntimeSafety(mode == .debug); |
| 118 | 118 | ||
| 119 | const x1 = (arg1[1]); | 119 | const x1 = (arg1[1]); |
| 120 | const x2 = (arg1[2]); | 120 | const x2 = (arg1[2]); |
| ... | @@ -454,7 +454,7 @@ pub fn mul(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme | ... | @@ -454,7 +454,7 @@ pub fn mul(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme |
| 454 | /// 0 ≤ eval out1 < m | 454 | /// 0 ≤ eval out1 < m |
| 455 | /// | 455 | /// |
| 456 | pub fn square(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement) void { | 456 | pub fn square(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement) void { |
| 457 | @setRuntimeSafety(mode == .Debug); | 457 | @setRuntimeSafety(mode == .debug); |
| 458 | 458 | ||
| 459 | const x1 = (arg1[1]); | 459 | const x1 = (arg1[1]); |
| 460 | const x2 = (arg1[2]); | 460 | const x2 = (arg1[2]); |
| ... | @@ -795,7 +795,7 @@ pub fn square(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEl | ... | @@ -795,7 +795,7 @@ pub fn square(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEl |
| 795 | /// 0 ≤ eval out1 < m | 795 | /// 0 ≤ eval out1 < m |
| 796 | /// | 796 | /// |
| 797 | pub fn add(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement, arg2: MontgomeryDomainFieldElement) void { | 797 | pub fn add(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement, arg2: MontgomeryDomainFieldElement) void { |
| 798 | @setRuntimeSafety(mode == .Debug); | 798 | @setRuntimeSafety(mode == .debug); |
| 799 | 799 | ||
| 800 | var x1: u64 = undefined; | 800 | var x1: u64 = undefined; |
| 801 | var x2: u1 = undefined; | 801 | var x2: u1 = undefined; |
| ... | @@ -848,7 +848,7 @@ pub fn add(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme | ... | @@ -848,7 +848,7 @@ pub fn add(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme |
| 848 | /// 0 ≤ eval out1 < m | 848 | /// 0 ≤ eval out1 < m |
| 849 | /// | 849 | /// |
| 850 | pub fn sub(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement, arg2: MontgomeryDomainFieldElement) void { | 850 | pub fn sub(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement, arg2: MontgomeryDomainFieldElement) void { |
| 851 | @setRuntimeSafety(mode == .Debug); | 851 | @setRuntimeSafety(mode == .debug); |
| 852 | 852 | ||
| 853 | var x1: u64 = undefined; | 853 | var x1: u64 = undefined; |
| 854 | var x2: u1 = undefined; | 854 | var x2: u1 = undefined; |
| ... | @@ -891,7 +891,7 @@ pub fn sub(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme | ... | @@ -891,7 +891,7 @@ pub fn sub(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme |
| 891 | /// 0 ≤ eval out1 < m | 891 | /// 0 ≤ eval out1 < m |
| 892 | /// | 892 | /// |
| 893 | pub fn opp(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement) void { | 893 | pub fn opp(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement) void { |
| 894 | @setRuntimeSafety(mode == .Debug); | 894 | @setRuntimeSafety(mode == .debug); |
| 895 | 895 | ||
| 896 | var x1: u64 = undefined; | 896 | var x1: u64 = undefined; |
| 897 | var x2: u1 = undefined; | 897 | var x2: u1 = undefined; |
| ... | @@ -934,7 +934,7 @@ pub fn opp(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme | ... | @@ -934,7 +934,7 @@ pub fn opp(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme |
| 934 | /// 0 ≤ eval out1 < m | 934 | /// 0 ≤ eval out1 < m |
| 935 | /// | 935 | /// |
| 936 | pub fn fromMontgomery(out1: *NonMontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement) void { | 936 | pub fn fromMontgomery(out1: *NonMontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement) void { |
| 937 | @setRuntimeSafety(mode == .Debug); | 937 | @setRuntimeSafety(mode == .debug); |
| 938 | 938 | ||
| 939 | const x1 = (arg1[0]); | 939 | const x1 = (arg1[0]); |
| 940 | var x2: u64 = undefined; | 940 | var x2: u64 = undefined; |
| ... | @@ -1167,7 +1167,7 @@ pub fn fromMontgomery(out1: *NonMontgomeryDomainFieldElement, arg1: MontgomeryDo | ... | @@ -1167,7 +1167,7 @@ pub fn fromMontgomery(out1: *NonMontgomeryDomainFieldElement, arg1: MontgomeryDo |
| 1167 | /// 0 ≤ eval out1 < m | 1167 | /// 0 ≤ eval out1 < m |
| 1168 | /// | 1168 | /// |
| 1169 | pub fn toMontgomery(out1: *MontgomeryDomainFieldElement, arg1: NonMontgomeryDomainFieldElement) void { | 1169 | pub fn toMontgomery(out1: *MontgomeryDomainFieldElement, arg1: NonMontgomeryDomainFieldElement) void { |
| 1170 | @setRuntimeSafety(mode == .Debug); | 1170 | @setRuntimeSafety(mode == .debug); |
| 1171 | 1171 | ||
| 1172 | const x1 = (arg1[1]); | 1172 | const x1 = (arg1[1]); |
| 1173 | const x2 = (arg1[2]); | 1173 | const x2 = (arg1[2]); |
| ... | @@ -1430,7 +1430,7 @@ pub fn toMontgomery(out1: *MontgomeryDomainFieldElement, arg1: NonMontgomeryDoma | ... | @@ -1430,7 +1430,7 @@ pub fn toMontgomery(out1: *MontgomeryDomainFieldElement, arg1: NonMontgomeryDoma |
| 1430 | /// Output Bounds: | 1430 | /// Output Bounds: |
| 1431 | /// out1: [0x0 ~> 0xffffffffffffffff] | 1431 | /// out1: [0x0 ~> 0xffffffffffffffff] |
| 1432 | pub fn nonzero(out1: *u64, arg1: [4]u64) void { | 1432 | pub fn nonzero(out1: *u64, arg1: [4]u64) void { |
| 1433 | @setRuntimeSafety(mode == .Debug); | 1433 | @setRuntimeSafety(mode == .debug); |
| 1434 | 1434 | ||
| 1435 | const x1 = ((arg1[0]) | ((arg1[1]) | ((arg1[2]) | (arg1[3])))); | 1435 | const x1 = ((arg1[0]) | ((arg1[1]) | ((arg1[2]) | (arg1[3])))); |
| 1436 | out1.* = x1; | 1436 | out1.* = x1; |
| ... | @@ -1448,7 +1448,7 @@ pub fn nonzero(out1: *u64, arg1: [4]u64) void { | ... | @@ -1448,7 +1448,7 @@ pub fn nonzero(out1: *u64, arg1: [4]u64) void { |
| 1448 | /// Output Bounds: | 1448 | /// Output Bounds: |
| 1449 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] | 1449 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] |
| 1450 | pub fn selectznz(out1: *[4]u64, arg1: u1, arg2: [4]u64, arg3: [4]u64) void { | 1450 | pub fn selectznz(out1: *[4]u64, arg1: u1, arg2: [4]u64, arg3: [4]u64) void { |
| 1451 | @setRuntimeSafety(mode == .Debug); | 1451 | @setRuntimeSafety(mode == .debug); |
| 1452 | 1452 | ||
| 1453 | var x1: u64 = undefined; | 1453 | var x1: u64 = undefined; |
| 1454 | cmovznzU64(&x1, arg1, (arg2[0]), (arg3[0])); | 1454 | cmovznzU64(&x1, arg1, (arg2[0]), (arg3[0])); |
| ... | @@ -1476,7 +1476,7 @@ pub fn selectznz(out1: *[4]u64, arg1: u1, arg2: [4]u64, arg3: [4]u64) void { | ... | @@ -1476,7 +1476,7 @@ pub fn selectznz(out1: *[4]u64, arg1: u1, arg2: [4]u64, arg3: [4]u64) void { |
| 1476 | /// Output Bounds: | 1476 | /// Output Bounds: |
| 1477 | /// out1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff]] | 1477 | /// out1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff]] |
| 1478 | pub fn toBytes(out1: *[32]u8, arg1: [4]u64) void { | 1478 | pub fn toBytes(out1: *[32]u8, arg1: [4]u64) void { |
| 1479 | @setRuntimeSafety(mode == .Debug); | 1479 | @setRuntimeSafety(mode == .debug); |
| 1480 | 1480 | ||
| 1481 | const x1 = (arg1[3]); | 1481 | const x1 = (arg1[3]); |
| 1482 | const x2 = (arg1[2]); | 1482 | const x2 = (arg1[2]); |
| ... | @@ -1585,7 +1585,7 @@ pub fn toBytes(out1: *[32]u8, arg1: [4]u64) void { | ... | @@ -1585,7 +1585,7 @@ pub fn toBytes(out1: *[32]u8, arg1: [4]u64) void { |
| 1585 | /// Output Bounds: | 1585 | /// Output Bounds: |
| 1586 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] | 1586 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] |
| 1587 | pub fn fromBytes(out1: *[4]u64, arg1: [32]u8) void { | 1587 | pub fn fromBytes(out1: *[4]u64, arg1: [32]u8) void { |
| 1588 | @setRuntimeSafety(mode == .Debug); | 1588 | @setRuntimeSafety(mode == .debug); |
| 1589 | 1589 | ||
| 1590 | const x1 = (@as(u64, (arg1[31])) << 56); | 1590 | const x1 = (@as(u64, (arg1[31])) << 56); |
| 1591 | const x2 = (@as(u64, (arg1[30])) << 48); | 1591 | const x2 = (@as(u64, (arg1[30])) << 48); |
| ... | @@ -1660,7 +1660,7 @@ pub fn fromBytes(out1: *[4]u64, arg1: [32]u8) void { | ... | @@ -1660,7 +1660,7 @@ pub fn fromBytes(out1: *[4]u64, arg1: [32]u8) void { |
| 1660 | /// 0 ≤ eval out1 < m | 1660 | /// 0 ≤ eval out1 < m |
| 1661 | /// | 1661 | /// |
| 1662 | pub fn setOne(out1: *MontgomeryDomainFieldElement) void { | 1662 | pub fn setOne(out1: *MontgomeryDomainFieldElement) void { |
| 1663 | @setRuntimeSafety(mode == .Debug); | 1663 | @setRuntimeSafety(mode == .debug); |
| 1664 | 1664 | ||
| 1665 | out1[0] = 0x1000003d1; | 1665 | out1[0] = 0x1000003d1; |
| 1666 | out1[1] = 0x0; | 1666 | out1[1] = 0x0; |
| ... | @@ -1677,7 +1677,7 @@ pub fn setOne(out1: *MontgomeryDomainFieldElement) void { | ... | @@ -1677,7 +1677,7 @@ pub fn setOne(out1: *MontgomeryDomainFieldElement) void { |
| 1677 | /// Output Bounds: | 1677 | /// Output Bounds: |
| 1678 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] | 1678 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] |
| 1679 | pub fn msat(out1: *[5]u64) void { | 1679 | pub fn msat(out1: *[5]u64) void { |
| 1680 | @setRuntimeSafety(mode == .Debug); | 1680 | @setRuntimeSafety(mode == .debug); |
| 1681 | 1681 | ||
| 1682 | out1[0] = 0xfffffffefffffc2f; | 1682 | out1[0] = 0xfffffffefffffc2f; |
| 1683 | out1[1] = 0xffffffffffffffff; | 1683 | out1[1] = 0xffffffffffffffff; |
| ... | @@ -1715,7 +1715,7 @@ pub fn msat(out1: *[5]u64) void { | ... | @@ -1715,7 +1715,7 @@ pub fn msat(out1: *[5]u64) void { |
| 1715 | /// out4: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] | 1715 | /// out4: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] |
| 1716 | /// out5: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] | 1716 | /// out5: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] |
| 1717 | pub fn divstep(out1: *u64, out2: *[5]u64, out3: *[5]u64, out4: *[4]u64, out5: *[4]u64, arg1: u64, arg2: [5]u64, arg3: [5]u64, arg4: [4]u64, arg5: [4]u64) void { | 1717 | pub fn divstep(out1: *u64, out2: *[5]u64, out3: *[5]u64, out4: *[4]u64, out5: *[4]u64, arg1: u64, arg2: [5]u64, arg3: [5]u64, arg4: [4]u64, arg5: [4]u64) void { |
| 1718 | @setRuntimeSafety(mode == .Debug); | 1718 | @setRuntimeSafety(mode == .debug); |
| 1719 | 1719 | ||
| 1720 | var x1: u64 = undefined; | 1720 | var x1: u64 = undefined; |
| 1721 | var x2: u1 = undefined; | 1721 | var x2: u1 = undefined; |
| ... | @@ -1949,7 +1949,7 @@ pub fn divstep(out1: *u64, out2: *[5]u64, out3: *[5]u64, out4: *[4]u64, out5: *[ | ... | @@ -1949,7 +1949,7 @@ pub fn divstep(out1: *u64, out2: *[5]u64, out3: *[5]u64, out4: *[4]u64, out5: *[ |
| 1949 | /// Output Bounds: | 1949 | /// Output Bounds: |
| 1950 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] | 1950 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] |
| 1951 | pub fn divstepPrecomp(out1: *[4]u64) void { | 1951 | pub fn divstepPrecomp(out1: *[4]u64) void { |
| 1952 | @setRuntimeSafety(mode == .Debug); | 1952 | @setRuntimeSafety(mode == .debug); |
| 1953 | 1953 | ||
| 1954 | out1[0] = 0xf201a41831525e0a; | 1954 | out1[0] = 0xf201a41831525e0a; |
| 1955 | out1[1] = 0x9953f9ddcd648d85; | 1955 | out1[1] = 0x9953f9ddcd648d85; |
lib/std/crypto/pcurves/secp256k1/secp256k1_scalar_64.zig+17-17| ... | @@ -79,7 +79,7 @@ fn subborrowxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) void { | ... | @@ -79,7 +79,7 @@ fn subborrowxU64(out1: *u64, out2: *u1, arg1: u1, arg2: u64, arg3: u64) void { |
| 79 | /// out1: [0x0 ~> 0xffffffffffffffff] | 79 | /// out1: [0x0 ~> 0xffffffffffffffff] |
| 80 | /// out2: [0x0 ~> 0xffffffffffffffff] | 80 | /// out2: [0x0 ~> 0xffffffffffffffff] |
| 81 | fn mulxU64(out1: *u64, out2: *u64, arg1: u64, arg2: u64) void { | 81 | fn mulxU64(out1: *u64, out2: *u64, arg1: u64, arg2: u64) void { |
| 82 | @setRuntimeSafety(mode == .Debug); | 82 | @setRuntimeSafety(mode == .debug); |
| 83 | 83 | ||
| 84 | const x = @as(u128, arg1) * @as(u128, arg2); | 84 | const x = @as(u128, arg1) * @as(u128, arg2); |
| 85 | out1.* = @as(u64, @truncate(x)); | 85 | out1.* = @as(u64, @truncate(x)); |
| ... | @@ -98,7 +98,7 @@ fn mulxU64(out1: *u64, out2: *u64, arg1: u64, arg2: u64) void { | ... | @@ -98,7 +98,7 @@ fn mulxU64(out1: *u64, out2: *u64, arg1: u64, arg2: u64) void { |
| 98 | /// Output Bounds: | 98 | /// Output Bounds: |
| 99 | /// out1: [0x0 ~> 0xffffffffffffffff] | 99 | /// out1: [0x0 ~> 0xffffffffffffffff] |
| 100 | fn cmovznzU64(out1: *u64, arg1: u1, arg2: u64, arg3: u64) void { | 100 | fn cmovznzU64(out1: *u64, arg1: u1, arg2: u64, arg3: u64) void { |
| 101 | @setRuntimeSafety(mode == .Debug); | 101 | @setRuntimeSafety(mode == .debug); |
| 102 | 102 | ||
| 103 | const mask = 0 -% @as(u64, arg1); | 103 | const mask = 0 -% @as(u64, arg1); |
| 104 | out1.* = (mask & arg3) | ((~mask) & arg2); | 104 | out1.* = (mask & arg3) | ((~mask) & arg2); |
| ... | @@ -114,7 +114,7 @@ fn cmovznzU64(out1: *u64, arg1: u1, arg2: u64, arg3: u64) void { | ... | @@ -114,7 +114,7 @@ fn cmovznzU64(out1: *u64, arg1: u1, arg2: u64, arg3: u64) void { |
| 114 | /// 0 ≤ eval out1 < m | 114 | /// 0 ≤ eval out1 < m |
| 115 | /// | 115 | /// |
| 116 | pub fn mul(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement, arg2: MontgomeryDomainFieldElement) void { | 116 | pub fn mul(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement, arg2: MontgomeryDomainFieldElement) void { |
| 117 | @setRuntimeSafety(mode == .Debug); | 117 | @setRuntimeSafety(mode == .debug); |
| 118 | 118 | ||
| 119 | const x1 = (arg1[1]); | 119 | const x1 = (arg1[1]); |
| 120 | const x2 = (arg1[2]); | 120 | const x2 = (arg1[2]); |
| ... | @@ -454,7 +454,7 @@ pub fn mul(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme | ... | @@ -454,7 +454,7 @@ pub fn mul(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme |
| 454 | /// 0 ≤ eval out1 < m | 454 | /// 0 ≤ eval out1 < m |
| 455 | /// | 455 | /// |
| 456 | pub fn square(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement) void { | 456 | pub fn square(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement) void { |
| 457 | @setRuntimeSafety(mode == .Debug); | 457 | @setRuntimeSafety(mode == .debug); |
| 458 | 458 | ||
| 459 | const x1 = (arg1[1]); | 459 | const x1 = (arg1[1]); |
| 460 | const x2 = (arg1[2]); | 460 | const x2 = (arg1[2]); |
| ... | @@ -795,7 +795,7 @@ pub fn square(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEl | ... | @@ -795,7 +795,7 @@ pub fn square(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEl |
| 795 | /// 0 ≤ eval out1 < m | 795 | /// 0 ≤ eval out1 < m |
| 796 | /// | 796 | /// |
| 797 | pub fn add(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement, arg2: MontgomeryDomainFieldElement) void { | 797 | pub fn add(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement, arg2: MontgomeryDomainFieldElement) void { |
| 798 | @setRuntimeSafety(mode == .Debug); | 798 | @setRuntimeSafety(mode == .debug); |
| 799 | 799 | ||
| 800 | var x1: u64 = undefined; | 800 | var x1: u64 = undefined; |
| 801 | var x2: u1 = undefined; | 801 | var x2: u1 = undefined; |
| ... | @@ -848,7 +848,7 @@ pub fn add(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme | ... | @@ -848,7 +848,7 @@ pub fn add(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme |
| 848 | /// 0 ≤ eval out1 < m | 848 | /// 0 ≤ eval out1 < m |
| 849 | /// | 849 | /// |
| 850 | pub fn sub(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement, arg2: MontgomeryDomainFieldElement) void { | 850 | pub fn sub(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement, arg2: MontgomeryDomainFieldElement) void { |
| 851 | @setRuntimeSafety(mode == .Debug); | 851 | @setRuntimeSafety(mode == .debug); |
| 852 | 852 | ||
| 853 | var x1: u64 = undefined; | 853 | var x1: u64 = undefined; |
| 854 | var x2: u1 = undefined; | 854 | var x2: u1 = undefined; |
| ... | @@ -891,7 +891,7 @@ pub fn sub(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme | ... | @@ -891,7 +891,7 @@ pub fn sub(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme |
| 891 | /// 0 ≤ eval out1 < m | 891 | /// 0 ≤ eval out1 < m |
| 892 | /// | 892 | /// |
| 893 | pub fn opp(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement) void { | 893 | pub fn opp(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement) void { |
| 894 | @setRuntimeSafety(mode == .Debug); | 894 | @setRuntimeSafety(mode == .debug); |
| 895 | 895 | ||
| 896 | var x1: u64 = undefined; | 896 | var x1: u64 = undefined; |
| 897 | var x2: u1 = undefined; | 897 | var x2: u1 = undefined; |
| ... | @@ -934,7 +934,7 @@ pub fn opp(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme | ... | @@ -934,7 +934,7 @@ pub fn opp(out1: *MontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldEleme |
| 934 | /// 0 ≤ eval out1 < m | 934 | /// 0 ≤ eval out1 < m |
| 935 | /// | 935 | /// |
| 936 | pub fn fromMontgomery(out1: *NonMontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement) void { | 936 | pub fn fromMontgomery(out1: *NonMontgomeryDomainFieldElement, arg1: MontgomeryDomainFieldElement) void { |
| 937 | @setRuntimeSafety(mode == .Debug); | 937 | @setRuntimeSafety(mode == .debug); |
| 938 | 938 | ||
| 939 | const x1 = (arg1[0]); | 939 | const x1 = (arg1[0]); |
| 940 | var x2: u64 = undefined; | 940 | var x2: u64 = undefined; |
| ... | @@ -1167,7 +1167,7 @@ pub fn fromMontgomery(out1: *NonMontgomeryDomainFieldElement, arg1: MontgomeryDo | ... | @@ -1167,7 +1167,7 @@ pub fn fromMontgomery(out1: *NonMontgomeryDomainFieldElement, arg1: MontgomeryDo |
| 1167 | /// 0 ≤ eval out1 < m | 1167 | /// 0 ≤ eval out1 < m |
| 1168 | /// | 1168 | /// |
| 1169 | pub fn toMontgomery(out1: *MontgomeryDomainFieldElement, arg1: NonMontgomeryDomainFieldElement) void { | 1169 | pub fn toMontgomery(out1: *MontgomeryDomainFieldElement, arg1: NonMontgomeryDomainFieldElement) void { |
| 1170 | @setRuntimeSafety(mode == .Debug); | 1170 | @setRuntimeSafety(mode == .debug); |
| 1171 | 1171 | ||
| 1172 | const x1 = (arg1[1]); | 1172 | const x1 = (arg1[1]); |
| 1173 | const x2 = (arg1[2]); | 1173 | const x2 = (arg1[2]); |
| ... | @@ -1490,7 +1490,7 @@ pub fn toMontgomery(out1: *MontgomeryDomainFieldElement, arg1: NonMontgomeryDoma | ... | @@ -1490,7 +1490,7 @@ pub fn toMontgomery(out1: *MontgomeryDomainFieldElement, arg1: NonMontgomeryDoma |
| 1490 | /// Output Bounds: | 1490 | /// Output Bounds: |
| 1491 | /// out1: [0x0 ~> 0xffffffffffffffff] | 1491 | /// out1: [0x0 ~> 0xffffffffffffffff] |
| 1492 | pub fn nonzero(out1: *u64, arg1: [4]u64) void { | 1492 | pub fn nonzero(out1: *u64, arg1: [4]u64) void { |
| 1493 | @setRuntimeSafety(mode == .Debug); | 1493 | @setRuntimeSafety(mode == .debug); |
| 1494 | 1494 | ||
| 1495 | const x1 = ((arg1[0]) | ((arg1[1]) | ((arg1[2]) | (arg1[3])))); | 1495 | const x1 = ((arg1[0]) | ((arg1[1]) | ((arg1[2]) | (arg1[3])))); |
| 1496 | out1.* = x1; | 1496 | out1.* = x1; |
| ... | @@ -1508,7 +1508,7 @@ pub fn nonzero(out1: *u64, arg1: [4]u64) void { | ... | @@ -1508,7 +1508,7 @@ pub fn nonzero(out1: *u64, arg1: [4]u64) void { |
| 1508 | /// Output Bounds: | 1508 | /// Output Bounds: |
| 1509 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] | 1509 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] |
| 1510 | pub fn selectznz(out1: *[4]u64, arg1: u1, arg2: [4]u64, arg3: [4]u64) void { | 1510 | pub fn selectznz(out1: *[4]u64, arg1: u1, arg2: [4]u64, arg3: [4]u64) void { |
| 1511 | @setRuntimeSafety(mode == .Debug); | 1511 | @setRuntimeSafety(mode == .debug); |
| 1512 | 1512 | ||
| 1513 | var x1: u64 = undefined; | 1513 | var x1: u64 = undefined; |
| 1514 | cmovznzU64(&x1, arg1, (arg2[0]), (arg3[0])); | 1514 | cmovznzU64(&x1, arg1, (arg2[0]), (arg3[0])); |
| ... | @@ -1536,7 +1536,7 @@ pub fn selectznz(out1: *[4]u64, arg1: u1, arg2: [4]u64, arg3: [4]u64) void { | ... | @@ -1536,7 +1536,7 @@ pub fn selectznz(out1: *[4]u64, arg1: u1, arg2: [4]u64, arg3: [4]u64) void { |
| 1536 | /// Output Bounds: | 1536 | /// Output Bounds: |
| 1537 | /// out1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff]] | 1537 | /// out1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff]] |
| 1538 | pub fn toBytes(out1: *[32]u8, arg1: [4]u64) void { | 1538 | pub fn toBytes(out1: *[32]u8, arg1: [4]u64) void { |
| 1539 | @setRuntimeSafety(mode == .Debug); | 1539 | @setRuntimeSafety(mode == .debug); |
| 1540 | 1540 | ||
| 1541 | const x1 = (arg1[3]); | 1541 | const x1 = (arg1[3]); |
| 1542 | const x2 = (arg1[2]); | 1542 | const x2 = (arg1[2]); |
| ... | @@ -1645,7 +1645,7 @@ pub fn toBytes(out1: *[32]u8, arg1: [4]u64) void { | ... | @@ -1645,7 +1645,7 @@ pub fn toBytes(out1: *[32]u8, arg1: [4]u64) void { |
| 1645 | /// Output Bounds: | 1645 | /// Output Bounds: |
| 1646 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] | 1646 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] |
| 1647 | pub fn fromBytes(out1: *[4]u64, arg1: [32]u8) void { | 1647 | pub fn fromBytes(out1: *[4]u64, arg1: [32]u8) void { |
| 1648 | @setRuntimeSafety(mode == .Debug); | 1648 | @setRuntimeSafety(mode == .debug); |
| 1649 | 1649 | ||
| 1650 | const x1 = (@as(u64, (arg1[31])) << 56); | 1650 | const x1 = (@as(u64, (arg1[31])) << 56); |
| 1651 | const x2 = (@as(u64, (arg1[30])) << 48); | 1651 | const x2 = (@as(u64, (arg1[30])) << 48); |
| ... | @@ -1720,7 +1720,7 @@ pub fn fromBytes(out1: *[4]u64, arg1: [32]u8) void { | ... | @@ -1720,7 +1720,7 @@ pub fn fromBytes(out1: *[4]u64, arg1: [32]u8) void { |
| 1720 | /// 0 ≤ eval out1 < m | 1720 | /// 0 ≤ eval out1 < m |
| 1721 | /// | 1721 | /// |
| 1722 | pub fn setOne(out1: *MontgomeryDomainFieldElement) void { | 1722 | pub fn setOne(out1: *MontgomeryDomainFieldElement) void { |
| 1723 | @setRuntimeSafety(mode == .Debug); | 1723 | @setRuntimeSafety(mode == .debug); |
| 1724 | 1724 | ||
| 1725 | out1[0] = 0x402da1732fc9bebf; | 1725 | out1[0] = 0x402da1732fc9bebf; |
| 1726 | out1[1] = 0x4551231950b75fc4; | 1726 | out1[1] = 0x4551231950b75fc4; |
| ... | @@ -1737,7 +1737,7 @@ pub fn setOne(out1: *MontgomeryDomainFieldElement) void { | ... | @@ -1737,7 +1737,7 @@ pub fn setOne(out1: *MontgomeryDomainFieldElement) void { |
| 1737 | /// Output Bounds: | 1737 | /// Output Bounds: |
| 1738 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] | 1738 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] |
| 1739 | pub fn msat(out1: *[5]u64) void { | 1739 | pub fn msat(out1: *[5]u64) void { |
| 1740 | @setRuntimeSafety(mode == .Debug); | 1740 | @setRuntimeSafety(mode == .debug); |
| 1741 | 1741 | ||
| 1742 | out1[0] = 0xbfd25e8cd0364141; | 1742 | out1[0] = 0xbfd25e8cd0364141; |
| 1743 | out1[1] = 0xbaaedce6af48a03b; | 1743 | out1[1] = 0xbaaedce6af48a03b; |
| ... | @@ -1775,7 +1775,7 @@ pub fn msat(out1: *[5]u64) void { | ... | @@ -1775,7 +1775,7 @@ pub fn msat(out1: *[5]u64) void { |
| 1775 | /// out4: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] | 1775 | /// out4: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] |
| 1776 | /// out5: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] | 1776 | /// out5: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] |
| 1777 | pub fn divstep(out1: *u64, out2: *[5]u64, out3: *[5]u64, out4: *[4]u64, out5: *[4]u64, arg1: u64, arg2: [5]u64, arg3: [5]u64, arg4: [4]u64, arg5: [4]u64) void { | 1777 | pub fn divstep(out1: *u64, out2: *[5]u64, out3: *[5]u64, out4: *[4]u64, out5: *[4]u64, arg1: u64, arg2: [5]u64, arg3: [5]u64, arg4: [4]u64, arg5: [4]u64) void { |
| 1778 | @setRuntimeSafety(mode == .Debug); | 1778 | @setRuntimeSafety(mode == .debug); |
| 1779 | 1779 | ||
| 1780 | var x1: u64 = undefined; | 1780 | var x1: u64 = undefined; |
| 1781 | var x2: u1 = undefined; | 1781 | var x2: u1 = undefined; |
| ... | @@ -2009,7 +2009,7 @@ pub fn divstep(out1: *u64, out2: *[5]u64, out3: *[5]u64, out4: *[4]u64, out5: *[ | ... | @@ -2009,7 +2009,7 @@ pub fn divstep(out1: *u64, out2: *[5]u64, out3: *[5]u64, out4: *[4]u64, out5: *[ |
| 2009 | /// Output Bounds: | 2009 | /// Output Bounds: |
| 2010 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] | 2010 | /// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] |
| 2011 | pub fn divstepPrecomp(out1: *[4]u64) void { | 2011 | pub fn divstepPrecomp(out1: *[4]u64) void { |
| 2012 | @setRuntimeSafety(mode == .Debug); | 2012 | @setRuntimeSafety(mode == .debug); |
| 2013 | 2013 | ||
| 2014 | out1[0] = 0xd7431a4d2b9cb4e9; | 2014 | out1[0] = 0xd7431a4d2b9cb4e9; |
| 2015 | out1[1] = 0xab67d35a32d9c503; | 2015 | out1[1] = 0xab67d35a32d9c503; |
lib/std/crypto/tls/Client.zig+1-1| ... | @@ -1588,7 +1588,7 @@ const CertificatePublicKey = struct { | ... | @@ -1588,7 +1588,7 @@ const CertificatePublicKey = struct { |
| 1588 | inline 128, 256, 384, 512 => |modulus_len| { | 1588 | inline 128, 256, 384, 512 => |modulus_len| { |
| 1589 | const key: PublicKey = try .fromBytes(exponent, modulus); | 1589 | const key: PublicKey = try .fromBytes(exponent, modulus); |
| 1590 | const sig = RsaSignature.fromBytes(modulus_len, encoded_sig); | 1590 | const sig = RsaSignature.fromBytes(modulus_len, encoded_sig); |
| 1591 | try RsaSignature.concatVerify(modulus_len, sig, msg, key, Hash); | 1591 | try RsaSignature.concatVerify(modulus_len, &sig, msg, key, Hash); |
| 1592 | }, | 1592 | }, |
| 1593 | else => return error.TlsBadRsaSignatureBitCount, | 1593 | else => return error.TlsBadRsaSignatureBitCount, |
| 1594 | } | 1594 | } |
lib/std/debug.zig+19-12| ... | @@ -151,6 +151,10 @@ pub fn FullPanic(comptime panicFn: fn ([]const u8, ?usize) noreturn) type { | ... | @@ -151,6 +151,10 @@ pub fn FullPanic(comptime panicFn: fn ([]const u8, ?usize) noreturn) type { |
| 151 | @branchHint(.cold); | 151 | @branchHint(.cold); |
| 152 | call("invalid error code", @returnAddress()); | 152 | call("invalid error code", @returnAddress()); |
| 153 | } | 153 | } |
| 154 | pub fn unexpectedErrorCode(err: anyerror) noreturn { | ||
| 155 | @branchHint(.cold); | ||
| 156 | std.debug.panicExtra(@returnAddress(), "unexpected error code, found error.{s}", .{@errorName(err)}); | ||
| 157 | } | ||
| 154 | pub fn integerOutOfBounds() noreturn { | 158 | pub fn integerOutOfBounds() noreturn { |
| 155 | @branchHint(.cold); | 159 | @branchHint(.cold); |
| 156 | call("integer does not fit in destination type", @returnAddress()); | 160 | call("integer does not fit in destination type", @returnAddress()); |
| ... | @@ -207,6 +211,10 @@ pub fn FullPanic(comptime panicFn: fn ([]const u8, ?usize) noreturn) type { | ... | @@ -207,6 +211,10 @@ pub fn FullPanic(comptime panicFn: fn ([]const u8, ?usize) noreturn) type { |
| 207 | @branchHint(.cold); | 211 | @branchHint(.cold); |
| 208 | call("'noreturn' function returned", @returnAddress()); | 212 | call("'noreturn' function returned", @returnAddress()); |
| 209 | } | 213 | } |
| 214 | pub fn loadUninstantiableType() noreturn { | ||
| 215 | @branchHint(.cold); | ||
| 216 | call("attempt to load uninstantiable type", @returnAddress()); | ||
| 217 | } | ||
| 210 | }; | 218 | }; |
| 211 | } | 219 | } |
| 212 | 220 | ||
| ... | @@ -237,13 +245,12 @@ pub const Symbol = struct { | ... | @@ -237,13 +245,12 @@ pub const Symbol = struct { |
| 237 | }; | 245 | }; |
| 238 | }; | 246 | }; |
| 239 | 247 | ||
| 240 | /// Deprecated because it returns the optimization mode of the standard | 248 | /// Deprecated in favor of `std.lang.Optimize.runtimeSafety`, to be removed after 0.18.0 |
| 241 | /// library, when the caller probably wants to use the optimization mode of | 249 | /// |
| 242 | /// their own module. | 250 | /// Returns whether the standard library has safety checks enabled. Callsites |
| 243 | pub const runtime_safety = switch (builtin.mode) { | 251 | /// likely would rather know whether their own module's optimization mode |
| 244 | .Debug, .ReleaseSafe => true, | 252 | /// (found via `@import("builtin").optimize`) has safety checks enabled. |
| 245 | .ReleaseFast, .ReleaseSmall => false, | 253 | pub const runtime_safety = builtin.mode.runtimeSafety(); |
| 246 | }; | ||
| 247 | 254 | ||
| 248 | /// Whether we can unwind the stack on this target, allowing capturing and/or printing the current | 255 | /// Whether we can unwind the stack on this target, allowing capturing and/or printing the current |
| 249 | /// stack trace. It is still legal to call `captureCurrentStackTrace`, `writeCurrentStackTrace`, and | 256 | /// stack trace. It is still legal to call `captureCurrentStackTrace`, `writeCurrentStackTrace`, and |
| ... | @@ -257,7 +264,7 @@ pub const sys_can_stack_trace = switch (builtin.cpu.arch) { | ... | @@ -257,7 +264,7 @@ pub const sys_can_stack_trace = switch (builtin.cpu.arch) { |
| 257 | // because Emscripten's implementation is very slow. | 264 | // because Emscripten's implementation is very slow. |
| 258 | .wasm32, | 265 | .wasm32, |
| 259 | .wasm64, | 266 | .wasm64, |
| 260 | => native_os == .emscripten and builtin.mode == .Debug, | 267 | => native_os == .emscripten and builtin.mode == .debug, |
| 261 | 268 | ||
| 262 | // `@returnAddress()` is unsupported in LLVM 21. | 269 | // `@returnAddress()` is unsupported in LLVM 21. |
| 263 | .bpfel, | 270 | .bpfel, |
| ... | @@ -419,16 +426,16 @@ pub const CpuContextPtr = if (cpu_context.Native == noreturn) noreturn else *con | ... | @@ -419,16 +426,16 @@ pub const CpuContextPtr = if (cpu_context.Native == noreturn) noreturn else *con |
| 419 | 426 | ||
| 420 | /// Invokes detectable illegal behavior when `ok` is `false`. | 427 | /// Invokes detectable illegal behavior when `ok` is `false`. |
| 421 | /// | 428 | /// |
| 422 | /// In Debug and ReleaseSafe modes, calls to this function are always | 429 | /// In debug and safe modes, calls to this function are always |
| 423 | /// generated, and the `unreachable` statement triggers a panic. | 430 | /// generated, and the `unreachable` statement triggers a panic. |
| 424 | /// | 431 | /// |
| 425 | /// In ReleaseFast and ReleaseSmall modes, calls to this function are optimized | 432 | /// In fast and small modes, calls to this function are optimized |
| 426 | /// away, and in fact the optimizer is able to use the assertion in its | 433 | /// away, and in fact the optimizer is able to use the assertion in its |
| 427 | /// heuristics. | 434 | /// heuristics. |
| 428 | /// | 435 | /// |
| 429 | /// Inside a test block, it is best to use the `testing` module rather than | 436 | /// Inside a test block, it is best to use the `testing` module rather than |
| 430 | /// this function, because this function may not detect a test failure in | 437 | /// this function, because this function may not detect a test failure in |
| 431 | /// ReleaseFast and ReleaseSmall mode. Outside of a test block, this assert | 438 | /// fast and small mode. Outside of a test block, this assert |
| 432 | /// function is the correct function to use. | 439 | /// function is the correct function to use. |
| 433 | pub fn assert(ok: bool) void { | 440 | pub fn assert(ok: bool) void { |
| 434 | @disableInstrumentation(); | 441 | @disableInstrumentation(); |
| ... | @@ -1760,7 +1767,7 @@ test "manage resources correctly" { | ... | @@ -1760,7 +1767,7 @@ test "manage resources correctly" { |
| 1760 | /// In release mode, it is size 0 and all methods are no-ops. | 1767 | /// In release mode, it is size 0 and all methods are no-ops. |
| 1761 | /// This is a pre-made type with default settings. | 1768 | /// This is a pre-made type with default settings. |
| 1762 | /// For more advanced usage, see `ConfigurableTrace`. | 1769 | /// For more advanced usage, see `ConfigurableTrace`. |
| 1763 | pub const Trace = ConfigurableTrace(2, 4, builtin.mode == .Debug); | 1770 | pub const Trace = ConfigurableTrace(2, 4, builtin.mode == .debug); |
| 1764 | 1771 | ||
| 1765 | pub fn ConfigurableTrace(comptime size: usize, comptime stack_frame_count: usize, comptime is_enabled: bool) type { | 1772 | pub fn ConfigurableTrace(comptime size: usize, comptime stack_frame_count: usize, comptime is_enabled: bool) type { |
| 1766 | return struct { | 1773 | return struct { |
lib/std/debug/Dwarf.zig+16-5| ... | @@ -450,6 +450,7 @@ fn scanAllFunctions(di: *Dwarf, gpa: Allocator, endian: Endian) ScanError!void { | ... | @@ -450,6 +450,7 @@ fn scanAllFunctions(di: *Dwarf, gpa: Allocator, endian: Endian) ScanError!void { |
| 450 | unit_header.format, | 450 | unit_header.format, |
| 451 | endian, | 451 | endian, |
| 452 | address_size, | 452 | address_size, |
| 453 | version, | ||
| 453 | )) orelse continue; | 454 | )) orelse continue; |
| 454 | 455 | ||
| 455 | switch (die_obj.tag_id) { | 456 | switch (die_obj.tag_id) { |
| ... | @@ -485,6 +486,7 @@ fn scanAllFunctions(di: *Dwarf, gpa: Allocator, endian: Endian) ScanError!void { | ... | @@ -485,6 +486,7 @@ fn scanAllFunctions(di: *Dwarf, gpa: Allocator, endian: Endian) ScanError!void { |
| 485 | unit_header.format, | 486 | unit_header.format, |
| 486 | endian, | 487 | endian, |
| 487 | address_size, | 488 | address_size, |
| 489 | version, | ||
| 488 | )) orelse return bad(); | 490 | )) orelse return bad(); |
| 489 | } else if (this_die_obj.getAttr(AT.specification)) |_| { | 491 | } else if (this_die_obj.getAttr(AT.specification)) |_| { |
| 490 | const after_die_offset = fr.seek; | 492 | const after_die_offset = fr.seek; |
| ... | @@ -500,6 +502,7 @@ fn scanAllFunctions(di: *Dwarf, gpa: Allocator, endian: Endian) ScanError!void { | ... | @@ -500,6 +502,7 @@ fn scanAllFunctions(di: *Dwarf, gpa: Allocator, endian: Endian) ScanError!void { |
| 500 | unit_header.format, | 502 | unit_header.format, |
| 501 | endian, | 503 | endian, |
| 502 | address_size, | 504 | address_size, |
| 505 | version, | ||
| 503 | )) orelse return bad(); | 506 | )) orelse return bad(); |
| 504 | } else { | 507 | } else { |
| 505 | break :x null; | 508 | break :x null; |
| ... | @@ -611,6 +614,7 @@ fn scanAllCompileUnits(di: *Dwarf, gpa: Allocator, endian: Endian) ScanError!voi | ... | @@ -611,6 +614,7 @@ fn scanAllCompileUnits(di: *Dwarf, gpa: Allocator, endian: Endian) ScanError!voi |
| 611 | unit_header.format, | 614 | unit_header.format, |
| 612 | endian, | 615 | endian, |
| 613 | address_size, | 616 | address_size, |
| 617 | version, | ||
| 614 | )) orelse return bad(); | 618 | )) orelse return bad(); |
| 615 | 619 | ||
| 616 | if (compile_unit_die.tag_id != DW.TAG.compile_unit) return bad(); | 620 | if (compile_unit_die.tag_id != DW.TAG.compile_unit) return bad(); |
| ... | @@ -931,6 +935,7 @@ fn parseDie( | ... | @@ -931,6 +935,7 @@ fn parseDie( |
| 931 | format: Format, | 935 | format: Format, |
| 932 | endian: Endian, | 936 | endian: Endian, |
| 933 | addr_size_bytes: u8, | 937 | addr_size_bytes: u8, |
| 938 | version: u16, | ||
| 934 | ) ScanError!?Die { | 939 | ) ScanError!?Die { |
| 935 | const abbrev_code = try fr.takeLeb128(u64); | 940 | const abbrev_code = try fr.takeLeb128(u64); |
| 936 | if (abbrev_code == 0) return null; | 941 | if (abbrev_code == 0) return null; |
| ... | @@ -939,7 +944,7 @@ fn parseDie( | ... | @@ -939,7 +944,7 @@ fn parseDie( |
| 939 | const attrs = attrs_buf[0..table_entry.attrs.len]; | 944 | const attrs = attrs_buf[0..table_entry.attrs.len]; |
| 940 | for (attrs, table_entry.attrs) |*result_attr, attr| result_attr.* = .{ | 945 | for (attrs, table_entry.attrs) |*result_attr, attr| result_attr.* = .{ |
| 941 | .id = attr.id, | 946 | .id = attr.id, |
| 942 | .value = try parseFormValue(fr, attr.form_id, format, endian, addr_size_bytes, attr.payload), | 947 | .value = try parseFormValue(fr, attr.form_id, format, endian, addr_size_bytes, attr.payload, version), |
| 943 | }; | 948 | }; |
| 944 | return .{ | 949 | return .{ |
| 945 | .tag_id = table_entry.tag_id, | 950 | .tag_id = table_entry.tag_id, |
| ... | @@ -1042,7 +1047,7 @@ fn runLineNumberProgram(d: *Dwarf, gpa: Allocator, endian: Endian, compile_unit: | ... | @@ -1042,7 +1047,7 @@ fn runLineNumberProgram(d: *Dwarf, gpa: Allocator, endian: Endian, compile_unit: |
| 1042 | for (try directories.addManyAsSlice(gpa, directories_count)) |*e| { | 1047 | for (try directories.addManyAsSlice(gpa, directories_count)) |*e| { |
| 1043 | e.* = .{ .path = &.{} }; | 1048 | e.* = .{ .path = &.{} }; |
| 1044 | for (dir_ent_fmt_buf[0..directory_entry_format_count]) |ent_fmt| { | 1049 | for (dir_ent_fmt_buf[0..directory_entry_format_count]) |ent_fmt| { |
| 1045 | const form_value = try parseFormValue(&fr, ent_fmt.form_code, unit_header.format, endian, addr_size_bytes, null); | 1050 | const form_value = try parseFormValue(&fr, ent_fmt.form_code, unit_header.format, endian, addr_size_bytes, null, version); |
| 1046 | switch (ent_fmt.content_type_code) { | 1051 | switch (ent_fmt.content_type_code) { |
| 1047 | DW.LNCT.path => e.path = try form_value.getString(d.*), | 1052 | DW.LNCT.path => e.path = try form_value.getString(d.*), |
| 1048 | DW.LNCT.directory_index => e.dir_index = try form_value.getUInt(u32), | 1053 | DW.LNCT.directory_index => e.dir_index = try form_value.getUInt(u32), |
| ... | @@ -1074,7 +1079,7 @@ fn runLineNumberProgram(d: *Dwarf, gpa: Allocator, endian: Endian, compile_unit: | ... | @@ -1074,7 +1079,7 @@ fn runLineNumberProgram(d: *Dwarf, gpa: Allocator, endian: Endian, compile_unit: |
| 1074 | for (try file_entries.addManyAsSlice(gpa, file_names_count)) |*e| { | 1079 | for (try file_entries.addManyAsSlice(gpa, file_names_count)) |*e| { |
| 1075 | e.* = .{ .path = &.{} }; | 1080 | e.* = .{ .path = &.{} }; |
| 1076 | for (file_ent_fmt_buf[0..file_name_entry_format_count]) |ent_fmt| { | 1081 | for (file_ent_fmt_buf[0..file_name_entry_format_count]) |ent_fmt| { |
| 1077 | const form_value = try parseFormValue(&fr, ent_fmt.form_code, unit_header.format, endian, addr_size_bytes, null); | 1082 | const form_value = try parseFormValue(&fr, ent_fmt.form_code, unit_header.format, endian, addr_size_bytes, null, version); |
| 1078 | switch (ent_fmt.content_type_code) { | 1083 | switch (ent_fmt.content_type_code) { |
| 1079 | DW.LNCT.path => e.path = try form_value.getString(d.*), | 1084 | DW.LNCT.path => e.path = try form_value.getString(d.*), |
| 1080 | DW.LNCT.directory_index => e.dir_index = try form_value.getUInt(u32), | 1085 | DW.LNCT.directory_index => e.dir_index = try form_value.getUInt(u32), |
| ... | @@ -1285,6 +1290,7 @@ fn parseFormValue( | ... | @@ -1285,6 +1290,7 @@ fn parseFormValue( |
| 1285 | endian: Endian, | 1290 | endian: Endian, |
| 1286 | addr_size_bytes: u8, | 1291 | addr_size_bytes: u8, |
| 1287 | implicit_const: ?i64, | 1292 | implicit_const: ?i64, |
| 1293 | version: u16, | ||
| 1288 | ) ScanError!FormValue { | 1294 | ) ScanError!FormValue { |
| 1289 | return switch (form_id) { | 1295 | return switch (form_id) { |
| 1290 | // DWARF5.pdf page 213: the size of this value is encoded in the | 1296 | // DWARF5.pdf page 213: the size of this value is encoded in the |
| ... | @@ -1319,7 +1325,12 @@ fn parseFormValue( | ... | @@ -1319,7 +1325,12 @@ fn parseFormValue( |
| 1319 | FORM.ref8 => .{ .ref = try r.takeInt(u64, endian) }, | 1325 | FORM.ref8 => .{ .ref = try r.takeInt(u64, endian) }, |
| 1320 | FORM.ref_udata => .{ .ref = try r.takeLeb128(u64) }, | 1326 | FORM.ref_udata => .{ .ref = try r.takeLeb128(u64) }, |
| 1321 | 1327 | ||
| 1322 | FORM.ref_addr => .{ .ref_addr = try readFormatSizedInt(r, format, endian) }, | 1328 | FORM.ref_addr => .{ |
| 1329 | .ref_addr = switch (version) { | ||
| 1330 | 2 => try readAddress(r, endian, addr_size_bytes), | ||
| 1331 | else => try readFormatSizedInt(r, format, endian), | ||
| 1332 | }, | ||
| 1333 | }, | ||
| 1323 | FORM.ref_sig8 => .{ .ref = try r.takeInt(u64, endian) }, | 1334 | FORM.ref_sig8 => .{ .ref = try r.takeInt(u64, endian) }, |
| 1324 | 1335 | ||
| 1325 | FORM.string => .{ .string = try r.takeSentinel(0) }, | 1336 | FORM.string => .{ .string = try r.takeSentinel(0) }, |
| ... | @@ -1330,7 +1341,7 @@ fn parseFormValue( | ... | @@ -1330,7 +1341,7 @@ fn parseFormValue( |
| 1330 | FORM.strx4 => .{ .strx = try r.takeInt(u32, endian) }, | 1341 | FORM.strx4 => .{ .strx = try r.takeInt(u32, endian) }, |
| 1331 | FORM.strx => .{ .strx = try r.takeLeb128(usize) }, | 1342 | FORM.strx => .{ .strx = try r.takeLeb128(usize) }, |
| 1332 | FORM.line_strp => .{ .line_strp = try readFormatSizedInt(r, format, endian) }, | 1343 | FORM.line_strp => .{ .line_strp = try readFormatSizedInt(r, format, endian) }, |
| 1333 | FORM.indirect => parseFormValue(r, try r.takeLeb128(u64), format, endian, addr_size_bytes, implicit_const), | 1344 | FORM.indirect => parseFormValue(r, try r.takeLeb128(u64), format, endian, addr_size_bytes, implicit_const, version), |
| 1334 | FORM.implicit_const => .{ .sdata = implicit_const orelse return bad() }, | 1345 | FORM.implicit_const => .{ .sdata = implicit_const orelse return bad() }, |
| 1335 | FORM.loclistx => .{ .loclistx = try r.takeLeb128(u64) }, | 1346 | FORM.loclistx => .{ .loclistx = try r.takeLeb128(u64) }, |
| 1336 | FORM.rnglistx => .{ .rnglistx = try r.takeLeb128(u64) }, | 1347 | FORM.rnglistx => .{ .rnglistx = try r.takeLeb128(u64) }, |
lib/std/debug/MachOFile.zig+174-54| ... | @@ -2,6 +2,8 @@ mapped_memory: []align(std.heap.page_size_min) const u8, | ... | @@ -2,6 +2,8 @@ mapped_memory: []align(std.heap.page_size_min) const u8, |
| 2 | symbols: []const Symbol, | 2 | symbols: []const Symbol, |
| 3 | strings: []const u8, | 3 | strings: []const u8, |
| 4 | text_vmaddr: u64, | 4 | text_vmaddr: u64, |
| 5 | uuid: ?Uuid, | ||
| 6 | adjacent_dsym: ?DsymFile, | ||
| 5 | 7 | ||
| 6 | /// Key is index into `strings` of the file path. | 8 | /// Key is index into `strings` of the file path. |
| 7 | ofiles: std.array_hash_map.Auto(u32, Error!OFile), | 9 | ofiles: std.array_hash_map.Auto(u32, Error!OFile), |
| ... | @@ -16,6 +18,7 @@ pub const Error = error{ | ... | @@ -16,6 +18,7 @@ pub const Error = error{ |
| 16 | }; | 18 | }; |
| 17 | 19 | ||
| 18 | pub fn deinit(mf: *MachOFile, gpa: Allocator) void { | 20 | pub fn deinit(mf: *MachOFile, gpa: Allocator) void { |
| 21 | if (mf.adjacent_dsym) |*dsym| dsym.deinit(gpa); | ||
| 19 | for (mf.ofiles.values()) |*maybe_of| { | 22 | for (mf.ofiles.values()) |*maybe_of| { |
| 20 | const of = &(maybe_of.* catch continue); | 23 | const of = &(maybe_of.* catch continue); |
| 21 | posix.munmap(of.mapped_memory); | 24 | posix.munmap(of.mapped_memory); |
| ... | @@ -36,48 +39,7 @@ pub fn load(gpa: Allocator, io: Io, path: []const u8, arch: std.Target.Cpu.Arch) | ... | @@ -36,48 +39,7 @@ pub fn load(gpa: Allocator, io: Io, path: []const u8, arch: std.Target.Cpu.Arch) |
| 36 | const all_mapped_memory = try mapDebugInfoFile(io, path); | 39 | const all_mapped_memory = try mapDebugInfoFile(io, path); |
| 37 | errdefer posix.munmap(all_mapped_memory); | 40 | errdefer posix.munmap(all_mapped_memory); |
| 38 | 41 | ||
| 39 | // In most cases, the file we just mapped is a Mach-O binary. However, it could be a "universal | 42 | const mapped_macho = try selectMachOSlice(all_mapped_memory, arch); |
| 40 | // binary": a simple file format which contains Mach-O binaries for multiple targets. For | ||
| 41 | // instance, `/usr/lib/dyld` is currently distributed as a universal binary containing images | ||
| 42 | // for both ARM64 macOS and x86_64 macOS. | ||
| 43 | if (all_mapped_memory.len < 4) return error.InvalidMachO; | ||
| 44 | const magic = std.mem.readInt(u32, all_mapped_memory.ptr[0..4], .little); | ||
| 45 | |||
| 46 | // The contents of a Mach-O file, which may or may not be the whole of `all_mapped_memory`. | ||
| 47 | const mapped_macho = switch (magic) { | ||
| 48 | macho.MH_MAGIC_64 => all_mapped_memory, | ||
| 49 | |||
| 50 | macho.FAT_CIGAM => mapped_macho: { | ||
| 51 | // This is the universal binary format (aka a "fat binary"). | ||
| 52 | var fat_r: Io.Reader = .fixed(all_mapped_memory); | ||
| 53 | const hdr = fat_r.takeStruct(macho.fat_header, .big) catch |err| switch (err) { | ||
| 54 | error.ReadFailed => unreachable, | ||
| 55 | error.EndOfStream => return error.InvalidMachO, | ||
| 56 | }; | ||
| 57 | const want_cpu_type = switch (arch) { | ||
| 58 | .x86_64 => macho.CPU_TYPE_X86_64, | ||
| 59 | .aarch64 => macho.CPU_TYPE_ARM64, | ||
| 60 | else => unreachable, | ||
| 61 | }; | ||
| 62 | for (0..hdr.nfat_arch) |_| { | ||
| 63 | const fat_arch = fat_r.takeStruct(macho.fat_arch, .big) catch |err| switch (err) { | ||
| 64 | error.ReadFailed => unreachable, | ||
| 65 | error.EndOfStream => return error.InvalidMachO, | ||
| 66 | }; | ||
| 67 | if (fat_arch.cputype != want_cpu_type) continue; | ||
| 68 | if (fat_arch.offset + fat_arch.size > all_mapped_memory.len) return error.InvalidMachO; | ||
| 69 | break :mapped_macho all_mapped_memory[fat_arch.offset..][0..fat_arch.size]; | ||
| 70 | } | ||
| 71 | // `arch` was not present in the fat binary. | ||
| 72 | return error.MissingDebugInfo; | ||
| 73 | }, | ||
| 74 | |||
| 75 | // Even on modern 64-bit targets, this format doesn't seem to be too extensively used. It | ||
| 76 | // will be fairly easy to add support here if necessary; it's very similar to above. | ||
| 77 | macho.FAT_CIGAM_64 => return error.UnsupportedDebugInfo, | ||
| 78 | |||
| 79 | else => return error.InvalidMachO, | ||
| 80 | }; | ||
| 81 | 43 | ||
| 82 | var r: Io.Reader = .fixed(mapped_macho); | 44 | var r: Io.Reader = .fixed(mapped_macho); |
| 83 | const hdr = r.takeStruct(macho.mach_header_64, .little) catch |err| switch (err) { | 45 | const hdr = r.takeStruct(macho.mach_header_64, .little) catch |err| switch (err) { |
| ... | @@ -88,21 +50,26 @@ pub fn load(gpa: Allocator, io: Io, path: []const u8, arch: std.Target.Cpu.Arch) | ... | @@ -88,21 +50,26 @@ pub fn load(gpa: Allocator, io: Io, path: []const u8, arch: std.Target.Cpu.Arch) |
| 88 | if (hdr.magic != macho.MH_MAGIC_64) | 50 | if (hdr.magic != macho.MH_MAGIC_64) |
| 89 | return error.InvalidMachO; | 51 | return error.InvalidMachO; |
| 90 | 52 | ||
| 91 | const symtab: macho.symtab_command, const text_vmaddr: u64 = lcs: { | 53 | const symtab: macho.symtab_command, const text_vmaddr: u64, const uuid: ?Uuid = lcs: { |
| 92 | var it: macho.LoadCommandIterator = try .init(&hdr, mapped_macho[@sizeOf(macho.mach_header_64)..]); | 54 | var it: macho.LoadCommandIterator = try .init(&hdr, mapped_macho[@sizeOf(macho.mach_header_64)..]); |
| 93 | var symtab: ?macho.symtab_command = null; | 55 | var symtab: ?macho.symtab_command = null; |
| 94 | var text_vmaddr: ?u64 = null; | 56 | var text_vmaddr: ?u64 = null; |
| 57 | var uuid: ?Uuid = null; | ||
| 95 | while (try it.next()) |cmd| switch (cmd.hdr.cmd) { | 58 | while (try it.next()) |cmd| switch (cmd.hdr.cmd) { |
| 96 | .SYMTAB => symtab = cmd.cast(macho.symtab_command) orelse return error.InvalidMachO, | 59 | .SYMTAB => symtab = cmd.cast(macho.symtab_command) orelse return error.InvalidMachO, |
| 97 | .SEGMENT_64 => if (cmd.cast(macho.segment_command_64)) |seg_cmd| { | 60 | .SEGMENT_64 => if (cmd.cast(macho.segment_command_64)) |seg_cmd| { |
| 98 | if (!mem.eql(u8, seg_cmd.segName(), "__TEXT")) continue; | 61 | if (!mem.eql(u8, seg_cmd.segName(), "__TEXT")) continue; |
| 99 | text_vmaddr = seg_cmd.vmaddr; | 62 | text_vmaddr = seg_cmd.vmaddr; |
| 100 | }, | 63 | }, |
| 64 | .UUID => if (cmd.cast(macho.uuid_command)) |uuid_cmd| { | ||
| 65 | uuid = uuid_cmd.uuid; | ||
| 66 | }, | ||
| 101 | else => {}, | 67 | else => {}, |
| 102 | }; | 68 | }; |
| 103 | break :lcs .{ | 69 | break :lcs .{ |
| 104 | symtab orelse return error.MissingDebugInfo, | 70 | symtab orelse return error.MissingDebugInfo, |
| 105 | text_vmaddr orelse return error.MissingDebugInfo, | 71 | text_vmaddr orelse return error.MissingDebugInfo, |
| 72 | uuid, | ||
| 106 | }; | 73 | }; |
| 107 | }; | 74 | }; |
| 108 | 75 | ||
| ... | @@ -253,15 +220,27 @@ pub fn load(gpa: Allocator, io: Io, path: []const u8, arch: std.Target.Cpu.Arch) | ... | @@ -253,15 +220,27 @@ pub fn load(gpa: Allocator, io: Io, path: []const u8, arch: std.Target.Cpu.Arch) |
| 253 | // This sort is so that we can binary search later. | 220 | // This sort is so that we can binary search later. |
| 254 | mem.sort(Symbol, symbols_slice, {}, Symbol.addressLessThan); | 221 | mem.sort(Symbol, symbols_slice, {}, Symbol.addressLessThan); |
| 255 | 222 | ||
| 223 | const adjacent_dsym = if (uuid) |expected_uuid| | ||
| 224 | try loadAdjacentDsym(gpa, io, path, arch, expected_uuid) | ||
| 225 | else | ||
| 226 | null; | ||
| 227 | |||
| 256 | return .{ | 228 | return .{ |
| 257 | .mapped_memory = all_mapped_memory, | 229 | .mapped_memory = all_mapped_memory, |
| 258 | .symbols = symbols_slice, | 230 | .symbols = symbols_slice, |
| 259 | .strings = strings, | 231 | .strings = strings, |
| 260 | .ofiles = .empty, | 232 | .ofiles = .empty, |
| 261 | .text_vmaddr = text_vmaddr, | 233 | .text_vmaddr = text_vmaddr, |
| 234 | .uuid = uuid, | ||
| 235 | .adjacent_dsym = adjacent_dsym, | ||
| 262 | }; | 236 | }; |
| 263 | } | 237 | } |
| 238 | |||
| 264 | pub fn getDwarfForAddress(mf: *MachOFile, gpa: Allocator, io: Io, vaddr: u64) !struct { *Dwarf, u64 } { | 239 | pub fn getDwarfForAddress(mf: *MachOFile, gpa: Allocator, io: Io, vaddr: u64) !struct { *Dwarf, u64 } { |
| 240 | if (mf.adjacent_dsym) |*dsym| { | ||
| 241 | return .{ &dsym.dwarf, vaddr }; | ||
| 242 | } | ||
| 243 | |||
| 265 | const symbol = Symbol.find(mf.symbols, vaddr) orelse return error.MissingDebugInfo; | 244 | const symbol = Symbol.find(mf.symbols, vaddr) orelse return error.MissingDebugInfo; |
| 266 | 245 | ||
| 267 | if (symbol.ofile == Symbol.unknown_ofile) return error.MissingDebugInfo; | 246 | if (symbol.ofile == Symbol.unknown_ofile) return error.MissingDebugInfo; |
| ... | @@ -324,6 +303,16 @@ const OFile = struct { | ... | @@ -324,6 +303,16 @@ const OFile = struct { |
| 324 | }; | 303 | }; |
| 325 | }; | 304 | }; |
| 326 | 305 | ||
| 306 | const DsymFile = struct { | ||
| 307 | mapped_memory: []align(std.heap.page_size_min) const u8, | ||
| 308 | dwarf: Dwarf, | ||
| 309 | |||
| 310 | fn deinit(df: *DsymFile, gpa: Allocator) void { | ||
| 311 | df.dwarf.deinit(gpa); | ||
| 312 | posix.munmap(df.mapped_memory); | ||
| 313 | } | ||
| 314 | }; | ||
| 315 | |||
| 327 | const Symbol = struct { | 316 | const Symbol = struct { |
| 328 | strx: u32, | 317 | strx: u32, |
| 329 | addr: u64, | 318 | addr: u64, |
| ... | @@ -394,6 +383,74 @@ fn appendStabSymbol( | ... | @@ -394,6 +383,74 @@ fn appendStabSymbol( |
| 394 | } | 383 | } |
| 395 | } | 384 | } |
| 396 | 385 | ||
| 386 | fn loadAdjacentDsym( | ||
| 387 | gpa: Allocator, | ||
| 388 | io: Io, | ||
| 389 | binary_path: []const u8, | ||
| 390 | arch: std.Target.Cpu.Arch, | ||
| 391 | uuid: Uuid, | ||
| 392 | ) Error!?DsymFile { | ||
| 393 | const s = std.fs.path.sep_str; | ||
| 394 | const dsym_path = try std.fmt.allocPrint( | ||
| 395 | gpa, | ||
| 396 | "{s}.dSYM" ++ s ++ "Contents" ++ s ++ "Resources" ++ s ++ "DWARF" ++ s ++ "{s}", | ||
| 397 | .{ binary_path, std.fs.path.basename(binary_path) }, | ||
| 398 | ); | ||
| 399 | defer gpa.free(dsym_path); | ||
| 400 | return loadDsymFile(gpa, io, dsym_path, arch, uuid) catch |err| switch (err) { | ||
| 401 | error.MissingDebugInfo, | ||
| 402 | error.InvalidMachO, | ||
| 403 | error.InvalidDwarf, | ||
| 404 | error.UnsupportedDebugInfo, | ||
| 405 | error.ReadFailed, | ||
| 406 | => null, | ||
| 407 | error.OutOfMemory => |e| return e, | ||
| 408 | }; | ||
| 409 | } | ||
| 410 | |||
| 411 | fn loadDsymFile( | ||
| 412 | gpa: Allocator, | ||
| 413 | io: Io, | ||
| 414 | path: []const u8, | ||
| 415 | arch: std.Target.Cpu.Arch, | ||
| 416 | expected_uuid: Uuid, | ||
| 417 | ) Error!DsymFile { | ||
| 418 | const all_mapped_memory = try mapDebugInfoFile(io, path); | ||
| 419 | errdefer posix.munmap(all_mapped_memory); | ||
| 420 | const mapped_macho = try selectMachOSlice(all_mapped_memory, arch); | ||
| 421 | |||
| 422 | var r: Io.Reader = .fixed(mapped_macho); | ||
| 423 | const hdr = r.takeStruct(macho.mach_header_64, .little) catch |err| switch (err) { | ||
| 424 | error.ReadFailed => unreachable, | ||
| 425 | error.EndOfStream => return error.InvalidMachO, | ||
| 426 | }; | ||
| 427 | if (hdr.magic != macho.MH_MAGIC_64) return error.InvalidMachO; | ||
| 428 | if (hdr.filetype != macho.MH_DSYM) return error.MissingDebugInfo; | ||
| 429 | |||
| 430 | var uuid: ?Uuid = null; | ||
| 431 | var dwarf_sections: ?[]align(1) const macho.section_64 = null; | ||
| 432 | |||
| 433 | var it: macho.LoadCommandIterator = try .init(&hdr, mapped_macho[@sizeOf(macho.mach_header_64)..]); | ||
| 434 | while (try it.next()) |lc| switch (lc.hdr.cmd) { | ||
| 435 | .SEGMENT_64 => if (lc.cast(macho.segment_command_64)) |seg_cmd| { | ||
| 436 | if (!mem.eql(u8, "__DWARF", seg_cmd.segName())) continue; | ||
| 437 | dwarf_sections = lc.getSections(); | ||
| 438 | }, | ||
| 439 | .UUID => if (lc.cast(macho.uuid_command)) |uuid_cmd| { | ||
| 440 | uuid = uuid_cmd.uuid; | ||
| 441 | }, | ||
| 442 | else => {}, | ||
| 443 | }; | ||
| 444 | |||
| 445 | const actual_uuid = uuid orelse return error.MissingDebugInfo; | ||
| 446 | if (!mem.eql(u8, &actual_uuid, &expected_uuid)) return error.MissingDebugInfo; | ||
| 447 | |||
| 448 | return .{ | ||
| 449 | .mapped_memory = all_mapped_memory, | ||
| 450 | .dwarf = try loadDwarfFromSections(gpa, mapped_macho, dwarf_sections orelse return error.MissingDebugInfo), | ||
| 451 | }; | ||
| 452 | } | ||
| 453 | |||
| 397 | fn loadOFile(gpa: Allocator, io: Io, o_file_name: []const u8) !OFile { | 454 | fn loadOFile(gpa: Allocator, io: Io, o_file_name: []const u8) !OFile { |
| 398 | const all_mapped_memory, const mapped_ofile = map: { | 455 | const all_mapped_memory, const mapped_ofile = map: { |
| 399 | const open_paren = paren: { | 456 | const open_paren = paren: { |
| ... | @@ -497,19 +554,38 @@ fn loadOFile(gpa: Allocator, io: Io, o_file_name: []const u8) !OFile { | ... | @@ -497,19 +554,38 @@ fn loadOFile(gpa: Allocator, io: Io, o_file_name: []const u8) !OFile { |
| 497 | gop.key_ptr.* = @intCast(sym_index); | 554 | gop.key_ptr.* = @intCast(sym_index); |
| 498 | } | 555 | } |
| 499 | 556 | ||
| 557 | const dwarf = try loadDwarfFromSections(gpa, mapped_ofile, seg_cmd.getSections()); | ||
| 558 | |||
| 559 | return .{ | ||
| 560 | .mapped_memory = all_mapped_memory, | ||
| 561 | .dwarf = dwarf, | ||
| 562 | .strtab = strtab, | ||
| 563 | .symtab_raw = symtab_raw, | ||
| 564 | .symbols_by_name = symbols_by_name.move(), | ||
| 565 | }; | ||
| 566 | } | ||
| 567 | |||
| 568 | fn loadDwarfFromSections( | ||
| 569 | gpa: Allocator, | ||
| 570 | mapped_macho: []const u8, | ||
| 571 | section_headers: []align(1) const macho.section_64, | ||
| 572 | ) !Dwarf { | ||
| 500 | var sections: Dwarf.SectionArray = @splat(null); | 573 | var sections: Dwarf.SectionArray = @splat(null); |
| 501 | for (seg_cmd.getSections()) |sect_raw| { | 574 | for (section_headers) |sect_raw| { |
| 502 | var sect = sect_raw; | 575 | var sect = sect_raw; |
| 503 | if (builtin.cpu.arch.endian() != .little) std.mem.byteSwapAllFields(macho.section_64, &sect); | 576 | if (builtin.cpu.arch.endian() != .little) std.mem.byteSwapAllFields(macho.section_64, &sect); |
| 504 | 577 | ||
| 505 | if (!std.mem.eql(u8, "__DWARF", sect.segName())) continue; | 578 | if (!std.mem.eql(u8, "__DWARF", sect.segName())) continue; |
| 506 | 579 | ||
| 507 | const section_index: usize = inline for (@typeInfo(Dwarf.Section.Id).@"enum".field_names, 0..) |section_name, i| { | 580 | const section_index: usize = inline for (@typeInfo(Dwarf.Section.Id).@"enum".field_names, 0..) |field_name, i| { |
| 508 | if (mem.eql(u8, "__" ++ section_name, sect.sectName())) break i; | 581 | const section_name_long = "__" ++ field_name; |
| 582 | // Some dwarf section names don't fit in the `sectname` buffer, so they are truncated. | ||
| 583 | const section_name_trunc = section_name_long[0..@min(section_name_long.len, sect.sectname.len)]; | ||
| 584 | if (mem.eql(u8, section_name_trunc, sect.sectName())) break i; | ||
| 509 | } else continue; | 585 | } else continue; |
| 510 | 586 | ||
| 511 | if (mapped_ofile.len < sect.offset + sect.size) return error.InvalidMachO; | 587 | if (mapped_macho.len < sect.offset + sect.size) return error.InvalidMachO; |
| 512 | const section_bytes = mapped_ofile[sect.offset..][0..sect.size]; | 588 | const section_bytes = mapped_macho[sect.offset..][0..sect.size]; |
| 513 | sections[section_index] = .{ | 589 | sections[section_index] = .{ |
| 514 | .data = section_bytes, | 590 | .data = section_bytes, |
| 515 | .owned = false, | 591 | .owned = false, |
| ... | @@ -539,13 +615,56 @@ fn loadOFile(gpa: Allocator, io: Io, o_file_name: []const u8) !OFile { | ... | @@ -539,13 +615,56 @@ fn loadOFile(gpa: Allocator, io: Io, o_file_name: []const u8) !OFile { |
| 539 | => |e| return e, | 615 | => |e| return e, |
| 540 | }; | 616 | }; |
| 541 | 617 | ||
| 542 | return .{ | 618 | return dwarf; |
| 543 | .mapped_memory = all_mapped_memory, | 619 | } |
| 544 | .dwarf = dwarf, | 620 | |
| 545 | .strtab = strtab, | 621 | fn selectMachOSlice( |
| 546 | .symtab_raw = symtab_raw, | 622 | all_mapped_memory: []align(std.heap.page_size_min) const u8, |
| 547 | .symbols_by_name = symbols_by_name.move(), | 623 | arch: std.Target.Cpu.Arch, |
| 624 | ) Error![]const u8 { | ||
| 625 | // In most cases, the file we just mapped is a Mach-O binary. However, it could be a "universal | ||
| 626 | // binary": a simple file format which contains Mach-O binaries for multiple targets. For | ||
| 627 | // instance, `/usr/lib/dyld` is currently distributed as a universal binary containing images | ||
| 628 | // for both ARM64 macOS and x86_64 macOS. | ||
| 629 | if (all_mapped_memory.len < 4) return error.InvalidMachO; | ||
| 630 | const magic = std.mem.readInt(u32, all_mapped_memory.ptr[0..4], .little); | ||
| 631 | |||
| 632 | // The contents of a Mach-O file, which may or may not be the whole of `all_mapped_memory`. | ||
| 633 | const mapped_macho = switch (magic) { | ||
| 634 | macho.MH_MAGIC_64 => all_mapped_memory, | ||
| 635 | |||
| 636 | macho.FAT_CIGAM => mapped_macho: { | ||
| 637 | // This is the universal binary format (aka a "fat binary"). | ||
| 638 | var fat_r: Io.Reader = .fixed(all_mapped_memory); | ||
| 639 | const hdr = fat_r.takeStruct(macho.fat_header, .big) catch |err| switch (err) { | ||
| 640 | error.ReadFailed => unreachable, | ||
| 641 | error.EndOfStream => return error.InvalidMachO, | ||
| 642 | }; | ||
| 643 | const want_cpu_type = switch (arch) { | ||
| 644 | .x86_64 => macho.CPU_TYPE_X86_64, | ||
| 645 | .aarch64 => macho.CPU_TYPE_ARM64, | ||
| 646 | else => unreachable, | ||
| 647 | }; | ||
| 648 | for (0..hdr.nfat_arch) |_| { | ||
| 649 | const fat_arch = fat_r.takeStruct(macho.fat_arch, .big) catch |err| switch (err) { | ||
| 650 | error.ReadFailed => unreachable, | ||
| 651 | error.EndOfStream => return error.InvalidMachO, | ||
| 652 | }; | ||
| 653 | if (fat_arch.cputype != want_cpu_type) continue; | ||
| 654 | if (fat_arch.offset + fat_arch.size > all_mapped_memory.len) return error.InvalidMachO; | ||
| 655 | break :mapped_macho all_mapped_memory[fat_arch.offset..][0..fat_arch.size]; | ||
| 656 | } | ||
| 657 | // `arch` was not present in the fat binary. | ||
| 658 | return error.MissingDebugInfo; | ||
| 659 | }, | ||
| 660 | |||
| 661 | // Even on modern 64-bit targets, this format doesn't seem to be too extensively used. It | ||
| 662 | // will be fairly easy to add support here if necessary; it's very similar to above. | ||
| 663 | macho.FAT_CIGAM_64 => return error.UnsupportedDebugInfo, | ||
| 664 | |||
| 665 | else => return error.InvalidMachO, | ||
| 548 | }; | 666 | }; |
| 667 | return mapped_macho; | ||
| 549 | } | 668 | } |
| 550 | 669 | ||
| 551 | /// Uses `mmap` to map the file at `path` into memory. | 670 | /// Uses `mmap` to map the file at `path` into memory. |
| ... | @@ -583,4 +702,5 @@ const testing = std.testing; | ... | @@ -583,4 +702,5 @@ const testing = std.testing; |
| 583 | 702 | ||
| 584 | const builtin = @import("builtin"); | 703 | const builtin = @import("builtin"); |
| 585 | 704 | ||
| 705 | const Uuid = @FieldType(macho.uuid_command, "uuid"); | ||
| 586 | const MachOFile = @This(); | 706 | const MachOFile = @This(); |
lib/std/debug/SelfInfo/Elf.zig+4-1| ... | @@ -428,6 +428,9 @@ fn findModule(si: *SelfInfo, gpa: Allocator, io: Io, address: usize, lock: enum | ... | @@ -428,6 +428,9 @@ fn findModule(si: *SelfInfo, gpa: Allocator, io: Io, address: usize, lock: enum |
| 428 | // Rebuild module list with the exclusive lock. | 428 | // Rebuild module list with the exclusive lock. |
| 429 | { | 429 | { |
| 430 | errdefer si.rwlock.unlock(io); | 430 | errdefer si.rwlock.unlock(io); |
| 431 | if (si.unwind_cache) |cache| { | ||
| 432 | @memset(cache, .empty); | ||
| 433 | } | ||
| 431 | for (si.modules.items) |*mod| { | 434 | for (si.modules.items) |*mod| { |
| 432 | unwind: { | 435 | unwind: { |
| 433 | const u = &(mod.unwind orelse break :unwind catch break :unwind); | 436 | const u = &(mod.unwind orelse break :unwind catch break :unwind); |
| ... | @@ -515,7 +518,7 @@ const DlIterContext = struct { | ... | @@ -515,7 +518,7 @@ const DlIterContext = struct { |
| 515 | for (info.phdr[0..info.phnum]) |phdr| { | 518 | for (info.phdr[0..info.phnum]) |phdr| { |
| 516 | if (phdr.type != .LOAD) continue; | 519 | if (phdr.type != .LOAD) continue; |
| 517 | try context.si.ranges.append(gpa, .{ | 520 | try context.si.ranges.append(gpa, .{ |
| 518 | // Overflowing addition handles VSDOs having p_vaddr = 0xffffffffff700000 | 521 | // Overflowing addition handles VSDOs having vaddr = 0xffffffffff700000 |
| 519 | .start = info.addr +% phdr.vaddr, | 522 | .start = info.addr +% phdr.vaddr, |
| 520 | .len = phdr.memsz, | 523 | .len = phdr.memsz, |
| 521 | .module_index = module_index, | 524 | .module_index = module_index, |
lib/std/debug/cpu_context.zig+2| ... | @@ -2020,6 +2020,8 @@ const signal_ucontext_t = switch (native_os) { | ... | @@ -2020,6 +2020,8 @@ const signal_ucontext_t = switch (native_os) { |
| 2020 | .mips64el, | 2020 | .mips64el, |
| 2021 | .or1k, | 2021 | .or1k, |
| 2022 | .s390x, | 2022 | .s390x, |
| 2023 | .sh, | ||
| 2024 | .sheb, | ||
| 2023 | .x86, | 2025 | .x86, |
| 2024 | .x86_64, | 2026 | .x86_64, |
| 2025 | .xtensa, | 2027 | .xtensa, |
lib/std/debug/no_panic.zig+10| ... | @@ -65,6 +65,11 @@ pub fn invalidErrorCode() noreturn { | ... | @@ -65,6 +65,11 @@ pub fn invalidErrorCode() noreturn { |
| 65 | @trap(); | 65 | @trap(); |
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | pub fn unexpectedErrorCode(_: anyerror) noreturn { | ||
| 69 | @branchHint(.cold); | ||
| 70 | @trap(); | ||
| 71 | } | ||
| 72 | |||
| 68 | pub fn integerOutOfBounds() noreturn { | 73 | pub fn integerOutOfBounds() noreturn { |
| 69 | @branchHint(.cold); | 74 | @branchHint(.cold); |
| 70 | @trap(); | 75 | @trap(); |
| ... | @@ -134,3 +139,8 @@ pub fn noreturnReturned() noreturn { | ... | @@ -134,3 +139,8 @@ pub fn noreturnReturned() noreturn { |
| 134 | @branchHint(.cold); | 139 | @branchHint(.cold); |
| 135 | @trap(); | 140 | @trap(); |
| 136 | } | 141 | } |
| 142 | |||
| 143 | pub fn loadUninstantiableType() noreturn { | ||
| 144 | @branchHint(.cold); | ||
| 145 | @trap(); | ||
| 146 | } |
lib/std/debug/simple_panic.zig+35| ... | @@ -20,109 +20,144 @@ pub fn call(msg: []const u8, ra: ?usize) noreturn { | ... | @@ -20,109 +20,144 @@ pub fn call(msg: []const u8, ra: ?usize) noreturn { |
| 20 | } | 20 | } |
| 21 | 21 | ||
| 22 | pub fn sentinelMismatch(expected: anytype, found: @TypeOf(expected)) noreturn { | 22 | pub fn sentinelMismatch(expected: anytype, found: @TypeOf(expected)) noreturn { |
| 23 | @branchHint(.cold); | ||
| 23 | _ = found; | 24 | _ = found; |
| 24 | call("sentinel mismatch", null); | 25 | call("sentinel mismatch", null); |
| 25 | } | 26 | } |
| 26 | 27 | ||
| 27 | pub fn unwrapError(err: anyerror) noreturn { | 28 | pub fn unwrapError(err: anyerror) noreturn { |
| 29 | @branchHint(.cold); | ||
| 28 | _ = &err; | 30 | _ = &err; |
| 29 | call("attempt to unwrap error", null); | 31 | call("attempt to unwrap error", null); |
| 30 | } | 32 | } |
| 31 | 33 | ||
| 32 | pub fn outOfBounds(index: usize, len: usize) noreturn { | 34 | pub fn outOfBounds(index: usize, len: usize) noreturn { |
| 35 | @branchHint(.cold); | ||
| 33 | _ = index; | 36 | _ = index; |
| 34 | _ = len; | 37 | _ = len; |
| 35 | call("index out of bounds", null); | 38 | call("index out of bounds", null); |
| 36 | } | 39 | } |
| 37 | 40 | ||
| 38 | pub fn startGreaterThanEnd(start: usize, end: usize) noreturn { | 41 | pub fn startGreaterThanEnd(start: usize, end: usize) noreturn { |
| 42 | @branchHint(.cold); | ||
| 39 | _ = start; | 43 | _ = start; |
| 40 | _ = end; | 44 | _ = end; |
| 41 | call("start index is larger than end index", null); | 45 | call("start index is larger than end index", null); |
| 42 | } | 46 | } |
| 43 | 47 | ||
| 44 | pub fn inactiveUnionField(active: anytype, accessed: @TypeOf(active)) noreturn { | 48 | pub fn inactiveUnionField(active: anytype, accessed: @TypeOf(active)) noreturn { |
| 49 | @branchHint(.cold); | ||
| 45 | _ = accessed; | 50 | _ = accessed; |
| 46 | call("access of inactive union field", null); | 51 | call("access of inactive union field", null); |
| 47 | } | 52 | } |
| 48 | 53 | ||
| 49 | pub fn sliceCastLenRemainder(src_len: usize) noreturn { | 54 | pub fn sliceCastLenRemainder(src_len: usize) noreturn { |
| 55 | @branchHint(.cold); | ||
| 50 | _ = src_len; | 56 | _ = src_len; |
| 51 | call("slice length does not divide exactly into destination elements", null); | 57 | call("slice length does not divide exactly into destination elements", null); |
| 52 | } | 58 | } |
| 53 | 59 | ||
| 54 | pub fn reachedUnreachable() noreturn { | 60 | pub fn reachedUnreachable() noreturn { |
| 61 | @branchHint(.cold); | ||
| 55 | call("reached unreachable code", null); | 62 | call("reached unreachable code", null); |
| 56 | } | 63 | } |
| 57 | 64 | ||
| 58 | pub fn unwrapNull() noreturn { | 65 | pub fn unwrapNull() noreturn { |
| 66 | @branchHint(.cold); | ||
| 59 | call("attempt to use null value", null); | 67 | call("attempt to use null value", null); |
| 60 | } | 68 | } |
| 61 | 69 | ||
| 62 | pub fn castToNull() noreturn { | 70 | pub fn castToNull() noreturn { |
| 71 | @branchHint(.cold); | ||
| 63 | call("cast causes pointer to be null", null); | 72 | call("cast causes pointer to be null", null); |
| 64 | } | 73 | } |
| 65 | 74 | ||
| 66 | pub fn incorrectAlignment() noreturn { | 75 | pub fn incorrectAlignment() noreturn { |
| 76 | @branchHint(.cold); | ||
| 67 | call("incorrect alignment", null); | 77 | call("incorrect alignment", null); |
| 68 | } | 78 | } |
| 69 | 79 | ||
| 70 | pub fn invalidErrorCode() noreturn { | 80 | pub fn invalidErrorCode() noreturn { |
| 81 | @branchHint(.cold); | ||
| 71 | call("invalid error code", null); | 82 | call("invalid error code", null); |
| 72 | } | 83 | } |
| 73 | 84 | ||
| 85 | pub fn unexpectedErrorCode(err: anyerror) noreturn { | ||
| 86 | @branchHint(.cold); | ||
| 87 | _ = err; | ||
| 88 | call("unexpected error code", null); | ||
| 89 | } | ||
| 90 | |||
| 74 | pub fn integerOutOfBounds() noreturn { | 91 | pub fn integerOutOfBounds() noreturn { |
| 92 | @branchHint(.cold); | ||
| 75 | call("integer does not fit in destination type", null); | 93 | call("integer does not fit in destination type", null); |
| 76 | } | 94 | } |
| 77 | 95 | ||
| 78 | pub fn integerOverflow() noreturn { | 96 | pub fn integerOverflow() noreturn { |
| 97 | @branchHint(.cold); | ||
| 79 | call("integer overflow", null); | 98 | call("integer overflow", null); |
| 80 | } | 99 | } |
| 81 | 100 | ||
| 82 | pub fn shlOverflow() noreturn { | 101 | pub fn shlOverflow() noreturn { |
| 102 | @branchHint(.cold); | ||
| 83 | call("left shift overflowed bits", null); | 103 | call("left shift overflowed bits", null); |
| 84 | } | 104 | } |
| 85 | 105 | ||
| 86 | pub fn shrOverflow() noreturn { | 106 | pub fn shrOverflow() noreturn { |
| 107 | @branchHint(.cold); | ||
| 87 | call("right shift overflowed bits", null); | 108 | call("right shift overflowed bits", null); |
| 88 | } | 109 | } |
| 89 | 110 | ||
| 90 | pub fn divideByZero() noreturn { | 111 | pub fn divideByZero() noreturn { |
| 112 | @branchHint(.cold); | ||
| 91 | call("division by zero", null); | 113 | call("division by zero", null); |
| 92 | } | 114 | } |
| 93 | 115 | ||
| 94 | pub fn exactDivisionRemainder() noreturn { | 116 | pub fn exactDivisionRemainder() noreturn { |
| 117 | @branchHint(.cold); | ||
| 95 | call("exact division produced remainder", null); | 118 | call("exact division produced remainder", null); |
| 96 | } | 119 | } |
| 97 | 120 | ||
| 98 | pub fn integerPartOutOfBounds() noreturn { | 121 | pub fn integerPartOutOfBounds() noreturn { |
| 122 | @branchHint(.cold); | ||
| 99 | call("integer part of floating point value out of bounds", null); | 123 | call("integer part of floating point value out of bounds", null); |
| 100 | } | 124 | } |
| 101 | 125 | ||
| 102 | pub fn corruptSwitch() noreturn { | 126 | pub fn corruptSwitch() noreturn { |
| 127 | @branchHint(.cold); | ||
| 103 | call("switch on corrupt value", null); | 128 | call("switch on corrupt value", null); |
| 104 | } | 129 | } |
| 105 | 130 | ||
| 106 | pub fn shiftRhsTooBig() noreturn { | 131 | pub fn shiftRhsTooBig() noreturn { |
| 132 | @branchHint(.cold); | ||
| 107 | call("shift amount is greater than the type size", null); | 133 | call("shift amount is greater than the type size", null); |
| 108 | } | 134 | } |
| 109 | 135 | ||
| 110 | pub fn invalidEnumValue() noreturn { | 136 | pub fn invalidEnumValue() noreturn { |
| 137 | @branchHint(.cold); | ||
| 111 | call("invalid enum value", null); | 138 | call("invalid enum value", null); |
| 112 | } | 139 | } |
| 113 | 140 | ||
| 114 | pub fn forLenMismatch() noreturn { | 141 | pub fn forLenMismatch() noreturn { |
| 142 | @branchHint(.cold); | ||
| 115 | call("for loop over objects with non-equal lengths", null); | 143 | call("for loop over objects with non-equal lengths", null); |
| 116 | } | 144 | } |
| 117 | 145 | ||
| 118 | pub fn copyLenMismatch() noreturn { | 146 | pub fn copyLenMismatch() noreturn { |
| 147 | @branchHint(.cold); | ||
| 119 | call("source and destination have non-equal lengths", null); | 148 | call("source and destination have non-equal lengths", null); |
| 120 | } | 149 | } |
| 121 | 150 | ||
| 122 | pub fn memcpyAlias() noreturn { | 151 | pub fn memcpyAlias() noreturn { |
| 152 | @branchHint(.cold); | ||
| 123 | call("@memcpy arguments alias", null); | 153 | call("@memcpy arguments alias", null); |
| 124 | } | 154 | } |
| 125 | 155 | ||
| 126 | pub fn noreturnReturned() noreturn { | 156 | pub fn noreturnReturned() noreturn { |
| 157 | @branchHint(.cold); | ||
| 127 | call("'noreturn' function returned", null); | 158 | call("'noreturn' function returned", null); |
| 128 | } | 159 | } |
| 160 | |||
| 161 | pub fn loadUninstantiableType() noreturn { | ||
| 162 | call("attempt to load uninstantiable type", null); | ||
| 163 | } |
lib/std/deque.zig+1-1| ... | @@ -696,7 +696,7 @@ fn fuzzAgainstArrayList(_: void, smith: *std.testing.Smith) anyerror!void { | ... | @@ -696,7 +696,7 @@ fn fuzzAgainstArrayList(_: void, smith: *std.testing.Smith) anyerror!void { |
| 696 | try q.ensureTotalCapacityPrecise(q_gpa, q.len + growth); | 696 | try q.ensureTotalCapacityPrecise(q_gpa, q.len + growth); |
| 697 | }, | 697 | }, |
| 698 | } | 698 | } |
| 699 | try testing.expectEqual(l.getLast(), q.back()); | 699 | try testing.expectEqual(l.last(), q.back()); |
| 700 | try testing.expectEqual( | 700 | try testing.expectEqual( |
| 701 | if (l.items.len > 0) l.items[0] else null, | 701 | if (l.items.len > 0) l.items[0] else null, |
| 702 | q.front(), | 702 | q.front(), |
lib/std/dynamic_library.zig+17-17| ... | @@ -103,7 +103,7 @@ pub fn get_DYNAMIC() ?[*]const elf.Dyn { | ... | @@ -103,7 +103,7 @@ pub fn get_DYNAMIC() ?[*]const elf.Dyn { |
| 103 | 103 | ||
| 104 | pub fn linkmap_iterator() error{InvalidExe}!LinkMap.Iterator { | 104 | pub fn linkmap_iterator() error{InvalidExe}!LinkMap.Iterator { |
| 105 | const _DYNAMIC = get_DYNAMIC() orelse { | 105 | const _DYNAMIC = get_DYNAMIC() orelse { |
| 106 | // No PT_DYNAMIC means this is a statically-linked non-PIE program. | 106 | // No PT.DYNAMIC means this is a statically-linked non-PIE program. |
| 107 | return .{ .current = null }; | 107 | return .{ .current = null }; |
| 108 | }; | 108 | }; |
| 109 | 109 | ||
| ... | @@ -261,10 +261,10 @@ pub const ElfDynLib = struct { | ... | @@ -261,10 +261,10 @@ pub const ElfDynLib = struct { |
| 261 | i += 1; | 261 | i += 1; |
| 262 | ph_addr += eh.e_phentsize; | 262 | ph_addr += eh.e_phentsize; |
| 263 | }) { | 263 | }) { |
| 264 | const ph = @as(*elf.Phdr, @ptrFromInt(ph_addr)); | 264 | const ph = @as(*elf.ElfN.Phdr, @ptrFromInt(ph_addr)); |
| 265 | switch (ph.p_type) { | 265 | switch (ph.type) { |
| 266 | elf.PT_LOAD => virt_addr_end = @max(virt_addr_end, ph.p_vaddr + ph.p_memsz), | 266 | .LOAD => virt_addr_end = @max(virt_addr_end, ph.vaddr + ph.memsz), |
| 267 | elf.PT_DYNAMIC => maybe_dynv = @as([*]usize, @ptrFromInt(elf_addr + ph.p_offset)), | 267 | .DYNAMIC => maybe_dynv = @as([*]usize, @ptrFromInt(elf_addr + ph.offset)), |
| 268 | else => {}, | 268 | else => {}, |
| 269 | } | 269 | } |
| 270 | } | 270 | } |
| ... | @@ -292,23 +292,23 @@ pub const ElfDynLib = struct { | ... | @@ -292,23 +292,23 @@ pub const ElfDynLib = struct { |
| 292 | i += 1; | 292 | i += 1; |
| 293 | ph_addr += eh.e_phentsize; | 293 | ph_addr += eh.e_phentsize; |
| 294 | }) { | 294 | }) { |
| 295 | const ph = @as(*elf.Phdr, @ptrFromInt(ph_addr)); | 295 | const ph = @as(*elf.ElfN.Phdr, @ptrFromInt(ph_addr)); |
| 296 | switch (ph.p_type) { | 296 | switch (ph.type) { |
| 297 | elf.PT_LOAD => { | 297 | .LOAD => { |
| 298 | // The VirtAddr may not be page-aligned; in such case there will be | 298 | // The VirtAddr may not be page-aligned; in such case there will be |
| 299 | // extra nonsense mapped before/after the VirtAddr,MemSiz | 299 | // extra nonsense mapped before/after the VirtAddr,MemSiz |
| 300 | const aligned_addr = (base + ph.p_vaddr) & ~(@as(usize, page_size) - 1); | 300 | const aligned_addr = (base + ph.vaddr) & ~(@as(usize, page_size) - 1); |
| 301 | const extra_bytes = (base + ph.p_vaddr) - aligned_addr; | 301 | const extra_bytes = (base + ph.vaddr) - aligned_addr; |
| 302 | const extended_memsz = mem.alignForward(usize, ph.p_memsz + extra_bytes, page_size); | 302 | const extended_memsz = mem.alignForward(usize, ph.memsz + extra_bytes, page_size); |
| 303 | const ptr = @as([*]align(std.heap.page_size_min) u8, @ptrFromInt(aligned_addr)); | 303 | const ptr = @as([*]align(std.heap.page_size_min) u8, @ptrFromInt(aligned_addr)); |
| 304 | const prot = elfToProt(ph.p_flags); | 304 | const prot = elfToProt(ph.flags); |
| 305 | _ = try posix.mmap( | 305 | _ = try posix.mmap( |
| 306 | ptr, | 306 | ptr, |
| 307 | extended_memsz, | 307 | extended_memsz, |
| 308 | prot, | 308 | prot, |
| 309 | .{ .TYPE = .PRIVATE, .FIXED = true }, | 309 | .{ .TYPE = .PRIVATE, .FIXED = true }, |
| 310 | file.handle, | 310 | file.handle, |
| 311 | ph.p_offset - extra_bytes, | 311 | ph.offset - extra_bytes, |
| 312 | ); | 312 | ); |
| 313 | }, | 313 | }, |
| 314 | else => {}, | 314 | else => {}, |
| ... | @@ -517,11 +517,11 @@ pub const ElfDynLib = struct { | ... | @@ -517,11 +517,11 @@ pub const ElfDynLib = struct { |
| 517 | return null; | 517 | return null; |
| 518 | } | 518 | } |
| 519 | 519 | ||
| 520 | fn elfToProt(elf_prot: u64) posix.PROT { | 520 | fn elfToProt(elf_prot: elf.PF) posix.PROT { |
| 521 | return .{ | 521 | return .{ |
| 522 | .READ = (elf_prot & elf.PF_R) != 0, | 522 | .READ = elf_prot.R, |
| 523 | .WRITE = (elf_prot & elf.PF_W) != 0, | 523 | .WRITE = elf_prot.W, |
| 524 | .EXEC = (elf_prot & elf.PF_X) != 0, | 524 | .EXEC = elf_prot.X, |
| 525 | }; | 525 | }; |
| 526 | } | 526 | } |
| 527 | }; | 527 | }; |
lib/std/elf.zig+19-88| ... | @@ -290,47 +290,6 @@ pub const VER_FLG_BASE = 1; | ... | @@ -290,47 +290,6 @@ pub const VER_FLG_BASE = 1; |
| 290 | /// Weak version identifier | 290 | /// Weak version identifier |
| 291 | pub const VER_FLG_WEAK = 2; | 291 | pub const VER_FLG_WEAK = 2; |
| 292 | 292 | ||
| 293 | /// Deprecated, use `@intFromEnum(std.elf.PT.NULL)` | ||
| 294 | pub const PT_NULL = @backingInt(std.elf.PT.NULL); | ||
| 295 | /// Deprecated, use `@intFromEnum(std.elf.PT.LOAD)` | ||
| 296 | pub const PT_LOAD = @backingInt(std.elf.PT.LOAD); | ||
| 297 | /// Deprecated, use `@intFromEnum(std.elf.PT.DYNAMIC)` | ||
| 298 | pub const PT_DYNAMIC = @backingInt(std.elf.PT.DYNAMIC); | ||
| 299 | /// Deprecated, use `@intFromEnum(std.elf.PT.INTERP)` | ||
| 300 | pub const PT_INTERP = @backingInt(std.elf.PT.INTERP); | ||
| 301 | /// Deprecated, use `@intFromEnum(std.elf.PT.NOTE)` | ||
| 302 | pub const PT_NOTE = @backingInt(std.elf.PT.NOTE); | ||
| 303 | /// Deprecated, use `@intFromEnum(std.elf.PT.SHLIB)` | ||
| 304 | pub const PT_SHLIB = @backingInt(std.elf.PT.SHLIB); | ||
| 305 | /// Deprecated, use `@intFromEnum(std.elf.PT.PHDR)` | ||
| 306 | pub const PT_PHDR = @backingInt(std.elf.PT.PHDR); | ||
| 307 | /// Deprecated, use `@intFromEnum(std.elf.PT.TLS)` | ||
| 308 | pub const PT_TLS = @backingInt(std.elf.PT.TLS); | ||
| 309 | /// Deprecated, use `std.elf.PT.NUM`. | ||
| 310 | pub const PT_NUM = PT.NUM; | ||
| 311 | /// Deprecated, use `@intFromEnum(std.elf.PT.LOOS)` | ||
| 312 | pub const PT_LOOS = @backingInt(std.elf.PT.LOOS); | ||
| 313 | /// Deprecated, use `@intFromEnum(std.elf.PT.GNU_EH_FRAME)` | ||
| 314 | pub const PT_GNU_EH_FRAME = @backingInt(std.elf.PT.GNU_EH_FRAME); | ||
| 315 | /// Deprecated, use `@intFromEnum(std.elf.PT.GNU_STACK)` | ||
| 316 | pub const PT_GNU_STACK = @backingInt(std.elf.PT.GNU_STACK); | ||
| 317 | /// Deprecated, use `@intFromEnum(std.elf.PT.GNU_RELRO)` | ||
| 318 | pub const PT_GNU_RELRO = @backingInt(std.elf.PT.GNU_RELRO); | ||
| 319 | /// Deprecated, use `@intFromEnum(std.elf.PT.LOSUNW)` | ||
| 320 | pub const PT_LOSUNW = @backingInt(std.elf.PT.LOSUNW); | ||
| 321 | /// Deprecated, use `@intFromEnum(std.elf.PT.SUNWBSS)` | ||
| 322 | pub const PT_SUNWBSS = @backingInt(std.elf.PT.SUNWBSS); | ||
| 323 | /// Deprecated, use `@intFromEnum(std.elf.PT.SUNWSTACK)` | ||
| 324 | pub const PT_SUNWSTACK = @backingInt(std.elf.PT.SUNWSTACK); | ||
| 325 | /// Deprecated, use `@intFromEnum(std.elf.PT.HISUNW)` | ||
| 326 | pub const PT_HISUNW = @backingInt(std.elf.PT.HISUNW); | ||
| 327 | /// Deprecated, use `@intFromEnum(std.elf.PT.HIOS)` | ||
| 328 | pub const PT_HIOS = @backingInt(std.elf.PT.HIOS); | ||
| 329 | /// Deprecated, use `@intFromEnum(std.elf.PT.LOPROC)` | ||
| 330 | pub const PT_LOPROC = @backingInt(std.elf.PT.LOPROC); | ||
| 331 | /// Deprecated, use `@intFromEnum(std.elf.PT.HIPROC)` | ||
| 332 | pub const PT_HIPROC = @backingInt(std.elf.PT.HIPROC); | ||
| 333 | |||
| 334 | pub const PN_XNUM = 0xffff; | 293 | pub const PN_XNUM = 0xffff; |
| 335 | 294 | ||
| 336 | /// Deprecated, use `@intFromEnum(std.elf.SHT.NULL)` | 295 | /// Deprecated, use `@intFromEnum(std.elf.SHT.NULL)` |
| ... | @@ -848,11 +807,11 @@ pub const ProgramHeaderIterator = struct { | ... | @@ -848,11 +807,11 @@ pub const ProgramHeaderIterator = struct { |
| 848 | file_reader: *Io.File.Reader, | 807 | file_reader: *Io.File.Reader, |
| 849 | index: usize = 0, | 808 | index: usize = 0, |
| 850 | 809 | ||
| 851 | pub fn next(it: *ProgramHeaderIterator) !?Elf64_Phdr { | 810 | pub fn next(it: *ProgramHeaderIterator) !?Elf64.Phdr { |
| 852 | if (it.index >= it.phnum) return null; | 811 | if (it.index >= it.phnum) return null; |
| 853 | defer it.index += 1; | 812 | defer it.index += 1; |
| 854 | 813 | ||
| 855 | const size: u64 = if (it.is_64) @sizeOf(Elf64_Phdr) else @sizeOf(Elf32_Phdr); | 814 | const size: u64 = if (it.is_64) @sizeOf(Elf64.Phdr) else @sizeOf(Elf32.Phdr); |
| 856 | const offset = it.phoff + size * it.index; | 815 | const offset = it.phoff + size * it.index; |
| 857 | try it.file_reader.seekTo(offset); | 816 | try it.file_reader.seekTo(offset); |
| 858 | 817 | ||
| ... | @@ -869,11 +828,11 @@ pub const ProgramHeaderBufferIterator = struct { | ... | @@ -869,11 +828,11 @@ pub const ProgramHeaderBufferIterator = struct { |
| 869 | buf: []const u8, | 828 | buf: []const u8, |
| 870 | index: usize = 0, | 829 | index: usize = 0, |
| 871 | 830 | ||
| 872 | pub fn next(it: *ProgramHeaderBufferIterator) !?Elf64_Phdr { | 831 | pub fn next(it: *ProgramHeaderBufferIterator) !?Elf64.Phdr { |
| 873 | if (it.index >= it.phnum) return null; | 832 | if (it.index >= it.phnum) return null; |
| 874 | defer it.index += 1; | 833 | defer it.index += 1; |
| 875 | 834 | ||
| 876 | const size: usize = if (it.is_64) @sizeOf(Elf64_Phdr) else @sizeOf(Elf32_Phdr); | 835 | const size: usize = if (it.is_64) @sizeOf(Elf64.Phdr) else @sizeOf(Elf32.Phdr); |
| 877 | const offset = @as(usize, @intCast(it.phoff)) + size * it.index; | 836 | const offset = @as(usize, @intCast(it.phoff)) + size * it.index; |
| 878 | var reader = Io.Reader.fixed(it.buf[offset..]); | 837 | var reader = Io.Reader.fixed(it.buf[offset..]); |
| 879 | 838 | ||
| ... | @@ -881,22 +840,22 @@ pub const ProgramHeaderBufferIterator = struct { | ... | @@ -881,22 +840,22 @@ pub const ProgramHeaderBufferIterator = struct { |
| 881 | } | 840 | } |
| 882 | }; | 841 | }; |
| 883 | 842 | ||
| 884 | pub fn takeProgramHeader(reader: *Io.Reader, is_64: bool, endian: Endian) !Elf64_Phdr { | 843 | pub fn takeProgramHeader(reader: *Io.Reader, is_64: bool, endian: Endian) !Elf64.Phdr { |
| 885 | if (is_64) { | 844 | if (is_64) { |
| 886 | const phdr = try reader.takeStruct(Elf64_Phdr, endian); | 845 | const phdr = try reader.takeStruct(Elf64.Phdr, endian); |
| 887 | return phdr; | 846 | return phdr; |
| 888 | } | 847 | } |
| 889 | 848 | ||
| 890 | const phdr = try reader.takeStruct(Elf32_Phdr, endian); | 849 | const phdr = try reader.takeStruct(Elf32.Phdr, endian); |
| 891 | return .{ | 850 | return .{ |
| 892 | .p_type = phdr.p_type, | 851 | .type = phdr.type, |
| 893 | .p_offset = phdr.p_offset, | 852 | .offset = phdr.offset, |
| 894 | .p_vaddr = phdr.p_vaddr, | 853 | .vaddr = phdr.vaddr, |
| 895 | .p_paddr = phdr.p_paddr, | 854 | .paddr = phdr.paddr, |
| 896 | .p_filesz = phdr.p_filesz, | 855 | .filesz = phdr.filesz, |
| 897 | .p_memsz = phdr.p_memsz, | 856 | .memsz = phdr.memsz, |
| 898 | .p_flags = phdr.p_flags, | 857 | .flags = phdr.flags, |
| 899 | .p_align = phdr.p_align, | 858 | .@"align" = phdr.@"align", |
| 900 | }; | 859 | }; |
| 901 | } | 860 | } |
| 902 | 861 | ||
| ... | @@ -1276,28 +1235,6 @@ pub const Elf64_Ehdr = extern struct { | ... | @@ -1276,28 +1235,6 @@ pub const Elf64_Ehdr = extern struct { |
| 1276 | e_shnum: Half, | 1235 | e_shnum: Half, |
| 1277 | e_shstrndx: Half, | 1236 | e_shstrndx: Half, |
| 1278 | }; | 1237 | }; |
| 1279 | /// Deprecated, use `std.elf.Elf32.Phdr` | ||
| 1280 | pub const Elf32_Phdr = extern struct { | ||
| 1281 | p_type: Word, | ||
| 1282 | p_offset: Elf32_Off, | ||
| 1283 | p_vaddr: Elf32_Addr, | ||
| 1284 | p_paddr: Elf32_Addr, | ||
| 1285 | p_filesz: Word, | ||
| 1286 | p_memsz: Word, | ||
| 1287 | p_flags: Word, | ||
| 1288 | p_align: Word, | ||
| 1289 | }; | ||
| 1290 | /// Deprecated, use `std.elf.Elf64.Phdr` | ||
| 1291 | pub const Elf64_Phdr = extern struct { | ||
| 1292 | p_type: Word, | ||
| 1293 | p_flags: Word, | ||
| 1294 | p_offset: Elf64_Off, | ||
| 1295 | p_vaddr: Elf64_Addr, | ||
| 1296 | p_paddr: Elf64_Addr, | ||
| 1297 | p_filesz: Elf64_Xword, | ||
| 1298 | p_memsz: Elf64_Xword, | ||
| 1299 | p_align: Elf64_Xword, | ||
| 1300 | }; | ||
| 1301 | /// Deprecated, use `std.elf.Elf32.Shdr` | 1238 | /// Deprecated, use `std.elf.Elf32.Shdr` |
| 1302 | pub const Elf32_Shdr = extern struct { | 1239 | pub const Elf32_Shdr = extern struct { |
| 1303 | sh_name: Word, | 1240 | sh_name: Word, |
| ... | @@ -1568,12 +1505,6 @@ pub const Ehdr = switch (@sizeOf(usize)) { | ... | @@ -1568,12 +1505,6 @@ pub const Ehdr = switch (@sizeOf(usize)) { |
| 1568 | 8 => Elf64_Ehdr, | 1505 | 8 => Elf64_Ehdr, |
| 1569 | else => @compileError("expected pointer size of 32 or 64"), | 1506 | else => @compileError("expected pointer size of 32 or 64"), |
| 1570 | }; | 1507 | }; |
| 1571 | /// Deprecated, use `std.elf.ElfN.Phdr` | ||
| 1572 | pub const Phdr = switch (@sizeOf(usize)) { | ||
| 1573 | 4 => Elf32_Phdr, | ||
| 1574 | 8 => Elf64_Phdr, | ||
| 1575 | else => @compileError("expected pointer size of 32 or 64"), | ||
| 1576 | }; | ||
| 1577 | pub const Dyn = switch (@sizeOf(usize)) { | 1508 | pub const Dyn = switch (@sizeOf(usize)) { |
| 1578 | 4 => Elf32_Dyn, | 1509 | 4 => Elf32_Dyn, |
| 1579 | 8 => Elf64_Dyn, | 1510 | 8 => Elf64_Dyn, |
| ... | @@ -3272,12 +3203,12 @@ pub const ar_hdr = extern struct { | ... | @@ -3272,12 +3203,12 @@ pub const ar_hdr = extern struct { |
| 3272 | ar_fmag: [2]u8, | 3203 | ar_fmag: [2]u8, |
| 3273 | 3204 | ||
| 3274 | pub fn date(self: ar_hdr) std.fmt.ParseIntError!u64 { | 3205 | pub fn date(self: ar_hdr) std.fmt.ParseIntError!u64 { |
| 3275 | const value = mem.trimEnd(u8, &self.ar_date, &[_]u8{0x20}); | 3206 | const value = mem.trimEnd(u8, &self.ar_date, " "); |
| 3276 | return std.fmt.parseInt(u64, value, 10); | 3207 | return std.fmt.parseInt(u64, value, 10); |
| 3277 | } | 3208 | } |
| 3278 | 3209 | ||
| 3279 | pub fn size(self: ar_hdr) std.fmt.ParseIntError!u32 { | 3210 | pub fn size(self: ar_hdr) std.fmt.ParseIntError!u32 { |
| 3280 | const value = mem.trimEnd(u8, &self.ar_size, &[_]u8{0x20}); | 3211 | const value = mem.trimEnd(u8, &self.ar_size, " "); |
| 3281 | return std.fmt.parseInt(u32, value, 10); | 3212 | return std.fmt.parseInt(u32, value, 10); |
| 3282 | } | 3213 | } |
| 3283 | 3214 | ||
| ... | @@ -3311,7 +3242,7 @@ pub const ar_hdr = extern struct { | ... | @@ -3311,7 +3242,7 @@ pub const ar_hdr = extern struct { |
| 3311 | pub fn nameOffset(self: ar_hdr) std.fmt.ParseIntError!?u32 { | 3242 | pub fn nameOffset(self: ar_hdr) std.fmt.ParseIntError!?u32 { |
| 3312 | const value = &self.ar_name; | 3243 | const value = &self.ar_name; |
| 3313 | if (value[0] != '/') return null; | 3244 | if (value[0] != '/') return null; |
| 3314 | const trimmed = mem.trimEnd(u8, value, &[_]u8{0x20}); | 3245 | const trimmed = mem.trimEnd(u8, value, " "); |
| 3315 | return try std.fmt.parseInt(u32, trimmed[1..], 10); | 3246 | return try std.fmt.parseInt(u32, trimmed[1..], 10); |
| 3316 | } | 3247 | } |
| 3317 | }; | 3248 | }; |
| ... | @@ -3319,7 +3250,7 @@ pub const ar_hdr = extern struct { | ... | @@ -3319,7 +3250,7 @@ pub const ar_hdr = extern struct { |
| 3319 | fn genSpecialMemberName(comptime name: []const u8) *const [16]u8 { | 3250 | fn genSpecialMemberName(comptime name: []const u8) *const [16]u8 { |
| 3320 | assert(name.len <= 16); | 3251 | assert(name.len <= 16); |
| 3321 | const padding = 16 - name.len; | 3252 | const padding = 16 - name.len; |
| 3322 | return name ++ @as([padding]u8, @splat(0x20)); | 3253 | return name ++ @as([padding]u8, @splat(' ')); |
| 3323 | } | 3254 | } |
| 3324 | 3255 | ||
| 3325 | // Archive files start with the ARMAG identifying string. Then follows a | 3256 | // Archive files start with the ARMAG identifying string. Then follows a |
lib/std/enums.zig+3-2| ... | @@ -33,7 +33,8 @@ pub fn fromInt(comptime E: type, integer: anytype) ?E { | ... | @@ -33,7 +33,8 @@ pub fn fromInt(comptime E: type, integer: anytype) ?E { |
| 33 | pub fn EnumFieldStruct(comptime E: type, comptime Data: type, comptime field_default: ?Data) type { | 33 | pub fn EnumFieldStruct(comptime E: type, comptime Data: type, comptime field_default: ?Data) type { |
| 34 | @setEvalBranchQuota(@typeInfo(E).@"enum".field_names.len + eval_branch_quota_cushion); | 34 | @setEvalBranchQuota(@typeInfo(E).@"enum".field_names.len + eval_branch_quota_cushion); |
| 35 | const default_ptr: ?*const anyopaque = if (field_default) |d| @ptrCast(&d) else null; | 35 | const default_ptr: ?*const anyopaque = if (field_default) |d| @ptrCast(&d) else null; |
| 36 | return @Struct(.auto, null, std.meta.fieldNames(E), &@splat(Data), &@splat(.{ .default_value_ptr = default_ptr })); | 36 | const field_names = @typeInfo(E).@"enum".field_names; |
| 37 | return @Struct(.auto, null, field_names, &@splat(Data), &@splat(.{ .default_value_ptr = default_ptr })); | ||
| 37 | } | 38 | } |
| 38 | 39 | ||
| 39 | /// Looks up the supplied field values in the given enum type. | 40 | /// Looks up the supplied field values in the given enum type. |
| ... | @@ -454,7 +455,7 @@ pub fn EnumMap(comptime E: type, comptime V: type) type { | ... | @@ -454,7 +455,7 @@ pub fn EnumMap(comptime E: type, comptime V: type) type { |
| 454 | } | 455 | } |
| 455 | } | 456 | } |
| 456 | } else { | 457 | } else { |
| 457 | inline for (std.meta.fieldNames(E)) |field_name| { | 458 | inline for (@typeInfo(E).@"enum".field_names) |field_name| { |
| 458 | const key = @field(E, field_name); | 459 | const key = @field(E, field_name); |
| 459 | if (@field(init_values, field_name)) |*v| { | 460 | if (@field(init_values, field_name)) |*v| { |
| 460 | const i = comptime Indexer.indexOf(key); | 461 | const i = comptime Indexer.indexOf(key); |
lib/std/fmt.zig+2-4| ... | @@ -261,7 +261,7 @@ test printInt { | ... | @@ -261,7 +261,7 @@ test printInt { |
| 261 | 261 | ||
| 262 | /// Converts values in the range [0, 100) to a base 10 string. | 262 | /// Converts values in the range [0, 100) to a base 10 string. |
| 263 | pub fn digits2(value: u8) [2]u8 { | 263 | pub fn digits2(value: u8) [2]u8 { |
| 264 | if (builtin.mode == .ReleaseSmall) { | 264 | if (builtin.mode == .small) { |
| 265 | return .{ @intCast('0' + value / 10), @intCast('0' + value % 10) }; | 265 | return .{ @intCast('0' + value / 10), @intCast('0' + value % 10) }; |
| 266 | } else { | 266 | } else { |
| 267 | return "00010203040506070809101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899"[value * 2 ..][0..2].*; | 267 | return "00010203040506070809101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899"[value * 2 ..][0..2].*; |
| ... | @@ -924,7 +924,7 @@ test "enum" { | ... | @@ -924,7 +924,7 @@ test "enum" { |
| 924 | 924 | ||
| 925 | // test very large enum to verify ct branch quota is large enough | 925 | // test very large enum to verify ct branch quota is large enough |
| 926 | // TODO: https://github.com/ziglang/zig/issues/15609 | 926 | // TODO: https://github.com/ziglang/zig/issues/15609 |
| 927 | if (!((builtin.cpu.arch == .wasm32) and builtin.mode == .Debug)) { | 927 | if (!((builtin.cpu.arch == .wasm32) and builtin.mode == .debug)) { |
| 928 | try expectFmt("enum: .INVALID_FUNCTION\n", "enum: {}\n", .{std.os.windows.Win32Error.INVALID_FUNCTION}); | 928 | try expectFmt("enum: .INVALID_FUNCTION\n", "enum: {}\n", .{std.os.windows.Win32Error.INVALID_FUNCTION}); |
| 929 | } | 929 | } |
| 930 | 930 | ||
| ... | @@ -1082,8 +1082,6 @@ test "float.libc.sanity" { | ... | @@ -1082,8 +1082,6 @@ test "float.libc.sanity" { |
| 1082 | } | 1082 | } |
| 1083 | 1083 | ||
| 1084 | test "union" { | 1084 | test "union" { |
| 1085 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 1086 | |||
| 1087 | const TU = union(enum) { | 1085 | const TU = union(enum) { |
| 1088 | float: f32, | 1086 | float: f32, |
| 1089 | int: u32, | 1087 | int: u32, |
lib/std/fmt/float.zig+1-1| ... | @@ -65,7 +65,7 @@ pub fn render(buf: []u8, value: anytype, options: Options) Error![]const u8 { | ... | @@ -65,7 +65,7 @@ pub fn render(buf: []u8, value: anytype, options: Options) Error![]const u8 { |
| 65 | 65 | ||
| 66 | const DT = if (@bitSizeOf(T) <= 64) u64 else u128; | 66 | const DT = if (@bitSizeOf(T) <= 64) u64 else u128; |
| 67 | const tables = switch (DT) { | 67 | const tables = switch (DT) { |
| 68 | u64 => if (@import("builtin").mode == .ReleaseSmall) &Backend64_TablesSmall else &Backend64_TablesFull, | 68 | u64 => if (builtin.mode == .small) &Backend64_TablesSmall else &Backend64_TablesFull, |
| 69 | u128 => &Backend128_Tables, | 69 | u128 => &Backend128_Tables, |
| 70 | else => unreachable, | 70 | else => unreachable, |
| 71 | }; | 71 | }; |
lib/std/fs/path.zig+9-3| ... | @@ -1830,7 +1830,7 @@ fn testRelativeWindows(from: []const u8, to: []const u8, expected_output: []cons | ... | @@ -1830,7 +1830,7 @@ fn testRelativeWindows(from: []const u8, to: []const u8, expected_output: []cons |
| 1830 | /// pointer address range of `path`, even if it is length zero. | 1830 | /// pointer address range of `path`, even if it is length zero. |
| 1831 | pub fn extension(path: []const u8) []const u8 { | 1831 | pub fn extension(path: []const u8) []const u8 { |
| 1832 | const filename = basename(path); | 1832 | const filename = basename(path); |
| 1833 | const index = mem.lastIndexOfScalar(u8, filename, '.') orelse return path[path.len..]; | 1833 | const index = mem.findScalarLast(u8, filename, '.') orelse return path[path.len..]; |
| 1834 | if (index == 0) return path[path.len..]; | 1834 | if (index == 0) return path[path.len..]; |
| 1835 | return filename[index..]; | 1835 | return filename[index..]; |
| 1836 | } | 1836 | } |
| ... | @@ -1887,8 +1887,8 @@ test extension { | ... | @@ -1887,8 +1887,8 @@ test extension { |
| 1887 | /// - "hello/world/lib" ⇒ "lib" | 1887 | /// - "hello/world/lib" ⇒ "lib" |
| 1888 | pub fn stem(path: []const u8) []const u8 { | 1888 | pub fn stem(path: []const u8) []const u8 { |
| 1889 | const filename = basename(path); | 1889 | const filename = basename(path); |
| 1890 | const index = mem.lastIndexOfScalar(u8, filename, '.') orelse return filename[0..]; | 1890 | const index = mem.findScalarLast(u8, filename, '.') orelse return filename; |
| 1891 | if (index == 0) return path; | 1891 | if (index == 0) return filename; |
| 1892 | return filename[0..index]; | 1892 | return filename[0..index]; |
| 1893 | } | 1893 | } |
| 1894 | 1894 | ||
| ... | @@ -1904,8 +1904,14 @@ test stem { | ... | @@ -1904,8 +1904,14 @@ test stem { |
| 1904 | try testStem("hello...", "hello.."); | 1904 | try testStem("hello...", "hello.."); |
| 1905 | try testStem("hello.", "hello"); | 1905 | try testStem("hello.", "hello"); |
| 1906 | try testStem("/hello.", "hello"); | 1906 | try testStem("/hello.", "hello"); |
| 1907 | try testStem("hello/world/.gitignore", ".gitignore"); | ||
| 1908 | try testStem("/.gitignore", ".gitignore"); | ||
| 1907 | try testStem(".gitignore", ".gitignore"); | 1909 | try testStem(".gitignore", ".gitignore"); |
| 1910 | try testStem(".gitignore/", ".gitignore"); | ||
| 1911 | try testStem("hello/world/.image.png", ".image"); | ||
| 1912 | try testStem("/.image.png", ".image"); | ||
| 1908 | try testStem(".image.png", ".image"); | 1913 | try testStem(".image.png", ".image"); |
| 1914 | try testStem(".image.png/", ".image"); | ||
| 1909 | try testStem("file.ext", "file"); | 1915 | try testStem("file.ext", "file"); |
| 1910 | try testStem("file.ext.", "file.ext"); | 1916 | try testStem("file.ext.", "file.ext"); |
| 1911 | try testStem("a.b.c", "a.b"); | 1917 | try testStem("a.b.c", "a.b"); |
lib/std/fs/test.zig+41-3| ... | @@ -758,6 +758,43 @@ test "readFileAlloc" { | ... | @@ -758,6 +758,43 @@ test "readFileAlloc" { |
| 758 | ); | 758 | ); |
| 759 | } | 759 | } |
| 760 | 760 | ||
| 761 | test "file operations with follow_symlinks=false" { | ||
| 762 | const io = testing.io; | ||
| 763 | |||
| 764 | var tmp_dir = tmpDir(.{}); | ||
| 765 | defer tmp_dir.cleanup(); | ||
| 766 | |||
| 767 | const contents = "this is a test.\nthis is a test.\nthis is a test.\nthis is a test.\n"; | ||
| 768 | try tmp_dir.dir.writeFile(io, .{ | ||
| 769 | .sub_path = "test_file", | ||
| 770 | .data = contents, | ||
| 771 | }); | ||
| 772 | |||
| 773 | // Without lock | ||
| 774 | { | ||
| 775 | var file = try tmp_dir.dir.openFile(io, "test_file", .{ .follow_symlinks = false }); | ||
| 776 | defer file.close(io); | ||
| 777 | |||
| 778 | var file_reader = file.reader(io, &.{}); | ||
| 779 | const actual_contents = try file_reader.interface.allocRemaining(testing.allocator, .unlimited); | ||
| 780 | defer testing.allocator.free(actual_contents); | ||
| 781 | |||
| 782 | try std.testing.expectEqualSlices(u8, contents, actual_contents); | ||
| 783 | } | ||
| 784 | |||
| 785 | // With lock | ||
| 786 | { | ||
| 787 | var file = try tmp_dir.dir.openFile(io, "test_file", .{ .follow_symlinks = false, .lock = .exclusive }); | ||
| 788 | defer file.close(io); | ||
| 789 | |||
| 790 | var file_reader = file.reader(io, &.{}); | ||
| 791 | const actual_contents = try file_reader.interface.allocRemaining(testing.allocator, .unlimited); | ||
| 792 | defer testing.allocator.free(actual_contents); | ||
| 793 | |||
| 794 | try std.testing.expectEqualSlices(u8, contents, actual_contents); | ||
| 795 | } | ||
| 796 | } | ||
| 797 | |||
| 761 | test "Dir.statFile" { | 798 | test "Dir.statFile" { |
| 762 | try testWithAllSupportedPathTypes(struct { | 799 | try testWithAllSupportedPathTypes(struct { |
| 763 | fn impl(ctx: *TestContext) !void { | 800 | fn impl(ctx: *TestContext) !void { |
| ... | @@ -902,6 +939,8 @@ test "createDirPathOpen parent dirs do not exist" { | ... | @@ -902,6 +939,8 @@ test "createDirPathOpen parent dirs do not exist" { |
| 902 | } | 939 | } |
| 903 | 940 | ||
| 904 | test "deleteDir" { | 941 | test "deleteDir" { |
| 942 | if (builtin.target.os.tag == .windows) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/35686 | ||
| 943 | |||
| 905 | try testWithAllSupportedPathTypes(struct { | 944 | try testWithAllSupportedPathTypes(struct { |
| 906 | fn impl(ctx: *TestContext) !void { | 945 | fn impl(ctx: *TestContext) !void { |
| 907 | const io = ctx.io; | 946 | const io = ctx.io; |
| ... | @@ -2168,7 +2207,7 @@ test "'.' and '..' in absolute functions" { | ... | @@ -2168,7 +2207,7 @@ test "'.' and '..' in absolute functions" { |
| 2168 | } | 2207 | } |
| 2169 | 2208 | ||
| 2170 | test "chmod" { | 2209 | test "chmod" { |
| 2171 | if (native_os == .windows or native_os == .wasi) return; | 2210 | if (native_os == .windows or native_os == .wasi) return error.SkipZigTest; |
| 2172 | 2211 | ||
| 2173 | const io = testing.io; | 2212 | const io = testing.io; |
| 2174 | 2213 | ||
| ... | @@ -2191,8 +2230,7 @@ test "chmod" { | ... | @@ -2191,8 +2230,7 @@ test "chmod" { |
| 2191 | } | 2230 | } |
| 2192 | 2231 | ||
| 2193 | test "change ownership" { | 2232 | test "change ownership" { |
| 2194 | if (native_os == .windows or native_os == .wasi) | 2233 | if (native_os == .windows or native_os == .wasi) return error.SkipZigTest; |
| 2195 | return error.SkipZigTest; | ||
| 2196 | 2234 | ||
| 2197 | const io = testing.io; | 2235 | const io = testing.io; |
| 2198 | 2236 |
lib/std/hash/auto_hash.zig+1-1| ... | @@ -225,7 +225,7 @@ fn testHashDeepRecursive(key: anytype) u64 { | ... | @@ -225,7 +225,7 @@ fn testHashDeepRecursive(key: anytype) u64 { |
| 225 | 225 | ||
| 226 | test "typeContainsSlice" { | 226 | test "typeContainsSlice" { |
| 227 | comptime { | 227 | comptime { |
| 228 | try testing.expect(!typeContainsSlice(std.meta.Tag(std.builtin.Type))); | 228 | try testing.expect(!typeContainsSlice(std.meta.Tag(std.lang.Type))); |
| 229 | 229 | ||
| 230 | try testing.expect(typeContainsSlice([]const u8)); | 230 | try testing.expect(typeContainsSlice([]const u8)); |
| 231 | try testing.expect(!typeContainsSlice(u8)); | 231 | try testing.expect(!typeContainsSlice(u8)); |
lib/std/hash/benchmark.zig+1-1| ... | @@ -355,7 +355,7 @@ fn usage() void { | ... | @@ -355,7 +355,7 @@ fn usage() void { |
| 355 | } | 355 | } |
| 356 | 356 | ||
| 357 | fn mode(comptime x: comptime_int) comptime_int { | 357 | fn mode(comptime x: comptime_int) comptime_int { |
| 358 | return if (builtin.mode == .Debug) x / 64 else x; | 358 | return if (builtin.mode == .debug) x / 64 else x; |
| 359 | } | 359 | } |
| 360 | 360 | ||
| 361 | pub fn main(init: std.process.Init) !void { | 361 | pub fn main(init: std.process.Init) !void { |
lib/std/hash/cityhash.zig+1-1| ... | @@ -16,7 +16,7 @@ fn fetch64(ptr: [*]const u8, offset: usize) u64 { | ... | @@ -16,7 +16,7 @@ fn fetch64(ptr: [*]const u8, offset: usize) u64 { |
| 16 | pub const CityHash32 = struct { | 16 | pub const CityHash32 = struct { |
| 17 | const Self = @This(); | 17 | const Self = @This(); |
| 18 | 18 | ||
| 19 | // Magic numbers for 32-bit hashing. Copied from Murmur3. | 19 | // Magic numbers for 32-bit hashing. Copied from Murmur3. |
| 20 | const c1: u32 = 0xcc9e2d51; | 20 | const c1: u32 = 0xcc9e2d51; |
| 21 | const c2: u32 = 0x1b873593; | 21 | const c2: u32 = 0x1b873593; |
| 22 | 22 |
lib/std/hash/xxhash.zig+1-5| ... | @@ -1,5 +1,4 @@ | ... | @@ -1,5 +1,4 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const builtin = @import("builtin"); | ||
| 3 | const mem = std.mem; | 2 | const mem = std.mem; |
| 4 | const expectEqual = std.testing.expectEqual; | 3 | const expectEqual = std.testing.expectEqual; |
| 5 | 4 | ||
| ... | @@ -761,7 +760,7 @@ pub const XxHash3 = struct { | ... | @@ -761,7 +760,7 @@ pub const XxHash3 = struct { |
| 761 | var accumulator_copy = self.accumulator; | 760 | var accumulator_copy = self.accumulator; |
| 762 | var last_block_copy: [block_bytes]u8 = undefined; | 761 | var last_block_copy: [block_bytes]u8 = undefined; |
| 763 | 762 | ||
| 764 | // Digest the last block onthe Accumulator copy. | 763 | // Digest the last block on the Accumulator copy. |
| 765 | return accumulator_copy.digest(self.total_len, last_block: { | 764 | return accumulator_copy.digest(self.total_len, last_block: { |
| 766 | if (self.buffered >= block_bytes) { | 765 | if (self.buffered >= block_bytes) { |
| 767 | const block_count = ((self.buffered - 1) / block_bytes) * block_bytes; | 766 | const block_count = ((self.buffered - 1) / block_bytes) * block_bytes; |
| ... | @@ -788,7 +787,6 @@ fn testExpect(comptime H: type, seed: anytype, input: []const u8, expected: u64) | ... | @@ -788,7 +787,6 @@ fn testExpect(comptime H: type, seed: anytype, input: []const u8, expected: u64) |
| 788 | } | 787 | } |
| 789 | 788 | ||
| 790 | test "xxhash3" { | 789 | test "xxhash3" { |
| 791 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 792 | const H = XxHash3; | 790 | const H = XxHash3; |
| 793 | // Non-Seeded Tests | 791 | // Non-Seeded Tests |
| 794 | try testExpect(H, 0, "", 0x2d06800538d394c2); | 792 | try testExpect(H, 0, "", 0x2d06800538d394c2); |
| ... | @@ -820,7 +818,6 @@ test "xxhash3" { | ... | @@ -820,7 +818,6 @@ test "xxhash3" { |
| 820 | } | 818 | } |
| 821 | 819 | ||
| 822 | test "xxhash3 smhasher" { | 820 | test "xxhash3 smhasher" { |
| 823 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 824 | const Test = struct { | 821 | const Test = struct { |
| 825 | fn do() !void { | 822 | fn do() !void { |
| 826 | try expectEqual(verify.smhasher(XxHash3.hash), 0x9a636405); | 823 | try expectEqual(verify.smhasher(XxHash3.hash), 0x9a636405); |
| ... | @@ -832,7 +829,6 @@ test "xxhash3 smhasher" { | ... | @@ -832,7 +829,6 @@ test "xxhash3 smhasher" { |
| 832 | } | 829 | } |
| 833 | 830 | ||
| 834 | test "xxhash3 iterative api" { | 831 | test "xxhash3 iterative api" { |
| 835 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 836 | const Test = struct { | 832 | const Test = struct { |
| 837 | fn do() !void { | 833 | fn do() !void { |
| 838 | try verify.iterativeApi(XxHash3); | 834 | try verify.iterativeApi(XxHash3); |
lib/std/hash_map.zig+1-1| ... | @@ -1518,7 +1518,7 @@ fn Custom( | ... | @@ -1518,7 +1518,7 @@ fn Custom( |
| 1518 | self.available = 0; | 1518 | self.available = 0; |
| 1519 | } | 1519 | } |
| 1520 | 1520 | ||
| 1521 | /// This function is used in the debugger pretty formatters in tools/ to fetch the | 1521 | /// This function is used in the debugger pretty formatters in lib/lldb/ to fetch the |
| 1522 | /// header type to facilitate fancy debug printing for this type. | 1522 | /// header type to facilitate fancy debug printing for this type. |
| 1523 | fn dbHelper(self: *Self, hdr: *Header, entry: *Entry) void { | 1523 | fn dbHelper(self: *Self, hdr: *Header, entry: *Entry) void { |
| 1524 | _ = self; | 1524 | _ = self; |
lib/std/heap/PageAllocator.zig+1| ... | @@ -24,6 +24,7 @@ pub const vtable: Allocator.VTable = .{ | ... | @@ -24,6 +24,7 @@ pub const vtable: Allocator.VTable = .{ |
| 24 | /// that don't provide a hint (for security reasons, but it serves our needs | 24 | /// that don't provide a hint (for security reasons, but it serves our needs |
| 25 | /// too). | 25 | /// too). |
| 26 | const enable_hints = switch (builtin.target.os.tag) { | 26 | const enable_hints = switch (builtin.target.os.tag) { |
| 27 | .linux => !builtin.target.cpu.arch.isSPARC(), // https://bugzilla.kernel.org/show_bug.cgi?id=221820 | ||
| 27 | .openbsd => false, | 28 | .openbsd => false, |
| 28 | else => true, | 29 | else => true, |
| 29 | }; | 30 | }; |
lib/std/heap/SafeAllocator.zig+2-2| ... | @@ -39,7 +39,7 @@ const SafeAllocator = @This(); | ... | @@ -39,7 +39,7 @@ const SafeAllocator = @This(); |
| 39 | const scoped_log = std.log.scoped(.SafeAllocator); | 39 | const scoped_log = std.log.scoped(.SafeAllocator); |
| 40 | 40 | ||
| 41 | pub const Options = struct { | 41 | pub const Options = struct { |
| 42 | const is_debug = @import("builtin").mode == .Debug; | 42 | const is_debug = @import("builtin").mode == .debug; |
| 43 | const page_size_log2 = @max(math.log2_int(usize, std.heap.page_size_max), 8); | 43 | const page_size_log2 = @max(math.log2_int(usize, std.heap.page_size_max), 8); |
| 44 | 44 | ||
| 45 | stack_trace_frames: usize = if (is_debug and std.debug.sys_can_stack_trace) 7 else 0, | 45 | stack_trace_frames: usize = if (is_debug and std.debug.sys_can_stack_trace) 7 else 0, |
| ... | @@ -1519,7 +1519,7 @@ const FuzzSingleThreadedAllocator = struct { | ... | @@ -1519,7 +1519,7 @@ const FuzzSingleThreadedAllocator = struct { |
| 1519 | @disableInstrumentation(); | 1519 | @disableInstrumentation(); |
| 1520 | 1520 | ||
| 1521 | const allocs_slice = f.allocs.slice(); | 1521 | const allocs_slice = f.allocs.slice(); |
| 1522 | const i = mem.indexOfScalar([*]u8, allocs_slice.items(.ptr), memory.ptr) orelse panic( | 1522 | const i = mem.findScalar([*]u8, allocs_slice.items(.ptr), memory.ptr) orelse panic( |
| 1523 | "invalid SafeAllocator free of {f}", | 1523 | "invalid SafeAllocator free of {f}", |
| 1524 | .{FormatMemory{ .memory = memory, .alignment = alignment }}, | 1524 | .{FormatMemory{ .memory = memory, .alignment = alignment }}, |
| 1525 | ); | 1525 | ); |
lib/std/http.zig+8-5| ... | @@ -20,6 +20,8 @@ pub const Version = enum { | ... | @@ -20,6 +20,8 @@ pub const Version = enum { |
| 20 | /// https://datatracker.ietf.org/doc/html/rfc7231#section-4 Initial definition | 20 | /// https://datatracker.ietf.org/doc/html/rfc7231#section-4 Initial definition |
| 21 | /// | 21 | /// |
| 22 | /// https://datatracker.ietf.org/doc/html/rfc5789#section-2 PATCH | 22 | /// https://datatracker.ietf.org/doc/html/rfc5789#section-2 PATCH |
| 23 | /// | ||
| 24 | /// https://datatracker.ietf.org/doc/html/rfc10008#name-query-method QUERY | ||
| 23 | pub const Method = enum { | 25 | pub const Method = enum { |
| 24 | GET, | 26 | GET, |
| 25 | HEAD, | 27 | HEAD, |
| ... | @@ -30,12 +32,13 @@ pub const Method = enum { | ... | @@ -30,12 +32,13 @@ pub const Method = enum { |
| 30 | OPTIONS, | 32 | OPTIONS, |
| 31 | TRACE, | 33 | TRACE, |
| 32 | PATCH, | 34 | PATCH, |
| 35 | QUERY, | ||
| 33 | 36 | ||
| 34 | /// Returns true if a request of this method is allowed to have a body | 37 | /// Returns true if a request of this method is allowed to have a body |
| 35 | /// Actual behavior from servers may vary and should still be checked | 38 | /// Actual behavior from servers may vary and should still be checked |
| 36 | pub fn requestHasBody(m: Method) bool { | 39 | pub fn requestHasBody(m: Method) bool { |
| 37 | return switch (m) { | 40 | return switch (m) { |
| 38 | .POST, .PUT, .PATCH => true, | 41 | .POST, .PUT, .PATCH, .QUERY => true, |
| 39 | .GET, .HEAD, .DELETE, .CONNECT, .OPTIONS, .TRACE => false, | 42 | .GET, .HEAD, .DELETE, .CONNECT, .OPTIONS, .TRACE => false, |
| 40 | }; | 43 | }; |
| 41 | } | 44 | } |
| ... | @@ -44,7 +47,7 @@ pub const Method = enum { | ... | @@ -44,7 +47,7 @@ pub const Method = enum { |
| 44 | /// Actual behavior from clients may vary and should still be checked | 47 | /// Actual behavior from clients may vary and should still be checked |
| 45 | pub fn responseHasBody(m: Method) bool { | 48 | pub fn responseHasBody(m: Method) bool { |
| 46 | return switch (m) { | 49 | return switch (m) { |
| 47 | .GET, .POST, .PUT, .DELETE, .CONNECT, .OPTIONS, .PATCH => true, | 50 | .GET, .POST, .PUT, .DELETE, .CONNECT, .OPTIONS, .PATCH, .QUERY => true, |
| 48 | .HEAD, .TRACE => false, | 51 | .HEAD, .TRACE => false, |
| 49 | }; | 52 | }; |
| 50 | } | 53 | } |
| ... | @@ -56,7 +59,7 @@ pub const Method = enum { | ... | @@ -56,7 +59,7 @@ pub const Method = enum { |
| 56 | /// https://datatracker.ietf.org/doc/html/rfc7231#section-4.2.1 | 59 | /// https://datatracker.ietf.org/doc/html/rfc7231#section-4.2.1 |
| 57 | pub fn safe(m: Method) bool { | 60 | pub fn safe(m: Method) bool { |
| 58 | return switch (m) { | 61 | return switch (m) { |
| 59 | .GET, .HEAD, .OPTIONS, .TRACE => true, | 62 | .GET, .HEAD, .OPTIONS, .TRACE, .QUERY => true, |
| 60 | .POST, .PUT, .DELETE, .CONNECT, .PATCH => false, | 63 | .POST, .PUT, .DELETE, .CONNECT, .PATCH => false, |
| 61 | }; | 64 | }; |
| 62 | } | 65 | } |
| ... | @@ -70,7 +73,7 @@ pub const Method = enum { | ... | @@ -70,7 +73,7 @@ pub const Method = enum { |
| 70 | /// https://datatracker.ietf.org/doc/html/rfc7231#section-4.2.2 | 73 | /// https://datatracker.ietf.org/doc/html/rfc7231#section-4.2.2 |
| 71 | pub fn idempotent(m: Method) bool { | 74 | pub fn idempotent(m: Method) bool { |
| 72 | return switch (m) { | 75 | return switch (m) { |
| 73 | .GET, .HEAD, .PUT, .DELETE, .OPTIONS, .TRACE => true, | 76 | .GET, .HEAD, .PUT, .DELETE, .OPTIONS, .TRACE, .QUERY => true, |
| 74 | .CONNECT, .POST, .PATCH => false, | 77 | .CONNECT, .POST, .PATCH => false, |
| 75 | }; | 78 | }; |
| 76 | } | 79 | } |
| ... | @@ -83,7 +86,7 @@ pub const Method = enum { | ... | @@ -83,7 +86,7 @@ pub const Method = enum { |
| 83 | /// https://datatracker.ietf.org/doc/html/rfc7231#section-4.2.3 | 86 | /// https://datatracker.ietf.org/doc/html/rfc7231#section-4.2.3 |
| 84 | pub fn cacheable(m: Method) bool { | 87 | pub fn cacheable(m: Method) bool { |
| 85 | return switch (m) { | 88 | return switch (m) { |
| 86 | .GET, .HEAD => true, | 89 | .GET, .HEAD, .QUERY => true, |
| 87 | .POST, .PUT, .DELETE, .CONNECT, .OPTIONS, .TRACE, .PATCH => false, | 90 | .POST, .PUT, .DELETE, .CONNECT, .OPTIONS, .TRACE, .PATCH => false, |
| 88 | }; | 91 | }; |
| 89 | } | 92 | } |
lib/std/http/Server.zig+1-1| ... | @@ -102,7 +102,7 @@ pub const Request = struct { | ... | @@ -102,7 +102,7 @@ pub const Request = struct { |
| 102 | const method = std.meta.stringToEnum(http.Method, first_line[0..method_end]) orelse | 102 | const method = std.meta.stringToEnum(http.Method, first_line[0..method_end]) orelse |
| 103 | return error.UnknownHttpMethod; | 103 | return error.UnknownHttpMethod; |
| 104 | 104 | ||
| 105 | const version_start = mem.lastIndexOfScalar(u8, first_line, ' ') orelse | 105 | const version_start = mem.findScalarLast(u8, first_line, ' ') orelse |
| 106 | return error.HttpHeadersInvalid; | 106 | return error.HttpHeadersInvalid; |
| 107 | if (version_start == method_end) return error.HttpHeadersInvalid; | 107 | if (version_start == method_end) return error.HttpHeadersInvalid; |
| 108 | 108 |
lib/std/http/test.zig+1-20| ... | @@ -1,5 +1,4 @@ | ... | @@ -1,5 +1,4 @@ |
| 1 | const builtin = @import("builtin"); | 1 | const builtin = @import("builtin"); |
| 2 | const native_endian = builtin.cpu.arch.endian(); | ||
| 3 | 2 | ||
| 4 | const std = @import("std"); | 3 | const std = @import("std"); |
| 5 | const http = std.http; | 4 | const http = std.http; |
| ... | @@ -34,7 +33,6 @@ test "content length reader state update" { | ... | @@ -34,7 +33,6 @@ test "content length reader state update" { |
| 34 | } | 33 | } |
| 35 | 34 | ||
| 36 | test "trailers" { | 35 | test "trailers" { |
| 37 | if (builtin.cpu.arch.isPowerPC64() and builtin.mode != .Debug) return error.SkipZigTest; // https://github.com/llvm/llvm-project/issues/194257 | ||
| 38 | if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30806 | 36 | if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30806 |
| 39 | 37 | ||
| 40 | const io = std.testing.io; | 38 | const io = std.testing.io; |
| ... | @@ -121,7 +119,6 @@ test "trailers" { | ... | @@ -121,7 +119,6 @@ test "trailers" { |
| 121 | } | 119 | } |
| 122 | 120 | ||
| 123 | test "HTTP server handles a chunked transfer coding request" { | 121 | test "HTTP server handles a chunked transfer coding request" { |
| 124 | if (builtin.cpu.arch.isPowerPC64() and builtin.mode != .Debug) return error.SkipZigTest; // https://github.com/llvm/llvm-project/issues/194257 | ||
| 125 | if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30806 | 122 | if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30806 |
| 126 | 123 | ||
| 127 | const io = std.testing.io; | 124 | const io = std.testing.io; |
| ... | @@ -190,7 +187,6 @@ test "HTTP server handles a chunked transfer coding request" { | ... | @@ -190,7 +187,6 @@ test "HTTP server handles a chunked transfer coding request" { |
| 190 | } | 187 | } |
| 191 | 188 | ||
| 192 | test "echo content server" { | 189 | test "echo content server" { |
| 193 | if (builtin.cpu.arch.isPowerPC64() and builtin.mode != .Debug) return error.SkipZigTest; // https://github.com/llvm/llvm-project/issues/194257 | ||
| 194 | if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30806 | 190 | if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30806 |
| 195 | 191 | ||
| 196 | const io = std.testing.io; | 192 | const io = std.testing.io; |
| ... | @@ -281,12 +277,11 @@ test "echo content server" { | ... | @@ -281,12 +277,11 @@ test "echo content server" { |
| 281 | } | 277 | } |
| 282 | 278 | ||
| 283 | test "Server.Request.respondStreaming non-chunked, unknown content-length" { | 279 | test "Server.Request.respondStreaming non-chunked, unknown content-length" { |
| 284 | if (builtin.cpu.arch.isPowerPC64() and builtin.mode != .Debug) return error.SkipZigTest; // https://github.com/llvm/llvm-project/issues/194257 | ||
| 285 | if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30806 | 280 | if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30806 |
| 286 | 281 | ||
| 287 | const io = std.testing.io; | 282 | const io = std.testing.io; |
| 288 | 283 | ||
| 289 | if (builtin.os.tag == .windows) { | 284 | if (builtin.cpu.arch == .aarch64 and builtin.os.tag == .windows) { |
| 290 | // https://github.com/ziglang/zig/issues/21457 | 285 | // https://github.com/ziglang/zig/issues/21457 |
| 291 | return error.SkipZigTest; | 286 | return error.SkipZigTest; |
| 292 | } | 287 | } |
| ... | @@ -360,7 +355,6 @@ test "Server.Request.respondStreaming non-chunked, unknown content-length" { | ... | @@ -360,7 +355,6 @@ test "Server.Request.respondStreaming non-chunked, unknown content-length" { |
| 360 | } | 355 | } |
| 361 | 356 | ||
| 362 | test "receiving arbitrary http headers from the client" { | 357 | test "receiving arbitrary http headers from the client" { |
| 363 | if (builtin.cpu.arch.isPowerPC64() and builtin.mode != .Debug) return error.SkipZigTest; // https://github.com/llvm/llvm-project/issues/194257 | ||
| 364 | if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30806 | 358 | if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30806 |
| 365 | 359 | ||
| 366 | const io = std.testing.io; | 360 | const io = std.testing.io; |
| ... | @@ -426,16 +420,10 @@ test "receiving arbitrary http headers from the client" { | ... | @@ -426,16 +420,10 @@ test "receiving arbitrary http headers from the client" { |
| 426 | } | 420 | } |
| 427 | 421 | ||
| 428 | test "general client/server API coverage" { | 422 | test "general client/server API coverage" { |
| 429 | if (builtin.cpu.arch.isPowerPC64() and builtin.mode != .Debug) return error.SkipZigTest; // https://github.com/llvm/llvm-project/issues/194257 | ||
| 430 | if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30806 | 423 | if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30806 |
| 431 | 424 | ||
| 432 | const io = std.testing.io; | 425 | const io = std.testing.io; |
| 433 | 426 | ||
| 434 | if (builtin.os.tag == .windows) { | ||
| 435 | // This test was never passing on Windows. | ||
| 436 | return error.SkipZigTest; | ||
| 437 | } | ||
| 438 | |||
| 439 | const test_server = try createTestServer(io, struct { | 427 | const test_server = try createTestServer(io, struct { |
| 440 | fn run(test_server: *TestServer) anyerror!void { | 428 | fn run(test_server: *TestServer) anyerror!void { |
| 441 | const net_server = &test_server.net_server; | 429 | const net_server = &test_server.net_server; |
| ... | @@ -922,7 +910,6 @@ test "general client/server API coverage" { | ... | @@ -922,7 +910,6 @@ test "general client/server API coverage" { |
| 922 | } | 910 | } |
| 923 | 911 | ||
| 924 | test "Server streams both reading and writing" { | 912 | test "Server streams both reading and writing" { |
| 925 | if (builtin.cpu.arch.isPowerPC64() and builtin.mode != .Debug) return error.SkipZigTest; // https://github.com/llvm/llvm-project/issues/194257 | ||
| 926 | if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30806 | 913 | if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30806 |
| 927 | 914 | ||
| 928 | const io = std.testing.io; | 915 | const io = std.testing.io; |
| ... | @@ -1162,10 +1149,6 @@ const TestServer = struct { | ... | @@ -1162,10 +1149,6 @@ const TestServer = struct { |
| 1162 | 1149 | ||
| 1163 | fn createTestServer(io: Io, S: type) !*TestServer { | 1150 | fn createTestServer(io: Io, S: type) !*TestServer { |
| 1164 | if (builtin.single_threaded) return error.SkipZigTest; | 1151 | if (builtin.single_threaded) return error.SkipZigTest; |
| 1165 | if (builtin.zig_backend == .stage2_llvm and native_endian == .big) { | ||
| 1166 | // https://github.com/ziglang/zig/issues/13782 | ||
| 1167 | return error.SkipZigTest; | ||
| 1168 | } | ||
| 1169 | 1152 | ||
| 1170 | const address = try net.IpAddress.parse("127.0.0.1", 0); | 1153 | const address = try net.IpAddress.parse("127.0.0.1", 0); |
| 1171 | 1154 | ||
| ... | @@ -1192,7 +1175,6 @@ fn createTestServer(io: Io, S: type) !*TestServer { | ... | @@ -1192,7 +1175,6 @@ fn createTestServer(io: Io, S: type) !*TestServer { |
| 1192 | } | 1175 | } |
| 1193 | 1176 | ||
| 1194 | test "redirect to different connection" { | 1177 | test "redirect to different connection" { |
| 1195 | if (builtin.cpu.arch.isPowerPC64() and builtin.mode != .Debug) return error.SkipZigTest; // https://github.com/llvm/llvm-project/issues/194257 | ||
| 1196 | if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30806 | 1178 | if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30806 |
| 1197 | 1179 | ||
| 1198 | const io = std.testing.io; | 1180 | const io = std.testing.io; |
| ... | @@ -1280,7 +1262,6 @@ test "redirect to different connection" { | ... | @@ -1280,7 +1262,6 @@ test "redirect to different connection" { |
| 1280 | } | 1262 | } |
| 1281 | 1263 | ||
| 1282 | test "boot failed connections from the pool" { | 1264 | test "boot failed connections from the pool" { |
| 1283 | if (builtin.cpu.arch.isPowerPC64() and builtin.mode != .Debug) return error.SkipZigTest; // https://github.com/llvm/llvm-project/issues/194257 | ||
| 1284 | if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30806 | 1265 | if (builtin.os.tag == .openbsd) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30806 |
| 1285 | 1266 | ||
| 1286 | const io = std.testing.io; | 1267 | const io = std.testing.io; |
lib/std/json/Stringify.zig+3-3| ... | @@ -54,8 +54,8 @@ else | ... | @@ -54,8 +54,8 @@ else |
| 54 | void = if (build_mode_has_safety) .none else {}, | 54 | void = if (build_mode_has_safety) .none else {}, |
| 55 | 55 | ||
| 56 | const build_mode_has_safety = switch (@import("builtin").mode) { | 56 | const build_mode_has_safety = switch (@import("builtin").mode) { |
| 57 | .Debug, .ReleaseSafe => true, | 57 | .debug, .safe => true, |
| 58 | .ReleaseFast, .ReleaseSmall => false, | 58 | .fast, .small => false, |
| 59 | }; | 59 | }; |
| 60 | 60 | ||
| 61 | /// The `safety_checks_hint` parameter determines how much memory is used to enable assertions that the above grammar is being followed, | 61 | /// The `safety_checks_hint` parameter determines how much memory is used to enable assertions that the above grammar is being followed, |
| ... | @@ -66,7 +66,7 @@ const build_mode_has_safety = switch (@import("builtin").mode) { | ... | @@ -66,7 +66,7 @@ const build_mode_has_safety = switch (@import("builtin").mode) { |
| 66 | /// If `.checked_to_fixed_depth` is used, there is additionally an assertion that the nesting depth never exceeds the given limit. | 66 | /// If `.checked_to_fixed_depth` is used, there is additionally an assertion that the nesting depth never exceeds the given limit. |
| 67 | /// `.checked_to_fixed_depth` embeds the storage required in the `Stringify` struct. | 67 | /// `.checked_to_fixed_depth` embeds the storage required in the `Stringify` struct. |
| 68 | /// `.assumed_correct` requires no space and performs none of these assertions. | 68 | /// `.assumed_correct` requires no space and performs none of these assertions. |
| 69 | /// In `ReleaseFast` and `ReleaseSmall` mode, the given `safety_checks_hint` is ignored and is always treated as `.assumed_correct`. | 69 | /// In fast and small optimization modes, the given `safety_checks_hint` is ignored and is always treated as `.assumed_correct`. |
| 70 | const safety_checks_hint: union(enum) { | 70 | const safety_checks_hint: union(enum) { |
| 71 | /// Rounded up to the nearest multiple of 8. | 71 | /// Rounded up to the nearest multiple of 8. |
| 72 | checked_to_fixed_depth: usize, | 72 | checked_to_fixed_depth: usize, |
lib/std/lang.zig+47-5| ... | @@ -107,13 +107,52 @@ pub const CodeModel = enum(u4) { | ... | @@ -107,13 +107,52 @@ pub const CodeModel = enum(u4) { |
| 107 | tiny, | 107 | tiny, |
| 108 | }; | 108 | }; |
| 109 | 109 | ||
| 110 | /// Deprecated, to be removed after 0.18.0 | ||
| 111 | pub const OptimizeMode = Optimize; | ||
| 112 | |||
| 110 | /// This data structure is used by the Zig language code generation and | 113 | /// This data structure is used by the Zig language code generation and |
| 111 | /// therefore must be kept in sync with the compiler implementation. | 114 | /// therefore must be kept in sync with the compiler implementation. |
| 112 | pub const OptimizeMode = enum { | 115 | pub const Optimize = enum { |
| 113 | Debug, | 116 | /// Safety checks enabled. Optimize for bug detection, accurate debug info, |
| 114 | ReleaseSafe, | 117 | /// and compilation speed (in that order). |
| 115 | ReleaseFast, | 118 | debug, |
| 116 | ReleaseSmall, | 119 | /// Safety checks enabled. Optimize for runtime performance. |
| 120 | safe, | ||
| 121 | /// Safety checks disabled. Optimize for runtime performance. | ||
| 122 | fast, | ||
| 123 | /// Safety checks disabled. Optimize for machine code size, then runtime performance. | ||
| 124 | small, | ||
| 125 | |||
| 126 | /// Deprecated, to be removed after 0.18.0 | ||
| 127 | pub const Debug: @This() = .debug; | ||
| 128 | /// Deprecated, to be removed after 0.18.0 | ||
| 129 | pub const ReleaseSafe: @This() = .safe; | ||
| 130 | /// Deprecated, to be removed after 0.18.0 | ||
| 131 | pub const ReleaseFast: @This() = .fast; | ||
| 132 | /// Deprecated, to be removed after 0.18.0 | ||
| 133 | pub const ReleaseSmall: @This() = .small; | ||
| 134 | /// Deprecated, to be removed after 0.18.0 | ||
| 135 | pub fn fromString(s: []const u8) ?@This() { | ||
| 136 | return std.StaticStringMap(@This()).initComptime(&.{ | ||
| 137 | .{ "Debug", .debug }, | ||
| 138 | .{ "ReleaseSafe", .safe }, | ||
| 139 | .{ "ReleaseFast", .fast }, | ||
| 140 | .{ "ReleaseSmall", .small }, | ||
| 141 | .{ "debug", .debug }, | ||
| 142 | .{ "safe", .safe }, | ||
| 143 | .{ "fast", .fast }, | ||
| 144 | .{ "small", .small }, | ||
| 145 | }).get(s); | ||
| 146 | } | ||
| 147 | |||
| 148 | /// Returns whether illegal behavior safety checks are enabled based on the | ||
| 149 | /// provided optimization mode. | ||
| 150 | pub fn runtimeSafety(o: @This()) bool { | ||
| 151 | return switch (o) { | ||
| 152 | .debug, .safe => true, | ||
| 153 | .fast, .small => false, | ||
| 154 | }; | ||
| 155 | } | ||
| 117 | }; | 156 | }; |
| 118 | 157 | ||
| 119 | /// The calling convention of a function defines how arguments and return values are passed, as well | 158 | /// The calling convention of a function defines how arguments and return values are passed, as well |
| ... | @@ -171,10 +210,12 @@ pub const CallingConvention = union(enum(u8)) { | ... | @@ -171,10 +210,12 @@ pub const CallingConvention = union(enum(u8)) { |
| 171 | x86_64_regcall_v4_win: CommonOptions, | 210 | x86_64_regcall_v4_win: CommonOptions, |
| 172 | x86_64_vectorcall: CommonOptions, | 211 | x86_64_vectorcall: CommonOptions, |
| 173 | x86_64_interrupt: CommonOptions, | 212 | x86_64_interrupt: CommonOptions, |
| 213 | x86_64_preserve_none: CommonOptions, | ||
| 174 | 214 | ||
| 175 | // Calling conventions for the `x86` architecture. | 215 | // Calling conventions for the `x86` architecture. |
| 176 | x86_sysv: X86RegparmOptions, | 216 | x86_sysv: X86RegparmOptions, |
| 177 | x86_win: X86RegparmOptions, | 217 | x86_win: X86RegparmOptions, |
| 218 | x86_mingw: X86RegparmOptions, | ||
| 178 | x86_stdcall: X86RegparmOptions, | 219 | x86_stdcall: X86RegparmOptions, |
| 179 | x86_fastcall: CommonOptions, | 220 | x86_fastcall: CommonOptions, |
| 180 | x86_thiscall: CommonOptions, | 221 | x86_thiscall: CommonOptions, |
| ... | @@ -197,6 +238,7 @@ pub const CallingConvention = union(enum(u8)) { | ... | @@ -197,6 +238,7 @@ pub const CallingConvention = union(enum(u8)) { |
| 197 | aarch64_aapcs_win: CommonOptions, | 238 | aarch64_aapcs_win: CommonOptions, |
| 198 | aarch64_vfabi: CommonOptions, | 239 | aarch64_vfabi: CommonOptions, |
| 199 | aarch64_vfabi_sve: CommonOptions, | 240 | aarch64_vfabi_sve: CommonOptions, |
| 241 | aarch64_preserve_none: CommonOptions, | ||
| 200 | 242 | ||
| 201 | /// The standard `alpha` calling convention. | 243 | /// The standard `alpha` calling convention. |
| 202 | alpha_osf: CommonOptions, | 244 | alpha_osf: CommonOptions, |
lib/std/log.zig+1-1| ... | @@ -53,7 +53,7 @@ pub const Level = enum { | ... | @@ -53,7 +53,7 @@ pub const Level = enum { |
| 53 | /// The default log level is based on build mode. | 53 | /// The default log level is based on build mode. |
| 54 | pub const default_level: Level = switch (builtin.mode) { | 54 | pub const default_level: Level = switch (builtin.mode) { |
| 55 | .Debug => .debug, | 55 | .Debug => .debug, |
| 56 | .ReleaseSafe, .ReleaseFast, .ReleaseSmall => .info, | 56 | .safe, .fast, .small => .info, |
| 57 | }; | 57 | }; |
| 58 | 58 | ||
| 59 | pub const ScopeLevel = struct { | 59 | pub const ScopeLevel = struct { |
lib/std/macho.zig+19| ... | @@ -588,6 +588,25 @@ pub const rpath_command = extern struct { | ... | @@ -588,6 +588,25 @@ pub const rpath_command = extern struct { |
| 588 | path: u32, | 588 | path: u32, |
| 589 | }; | 589 | }; |
| 590 | 590 | ||
| 591 | pub const encryption_info_command = extern struct { | ||
| 592 | cmd: LC = .ENCRYPTION_INFO, | ||
| 593 | cmdsize: u32 = @sizeOf(encryption_info_command), | ||
| 594 | |||
| 595 | cryptoff: u32, | ||
| 596 | cryptsize: u32, | ||
| 597 | cryptid: u32 = 0, | ||
| 598 | }; | ||
| 599 | |||
| 600 | pub const encryption_info_command_64 = extern struct { | ||
| 601 | cmd: LC = .ENCRYPTION_INFO_64, | ||
| 602 | cmdsize: u32 = @sizeOf(encryption_info_command_64), | ||
| 603 | |||
| 604 | cryptoff: u32, | ||
| 605 | cryptsize: u32, | ||
| 606 | cryptid: u32 = 0, | ||
| 607 | _pad: u32 = 0, | ||
| 608 | }; | ||
| 609 | |||
| 591 | /// The segment load command indicates that a part of this file is to be | 610 | /// The segment load command indicates that a part of this file is to be |
| 592 | /// mapped into the task's address space. The size of this segment in memory, | 611 | /// mapped into the task's address space. The size of this segment in memory, |
| 593 | /// vmsize, maybe equal to or larger than the amount to map from this file, | 612 | /// vmsize, maybe equal to or larger than the amount to map from this file, |
lib/std/math.zig+5-4| ... | @@ -75,7 +75,7 @@ pub const snan = float.snan; | ... | @@ -75,7 +75,7 @@ pub const snan = float.snan; |
| 75 | /// | 75 | /// |
| 76 | /// NaN values are never considered equal to any value. | 76 | /// NaN values are never considered equal to any value. |
| 77 | pub fn approxEqAbs(comptime T: type, x: T, y: T, tolerance: T) bool { | 77 | pub fn approxEqAbs(comptime T: type, x: T, y: T, tolerance: T) bool { |
| 78 | assert(@typeInfo(T) == .float or @typeInfo(T) == .comptime_float); | 78 | comptime assert(@typeInfo(T) == .float or @typeInfo(T) == .comptime_float); |
| 79 | assert(tolerance >= 0); | 79 | assert(tolerance >= 0); |
| 80 | 80 | ||
| 81 | // Fast path for equal values (and signed zeros and infinites). | 81 | // Fast path for equal values (and signed zeros and infinites). |
| ... | @@ -103,7 +103,7 @@ pub fn approxEqAbs(comptime T: type, x: T, y: T, tolerance: T) bool { | ... | @@ -103,7 +103,7 @@ pub fn approxEqAbs(comptime T: type, x: T, y: T, tolerance: T) bool { |
| 103 | /// | 103 | /// |
| 104 | /// NaN values are never considered equal to any value. | 104 | /// NaN values are never considered equal to any value. |
| 105 | pub fn approxEqRel(comptime T: type, x: T, y: T, tolerance: T) bool { | 105 | pub fn approxEqRel(comptime T: type, x: T, y: T, tolerance: T) bool { |
| 106 | assert(@typeInfo(T) == .float or @typeInfo(T) == .comptime_float); | 106 | comptime assert(@typeInfo(T) == .float or @typeInfo(T) == .comptime_float); |
| 107 | assert(tolerance > 0); | 107 | assert(tolerance > 0); |
| 108 | 108 | ||
| 109 | // Fast path for equal values (and signed zeros and infinites). | 109 | // Fast path for equal values (and signed zeros and infinites). |
| ... | @@ -461,7 +461,7 @@ pub fn wrap(x: anytype, r: anytype) @TypeOf(x) { | ... | @@ -461,7 +461,7 @@ pub fn wrap(x: anytype, r: anytype) @TypeOf(x) { |
| 461 | } | 461 | } |
| 462 | } | 462 | } |
| 463 | test wrap { | 463 | test wrap { |
| 464 | if (builtin.os.tag == .windows and builtin.cpu.arch == .x86) { | 464 | if (builtin.os.tag == .windows and builtin.cpu.arch == .x86 and builtin.abi == .msvc) { |
| 465 | // https://codeberg.org/ziglang/zig/issues/35520 | 465 | // https://codeberg.org/ziglang/zig/issues/35520 |
| 466 | return error.SkipZigTest; | 466 | return error.SkipZigTest; |
| 467 | } | 467 | } |
| ... | @@ -1385,7 +1385,8 @@ pub fn lerp(a: anytype, b: anytype, t: anytype) @TypeOf(a, b, t) { | ... | @@ -1385,7 +1385,8 @@ pub fn lerp(a: anytype, b: anytype, t: anytype) @TypeOf(a, b, t) { |
| 1385 | } | 1385 | } |
| 1386 | 1386 | ||
| 1387 | test lerp { | 1387 | test lerp { |
| 1388 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/17884 | 1388 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; |
| 1389 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isX86()) return error.SkipZigTest; | ||
| 1389 | if (builtin.zig_backend == .stage2_x86_64 and !comptime builtin.cpu.has(.x86, .fma)) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/17884 | 1390 | if (builtin.zig_backend == .stage2_x86_64 and !comptime builtin.cpu.has(.x86, .fma)) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/17884 |
| 1390 | 1391 | ||
| 1391 | try testing.expectEqual(@as(f64, 75), lerp(50, 100, 0.5)); | 1392 | try testing.expectEqual(@as(f64, 75), lerp(50, 100, 0.5)); |
lib/std/math/acos.zig-4| ... | @@ -337,8 +337,6 @@ fn acosBinary128(x: f128) f128 { | ... | @@ -337,8 +337,6 @@ fn acosBinary128(x: f128) f128 { |
| 337 | } | 337 | } |
| 338 | 338 | ||
| 339 | test "acosBinary16.special" { | 339 | test "acosBinary16.special" { |
| 340 | if (builtin.target.cpu.arch == .x86_64 and builtin.target.os.tag == .macos) return error.SkipZigTest; | ||
| 341 | |||
| 342 | try testing.expectApproxEqAbs(0x1.92p0, acosBinary16(0x0p+0), math.floatEpsAt(f16, 0x1.92p0)); | 340 | try testing.expectApproxEqAbs(0x1.92p0, acosBinary16(0x0p+0), math.floatEpsAt(f16, 0x1.92p0)); |
| 343 | try testing.expectApproxEqAbs(0x1.92p1, acosBinary16(-0x1p+0), math.floatEpsAt(f16, 0x1.92p1)); | 341 | try testing.expectApproxEqAbs(0x1.92p1, acosBinary16(-0x1p+0), math.floatEpsAt(f16, 0x1.92p1)); |
| 344 | try testing.expectEqual(0x0p+0, acosBinary16(0x1p+0)); | 342 | try testing.expectEqual(0x0p+0, acosBinary16(0x1p+0)); |
| ... | @@ -350,8 +348,6 @@ test "acosBinary16.special" { | ... | @@ -350,8 +348,6 @@ test "acosBinary16.special" { |
| 350 | } | 348 | } |
| 351 | 349 | ||
| 352 | test "acosBinary16" { | 350 | test "acosBinary16" { |
| 353 | if (builtin.target.cpu.arch == .x86_64 and builtin.target.os.tag == .macos) return error.SkipZigTest; | ||
| 354 | |||
| 355 | try testing.expectApproxEqAbs(0x1.834p0, acosBinary16(0x1.db4p-5), math.floatEpsAt(f16, 0x1.834p0)); | 351 | try testing.expectApproxEqAbs(0x1.834p0, acosBinary16(0x1.db4p-5), math.floatEpsAt(f16, 0x1.834p0)); |
| 356 | try testing.expectApproxEqAbs(0x1.d48p0, acosBinary16(-0x1.068p-2), math.floatEpsAt(f16, 0x1.d48p0)); | 352 | try testing.expectApproxEqAbs(0x1.d48p0, acosBinary16(-0x1.068p-2), math.floatEpsAt(f16, 0x1.d48p0)); |
| 357 | try testing.expectApproxEqAbs(0x1.b7cp0, acosBinary16(-0x1.2c4p-3), math.floatEpsAt(f16, 0x1.b7cp0)); | 353 | try testing.expectApproxEqAbs(0x1.b7cp0, acosBinary16(-0x1.2c4p-3), math.floatEpsAt(f16, 0x1.b7cp0)); |
lib/std/math/asin.zig-4| ... | @@ -326,8 +326,6 @@ fn asinBinary128(x: f128) f128 { | ... | @@ -326,8 +326,6 @@ fn asinBinary128(x: f128) f128 { |
| 326 | } | 326 | } |
| 327 | 327 | ||
| 328 | test "asinBinary16.special" { | 328 | test "asinBinary16.special" { |
| 329 | if (builtin.target.cpu.arch == .x86_64 and builtin.target.os.tag == .macos) return error.SkipZigTest; | ||
| 330 | |||
| 331 | try testing.expectApproxEqAbs(0x1.92p0, asinBinary16(0x1p+0), math.floatEpsAt(f16, 0x1.92p0)); | 329 | try testing.expectApproxEqAbs(0x1.92p0, asinBinary16(0x1p+0), math.floatEpsAt(f16, 0x1.92p0)); |
| 332 | try testing.expectApproxEqAbs(-0x1.92p0, asinBinary16(-0x1p+0), math.floatEpsAt(f16, -0x1.92p0)); | 330 | try testing.expectApproxEqAbs(-0x1.92p0, asinBinary16(-0x1p+0), math.floatEpsAt(f16, -0x1.92p0)); |
| 333 | try testing.expectEqual(0x0p+0, asinBinary16(0x0p+0)); | 331 | try testing.expectEqual(0x0p+0, asinBinary16(0x0p+0)); |
| ... | @@ -340,8 +338,6 @@ test "asinBinary16.special" { | ... | @@ -340,8 +338,6 @@ test "asinBinary16.special" { |
| 340 | } | 338 | } |
| 341 | 339 | ||
| 342 | test "asinBinary16" { | 340 | test "asinBinary16" { |
| 343 | if (builtin.target.cpu.arch == .x86_64 and builtin.target.os.tag == .macos) return error.SkipZigTest; | ||
| 344 | |||
| 345 | try testing.expectApproxEqAbs(-0x1.e4cp-6, asinBinary16(-0x1.e4cp-6), math.floatEpsAt(f16, -0x1.e4cp-6)); | 341 | try testing.expectApproxEqAbs(-0x1.e4cp-6, asinBinary16(-0x1.e4cp-6), math.floatEpsAt(f16, -0x1.e4cp-6)); |
| 346 | try testing.expectApproxEqAbs(0x1.2a8p0, asinBinary16(0x1.d68p-1), math.floatEpsAt(f16, 0x1.2a8p0)); | 342 | try testing.expectApproxEqAbs(0x1.2a8p0, asinBinary16(0x1.d68p-1), math.floatEpsAt(f16, 0x1.2a8p0)); |
| 347 | try testing.expectApproxEqAbs(-0x1.eep-1, asinBinary16(-0x1.a4cp-1), math.floatEpsAt(f16, -0x1.eep-1)); | 343 | try testing.expectApproxEqAbs(-0x1.eep-1, asinBinary16(-0x1.a4cp-1), math.floatEpsAt(f16, -0x1.eep-1)); |
lib/std/math/atan.zig-4| ... | @@ -481,8 +481,6 @@ fn atanBinary128(x: f128) f128 { | ... | @@ -481,8 +481,6 @@ fn atanBinary128(x: f128) f128 { |
| 481 | } | 481 | } |
| 482 | 482 | ||
| 483 | test "atanBinary16.special" { | 483 | test "atanBinary16.special" { |
| 484 | if (builtin.target.cpu.arch == .x86_64 and builtin.target.os.tag == .macos) return error.SkipZigTest; | ||
| 485 | |||
| 486 | try testing.expectEqual(0x0p+0, atanBinary16(0x0p+0)); | 484 | try testing.expectEqual(0x0p+0, atanBinary16(0x0p+0)); |
| 487 | try testing.expectEqual(-0x0p+0, atanBinary16(-0x0p+0)); | 485 | try testing.expectEqual(-0x0p+0, atanBinary16(-0x0p+0)); |
| 488 | try testing.expectApproxEqAbs(0x1.92p-1, atanBinary16(0x1p+0), math.floatEpsAt(f16, 0x1.92p-1)); | 486 | try testing.expectApproxEqAbs(0x1.92p-1, atanBinary16(0x1p+0), math.floatEpsAt(f16, 0x1.92p-1)); |
| ... | @@ -493,8 +491,6 @@ test "atanBinary16.special" { | ... | @@ -493,8 +491,6 @@ test "atanBinary16.special" { |
| 493 | } | 491 | } |
| 494 | 492 | ||
| 495 | test "atanBinary16" { | 493 | test "atanBinary16" { |
| 496 | if (builtin.target.cpu.arch == .x86_64 and builtin.target.os.tag == .macos) return error.SkipZigTest; | ||
| 497 | |||
| 498 | try testing.expectApproxEqAbs(-0x1.74cp-2, atanBinary16(-0x1.864p-2), math.floatEpsAt(f16, -0x1.74cp-2)); | 494 | try testing.expectApproxEqAbs(-0x1.74cp-2, atanBinary16(-0x1.864p-2), math.floatEpsAt(f16, -0x1.74cp-2)); |
| 499 | try testing.expectApproxEqAbs(-0x1.374p0, atanBinary16(-0x1.59cp1), math.floatEpsAt(f16, -0x1.374p0)); | 495 | try testing.expectApproxEqAbs(-0x1.374p0, atanBinary16(-0x1.59cp1), math.floatEpsAt(f16, -0x1.374p0)); |
| 500 | try testing.expectApproxEqAbs(-0x1.11cp0, atanBinary16(-0x1.d2cp0), math.floatEpsAt(f16, -0x1.11cp0)); | 496 | try testing.expectApproxEqAbs(-0x1.11cp0, atanBinary16(-0x1.d2cp0), math.floatEpsAt(f16, -0x1.11cp0)); |
lib/std/math/atan2.zig+4-4| ... | @@ -252,8 +252,8 @@ test "atan2_32.special" { | ... | @@ -252,8 +252,8 @@ test "atan2_32.special" { |
| 252 | 252 | ||
| 253 | try expect(math.isNan(atan2_32(1.0, math.nan(f32)))); | 253 | try expect(math.isNan(atan2_32(1.0, math.nan(f32)))); |
| 254 | try expect(math.isNan(atan2_32(math.nan(f32), 1.0))); | 254 | try expect(math.isNan(atan2_32(math.nan(f32), 1.0))); |
| 255 | try expect(atan2_32(0.0, 5.0) == 0.0); | 255 | try expect(math.isPositiveZero(atan2_32(0.0, 5.0))); |
| 256 | try expect(atan2_32(-0.0, 5.0) == -0.0); | 256 | try expect(math.isNegativeZero(atan2_32(-0.0, 5.0))); |
| 257 | try expect(math.approxEqAbs(f32, atan2_32(0.0, -5.0), math.pi, epsilon)); | 257 | try expect(math.approxEqAbs(f32, atan2_32(0.0, -5.0), math.pi, epsilon)); |
| 258 | //expect(math.approxEqAbs(f32, atan2_32(-0.0, -5.0), -math.pi, .{.rel=0,.abs=epsilon})); TODO support negative zero? | 258 | //expect(math.approxEqAbs(f32, atan2_32(-0.0, -5.0), -math.pi, .{.rel=0,.abs=epsilon})); TODO support negative zero? |
| 259 | try expect(math.approxEqAbs(f32, atan2_32(1.0, 0.0), math.pi / 2.0, epsilon)); | 259 | try expect(math.approxEqAbs(f32, atan2_32(1.0, 0.0), math.pi / 2.0, epsilon)); |
| ... | @@ -276,8 +276,8 @@ test "atan2_64.special" { | ... | @@ -276,8 +276,8 @@ test "atan2_64.special" { |
| 276 | 276 | ||
| 277 | try expect(math.isNan(atan2_64(1.0, math.nan(f64)))); | 277 | try expect(math.isNan(atan2_64(1.0, math.nan(f64)))); |
| 278 | try expect(math.isNan(atan2_64(math.nan(f64), 1.0))); | 278 | try expect(math.isNan(atan2_64(math.nan(f64), 1.0))); |
| 279 | try expect(atan2_64(0.0, 5.0) == 0.0); | 279 | try expect(math.isPositiveZero(atan2_64(0.0, 5.0))); |
| 280 | try expect(atan2_64(-0.0, 5.0) == -0.0); | 280 | try expect(math.isNegativeZero(atan2_64(-0.0, 5.0))); |
| 281 | try expect(math.approxEqAbs(f64, atan2_64(0.0, -5.0), math.pi, epsilon)); | 281 | try expect(math.approxEqAbs(f64, atan2_64(0.0, -5.0), math.pi, epsilon)); |
| 282 | //expect(math.approxEqAbs(f64, atan2_64(-0.0, -5.0), -math.pi, .{.rel=0,.abs=epsilon})); TODO support negative zero? | 282 | //expect(math.approxEqAbs(f64, atan2_64(-0.0, -5.0), -math.pi, .{.rel=0,.abs=epsilon})); TODO support negative zero? |
| 283 | try expect(math.approxEqAbs(f64, atan2_64(1.0, 0.0), math.pi / 2.0, epsilon)); | 283 | try expect(math.approxEqAbs(f64, atan2_64(1.0, 0.0), math.pi / 2.0, epsilon)); |
lib/std/math/big/int_test.zig+1-38| ... | @@ -1,5 +1,4 @@ | ... | @@ -1,5 +1,4 @@ |
| 1 | const std = @import("../../std.zig"); | 1 | const std = @import("../../std.zig"); |
| 2 | const builtin = @import("builtin"); | ||
| 3 | const mem = std.mem; | 2 | const mem = std.mem; |
| 4 | const testing = std.testing; | 3 | const testing = std.testing; |
| 5 | const Managed = std.math.big.int.Managed; | 4 | const Managed = std.math.big.int.Managed; |
| ... | @@ -276,8 +275,6 @@ fn setFloat(comptime Float: type) !void { | ... | @@ -276,8 +275,6 @@ fn setFloat(comptime Float: type) !void { |
| 276 | try expectNormalized(1 << 10, res.toConst()); | 275 | try expectNormalized(1 << 10, res.toConst()); |
| 277 | } | 276 | } |
| 278 | test setFloat { | 277 | test setFloat { |
| 279 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 280 | |||
| 281 | try setFloat(f16); | 278 | try setFloat(f16); |
| 282 | try setFloat(f32); | 279 | try setFloat(f32); |
| 283 | try setFloat(f64); | 280 | try setFloat(f64); |
| ... | @@ -484,7 +481,6 @@ fn toFloat(comptime Float: type) !void { | ... | @@ -484,7 +481,6 @@ fn toFloat(comptime Float: type) !void { |
| 484 | ); | 481 | ); |
| 485 | } | 482 | } |
| 486 | test toFloat { | 483 | test toFloat { |
| 487 | if (builtin.cpu.arch == .x86) return error.SkipZigTest; | ||
| 488 | try toFloat(f16); | 484 | try toFloat(f16); |
| 489 | try toFloat(f32); | 485 | try toFloat(f32); |
| 490 | try toFloat(f64); | 486 | try toFloat(f64); |
| ... | @@ -1391,8 +1387,6 @@ test "mul multi-single" { | ... | @@ -1391,8 +1387,6 @@ test "mul multi-single" { |
| 1391 | } | 1387 | } |
| 1392 | 1388 | ||
| 1393 | test "mul multi-multi" { | 1389 | test "mul multi-multi" { |
| 1394 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 1395 | |||
| 1396 | var op1: u256 = 0x998888efefefefefefefef; | 1390 | var op1: u256 = 0x998888efefefefefefefef; |
| 1397 | var op2: u256 = 0x333000abababababababab; | 1391 | var op2: u256 = 0x333000abababababababab; |
| 1398 | _ = .{ &op1, &op2 }; | 1392 | _ = .{ &op1, &op2 }; |
| ... | @@ -1514,8 +1508,6 @@ test "mulWrap single-single signed" { | ... | @@ -1514,8 +1508,6 @@ test "mulWrap single-single signed" { |
| 1514 | } | 1508 | } |
| 1515 | 1509 | ||
| 1516 | test "mulWrap multi-multi unsigned" { | 1510 | test "mulWrap multi-multi unsigned" { |
| 1517 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 1518 | |||
| 1519 | var op1: u256 = 0x998888efefefefefefefef; | 1511 | var op1: u256 = 0x998888efefefefefefefef; |
| 1520 | var op2: u256 = 0x333000abababababababab; | 1512 | var op2: u256 = 0x333000abababababababab; |
| 1521 | _ = .{ &op1, &op2 }; | 1513 | _ = .{ &op1, &op2 }; |
| ... | @@ -1533,11 +1525,6 @@ test "mulWrap multi-multi unsigned" { | ... | @@ -1533,11 +1525,6 @@ test "mulWrap multi-multi unsigned" { |
| 1533 | } | 1525 | } |
| 1534 | 1526 | ||
| 1535 | test "mulWrap multi-multi signed" { | 1527 | test "mulWrap multi-multi signed" { |
| 1536 | switch (builtin.zig_backend) { | ||
| 1537 | .stage2_c => return error.SkipZigTest, | ||
| 1538 | else => {}, | ||
| 1539 | } | ||
| 1540 | |||
| 1541 | var a = try Managed.initSet(testing.allocator, maxInt(SignedDoubleLimb) - 1); | 1528 | var a = try Managed.initSet(testing.allocator, maxInt(SignedDoubleLimb) - 1); |
| 1542 | defer a.deinit(); | 1529 | defer a.deinit(); |
| 1543 | var b = try Managed.initSet(testing.allocator, maxInt(SignedDoubleLimb)); | 1530 | var b = try Managed.initSet(testing.allocator, maxInt(SignedDoubleLimb)); |
| ... | @@ -1744,8 +1731,6 @@ test "div q=0 alias" { | ... | @@ -1744,8 +1731,6 @@ test "div q=0 alias" { |
| 1744 | } | 1731 | } |
| 1745 | 1732 | ||
| 1746 | test "div multi-multi q < r" { | 1733 | test "div multi-multi q < r" { |
| 1747 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 1748 | |||
| 1749 | const op1 = 0x1ffffffff0078f432; | 1734 | const op1 = 0x1ffffffff0078f432; |
| 1750 | const op2 = 0x1ffffffff01000000; | 1735 | const op2 = 0x1ffffffff01000000; |
| 1751 | var a = try Managed.initSet(testing.allocator, op1); | 1736 | var a = try Managed.initSet(testing.allocator, op1); |
| ... | @@ -2166,8 +2151,6 @@ test "div ceil multi-limb" { | ... | @@ -2166,8 +2151,6 @@ test "div ceil multi-limb" { |
| 2166 | } | 2151 | } |
| 2167 | 2152 | ||
| 2168 | test "div multi-multi with rem" { | 2153 | test "div multi-multi with rem" { |
| 2169 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 2170 | |||
| 2171 | var a = try Managed.initSet(testing.allocator, 0x8888999911110000ffffeeeeddddccccbbbbaaaa9999); | 2154 | var a = try Managed.initSet(testing.allocator, 0x8888999911110000ffffeeeeddddccccbbbbaaaa9999); |
| 2172 | defer a.deinit(); | 2155 | defer a.deinit(); |
| 2173 | var b = try Managed.initSet(testing.allocator, 0x99990000111122223333); | 2156 | var b = try Managed.initSet(testing.allocator, 0x99990000111122223333); |
| ... | @@ -2184,8 +2167,6 @@ test "div multi-multi with rem" { | ... | @@ -2184,8 +2167,6 @@ test "div multi-multi with rem" { |
| 2184 | } | 2167 | } |
| 2185 | 2168 | ||
| 2186 | test "div multi-multi no rem" { | 2169 | test "div multi-multi no rem" { |
| 2187 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 2188 | |||
| 2189 | var a = try Managed.initSet(testing.allocator, 0x8888999911110000ffffeeeedb4fec200ee3a4286361); | 2170 | var a = try Managed.initSet(testing.allocator, 0x8888999911110000ffffeeeedb4fec200ee3a4286361); |
| 2190 | defer a.deinit(); | 2171 | defer a.deinit(); |
| 2191 | var b = try Managed.initSet(testing.allocator, 0x99990000111122223333); | 2172 | var b = try Managed.initSet(testing.allocator, 0x99990000111122223333); |
| ... | @@ -2202,8 +2183,6 @@ test "div multi-multi no rem" { | ... | @@ -2202,8 +2183,6 @@ test "div multi-multi no rem" { |
| 2202 | } | 2183 | } |
| 2203 | 2184 | ||
| 2204 | test "div multi-multi (2 branch)" { | 2185 | test "div multi-multi (2 branch)" { |
| 2205 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 2206 | |||
| 2207 | var a = try Managed.initSet(testing.allocator, 0x866666665555555588888887777777761111111111111111); | 2186 | var a = try Managed.initSet(testing.allocator, 0x866666665555555588888887777777761111111111111111); |
| 2208 | defer a.deinit(); | 2187 | defer a.deinit(); |
| 2209 | var b = try Managed.initSet(testing.allocator, 0x86666666555555554444444433333333); | 2188 | var b = try Managed.initSet(testing.allocator, 0x86666666555555554444444433333333); |
| ... | @@ -2220,8 +2199,6 @@ test "div multi-multi (2 branch)" { | ... | @@ -2220,8 +2199,6 @@ test "div multi-multi (2 branch)" { |
| 2220 | } | 2199 | } |
| 2221 | 2200 | ||
| 2222 | test "div multi-multi (3.1/3.3 branch)" { | 2201 | test "div multi-multi (3.1/3.3 branch)" { |
| 2223 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 2224 | |||
| 2225 | var a = try Managed.initSet(testing.allocator, 0x11111111111111111111111111111111111111111111111111111111111111); | 2202 | var a = try Managed.initSet(testing.allocator, 0x11111111111111111111111111111111111111111111111111111111111111); |
| 2226 | defer a.deinit(); | 2203 | defer a.deinit(); |
| 2227 | var b = try Managed.initSet(testing.allocator, 0x1111111111111111111111111111111111111111171); | 2204 | var b = try Managed.initSet(testing.allocator, 0x1111111111111111111111111111111111111111171); |
| ... | @@ -2238,8 +2215,6 @@ test "div multi-multi (3.1/3.3 branch)" { | ... | @@ -2238,8 +2215,6 @@ test "div multi-multi (3.1/3.3 branch)" { |
| 2238 | } | 2215 | } |
| 2239 | 2216 | ||
| 2240 | test "div multi-single zero-limb trailing" { | 2217 | test "div multi-single zero-limb trailing" { |
| 2241 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 2242 | |||
| 2243 | var a = try Managed.initSet(testing.allocator, 0x60000000000000000000000000000000000000000000000000000000000000000); | 2218 | var a = try Managed.initSet(testing.allocator, 0x60000000000000000000000000000000000000000000000000000000000000000); |
| 2244 | defer a.deinit(); | 2219 | defer a.deinit(); |
| 2245 | var b = try Managed.initSet(testing.allocator, 0x10000000000000000); | 2220 | var b = try Managed.initSet(testing.allocator, 0x10000000000000000); |
| ... | @@ -2258,8 +2233,6 @@ test "div multi-single zero-limb trailing" { | ... | @@ -2258,8 +2233,6 @@ test "div multi-single zero-limb trailing" { |
| 2258 | } | 2233 | } |
| 2259 | 2234 | ||
| 2260 | test "div multi-multi zero-limb trailing (with rem)" { | 2235 | test "div multi-multi zero-limb trailing (with rem)" { |
| 2261 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 2262 | |||
| 2263 | var a = try Managed.initSet(testing.allocator, 0x86666666555555558888888777777776111111111111111100000000000000000000000000000000); | 2236 | var a = try Managed.initSet(testing.allocator, 0x86666666555555558888888777777776111111111111111100000000000000000000000000000000); |
| 2264 | defer a.deinit(); | 2237 | defer a.deinit(); |
| 2265 | var b = try Managed.initSet(testing.allocator, 0x8666666655555555444444443333333300000000000000000000000000000000); | 2238 | var b = try Managed.initSet(testing.allocator, 0x8666666655555555444444443333333300000000000000000000000000000000); |
| ... | @@ -2279,8 +2252,6 @@ test "div multi-multi zero-limb trailing (with rem)" { | ... | @@ -2279,8 +2252,6 @@ test "div multi-multi zero-limb trailing (with rem)" { |
| 2279 | } | 2252 | } |
| 2280 | 2253 | ||
| 2281 | test "div multi-multi zero-limb trailing (with rem) and dividend zero-limb count > divisor zero-limb count" { | 2254 | test "div multi-multi zero-limb trailing (with rem) and dividend zero-limb count > divisor zero-limb count" { |
| 2282 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 2283 | |||
| 2284 | var a = try Managed.initSet(testing.allocator, 0x8666666655555555888888877777777611111111111111110000000000000000); | 2255 | var a = try Managed.initSet(testing.allocator, 0x8666666655555555888888877777777611111111111111110000000000000000); |
| 2285 | defer a.deinit(); | 2256 | defer a.deinit(); |
| 2286 | var b = try Managed.initSet(testing.allocator, 0x8666666655555555444444443333333300000000000000000000000000000000); | 2257 | var b = try Managed.initSet(testing.allocator, 0x8666666655555555444444443333333300000000000000000000000000000000); |
| ... | @@ -2300,8 +2271,6 @@ test "div multi-multi zero-limb trailing (with rem) and dividend zero-limb count | ... | @@ -2300,8 +2271,6 @@ test "div multi-multi zero-limb trailing (with rem) and dividend zero-limb count |
| 2300 | } | 2271 | } |
| 2301 | 2272 | ||
| 2302 | test "div multi-multi zero-limb trailing (with rem) and dividend zero-limb count < divisor zero-limb count" { | 2273 | test "div multi-multi zero-limb trailing (with rem) and dividend zero-limb count < divisor zero-limb count" { |
| 2303 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 2304 | |||
| 2305 | var a = try Managed.initSet(testing.allocator, 0x86666666555555558888888777777776111111111111111100000000000000000000000000000000); | 2274 | var a = try Managed.initSet(testing.allocator, 0x86666666555555558888888777777776111111111111111100000000000000000000000000000000); |
| 2306 | defer a.deinit(); | 2275 | defer a.deinit(); |
| 2307 | var b = try Managed.initSet(testing.allocator, 0x866666665555555544444444333333330000000000000000); | 2276 | var b = try Managed.initSet(testing.allocator, 0x866666665555555544444444333333330000000000000000); |
| ... | @@ -2832,10 +2801,6 @@ test "bitNotWrap signed multi" { | ... | @@ -2832,10 +2801,6 @@ test "bitNotWrap signed multi" { |
| 2832 | } | 2801 | } |
| 2833 | 2802 | ||
| 2834 | test "bitNotWrap more than two limbs" { | 2803 | test "bitNotWrap more than two limbs" { |
| 2835 | // This test requires int sizes greater than 128 bits. | ||
| 2836 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 2837 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 2838 | |||
| 2839 | var a = try Managed.initSet(testing.allocator, maxInt(Limb)); | 2804 | var a = try Managed.initSet(testing.allocator, maxInt(Limb)); |
| 2840 | defer a.deinit(); | 2805 | defer a.deinit(); |
| 2841 | 2806 | ||
| ... | @@ -3179,8 +3144,6 @@ test "gcd non-one large" { | ... | @@ -3179,8 +3144,6 @@ test "gcd non-one large" { |
| 3179 | } | 3144 | } |
| 3180 | 3145 | ||
| 3181 | test "gcd large multi-limb result" { | 3146 | test "gcd large multi-limb result" { |
| 3182 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 3183 | |||
| 3184 | var a = try Managed.initSet(testing.allocator, 0x12345678123456781234567812345678123456781234567812345678); | 3147 | var a = try Managed.initSet(testing.allocator, 0x12345678123456781234567812345678123456781234567812345678); |
| 3185 | defer a.deinit(); | 3148 | defer a.deinit(); |
| 3186 | var b = try Managed.initSet(testing.allocator, 0x12345671234567123456712345671234567123456712345671234567); | 3149 | var b = try Managed.initSet(testing.allocator, 0x12345671234567123456712345671234567123456712345671234567); |
| ... | @@ -3431,7 +3394,7 @@ test "big int conversion read/write twos complement" { | ... | @@ -3431,7 +3394,7 @@ test "big int conversion read/write twos complement" { |
| 3431 | var buffer1 = try testing.allocator.alloc(u8, 64); | 3394 | var buffer1 = try testing.allocator.alloc(u8, 64); |
| 3432 | defer testing.allocator.free(buffer1); | 3395 | defer testing.allocator.free(buffer1); |
| 3433 | 3396 | ||
| 3434 | const endians = [_]std.builtin.Endian{ .little, .big }; | 3397 | const endians = [_]std.lang.Endian{ .little, .big }; |
| 3435 | const abi_size = 64; | 3398 | const abi_size = 64; |
| 3436 | 3399 | ||
| 3437 | for (endians) |endian| { | 3400 | for (endians) |endian| { |
lib/std/math/float.zig+3-3| ... | @@ -112,17 +112,17 @@ pub fn FloatRepr(comptime Float: type) type { | ... | @@ -112,17 +112,17 @@ pub fn FloatRepr(comptime Float: type) type { |
| 112 | /// This currently truncates denormal values, which needs to be fixed before this can be used to | 112 | /// This currently truncates denormal values, which needs to be fixed before this can be used to |
| 113 | /// produce a rounded value. | 113 | /// produce a rounded value. |
| 114 | pub fn reconstruct(normalized: Normalized, sign: std.math.Sign) Float { | 114 | pub fn reconstruct(normalized: Normalized, sign: std.math.Sign) Float { |
| 115 | if (normalized.exponent > BiasedExponent.max_normal.unbias()) return @bitCast(Repr{ | 115 | if (normalized.exponent > comptime BiasedExponent.max_normal.unbias()) return @bitCast(Repr{ |
| 116 | .mantissa = 0, | 116 | .mantissa = 0, |
| 117 | .exponent = .infinite, | 117 | .exponent = .infinite, |
| 118 | .sign = sign, | 118 | .sign = sign, |
| 119 | }); | 119 | }); |
| 120 | const mantissa = @as(Mantissa, 1 << fractional_bits) | normalized.fraction; | 120 | const mantissa = @as(Mantissa, 1 << fractional_bits) | normalized.fraction; |
| 121 | if (normalized.exponent < BiasedExponent.min_normal.unbias()) return @bitCast(Repr{ | 121 | if (normalized.exponent < comptime BiasedExponent.min_normal.unbias()) return @bitCast(Repr{ |
| 122 | .mantissa = @truncate(std.math.shr( | 122 | .mantissa = @truncate(std.math.shr( |
| 123 | Mantissa, | 123 | Mantissa, |
| 124 | mantissa, | 124 | mantissa, |
| 125 | BiasedExponent.min_normal.unbias() - normalized.exponent, | 125 | (comptime BiasedExponent.min_normal.unbias()) - normalized.exponent, |
| 126 | )), | 126 | )), |
| 127 | .exponent = .denormal, | 127 | .exponent = .denormal, |
| 128 | .sign = sign, | 128 | .sign = sign, |
lib/std/math/gamma.zig-2| ... | @@ -263,8 +263,6 @@ test gamma { | ... | @@ -263,8 +263,6 @@ test gamma { |
| 263 | } | 263 | } |
| 264 | 264 | ||
| 265 | test "gamma.special" { | 265 | test "gamma.special" { |
| 266 | if (builtin.cpu.arch.isArm() and builtin.target.abi.float() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234 | ||
| 267 | |||
| 268 | inline for (&.{ f32, f64 }) |T| { | 266 | inline for (&.{ f32, f64 }) |T| { |
| 269 | try expect(std.math.isNan(gamma(T, -std.math.nan(T)))); | 267 | try expect(std.math.isNan(gamma(T, -std.math.nan(T)))); |
| 270 | try expect(std.math.isNan(gamma(T, std.math.nan(T)))); | 268 | try expect(std.math.isNan(gamma(T, std.math.nan(T)))); |
lib/std/math/hypot.zig-9| ... | @@ -1,4 +1,3 @@ | ... | @@ -1,4 +1,3 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 2 | const std = @import("../std.zig"); | 1 | const std = @import("../std.zig"); |
| 3 | const math = std.math; | 2 | const math = std.math; |
| 4 | const expect = std.testing.expect; | 3 | const expect = std.testing.expect; |
| ... | @@ -93,14 +92,10 @@ const hypot_test_cases = .{ | ... | @@ -93,14 +92,10 @@ const hypot_test_cases = .{ |
| 93 | }; | 92 | }; |
| 94 | 93 | ||
| 95 | test hypot { | 94 | test hypot { |
| 96 | if (builtin.cpu.arch.isPowerPC() and builtin.mode != .Debug) return error.SkipZigTest; // https://github.com/llvm/llvm-project/issues/171869 | ||
| 97 | try expect(hypot(0.3, 0.4) == 0.5); | 95 | try expect(hypot(0.3, 0.4) == 0.5); |
| 98 | } | 96 | } |
| 99 | 97 | ||
| 100 | test "hypot.correct" { | 98 | test "hypot.correct" { |
| 101 | if (builtin.target.cpu.arch == .x86_64 and builtin.target.os.tag == .macos) return error.SkipZigTest; | ||
| 102 | if (builtin.cpu.arch.isPowerPC() and builtin.mode != .Debug) return error.SkipZigTest; // https://github.com/llvm/llvm-project/issues/171869 | ||
| 103 | |||
| 104 | inline for (.{ f16, f32, f64, f128 }) |T| { | 99 | inline for (.{ f16, f32, f64, f128 }) |T| { |
| 105 | inline for (hypot_test_cases) |v| { | 100 | inline for (hypot_test_cases) |v| { |
| 106 | const a: T, const b: T, const c: T = v; | 101 | const a: T, const b: T, const c: T = v; |
| ... | @@ -110,9 +105,6 @@ test "hypot.correct" { | ... | @@ -110,9 +105,6 @@ test "hypot.correct" { |
| 110 | } | 105 | } |
| 111 | 106 | ||
| 112 | test "hypot.precise" { | 107 | test "hypot.precise" { |
| 113 | if (builtin.target.cpu.arch == .x86_64 and builtin.target.os.tag == .macos) return error.SkipZigTest; | ||
| 114 | if (builtin.cpu.arch.isPowerPC() and builtin.mode != .Debug) return error.SkipZigTest; // https://github.com/llvm/llvm-project/issues/171869 | ||
| 115 | |||
| 116 | inline for (.{ f16, f32, f64 }) |T| { // f128 seems to be 5 ulp | 108 | inline for (.{ f16, f32, f64 }) |T| { // f128 seems to be 5 ulp |
| 117 | inline for (hypot_test_cases) |v| { | 109 | inline for (hypot_test_cases) |v| { |
| 118 | const a: T, const b: T, const c: T = v; | 110 | const a: T, const b: T, const c: T = v; |
| ... | @@ -122,7 +114,6 @@ test "hypot.precise" { | ... | @@ -122,7 +114,6 @@ test "hypot.precise" { |
| 122 | } | 114 | } |
| 123 | 115 | ||
| 124 | test "hypot.special" { | 116 | test "hypot.special" { |
| 125 | if (builtin.cpu.arch.isPowerPC() and builtin.mode != .Debug) return error.SkipZigTest; // https://github.com/llvm/llvm-project/issues/171869 | ||
| 126 | @setEvalBranchQuota(2000); | 117 | @setEvalBranchQuota(2000); |
| 127 | inline for (.{ f16, f32, f64, f128 }) |T| { | 118 | inline for (.{ f16, f32, f64, f128 }) |T| { |
| 128 | try expect(math.isNan(hypot(nan(T), 0.0))); | 119 | try expect(math.isNan(hypot(nan(T), 0.0))); |
lib/std/math/isnan.zig+1-7| ... | @@ -27,13 +27,6 @@ test isNan { | ... | @@ -27,13 +27,6 @@ test isNan { |
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | test isSignalNan { | 29 | test isSignalNan { |
| 30 | if (builtin.zig_backend == .stage2_x86_64 and builtin.object_format == .coff and builtin.abi != .gnu) return error.SkipZigTest; | ||
| 31 | |||
| 32 | if (builtin.os.tag == .windows) { | ||
| 33 | // https://codeberg.org/ziglang/zig/issues/35519 | ||
| 34 | return error.SkipZigTest; | ||
| 35 | } | ||
| 36 | |||
| 37 | inline for ([_]type{ f16, f32, f64, f80, f128, c_longdouble }) |T| { | 30 | inline for ([_]type{ f16, f32, f64, f80, f128, c_longdouble }) |T| { |
| 38 | // TODO: Signalling NaN values get converted to quiet NaN values in | 31 | // TODO: Signalling NaN values get converted to quiet NaN values in |
| 39 | // some cases where they shouldn't such that this can fail. | 32 | // some cases where they shouldn't such that this can fail. |
| ... | @@ -43,6 +36,7 @@ test isSignalNan { | ... | @@ -43,6 +36,7 @@ test isSignalNan { |
| 43 | builtin.cpu.arch != .hexagon and | 36 | builtin.cpu.arch != .hexagon and |
| 44 | !builtin.cpu.arch.isMIPS32() and | 37 | !builtin.cpu.arch.isMIPS32() and |
| 45 | !builtin.cpu.arch.isPowerPC() and | 38 | !builtin.cpu.arch.isPowerPC() and |
| 39 | !(builtin.cpu.arch.isX86() and builtin.os.tag == .windows and builtin.abi == .msvc) and // https://codeberg.org/ziglang/zig/issues/35519 | ||
| 46 | builtin.zig_backend != .stage2_c) | 40 | builtin.zig_backend != .stage2_c) |
| 47 | { | 41 | { |
| 48 | try expect(isSignalNan(math.snan(T))); | 42 | try expect(isSignalNan(math.snan(T))); |
lib/std/math/log10.zig-5| ... | @@ -1,5 +1,4 @@ | ... | @@ -1,5 +1,4 @@ |
| 1 | const std = @import("../std.zig"); | 1 | const std = @import("../std.zig"); |
| 2 | const builtin = @import("builtin"); | ||
| 3 | const testing = std.testing; | 2 | const testing = std.testing; |
| 4 | 3 | ||
| 5 | /// Returns the base-10 logarithm of x. | 4 | /// Returns the base-10 logarithm of x. |
| ... | @@ -135,10 +134,6 @@ inline fn less_than_5(x: u32) u32 { | ... | @@ -135,10 +134,6 @@ inline fn less_than_5(x: u32) u32 { |
| 135 | } | 134 | } |
| 136 | 135 | ||
| 137 | test log10_int { | 136 | test log10_int { |
| 138 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 139 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | ||
| 140 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 141 | |||
| 142 | inline for ( | 137 | inline for ( |
| 143 | .{ u8, u16, u32, u64, u128, u256, u512 }, | 138 | .{ u8, u16, u32, u64, u128, u256, u512 }, |
| 144 | .{ 2, 4, 9, 19, 38, 77, 154 }, | 139 | .{ 2, 4, 9, 19, 38, 77, 154 }, |
lib/std/math/modf.zig-4| ... | @@ -1,5 +1,4 @@ | ... | @@ -1,5 +1,4 @@ |
| 1 | const std = @import("../std.zig"); | 1 | const std = @import("../std.zig"); |
| 2 | const builtin = @import("builtin"); | ||
| 3 | const math = std.math; | 2 | const math = std.math; |
| 4 | const expect = std.testing.expect; | 3 | const expect = std.testing.expect; |
| 5 | const expectEqual = std.testing.expectEqual; | 4 | const expectEqual = std.testing.expectEqual; |
| ... | @@ -85,9 +84,6 @@ fn ModfTests(comptime T: type) type { | ... | @@ -85,9 +84,6 @@ fn ModfTests(comptime T: type) type { |
| 85 | try expectApproxEqAbs(expected_c, r.fpart, epsilon); | 84 | try expectApproxEqAbs(expected_c, r.fpart, epsilon); |
| 86 | } | 85 | } |
| 87 | test "vector" { | 86 | test "vector" { |
| 88 | if (builtin.os.tag.isDarwin() and builtin.cpu.arch == .aarch64) return error.SkipZigTest; | ||
| 89 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; // https://github.com/llvm/llvm-project/issues/194256 | ||
| 90 | |||
| 91 | const widths = [_]comptime_int{ 1, 2, 3, 4, 8, 16 }; | 87 | const widths = [_]comptime_int{ 1, 2, 3, 4, 8, 16 }; |
| 92 | 88 | ||
| 93 | inline for (widths) |len| { | 89 | inline for (widths) |len| { |
lib/std/math/signbit.zig+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 1 | const std = @import("../std.zig"); | 2 | const std = @import("../std.zig"); |
| 2 | const math = std.math; | 3 | const math = std.math; |
| 3 | const expect = std.testing.expect; | 4 | const expect = std.testing.expect; |
lib/std/mem.zig+166-127| ... | @@ -9,6 +9,7 @@ const assert = debug.assert; | ... | @@ -9,6 +9,7 @@ const assert = debug.assert; |
| 9 | const math = std.math; | 9 | const math = std.math; |
| 10 | const testing = std.testing; | 10 | const testing = std.testing; |
| 11 | const Endian = std.lang.Endian; | 11 | const Endian = std.lang.Endian; |
| 12 | const AbsorbSentinel = std.meta.AbsorbSentinel; | ||
| 12 | 13 | ||
| 13 | /// The standard library currently thoroughly depends on byte size | 14 | /// The standard library currently thoroughly depends on byte size |
| 14 | /// being 8 bits. (see the use of u8 throughout allocation code as | 15 | /// being 8 bits. (see the use of u8 throughout allocation code as |
| ... | @@ -756,7 +757,8 @@ pub fn eql(comptime T: type, a: []const T, b: []const T) bool { | ... | @@ -756,7 +757,8 @@ pub fn eql(comptime T: type, a: []const T, b: []const T) bool { |
| 756 | } | 757 | } |
| 757 | 758 | ||
| 758 | if (a.len != b.len) return false; | 759 | if (a.len != b.len) return false; |
| 759 | if (a.len == 0 or a.ptr == b.ptr) return true; | 760 | if (a.len == 0) return true; |
| 761 | if (@typeInfo(T) != .float and a.ptr == b.ptr) return true; | ||
| 760 | 762 | ||
| 761 | for (a, b) |a_elem, b_elem| { | 763 | for (a, b) |a_elem, b_elem| { |
| 762 | if (a_elem != b_elem) return false; | 764 | if (a_elem != b_elem) return false; |
| ... | @@ -781,6 +783,9 @@ test eql { | ... | @@ -781,6 +783,9 @@ test eql { |
| 781 | 783 | ||
| 782 | try testing.expect(eql(void, &.{ {}, {} }, &.{ {}, {} })); | 784 | try testing.expect(eql(void, &.{ {}, {} }, &.{ {}, {} })); |
| 783 | try testing.expect(!eql(void, &.{{}}, &.{ {}, {} })); | 785 | try testing.expect(!eql(void, &.{{}}, &.{ {}, {} })); |
| 786 | |||
| 787 | const x: [3]f64 = .{ 42.0, math.nan(f64), 3.1415 }; | ||
| 788 | try testing.expect(!eql(f64, &x, &x)); | ||
| 784 | } | 789 | } |
| 785 | 790 | ||
| 786 | /// std.mem.eql heavily optimized for slices of bytes. | 791 | /// std.mem.eql heavily optimized for slices of bytes. |
| ... | @@ -850,20 +855,25 @@ pub const indexOfDiff = findDiff; | ... | @@ -850,20 +855,25 @@ pub const indexOfDiff = findDiff; |
| 850 | /// Compares two slices and returns the index of the first inequality. | 855 | /// Compares two slices and returns the index of the first inequality. |
| 851 | /// Returns null if the slices are equal. | 856 | /// Returns null if the slices are equal. |
| 852 | pub fn findDiff(comptime T: type, a: []const T, b: []const T) ?usize { | 857 | pub fn findDiff(comptime T: type, a: []const T, b: []const T) ?usize { |
| 853 | const shortest = @min(a.len, b.len); | 858 | const shorter = @min(a.len, b.len); |
| 854 | if (a.ptr == b.ptr) | 859 | if (@typeInfo(T) != .float and a.ptr == b.ptr) { |
| 855 | return if (a.len == b.len) null else shortest; | 860 | return if (a.len == b.len) null else shorter; |
| 856 | var index: usize = 0; | 861 | } |
| 857 | while (index < shortest) : (index += 1) if (a[index] != b[index]) return index; | 862 | for (a[0..shorter], b[0..shorter], 0..) |a_elem, b_elem, i| { |
| 858 | return if (a.len == b.len) null else shortest; | 863 | if (a_elem != b_elem) return i; |
| 864 | } | ||
| 865 | return if (a.len == b.len) null else shorter; | ||
| 859 | } | 866 | } |
| 860 | 867 | ||
| 861 | test findDiff { | 868 | test findDiff { |
| 862 | try testing.expectEqual(findDiff(u8, "one", "one"), null); | 869 | try testing.expectEqual(null, findDiff(u8, "one", "one")); |
| 863 | try testing.expectEqual(findDiff(u8, "one two", "one"), 3); | 870 | try testing.expectEqual(3, findDiff(u8, "one two", "one")); |
| 864 | try testing.expectEqual(findDiff(u8, "one", "one two"), 3); | 871 | try testing.expectEqual(3, findDiff(u8, "one", "one two")); |
| 865 | try testing.expectEqual(findDiff(u8, "one twx", "one two"), 6); | 872 | try testing.expectEqual(6, findDiff(u8, "one twx", "one two")); |
| 866 | try testing.expectEqual(findDiff(u8, "xne", "one"), 0); | 873 | try testing.expectEqual(0, findDiff(u8, "xne", "one")); |
| 874 | |||
| 875 | const x: [3]f64 = .{ 42.0, math.nan(f64), 3.1415 }; | ||
| 876 | try testing.expectEqual(1, findDiff(f64, &x, &x)); | ||
| 867 | } | 877 | } |
| 868 | 878 | ||
| 869 | /// Takes a sentinel-terminated pointer and returns a slice preserving pointer attributes. | 879 | /// Takes a sentinel-terminated pointer and returns a slice preserving pointer attributes. |
| ... | @@ -1519,7 +1529,7 @@ pub fn findLast(comptime T: type, haystack: []const T, needle: []const T) ?usize | ... | @@ -1519,7 +1529,7 @@ pub fn findLast(comptime T: type, haystack: []const T, needle: []const T) ?usize |
| 1519 | if (needle.len == 0) return haystack.len; | 1529 | if (needle.len == 0) return haystack.len; |
| 1520 | 1530 | ||
| 1521 | if (!std.meta.hasUniqueRepresentation(T) or haystack.len < 52 or needle.len <= 4) | 1531 | if (!std.meta.hasUniqueRepresentation(T) or haystack.len < 52 or needle.len <= 4) |
| 1522 | return lastIndexOfLinear(T, haystack, needle); | 1532 | return findLastLinear(T, haystack, needle); |
| 1523 | 1533 | ||
| 1524 | const haystack_bytes = sliceAsBytes(haystack); | 1534 | const haystack_bytes = sliceAsBytes(haystack); |
| 1525 | const needle_bytes = sliceAsBytes(needle); | 1535 | const needle_bytes = sliceAsBytes(needle); |
| ... | @@ -1574,26 +1584,26 @@ pub fn findPos(comptime T: type, haystack: []const T, start_index: usize, needle | ... | @@ -1574,26 +1584,26 @@ pub fn findPos(comptime T: type, haystack: []const T, start_index: usize, needle |
| 1574 | 1584 | ||
| 1575 | test find { | 1585 | test find { |
| 1576 | try testing.expect(find(u8, "one two three four five six seven eight nine ten eleven", "three four").? == 8); | 1586 | try testing.expect(find(u8, "one two three four five six seven eight nine ten eleven", "three four").? == 8); |
| 1577 | try testing.expect(lastIndexOf(u8, "one two three four five six seven eight nine ten eleven", "three four").? == 8); | 1587 | try testing.expect(findLast(u8, "one two three four five six seven eight nine ten eleven", "three four").? == 8); |
| 1578 | try testing.expect(find(u8, "one two three four five six seven eight nine ten eleven", "two two") == null); | 1588 | try testing.expect(find(u8, "one two three four five six seven eight nine ten eleven", "two two") == null); |
| 1579 | try testing.expect(lastIndexOf(u8, "one two three four five six seven eight nine ten eleven", "two two") == null); | 1589 | try testing.expect(findLast(u8, "one two three four five six seven eight nine ten eleven", "two two") == null); |
| 1580 | 1590 | ||
| 1581 | try testing.expect(find(u8, "one two three four five six seven eight nine ten", "").? == 0); | 1591 | try testing.expect(find(u8, "one two three four five six seven eight nine ten", "").? == 0); |
| 1582 | try testing.expect(lastIndexOf(u8, "one two three four five six seven eight nine ten", "").? == 48); | 1592 | try testing.expect(findLast(u8, "one two three four five six seven eight nine ten", "").? == 48); |
| 1583 | 1593 | ||
| 1584 | try testing.expect(find(u8, "one two three four", "four").? == 14); | 1594 | try testing.expect(find(u8, "one two three four", "four").? == 14); |
| 1585 | try testing.expect(lastIndexOf(u8, "one two three two four", "two").? == 14); | 1595 | try testing.expect(findLast(u8, "one two three two four", "two").? == 14); |
| 1586 | try testing.expect(find(u8, "one two three four", "gour") == null); | 1596 | try testing.expect(find(u8, "one two three four", "gour") == null); |
| 1587 | try testing.expect(lastIndexOf(u8, "one two three four", "gour") == null); | 1597 | try testing.expect(findLast(u8, "one two three four", "gour") == null); |
| 1588 | try testing.expect(find(u8, "foo", "foo").? == 0); | 1598 | try testing.expect(find(u8, "foo", "foo").? == 0); |
| 1589 | try testing.expect(lastIndexOf(u8, "foo", "foo").? == 0); | 1599 | try testing.expect(findLast(u8, "foo", "foo").? == 0); |
| 1590 | try testing.expect(find(u8, "foo", "fool") == null); | 1600 | try testing.expect(find(u8, "foo", "fool") == null); |
| 1591 | try testing.expect(lastIndexOf(u8, "foo", "lfoo") == null); | 1601 | try testing.expect(findLast(u8, "foo", "lfoo") == null); |
| 1592 | try testing.expect(lastIndexOf(u8, "foo", "fool") == null); | 1602 | try testing.expect(findLast(u8, "foo", "fool") == null); |
| 1593 | 1603 | ||
| 1594 | try testing.expect(find(u8, "foo foo", "foo").? == 0); | 1604 | try testing.expect(find(u8, "foo foo", "foo").? == 0); |
| 1595 | try testing.expect(lastIndexOf(u8, "foo foo", "foo").? == 4); | 1605 | try testing.expect(findLast(u8, "foo foo", "foo").? == 4); |
| 1596 | try testing.expect(lastIndexOfAny(u8, "boo, cat", "abo").? == 6); | 1606 | try testing.expect(findLastAny(u8, "boo, cat", "abo").? == 6); |
| 1597 | try testing.expect(findScalarLast(u8, "boo", 'o').? == 2); | 1607 | try testing.expect(findScalarLast(u8, "boo", 'o').? == 2); |
| 1598 | } | 1608 | } |
| 1599 | 1609 | ||
| ... | @@ -1615,13 +1625,13 @@ test "find multibyte" { | ... | @@ -1615,13 +1625,13 @@ test "find multibyte" { |
| 1615 | // make haystack and needle long enough to trigger Boyer-Moore-Horspool algorithm | 1625 | // make haystack and needle long enough to trigger Boyer-Moore-Horspool algorithm |
| 1616 | const haystack = [_]u16{ 0xbbaa, 0xccbb, 0xddcc, 0xeedd, 0xffee, 0x00ff } ++ @as([100]u16, @splat(0)); | 1626 | const haystack = [_]u16{ 0xbbaa, 0xccbb, 0xddcc, 0xeedd, 0xffee, 0x00ff } ++ @as([100]u16, @splat(0)); |
| 1617 | const needle = [_]u16{ 0xbbaa, 0xccbb, 0xddcc, 0xeedd, 0xffee }; | 1627 | const needle = [_]u16{ 0xbbaa, 0xccbb, 0xddcc, 0xeedd, 0xffee }; |
| 1618 | try testing.expectEqual(lastIndexOf(u16, &haystack, &needle), 0); | 1628 | try testing.expectEqual(findLast(u16, &haystack, &needle), 0); |
| 1619 | 1629 | ||
| 1620 | // check for misaligned false positives (little and big endian) | 1630 | // check for misaligned false positives (little and big endian) |
| 1621 | const needleLE = [_]u16{ 0xbbbb, 0xcccc, 0xdddd, 0xeeee, 0xffff }; | 1631 | const needleLE = [_]u16{ 0xbbbb, 0xcccc, 0xdddd, 0xeeee, 0xffff }; |
| 1622 | try testing.expectEqual(lastIndexOf(u16, &haystack, &needleLE), null); | 1632 | try testing.expectEqual(findLast(u16, &haystack, &needleLE), null); |
| 1623 | const needleBE = [_]u16{ 0xaacc, 0xbbdd, 0xccee, 0xddff, 0xee00 }; | 1633 | const needleBE = [_]u16{ 0xaacc, 0xbbdd, 0xccee, 0xddff, 0xee00 }; |
| 1624 | try testing.expectEqual(lastIndexOf(u16, &haystack, &needleBE), null); | 1634 | try testing.expectEqual(findLast(u16, &haystack, &needleBE), null); |
| 1625 | } | 1635 | } |
| 1626 | } | 1636 | } |
| 1627 | 1637 | ||
| ... | @@ -2215,33 +2225,54 @@ test writeVarPackedInt { | ... | @@ -2215,33 +2225,54 @@ test writeVarPackedInt { |
| 2215 | try testing.expectEqual(T{ .a = 1, .b = value, .c = 4 }, st); | 2225 | try testing.expectEqual(T{ .a = 1, .b = value, .c = 4 }, st); |
| 2216 | } | 2226 | } |
| 2217 | 2227 | ||
| 2218 | /// Swap the byte order of all the members of the fields of a struct | 2228 | /// Deprecated: use `byteSwap` instead. |
| 2219 | /// (Changing their endianness) | 2229 | pub const byteSwapAllFields = byteSwap; |
| 2220 | pub fn byteSwapAllFields(comptime S: type, ptr: *S) void { | 2230 | |
| 2221 | byteSwapAllFieldsAligned(S, .of(S), ptr); | 2231 | /// Deprecated: use `byteSwapAligned` instead. |
| 2232 | pub const byteSwapAllFieldsAligned = byteSwapAligned; | ||
| 2233 | |||
| 2234 | /// Reverses the byte order. | ||
| 2235 | /// Handles structs, unions, arrays, enums, floats, and integers recursively. | ||
| 2236 | /// The order of extern struct fields and array elements remains unchanged and | ||
| 2237 | /// will be byte swapped recursively. | ||
| 2238 | /// Useful for converting between little-endian and big-endian representations. | ||
| 2239 | pub fn byteSwap(comptime S: type, ptr: *S) void { | ||
| 2240 | byteSwapAligned(S, .of(S), ptr); | ||
| 2222 | } | 2241 | } |
| 2223 | 2242 | ||
| 2224 | /// Swap the byte order of all the members of the fields of a struct | 2243 | /// Reverses the byte order. |
| 2225 | /// (Changing their endianness) | 2244 | /// Handles structs, unions, arrays, enums, floats, and integers recursively. |
| 2226 | pub fn byteSwapAllFieldsAligned(comptime S: type, comptime a: Alignment, ptr: *align(a.toByteUnits()) S) void { | 2245 | /// The order of extern struct fields and array elements remains unchanged and |
| 2246 | /// will be byte swapped recursively. | ||
| 2247 | /// Useful for converting between little-endian and big-endian representations. | ||
| 2248 | pub fn byteSwapAligned( | ||
| 2249 | comptime S: type, | ||
| 2250 | comptime a: Alignment, | ||
| 2251 | ptr: *align(a.toByteUnits()) S, | ||
| 2252 | ) void { | ||
| 2227 | switch (@typeInfo(S)) { | 2253 | switch (@typeInfo(S)) { |
| 2228 | .@"struct" => |@"struct"| { | 2254 | .@"struct" => |@"struct"| { |
| 2229 | if (@"struct".backing_integer) |Int| { | 2255 | if (@"struct".backing_integer) |Int| { |
| 2230 | ptr.* = @bitCast(@byteSwap(@as(Int, @bitCast(ptr.*)))); | 2256 | ptr.* = @bitCast(@byteSwap(@as(Int, @bitCast(ptr.*)))); |
| 2231 | } else inline for (@"struct".field_types, @"struct".field_names, @"struct".field_attrs) |f_type, f_name, f_attr| { | 2257 | } else { |
| 2232 | switch (@typeInfo(f_type)) { | 2258 | if (@"struct".layout != .@"extern") { |
| 2233 | .@"struct" => byteSwapAllFieldsAligned(f_type, .fromByteUnits(f_attr.@"align" orelse @alignOf(f_type)), &@field(ptr, f_name)), | 2259 | @compileError("byteSwapAligned expects a packed or extern struct"); |
| 2234 | .@"union", .array => byteSwapAllFieldsAligned(f_type, .fromByteUnits(f_attr.@"align" orelse @alignOf(f_type)), &@field(ptr, f_name)), | 2260 | } |
| 2235 | .@"enum" => { | 2261 | inline for (@"struct".field_types, @"struct".field_names, @"struct".field_attrs) |f_type, f_name, f_attr| { |
| 2236 | @field(ptr, f_name) = @fromBackingInt(@intCast(@byteSwap(@backingInt(@field(ptr, f_name))))); | 2262 | switch (@typeInfo(f_type)) { |
| 2237 | }, | 2263 | .@"struct" => byteSwapAligned(f_type, .fromByteUnits(f_attr.@"align" orelse @alignOf(f_type)), &@field(ptr, f_name)), |
| 2238 | .bool => {}, | 2264 | .@"union", .array => byteSwapAligned(f_type, .fromByteUnits(f_attr.@"align" orelse @alignOf(f_type)), &@field(ptr, f_name)), |
| 2239 | .float => |float| { | 2265 | .@"enum" => { |
| 2240 | @field(ptr, f_name) = @bitCast(@byteSwap(@as(@Int(.unsigned, float.bits), @bitCast(@field(ptr, f_name))))); | 2266 | @field(ptr, f_name) = @fromBackingInt(@byteSwap(@backingInt(@field(ptr, f_name)))); |
| 2241 | }, | 2267 | }, |
| 2242 | else => { | 2268 | .bool => {}, |
| 2243 | @field(ptr, f_name) = @byteSwap(@field(ptr, f_name)); | 2269 | .float => |float| { |
| 2244 | }, | 2270 | @field(ptr, f_name) = @bitCast(@byteSwap(@as(@Int(.unsigned, float.bits), @bitCast(@field(ptr, f_name))))); |
| 2271 | }, | ||
| 2272 | else => { | ||
| 2273 | @field(ptr, f_name) = @byteSwap(@field(ptr, f_name)); | ||
| 2274 | }, | ||
| 2275 | } | ||
| 2245 | } | 2276 | } |
| 2246 | } | 2277 | } |
| 2247 | }, | 2278 | }, |
| ... | @@ -2249,7 +2280,7 @@ pub fn byteSwapAllFieldsAligned(comptime S: type, comptime a: Alignment, ptr: *a | ... | @@ -2249,7 +2280,7 @@ pub fn byteSwapAllFieldsAligned(comptime S: type, comptime a: Alignment, ptr: *a |
| 2249 | ptr.* = @bitCast(@byteSwap(@as(Int, @bitCast(ptr.*)))); | 2280 | ptr.* = @bitCast(@byteSwap(@as(Int, @bitCast(ptr.*)))); |
| 2250 | } else { | 2281 | } else { |
| 2251 | if (@"union".layout != .@"extern") { | 2282 | if (@"union".layout != .@"extern") { |
| 2252 | @compileError("byteSwapAllFields expects a packed or extern union"); | 2283 | @compileError("byteSwapAligned expects a packed or extern union"); |
| 2253 | } | 2284 | } |
| 2254 | 2285 | ||
| 2255 | const first_size = @bitSizeOf(@"union".field_types[0]); | 2286 | const first_size = @bitSizeOf(@"union".field_types[0]); |
| ... | @@ -2266,13 +2297,21 @@ pub fn byteSwapAllFieldsAligned(comptime S: type, comptime a: Alignment, ptr: *a | ... | @@ -2266,13 +2297,21 @@ pub fn byteSwapAllFieldsAligned(comptime S: type, comptime a: Alignment, ptr: *a |
| 2266 | .array => |array| { | 2297 | .array => |array| { |
| 2267 | byteSwapAllElements(array.child, ptr); | 2298 | byteSwapAllElements(array.child, ptr); |
| 2268 | }, | 2299 | }, |
| 2300 | .@"enum" => { | ||
| 2301 | ptr.* = @fromBackingInt(@byteSwap(@backingInt(ptr.*))); | ||
| 2302 | }, | ||
| 2303 | .bool => {}, | ||
| 2304 | .float => |float| { | ||
| 2305 | const int_repr: @Int(.unsigned, float.bits) = @bitCast(ptr.*); | ||
| 2306 | ptr.* = @bitCast(@byteSwap(int_repr)); | ||
| 2307 | }, | ||
| 2269 | else => { | 2308 | else => { |
| 2270 | ptr.* = @byteSwap(ptr.*); | 2309 | ptr.* = @byteSwap(ptr.*); |
| 2271 | }, | 2310 | }, |
| 2272 | } | 2311 | } |
| 2273 | } | 2312 | } |
| 2274 | 2313 | ||
| 2275 | test byteSwapAllFields { | 2314 | test byteSwap { |
| 2276 | const T = extern struct { | 2315 | const T = extern struct { |
| 2277 | f0: u8, | 2316 | f0: u8, |
| 2278 | f1: u16, | 2317 | f1: u16, |
| ... | @@ -2304,6 +2343,9 @@ test byteSwapAllFields { | ... | @@ -2304,6 +2343,9 @@ test byteSwapAllFields { |
| 2304 | } align(4), | 2343 | } align(4), |
| 2305 | f2: u32, | 2344 | f2: u32, |
| 2306 | }; | 2345 | }; |
| 2346 | const E = enum(u32) { | ||
| 2347 | _, | ||
| 2348 | }; | ||
| 2307 | var s = T{ | 2349 | var s = T{ |
| 2308 | .f0 = 0x12, | 2350 | .f0 = 0x12, |
| 2309 | .f1 = 0x1234, | 2351 | .f1 = 0x1234, |
| ... | @@ -2327,10 +2369,14 @@ test byteSwapAllFields { | ... | @@ -2327,10 +2369,14 @@ test byteSwapAllFields { |
| 2327 | .f1 = .{ .f0 = 0x123456789ABCDEF0 }, | 2369 | .f1 = .{ .f0 = 0x123456789ABCDEF0 }, |
| 2328 | .f2 = 0x87654321, | 2370 | .f2 = 0x87654321, |
| 2329 | }; | 2371 | }; |
| 2330 | byteSwapAllFields(T, &s); | 2372 | var e: E = @fromBackingInt(0x12345678); |
| 2331 | byteSwapAllFields(K, &k); | 2373 | var f: f32 = @bitCast(@as(u32, 0x4640e400)); |
| 2332 | byteSwapAllFields(P, &p); | 2374 | byteSwap(T, &s); |
| 2333 | byteSwapAllFields(A, &a); | 2375 | byteSwap(K, &k); |
| 2376 | byteSwap(P, &p); | ||
| 2377 | byteSwap(A, &a); | ||
| 2378 | byteSwap(E, &e); | ||
| 2379 | byteSwap(f32, &f); | ||
| 2334 | try std.testing.expectEqual(T{ | 2380 | try std.testing.expectEqual(T{ |
| 2335 | .f0 = 0x12, | 2381 | .f0 = 0x12, |
| 2336 | .f1 = 0x3412, | 2382 | .f1 = 0x3412, |
| ... | @@ -2354,28 +2400,15 @@ test byteSwapAllFields { | ... | @@ -2354,28 +2400,15 @@ test byteSwapAllFields { |
| 2354 | .f1 = .{ .f0 = 0xF0DEBC9A78563412 }, | 2400 | .f1 = .{ .f0 = 0xF0DEBC9A78563412 }, |
| 2355 | .f2 = 0x21436587, | 2401 | .f2 = 0x21436587, |
| 2356 | }, a); | 2402 | }, a); |
| 2403 | try std.testing.expectEqual(@as(E, @fromBackingInt(0x78563412)), e); | ||
| 2404 | try std.testing.expectEqual(@as(f32, @bitCast(@as(u32, 0x00e44046))), f); | ||
| 2357 | } | 2405 | } |
| 2358 | 2406 | ||
| 2359 | /// Reverses the byte order of all elements in a slice. | 2407 | /// Reverses the byte order of all elements in a slice. |
| 2360 | /// Handles structs, unions, arrays, enums, floats, and integers recursively. | 2408 | /// Handles structs, unions, arrays, enums, floats, and integers recursively. |
| 2361 | /// Useful for converting between little-endian and big-endian representations. | 2409 | /// Useful for converting between little-endian and big-endian representations. |
| 2362 | pub fn byteSwapAllElements(comptime Elem: type, slice: []Elem) void { | 2410 | pub fn byteSwapAllElements(comptime Elem: type, slice: []Elem) void { |
| 2363 | for (slice) |*elem| { | 2411 | for (slice) |*elem| byteSwap(Elem, elem); |
| 2364 | switch (@typeInfo(@TypeOf(elem.*))) { | ||
| 2365 | .@"struct", .@"union", .array => byteSwapAllFields(@TypeOf(elem.*), elem), | ||
| 2366 | .@"enum" => { | ||
| 2367 | elem.* = @fromBackingInt(@intCast(@byteSwap(@backingInt(elem.*)))); | ||
| 2368 | }, | ||
| 2369 | .bool => {}, | ||
| 2370 | .float => |float| { | ||
| 2371 | const int_repr: @Int(.unsigned, float.bits) = @bitCast(elem.*); | ||
| 2372 | elem.* = @bitCast(@byteSwap(int_repr)); | ||
| 2373 | }, | ||
| 2374 | else => { | ||
| 2375 | elem.* = @byteSwap(elem.*); | ||
| 2376 | }, | ||
| 2377 | } | ||
| 2378 | } | ||
| 2379 | } | 2412 | } |
| 2380 | 2413 | ||
| 2381 | /// Returns an iterator that iterates over the slices of `buffer` that are not | 2414 | /// Returns an iterator that iterates over the slices of `buffer` that are not |
| ... | @@ -3453,8 +3486,8 @@ pub fn SplitBackwardsIterator(comptime T: type, comptime delimiter_type: Delimit | ... | @@ -3453,8 +3486,8 @@ pub fn SplitBackwardsIterator(comptime T: type, comptime delimiter_type: Delimit |
| 3453 | pub fn next(self: *Self) ?[]const T { | 3486 | pub fn next(self: *Self) ?[]const T { |
| 3454 | const end = self.index orelse return null; | 3487 | const end = self.index orelse return null; |
| 3455 | const start = if (switch (delimiter_type) { | 3488 | const start = if (switch (delimiter_type) { |
| 3456 | .sequence => lastIndexOf(T, self.buffer[0..end], self.delimiter), | 3489 | .sequence => findLast(T, self.buffer[0..end], self.delimiter), |
| 3457 | .any => lastIndexOfAny(T, self.buffer[0..end], self.delimiter), | 3490 | .any => findLastAny(T, self.buffer[0..end], self.delimiter), |
| 3458 | .scalar => findScalarLast(T, self.buffer[0..end], self.delimiter), | 3491 | .scalar => findScalarLast(T, self.buffer[0..end], self.delimiter), |
| 3459 | }) |delim_start| blk: { | 3492 | }) |delim_start| blk: { |
| 3460 | self.index = delim_start; | 3493 | self.index = delim_start; |
| ... | @@ -4706,22 +4739,28 @@ test "sliceAsBytes preserves pointer attributes" { | ... | @@ -4706,22 +4739,28 @@ test "sliceAsBytes preserves pointer attributes" { |
| 4706 | try testing.expectEqual(in_attrs.@"align", out_attrs.@"align"); | 4739 | try testing.expectEqual(in_attrs.@"align", out_attrs.@"align"); |
| 4707 | } | 4740 | } |
| 4708 | 4741 | ||
| 4709 | fn AbsorbSentinelReturnType(comptime Slice: type) type { | ||
| 4710 | const info = @typeInfo(Slice).pointer; | ||
| 4711 | assert(info.size == .slice); | ||
| 4712 | return @Pointer(.slice, info.attrs, info.child, null); | ||
| 4713 | } | ||
| 4714 | |||
| 4715 | /// If the provided slice is not sentinel terminated, do nothing and return that slice. | 4742 | /// If the provided slice is not sentinel terminated, do nothing and return that slice. |
| 4716 | /// If it is sentinel-terminated, return a non-sentinel-terminated slice with the | 4743 | /// If it is sentinel-terminated, return a non-sentinel-terminated slice with the |
| 4717 | /// length increased by one to include the absorbed sentinel element. | 4744 | /// length increased by one to include the absorbed sentinel element. |
| 4718 | pub fn absorbSentinel(slice: anytype) AbsorbSentinelReturnType(@TypeOf(slice)) { | 4745 | pub fn absorbSentinel(slice: anytype) AbsorbSentinel(@TypeOf(slice)) { |
| 4719 | const info = @typeInfo(@TypeOf(slice)).pointer; | 4746 | const info = @typeInfo(@TypeOf(slice)).pointer; |
| 4720 | comptime assert(info.size == .slice); | 4747 | switch (info.size) { |
| 4721 | if (info.sentinel_ptr == null) { | 4748 | .slice => { |
| 4722 | return slice; | 4749 | if (info.sentinel_ptr == null) { |
| 4723 | } else { | 4750 | return slice; |
| 4724 | return slice.ptr[0 .. slice.len + 1]; | 4751 | } else { |
| 4752 | return slice.ptr[0 .. slice.len + 1]; | ||
| 4753 | } | ||
| 4754 | }, | ||
| 4755 | .one => { | ||
| 4756 | const child_info = @typeInfo(info.child).array; | ||
| 4757 | if (child_info.sentinel_ptr == null) { | ||
| 4758 | return slice; | ||
| 4759 | } else { | ||
| 4760 | return slice[0 .. child_info.len + 1]; | ||
| 4761 | } | ||
| 4762 | }, | ||
| 4763 | else => unreachable, | ||
| 4725 | } | 4764 | } |
| 4726 | } | 4765 | } |
| 4727 | 4766 | ||
| ... | @@ -4730,21 +4769,28 @@ test absorbSentinel { | ... | @@ -4730,21 +4769,28 @@ test absorbSentinel { |
| 4730 | var buffer: [3:0]u8 = .{ 1, 2, 3 }; | 4769 | var buffer: [3:0]u8 = .{ 1, 2, 3 }; |
| 4731 | const foo: [:0]const u8 = &buffer; | 4770 | const foo: [:0]const u8 = &buffer; |
| 4732 | const bar: []const u8 = &buffer; | 4771 | const bar: []const u8 = &buffer; |
| 4772 | const baz: *const [3:0]u8 = &buffer; | ||
| 4733 | try testing.expectEqual([]const u8, @TypeOf(absorbSentinel(foo))); | 4773 | try testing.expectEqual([]const u8, @TypeOf(absorbSentinel(foo))); |
| 4734 | try testing.expectEqual([]const u8, @TypeOf(absorbSentinel(bar))); | 4774 | try testing.expectEqual([]const u8, @TypeOf(absorbSentinel(bar))); |
| 4775 | try testing.expectEqual(*const [4]u8, @TypeOf(absorbSentinel(baz))); | ||
| 4735 | try testing.expectEqualSlices(u8, &.{ 1, 2, 3, 0 }, absorbSentinel(foo)); | 4776 | try testing.expectEqualSlices(u8, &.{ 1, 2, 3, 0 }, absorbSentinel(foo)); |
| 4736 | try testing.expectEqualSlices(u8, &.{ 1, 2, 3 }, absorbSentinel(bar)); | 4777 | try testing.expectEqualSlices(u8, &.{ 1, 2, 3 }, absorbSentinel(bar)); |
| 4778 | try testing.expectEqualSlices(u8, &.{ 1, 2, 3, 0 }, absorbSentinel(baz)); | ||
| 4737 | } | 4779 | } |
| 4738 | { | 4780 | { |
| 4739 | var buffer: [3:0]u8 = .{ 1, 2, 3 }; | 4781 | var buffer: [3:0]u8 = .{ 1, 2, 3 }; |
| 4740 | const foo: [:0]u8 = &buffer; | 4782 | const foo: [:0]u8 = &buffer; |
| 4741 | const bar: []u8 = &buffer; | 4783 | const bar: []u8 = &buffer; |
| 4784 | const baz: *[3:0]u8 = &buffer; | ||
| 4742 | try testing.expectEqual([]u8, @TypeOf(absorbSentinel(foo))); | 4785 | try testing.expectEqual([]u8, @TypeOf(absorbSentinel(foo))); |
| 4743 | try testing.expectEqual([]u8, @TypeOf(absorbSentinel(bar))); | 4786 | try testing.expectEqual([]u8, @TypeOf(absorbSentinel(bar))); |
| 4787 | try testing.expectEqual(*[4]u8, @TypeOf(absorbSentinel(baz))); | ||
| 4744 | var expected_foo = [_]u8{ 1, 2, 3, 0 }; | 4788 | var expected_foo = [_]u8{ 1, 2, 3, 0 }; |
| 4745 | try testing.expectEqualSlices(u8, &expected_foo, absorbSentinel(foo)); | 4789 | try testing.expectEqualSlices(u8, &expected_foo, absorbSentinel(foo)); |
| 4746 | var expected_bar = [_]u8{ 1, 2, 3 }; | 4790 | var expected_bar = [_]u8{ 1, 2, 3 }; |
| 4747 | try testing.expectEqualSlices(u8, &expected_bar, absorbSentinel(bar)); | 4791 | try testing.expectEqualSlices(u8, &expected_bar, absorbSentinel(bar)); |
| 4792 | var expected_baz = [_]u8{ 1, 2, 3, 0 }; | ||
| 4793 | try testing.expectEqualSlices(u8, &expected_baz, absorbSentinel(baz)); | ||
| 4748 | } | 4794 | } |
| 4749 | } | 4795 | } |
| 4750 | 4796 | ||
| ... | @@ -4780,62 +4826,58 @@ pub fn alignForwardLog2(addr: usize, log2_alignment: u8) usize { | ... | @@ -4780,62 +4826,58 @@ pub fn alignForwardLog2(addr: usize, log2_alignment: u8) usize { |
| 4780 | pub fn doNotOptimizeAway(val: anytype) void { | 4826 | pub fn doNotOptimizeAway(val: anytype) void { |
| 4781 | if (@inComptime()) return; | 4827 | if (@inComptime()) return; |
| 4782 | 4828 | ||
| 4783 | const max_gp_register_bits = @bitSizeOf(c_long); | 4829 | if (builtin.zig_backend == .stage2_c and builtin.abi == .msvc) { |
| 4784 | const t = @typeInfo(@TypeOf(val)); | 4830 | _ = @atomicRmw(*const anyopaque, @as(*volatile *const anyopaque, &struct { |
| 4785 | switch (t) { | 4831 | var escape: *const anyopaque = undefined; |
| 4832 | }.escape), .Xchg, &val, .acq_rel); // TODO: syncscope("singlethreaded") | ||
| 4833 | return; | ||
| 4834 | } | ||
| 4835 | |||
| 4836 | switch (@typeInfo(@TypeOf(val))) { | ||
| 4786 | .void, .null, .comptime_int, .comptime_float => return, | 4837 | .void, .null, .comptime_int, .comptime_float => return, |
| 4787 | .@"enum" => doNotOptimizeAway(@backingInt(val)), | 4838 | .@"enum" => doNotOptimizeAway(@backingInt(val)), |
| 4788 | .bool => doNotOptimizeAway(@intFromBool(val)), | 4839 | .bool => doNotOptimizeAway(@intFromBool(val)), |
| 4789 | .int => { | 4840 | .int => |int| { |
| 4790 | const bits = t.int.bits; | 4841 | // SPIR-V targets do not have registers per se, they have values |
| 4791 | if (bits <= max_gp_register_bits and builtin.zig_backend != .stage2_c) { | 4842 | // tied to IDs that can be passed to valid instructions. Some |
| 4843 | // SPIR-V targets do not define c_long, so we just allow any sized | ||
| 4844 | // integer on these targets | ||
| 4845 | const val_fits_in_gp_register = builtin.target.cpu.arch.isSpirV() or fits: { | ||
| 4846 | const max_gp_register_bits = @bitSizeOf(c_long); | ||
| 4847 | break :fits int.bits <= max_gp_register_bits; | ||
| 4848 | }; | ||
| 4849 | if (val_fits_in_gp_register) { | ||
| 4792 | const val2 = @as( | 4850 | const val2 = @as( |
| 4793 | @Int(t.int.signedness, @max(8, std.math.ceilPowerOfTwoAssert(u16, bits))), | 4851 | @Int(int.signedness, @max(8, std.math.ceilPowerOfTwoAssert(u16, int.bits))), |
| 4794 | val, | 4852 | val, |
| 4795 | ); | 4853 | ); |
| 4796 | asm volatile ("" | 4854 | asm volatile ("" |
| 4797 | : | 4855 | : |
| 4798 | : [_] "r" (val2), | 4856 | : [_] "r" (val2), |
| 4799 | ); | 4857 | ); |
| 4800 | } else doNotOptimizeAway(&val); | ||
| 4801 | }, | ||
| 4802 | .float => { | ||
| 4803 | if ((t.float.bits == 32 or t.float.bits == 64) and builtin.zig_backend != .stage2_c) { | ||
| 4804 | asm volatile ("" | ||
| 4805 | : | ||
| 4806 | : [_] "rm" (val), | ||
| 4807 | ); | ||
| 4808 | } else doNotOptimizeAway(&val); | ||
| 4809 | }, | ||
| 4810 | .pointer => { | ||
| 4811 | if (builtin.zig_backend == .stage2_c) { | ||
| 4812 | doNotOptimizeAwayC(val); | ||
| 4813 | } else { | 4858 | } else { |
| 4814 | asm volatile ("" | 4859 | doNotOptimizeAway(&val); |
| 4815 | : | ||
| 4816 | : [_] "m" (val), | ||
| 4817 | : .{ .memory = true }); | ||
| 4818 | } | 4860 | } |
| 4819 | }, | 4861 | }, |
| 4820 | .array => { | 4862 | .float => |float| switch (float.bits) { |
| 4821 | if (t.array.len * @sizeOf(t.array.child) <= 64) { | 4863 | else => comptime unreachable, |
| 4822 | for (val) |v| doNotOptimizeAway(v); | 4864 | 16, 80, 128 => doNotOptimizeAway(&val), |
| 4823 | } else doNotOptimizeAway(&val); | 4865 | 32, 64 => asm volatile ("" |
| 4866 | : | ||
| 4867 | : [_] "rm" (val), | ||
| 4868 | ), | ||
| 4824 | }, | 4869 | }, |
| 4870 | .pointer => asm volatile ("" | ||
| 4871 | : | ||
| 4872 | : [_] "m" (val), | ||
| 4873 | : .{ .memory = true }), | ||
| 4874 | .array => |array| if (array.len * @sizeOf(array.child) <= 64) { | ||
| 4875 | for (val) |v| doNotOptimizeAway(v); | ||
| 4876 | } else doNotOptimizeAway(&val), | ||
| 4825 | else => doNotOptimizeAway(&val), | 4877 | else => doNotOptimizeAway(&val), |
| 4826 | } | 4878 | } |
| 4827 | } | 4879 | } |
| 4828 | 4880 | ||
| 4829 | /// .stage2_c doesn't support asm blocks yet, so use volatile stores instead | ||
| 4830 | var deopt_target: if (builtin.zig_backend == .stage2_c) u8 else void = undefined; | ||
| 4831 | fn doNotOptimizeAwayC(ptr: anytype) void { | ||
| 4832 | const dest = @as(*volatile u8, @ptrCast(&deopt_target)); | ||
| 4833 | for (asBytes(ptr)) |b| { | ||
| 4834 | dest.* = b; | ||
| 4835 | } | ||
| 4836 | dest.* = 0; | ||
| 4837 | } | ||
| 4838 | |||
| 4839 | test doNotOptimizeAway { | 4881 | test doNotOptimizeAway { |
| 4840 | comptime doNotOptimizeAway("test"); | 4882 | comptime doNotOptimizeAway("test"); |
| 4841 | 4883 | ||
| ... | @@ -4994,12 +5036,9 @@ pub fn alignInSlice(slice: anytype, comptime new_alignment: usize) ?AlignedSlice | ... | @@ -4994,12 +5036,9 @@ pub fn alignInSlice(slice: anytype, comptime new_alignment: usize) ?AlignedSlice |
| 4994 | } | 5036 | } |
| 4995 | 5037 | ||
| 4996 | test "read/write(Var)PackedInt" { | 5038 | test "read/write(Var)PackedInt" { |
| 4997 | switch (builtin.cpu.arch) { | 5039 | // This test generates too much code to execute on WASI. |
| 4998 | // This test generates too much code to execute on WASI. | 5040 | // LLVM backend fails with "too many locals: locals exceed maximum" |
| 4999 | // LLVM backend fails with "too many locals: locals exceed maximum" | 5041 | if (builtin.cpu.arch.isWasm()) return error.SkipZigTest; |
| 5000 | .wasm32, .wasm64 => return error.SkipZigTest, | ||
| 5001 | else => {}, | ||
| 5002 | } | ||
| 5003 | 5042 | ||
| 5004 | const foreign_endian: Endian = if (native_endian == .big) .little else .big; | 5043 | const foreign_endian: Endian = if (native_endian == .big) .little else .big; |
| 5005 | const expect = std.testing.expect; | 5044 | const expect = std.testing.expect; |
lib/std/mem/Allocator.zig+56-16| ... | @@ -8,6 +8,8 @@ const assert = std.debug.assert; | ... | @@ -8,6 +8,8 @@ const assert = std.debug.assert; |
| 8 | const math = std.math; | 8 | const math = std.math; |
| 9 | const mem = std.mem; | 9 | const mem = std.mem; |
| 10 | const Alignment = std.mem.Alignment; | 10 | const Alignment = std.mem.Alignment; |
| 11 | const Slice = std.meta.Slice; | ||
| 12 | const AbsorbSentinel = std.meta.AbsorbSentinel; | ||
| 11 | 13 | ||
| 12 | pub const Error = error{OutOfMemory}; | 14 | pub const Error = error{OutOfMemory}; |
| 13 | pub const Log2Align = math.Log2Int(usize); | 15 | pub const Log2Align = math.Log2Int(usize); |
| ... | @@ -316,8 +318,10 @@ pub fn allocBytesAligned( | ... | @@ -316,8 +318,10 @@ pub fn allocBytesAligned( |
| 316 | /// `new_len` may be zero, in which case the allocation is freed. | 318 | /// `new_len` may be zero, in which case the allocation is freed. |
| 317 | pub fn resize(self: Allocator, allocation: anytype, new_len: usize) bool { | 319 | pub fn resize(self: Allocator, allocation: anytype, new_len: usize) bool { |
| 318 | const slice_info = @typeInfo(@TypeOf(allocation)).pointer; | 320 | const slice_info = @typeInfo(@TypeOf(allocation)).pointer; |
| 319 | comptime assert(slice_info.size == .slice); | 321 | const T = if (slice_info.size != .slice) comptime T: { |
| 320 | const T = slice_info.child; | 322 | assert(slice_info.size == .one); |
| 323 | break :T @typeInfo(slice_info.child).array.child; | ||
| 324 | } else slice_info.child; | ||
| 321 | if (new_len == 0) { | 325 | if (new_len == 0) { |
| 322 | self.free(allocation); | 326 | self.free(allocation); |
| 323 | return true; | 327 | return true; |
| ... | @@ -326,9 +330,6 @@ pub fn resize(self: Allocator, allocation: anytype, new_len: usize) bool { | ... | @@ -326,9 +330,6 @@ pub fn resize(self: Allocator, allocation: anytype, new_len: usize) bool { |
| 326 | return false; | 330 | return false; |
| 327 | } | 331 | } |
| 328 | const old_memory: []u8 = @ptrCast(@constCast(mem.absorbSentinel(allocation))); | 332 | const old_memory: []u8 = @ptrCast(@constCast(mem.absorbSentinel(allocation))); |
| 329 | // I would like to use saturating multiplication here, but LLVM cannot lower it | ||
| 330 | // on WebAssembly: https://github.com/ziglang/zig/issues/9660 | ||
| 331 | //const new_len_bytes = new_len *| @sizeOf(T); | ||
| 332 | const new_len_bytes = math.mul(usize, @sizeOf(T), new_len) catch return false; | 333 | const new_len_bytes = math.mul(usize, @sizeOf(T), new_len) catch return false; |
| 333 | return self.rawResize( | 334 | return self.rawResize( |
| 334 | old_memory, | 335 | old_memory, |
| ... | @@ -354,10 +355,12 @@ pub fn resize(self: Allocator, allocation: anytype, new_len: usize) bool { | ... | @@ -354,10 +355,12 @@ pub fn resize(self: Allocator, allocation: anytype, new_len: usize) bool { |
| 354 | /// `new_len` may be zero, in which case the allocation is freed. | 355 | /// `new_len` may be zero, in which case the allocation is freed. |
| 355 | /// | 356 | /// |
| 356 | /// If the allocation's elements' type is zero bytes sized, `allocation.len` is set to `new_len`. | 357 | /// If the allocation's elements' type is zero bytes sized, `allocation.len` is set to `new_len`. |
| 357 | pub fn remap(self: Allocator, allocation: anytype, new_len: usize) ?@TypeOf(allocation) { | 358 | pub fn remap(self: Allocator, allocation: anytype, new_len: usize) ?Slice(AbsorbSentinel(@TypeOf(allocation))) { |
| 358 | const slice_info = @typeInfo(@TypeOf(allocation)).pointer; | 359 | const slice_info = @typeInfo(@TypeOf(allocation)).pointer; |
| 359 | comptime assert(slice_info.size == .slice); | 360 | const T = if (slice_info.size != .slice) comptime T: { |
| 360 | const T = slice_info.child; | 361 | assert(slice_info.size == .one); |
| 362 | break :T @typeInfo(slice_info.child).array.child; | ||
| 363 | } else slice_info.child; | ||
| 361 | 364 | ||
| 362 | if (new_len == 0) { | 365 | if (new_len == 0) { |
| 363 | self.free(allocation); | 366 | self.free(allocation); |
| ... | @@ -372,9 +375,6 @@ pub fn remap(self: Allocator, allocation: anytype, new_len: usize) ?@TypeOf(allo | ... | @@ -372,9 +375,6 @@ pub fn remap(self: Allocator, allocation: anytype, new_len: usize) ?@TypeOf(allo |
| 372 | return new_memory; | 375 | return new_memory; |
| 373 | } | 376 | } |
| 374 | const old_memory: []u8 = @ptrCast(@constCast(mem.absorbSentinel(allocation))); | 377 | const old_memory: []u8 = @ptrCast(@constCast(mem.absorbSentinel(allocation))); |
| 375 | // I would like to use saturating multiplication here, but LLVM cannot lower it | ||
| 376 | // on WebAssembly: https://github.com/ziglang/zig/issues/9660 | ||
| 377 | //const new_len_bytes = new_len *| @sizeOf(T); | ||
| 378 | const new_len_bytes = math.mul(usize, @sizeOf(T), new_len) catch return null; | 378 | const new_len_bytes = math.mul(usize, @sizeOf(T), new_len) catch return null; |
| 379 | const new_ptr = self.rawRemap( | 379 | const new_ptr = self.rawRemap( |
| 380 | old_memory, | 380 | old_memory, |
| ... | @@ -399,7 +399,7 @@ pub fn remap(self: Allocator, allocation: anytype, new_len: usize) ?@TypeOf(allo | ... | @@ -399,7 +399,7 @@ pub fn remap(self: Allocator, allocation: anytype, new_len: usize) ?@TypeOf(allo |
| 399 | /// do the realloc more efficiently than the caller | 399 | /// do the realloc more efficiently than the caller |
| 400 | /// * `resize` which returns `false` when the `Allocator` implementation cannot | 400 | /// * `resize` which returns `false` when the `Allocator` implementation cannot |
| 401 | /// change the size without relocating the allocation. | 401 | /// change the size without relocating the allocation. |
| 402 | pub fn realloc(self: Allocator, old_mem: anytype, new_n: usize) Error!@TypeOf(old_mem) { | 402 | pub fn realloc(self: Allocator, old_mem: anytype, new_n: usize) Error!Slice(AbsorbSentinel(@TypeOf(old_mem))) { |
| 403 | return self.reallocAdvanced(old_mem, new_n, @returnAddress()); | 403 | return self.reallocAdvanced(old_mem, new_n, @returnAddress()); |
| 404 | } | 404 | } |
| 405 | 405 | ||
| ... | @@ -408,10 +408,12 @@ pub fn reallocAdvanced( | ... | @@ -408,10 +408,12 @@ pub fn reallocAdvanced( |
| 408 | old_mem: anytype, | 408 | old_mem: anytype, |
| 409 | new_n: usize, | 409 | new_n: usize, |
| 410 | return_address: usize, | 410 | return_address: usize, |
| 411 | ) Error!@TypeOf(old_mem) { | 411 | ) Error!Slice(AbsorbSentinel(@TypeOf(old_mem))) { |
| 412 | const slice_info = @typeInfo(@TypeOf(old_mem)).pointer; | 412 | const slice_info = @typeInfo(@TypeOf(old_mem)).pointer; |
| 413 | comptime assert(slice_info.size == .slice); | 413 | const T = if (slice_info.size != .slice) comptime T: { |
| 414 | const T = slice_info.child; | 414 | assert(slice_info.size == .one); |
| 415 | break :T @typeInfo(slice_info.child).array.child; | ||
| 416 | } else slice_info.child; | ||
| 415 | if (old_mem.len == 0) { | 417 | if (old_mem.len == 0) { |
| 416 | return self.allocAdvancedWithRetAddr(T, .fromByteUnitsOptional(slice_info.attrs.@"align"), new_n, return_address); | 418 | return self.allocAdvancedWithRetAddr(T, .fromByteUnitsOptional(slice_info.attrs.@"align"), new_n, return_address); |
| 417 | } | 419 | } |
| ... | @@ -446,7 +448,6 @@ pub fn reallocAdvanced( | ... | @@ -446,7 +448,6 @@ pub fn reallocAdvanced( |
| 446 | pub fn free(self: Allocator, memory: anytype) void { | 448 | pub fn free(self: Allocator, memory: anytype) void { |
| 447 | const slice_info = @typeInfo(@TypeOf(memory)).pointer; | 449 | const slice_info = @typeInfo(@TypeOf(memory)).pointer; |
| 448 | if (slice_info.size != .slice) { | 450 | if (slice_info.size != .slice) { |
| 449 | // slicing with comptime-known start and end results in *[len]T, which may be free'd | ||
| 450 | comptime assert(slice_info.size == .one and @typeInfo(slice_info.child) == .array); | 451 | comptime assert(slice_info.size == .one and @typeInfo(slice_info.child) == .array); |
| 451 | } | 452 | } |
| 452 | const bytes: []u8 = @ptrCast(@constCast(mem.absorbSentinel(memory))); | 453 | const bytes: []u8 = @ptrCast(@constCast(mem.absorbSentinel(memory))); |
| ... | @@ -587,4 +588,43 @@ fn unreachableFree( | ... | @@ -587,4 +588,43 @@ fn unreachableFree( |
| 587 | test failing { | 588 | test failing { |
| 588 | const f: Allocator = .failing; | 589 | const f: Allocator = .failing; |
| 589 | try std.testing.expectError(error.OutOfMemory, f.alloc(u8, 123)); | 590 | try std.testing.expectError(error.OutOfMemory, f.alloc(u8, 123)); |
| 591 | // Expect very large allocations to fail at the implementation level and not in the interface | ||
| 592 | try std.testing.expectError(error.OutOfMemory, f.alloc(u8, std.math.maxInt(usize))); | ||
| 593 | try std.testing.expectError(error.OutOfMemory, f.allocSentinel(u8, std.math.maxInt(usize) - 1, 0)); | ||
| 594 | } | ||
| 595 | |||
| 596 | test "free single-pointer to array" { | ||
| 597 | const allocator = std.testing.allocator; | ||
| 598 | { | ||
| 599 | const allocation = try allocator.alloc(u32, 128); | ||
| 600 | allocation[127] = 0; | ||
| 601 | const ptr: *[127:0]u32 = allocation[0..127 :0]; | ||
| 602 | allocator.free(ptr); | ||
| 603 | } | ||
| 604 | { | ||
| 605 | const allocation = try allocator.alloc(u32, 128); | ||
| 606 | allocation[127] = 0; | ||
| 607 | const ptr: *[127:0]u32 = allocation[0..127 :0]; | ||
| 608 | if (allocator.resize(ptr, 16)) { | ||
| 609 | allocator.free(ptr[0..16]); | ||
| 610 | } else allocator.free(ptr); | ||
| 611 | } | ||
| 612 | { | ||
| 613 | const allocation = try allocator.alloc(u32, 128); | ||
| 614 | allocation[127] = 0; | ||
| 615 | const ptr: *[127:0]u32 = allocation[0..127 :0]; | ||
| 616 | if (allocator.remap(ptr, 16)) |new| { | ||
| 617 | allocator.free(new); | ||
| 618 | } else allocator.free(ptr); | ||
| 619 | } | ||
| 620 | { | ||
| 621 | const allocation = try allocator.alloc(u32, 128); | ||
| 622 | allocation[127] = 0; | ||
| 623 | const ptr: *[127:0]u32 = allocation[0..127 :0]; | ||
| 624 | if (allocator.realloc(ptr, 16)) |new| { | ||
| 625 | allocator.free(new); | ||
| 626 | } else |_| { | ||
| 627 | allocator.free(allocation); | ||
| 628 | } | ||
| 629 | } | ||
| 590 | } | 630 | } |
lib/std/meta.zig+69-12| ... | @@ -1,10 +1,9 @@ | ... | @@ -1,10 +1,9 @@ |
| 1 | const builtin = @import("builtin"); | 1 | const builtin = @import("builtin"); |
| 2 | |||
| 2 | const std = @import("std.zig"); | 3 | const std = @import("std.zig"); |
| 3 | const debug = std.debug; | 4 | const assert = std.debug.assert; |
| 4 | const mem = std.mem; | 5 | const mem = std.mem; |
| 5 | const math = std.math; | ||
| 6 | const testing = std.testing; | 6 | const testing = std.testing; |
| 7 | const root = @import("root"); | ||
| 8 | 7 | ||
| 9 | pub const TrailerFlags = @import("meta/trailer_flags.zig").TrailerFlags; | 8 | pub const TrailerFlags = @import("meta/trailer_flags.zig").TrailerFlags; |
| 10 | 9 | ||
| ... | @@ -198,15 +197,17 @@ test containerLayout { | ... | @@ -198,15 +197,17 @@ test containerLayout { |
| 198 | try testing.expect(containerLayout(U3) == .@"extern"); | 197 | try testing.expect(containerLayout(U3) == .@"extern"); |
| 199 | } | 198 | } |
| 200 | 199 | ||
| 201 | /// Instead of this function, prefer to use e.g. `@typeInfo(foo).@"struct".decl_names` | 200 | /// Returns the list of declaration names of namespace types. |
| 202 | /// directly when you know what kind of type it is. | 201 | /// |
| 202 | /// This function is only useful when the callsite does not know statically | ||
| 203 | /// which kind of container it is. | ||
| 203 | pub fn declarations(comptime T: type) []const [:0]const u8 { | 204 | pub fn declarations(comptime T: type) []const [:0]const u8 { |
| 204 | return switch (@typeInfo(T)) { | 205 | return switch (@typeInfo(T)) { |
| 205 | .@"struct" => |info| info.decl_names, | 206 | .@"struct" => |info| info.decl_names, |
| 206 | .@"enum" => |info| info.decl_names, | 207 | .@"enum" => |info| info.decl_names, |
| 207 | .@"union" => |info| info.decl_names, | 208 | .@"union" => |info| info.decl_names, |
| 208 | .@"opaque" => |info| info.decl_names, | 209 | .@"opaque" => |info| info.decl_names, |
| 209 | else => @compileError("Expected struct, enum, union, or opaque type, found '" ++ @typeName(T) ++ "'"), | 210 | else => comptime unreachable, // type lacks namespace |
| 210 | }; | 211 | }; |
| 211 | } | 212 | } |
| 212 | 213 | ||
| ... | @@ -242,10 +243,13 @@ test declarations { | ... | @@ -242,10 +243,13 @@ test declarations { |
| 242 | } | 243 | } |
| 243 | 244 | ||
| 244 | /// To be removed after Zig 0.17.0 is tagged. | 245 | /// To be removed after Zig 0.17.0 is tagged. |
| 245 | pub const declarationInfo = @compileError("Deprecated; use '@hasDecl' instead"); | 246 | pub const declarationInfo = @compileError("deprecated in favor of @hasDecl"); |
| 246 | /// To be removed after Zig 0.17.0 is tagged. | 247 | /// To be removed after Zig 0.17.0 is tagged. |
| 247 | pub const fields = @compileError("Deprecated; use 'fieldNames' and 'fieldTypes' instead"); | 248 | pub const fields = @compileError("deprecated in favor of @typeInfo"); |
| 248 | 249 | ||
| 250 | /// Deprecated in favor of `@typeInfo`. | ||
| 251 | /// | ||
| 252 | /// To be removed after 0.17.0 is tagged. | ||
| 249 | pub fn fieldInfo(comptime T: type, comptime field: FieldEnum(T)) switch (@typeInfo(T)) { | 253 | pub fn fieldInfo(comptime T: type, comptime field: FieldEnum(T)) switch (@typeInfo(T)) { |
| 250 | .@"struct" => struct { name: [:0]const u8, type: type, attrs: Type.Struct.FieldAttributes }, | 254 | .@"struct" => struct { name: [:0]const u8, type: type, attrs: Type.Struct.FieldAttributes }, |
| 251 | .@"union" => struct { name: [:0]const u8, type: type, attrs: Type.Union.FieldAttributes }, | 255 | .@"union" => struct { name: [:0]const u8, type: type, attrs: Type.Union.FieldAttributes }, |
| ... | @@ -299,13 +303,16 @@ test fieldInfo { | ... | @@ -299,13 +303,16 @@ test fieldInfo { |
| 299 | try testing.expect(comptime uf.type == u8); | 303 | try testing.expect(comptime uf.type == u8); |
| 300 | } | 304 | } |
| 301 | 305 | ||
| 306 | /// Deprecated in favor of `@typeInfo`. | ||
| 307 | /// | ||
| 308 | /// To be removed after 0.17.0 is tagged. | ||
| 302 | pub fn fieldNames(comptime T: type) []const [:0]const u8 { | 309 | pub fn fieldNames(comptime T: type) []const [:0]const u8 { |
| 303 | return switch (@typeInfo(T)) { | 310 | return switch (@typeInfo(T)) { |
| 304 | .@"struct" => |s| s.field_names, | 311 | .@"struct" => |s| s.field_names, |
| 305 | .@"union" => |u| u.field_names, | 312 | .@"union" => |u| u.field_names, |
| 306 | .@"enum" => |e| e.field_names, | 313 | .@"enum" => |e| e.field_names, |
| 307 | .error_set => |es| es.error_names.?, | 314 | .error_set => |es| es.error_names.?, |
| 308 | else => @compileError("Expected struct, union, error set or enum type, found '" ++ @typeName(T) ++ "'"), | 315 | else => comptime unreachable, |
| 309 | }; | 316 | }; |
| 310 | } | 317 | } |
| 311 | 318 | ||
| ... | @@ -337,11 +344,14 @@ test fieldNames { | ... | @@ -337,11 +344,14 @@ test fieldNames { |
| 337 | try testing.expectEqualSlices(u8, u1names[1], "b"); | 344 | try testing.expectEqualSlices(u8, u1names[1], "b"); |
| 338 | } | 345 | } |
| 339 | 346 | ||
| 347 | /// Deprecated in favor of `@typeInfo`. | ||
| 348 | /// | ||
| 349 | /// To be removed after 0.17.0 is tagged. | ||
| 340 | pub fn fieldTypes(comptime T: type) []const type { | 350 | pub fn fieldTypes(comptime T: type) []const type { |
| 341 | return switch (@typeInfo(T)) { | 351 | return switch (@typeInfo(T)) { |
| 342 | .@"struct" => |s| s.field_types, | 352 | .@"struct" => |s| s.field_types, |
| 343 | .@"union" => |u| u.field_types, | 353 | .@"union" => |u| u.field_types, |
| 344 | else => @compileError("Expected struct or union type, found '" ++ @typeName(T) ++ "'"), | 354 | else => comptime unreachable, |
| 345 | }; | 355 | }; |
| 346 | } | 356 | } |
| 347 | 357 | ||
| ... | @@ -821,8 +831,8 @@ pub fn isError(error_union: anytype) bool { | ... | @@ -821,8 +831,8 @@ pub fn isError(error_union: anytype) bool { |
| 821 | } | 831 | } |
| 822 | 832 | ||
| 823 | test isError { | 833 | test isError { |
| 824 | try std.testing.expect(isError(math.divTrunc(u8, 5, 0))); | 834 | try std.testing.expect(isError(std.math.divTrunc(u8, 5, 0))); |
| 825 | try std.testing.expect(!isError(math.divTrunc(u8, 5, 5))); | 835 | try std.testing.expect(!isError(std.math.divTrunc(u8, 5, 5))); |
| 826 | } | 836 | } |
| 827 | 837 | ||
| 828 | /// Returns true if a type has a namespace and the namespace contains `name`; | 838 | /// Returns true if a type has a namespace and the namespace contains `name`; |
| ... | @@ -1070,3 +1080,50 @@ test hasUniqueRepresentation { | ... | @@ -1070,3 +1080,50 @@ test hasUniqueRepresentation { |
| 1070 | 1080 | ||
| 1071 | try testing.expect(hasUniqueRepresentation(StructWithComptimeFields)); | 1081 | try testing.expect(hasUniqueRepresentation(StructWithComptimeFields)); |
| 1072 | } | 1082 | } |
| 1083 | |||
| 1084 | /// Given a pointer type, type-erases the array length if present, returning an | ||
| 1085 | /// equivalent pointer type that is always a slice. | ||
| 1086 | pub fn Slice(comptime Pointer: type) type { | ||
| 1087 | const info = @typeInfo(Pointer).pointer; | ||
| 1088 | switch (info.size) { | ||
| 1089 | .slice => return Pointer, | ||
| 1090 | .one => { | ||
| 1091 | const child_info = @typeInfo(info.child); | ||
| 1092 | comptime assert(child_info == .array); | ||
| 1093 | const sentinel_ptr: ?*const child_info.array.child = @ptrCast(@alignCast(child_info.array.sentinel_ptr)); | ||
| 1094 | return @Pointer( | ||
| 1095 | .slice, | ||
| 1096 | info.attrs, | ||
| 1097 | child_info.array.child, | ||
| 1098 | if (sentinel_ptr) |ptr| ptr.* else null, | ||
| 1099 | ); | ||
| 1100 | }, | ||
| 1101 | else => unreachable, | ||
| 1102 | } | ||
| 1103 | } | ||
| 1104 | |||
| 1105 | /// Given a pointer type, removes the sentinel if present, returning an | ||
| 1106 | /// equivalent pointer type with no sentinel | ||
| 1107 | pub fn AbsorbSentinel(comptime Pointer: type) type { | ||
| 1108 | const info = @typeInfo(Pointer).pointer; | ||
| 1109 | switch (info.size) { | ||
| 1110 | .slice => return @Pointer(.slice, info.attrs, info.child, null), | ||
| 1111 | .one => { | ||
| 1112 | const child_info = @typeInfo(info.child).array; | ||
| 1113 | if (child_info.sentinel_ptr == null) { | ||
| 1114 | return Pointer; | ||
| 1115 | } else { | ||
| 1116 | return @Pointer(.one, info.attrs, [child_info.len + 1]child_info.child, null); | ||
| 1117 | } | ||
| 1118 | }, | ||
| 1119 | else => unreachable, | ||
| 1120 | } | ||
| 1121 | } | ||
| 1122 | |||
| 1123 | test Slice { | ||
| 1124 | try testing.expectEqual([]i32, Slice(*[10]i32)); | ||
| 1125 | } | ||
| 1126 | |||
| 1127 | test AbsorbSentinel { | ||
| 1128 | try testing.expectEqual(*[5]u32, AbsorbSentinel(*[4:0]u32)); | ||
| 1129 | } |
lib/std/meta/trailer_flags.zig+1-1| ... | @@ -39,7 +39,7 @@ pub fn TrailerFlags(comptime Fields: type) type { | ... | @@ -39,7 +39,7 @@ pub fn TrailerFlags(comptime Fields: type) type { |
| 39 | break :blk @Struct(.auto, null, &field_names, &field_types, &field_attrs); | 39 | break :blk @Struct(.auto, null, &field_names, &field_types, &field_attrs); |
| 40 | }; | 40 | }; |
| 41 | 41 | ||
| 42 | pub const Self = @This(); | 42 | const Self = @This(); |
| 43 | 43 | ||
| 44 | pub fn has(self: Self, comptime field: FieldEnum) bool { | 44 | pub fn has(self: Self, comptime field: FieldEnum) bool { |
| 45 | const field_index = @backingInt(field); | 45 | const field_index = @backingInt(field); |
lib/std/multi_array_list.zig+2-2| ... | @@ -163,7 +163,7 @@ pub fn MultiArrayList(comptime T: type) type { | ... | @@ -163,7 +163,7 @@ pub fn MultiArrayList(comptime T: type) type { |
| 163 | }; | 163 | }; |
| 164 | } | 164 | } |
| 165 | 165 | ||
| 166 | /// This function is used in the debugger pretty formatters in tools/ to fetch the | 166 | /// This function is used in the debugger pretty formatters in lib/lldb/ to fetch the |
| 167 | /// child field order and entry type to facilitate fancy debug printing for this type. | 167 | /// child field order and entry type to facilitate fancy debug printing for this type. |
| 168 | fn dbHelper(self: *Slice, child: *Elem, field: *Field, entry: *Entry) void { | 168 | fn dbHelper(self: *Slice, child: *Elem, field: *Field, entry: *Entry) void { |
| 169 | _ = self; | 169 | _ = self; |
| ... | @@ -681,7 +681,7 @@ pub fn MultiArrayList(comptime T: type) type { | ... | @@ -681,7 +681,7 @@ pub fn MultiArrayList(comptime T: type) type { |
| 681 | } | 681 | } |
| 682 | break :entry @Struct(.@"extern", null, &entry_field_names, &entry_field_types, &entry_field_attrs); | 682 | break :entry @Struct(.@"extern", null, &entry_field_names, &entry_field_types, &entry_field_attrs); |
| 683 | }; | 683 | }; |
| 684 | /// This function is used in the debugger pretty formatters in tools/ to fetch the | 684 | /// This function is used in the debugger pretty formatters in lib/lldb/ to fetch the |
| 685 | /// child field order and entry type to facilitate fancy debug printing for this type. | 685 | /// child field order and entry type to facilitate fancy debug printing for this type. |
| 686 | fn dbHelper(self: *Self, child: *Elem, field: *Field, entry: *Entry) void { | 686 | fn dbHelper(self: *Self, child: *Elem, field: *Field, entry: *Entry) void { |
| 687 | _ = self; | 687 | _ = self; |
lib/std/os/emscripten.zig+1-1| ... | @@ -730,7 +730,7 @@ pub const clock_t = i32; | ... | @@ -730,7 +730,7 @@ pub const clock_t = i32; |
| 730 | pub const dl_phdr_info = extern struct { | 730 | pub const dl_phdr_info = extern struct { |
| 731 | addr: usize, | 731 | addr: usize, |
| 732 | name: ?[*:0]const u8, | 732 | name: ?[*:0]const u8, |
| 733 | phdr: [*]std.elf.Phdr, | 733 | phdr: [*]std.elf.ElfN.Phdr, |
| 734 | phnum: u16, | 734 | phnum: u16, |
| 735 | }; | 735 | }; |
| 736 | 736 |
lib/std/os/linux.zig+4-6| ... | @@ -2058,8 +2058,8 @@ pub const F = struct { | ... | @@ -2058,8 +2058,8 @@ pub const F = struct { |
| 2058 | }, | 2058 | }, |
| 2059 | }; | 2059 | }; |
| 2060 | 2060 | ||
| 2061 | pub const SETSIG = if (is_hppa or native_arch == .alpha) 13 else 11; | 2061 | pub const SETSIG = if (is_hppa) 13 else 10; |
| 2062 | pub const GETSIG = if (is_hppa or native_arch == .alpha) 14 else 12; | 2062 | pub const GETSIG = if (is_hppa) 14 else 11; |
| 2063 | 2063 | ||
| 2064 | pub const SETOWN_EX = 15; | 2064 | pub const SETOWN_EX = 15; |
| 2065 | pub const GETOWN_EX = 16; | 2065 | pub const GETOWN_EX = 16; |
| ... | @@ -8181,13 +8181,11 @@ pub const rusage = extern struct { | ... | @@ -8181,13 +8181,11 @@ pub const rusage = extern struct { |
| 8181 | 8181 | ||
| 8182 | pub const NCC = if (is_ppc) 10 else 8; | 8182 | pub const NCC = if (is_ppc) 10 else 8; |
| 8183 | pub const NCCS = if (is_mips) | 8183 | pub const NCCS = if (is_mips) |
| 8184 | 32 | 8184 | 23 |
| 8185 | else if (is_ppc or native_arch == .alpha) | ||
| 8186 | 19 | ||
| 8187 | else if (is_sparc) | 8185 | else if (is_sparc) |
| 8188 | 17 | 8186 | 17 |
| 8189 | else | 8187 | else |
| 8190 | 32; | 8188 | 19; |
| 8191 | 8189 | ||
| 8192 | pub const speed_t = if (is_ppc) enum(c_uint) { | 8190 | pub const speed_t = if (is_ppc) enum(c_uint) { |
| 8193 | B0 = 0x0000000, | 8191 | B0 = 0x0000000, |
lib/std/os/linux/IoUring.zig+1-1| ... | @@ -267,7 +267,7 @@ pub fn cq_ready(self: *IoUring) u32 { | ... | @@ -267,7 +267,7 @@ pub fn cq_ready(self: *IoUring) u32 { |
| 267 | } | 267 | } |
| 268 | 268 | ||
| 269 | /// Copies as many CQEs as are ready, and that can fit into the destination `cqes` slice. | 269 | /// Copies as many CQEs as are ready, and that can fit into the destination `cqes` slice. |
| 270 | /// If none are available, enters into the kernel to wait for at most `wait_nr` CQEs. | 270 | /// If none are available, enters into the kernel to wait for at least `wait_nr` CQEs. |
| 271 | /// Returns the number of CQEs copied, advancing the CQ ring. | 271 | /// Returns the number of CQEs copied, advancing the CQ ring. |
| 272 | /// Provides all the wait/peek methods found in liburing, but with batching and a single method. | 272 | /// Provides all the wait/peek methods found in liburing, but with batching and a single method. |
| 273 | /// The rationale for copying CQEs rather than copying pointers is that pointers are 8 bytes | 273 | /// The rationale for copying CQEs rather than copying pointers is that pointers are 8 bytes |
lib/std/os/linux/IoUring/test.zig+26-64| ... | @@ -475,9 +475,6 @@ test "close" { | ... | @@ -475,9 +475,6 @@ test "close" { |
| 475 | } | 475 | } |
| 476 | 476 | ||
| 477 | test "accept/connect/send/recv" { | 477 | test "accept/connect/send/recv" { |
| 478 | const io = testing.io; | ||
| 479 | _ = io; | ||
| 480 | |||
| 481 | var ring = IoUring.init(16, 0) catch |err| switch (err) { | 478 | var ring = IoUring.init(16, 0) catch |err| switch (err) { |
| 482 | error.SystemOutdated => return error.SkipZigTest, | 479 | error.SystemOutdated => return error.SkipZigTest, |
| 483 | error.PermissionDenied => return error.SkipZigTest, | 480 | error.PermissionDenied => return error.SkipZigTest, |
| ... | @@ -620,7 +617,7 @@ test "timeout (after a relative time)" { | ... | @@ -620,7 +617,7 @@ test "timeout (after a relative time)" { |
| 620 | 617 | ||
| 621 | const ms = 10; | 618 | const ms = 10; |
| 622 | const margin = 5; | 619 | const margin = 5; |
| 623 | const ts: linux.kernel_timespec = .{ .sec = 0, .nsec = ms * 1000000 }; | 620 | const ts: linux.kernel_timespec = .{ .sec = 0, .nsec = ms * std.time.ns_per_ms }; |
| 624 | 621 | ||
| 625 | const started = std.Io.Clock.awake.now(io); | 622 | const started = std.Io.Clock.awake.now(io); |
| 626 | const sqe = try ring.timeout(0x55555555, &ts, 0, 0); | 623 | const sqe = try ring.timeout(0x55555555, &ts, 0, 0); |
| ... | @@ -730,9 +727,6 @@ test "timeout_remove" { | ... | @@ -730,9 +727,6 @@ test "timeout_remove" { |
| 730 | } | 727 | } |
| 731 | 728 | ||
| 732 | test "accept/connect/recv/link_timeout" { | 729 | test "accept/connect/recv/link_timeout" { |
| 733 | const io = testing.io; | ||
| 734 | _ = io; | ||
| 735 | |||
| 736 | var ring = IoUring.init(16, 0) catch |err| switch (err) { | 730 | var ring = IoUring.init(16, 0) catch |err| switch (err) { |
| 737 | error.SystemOutdated => return error.SkipZigTest, | 731 | error.SystemOutdated => return error.SkipZigTest, |
| 738 | error.PermissionDenied => return error.SkipZigTest, | 732 | error.PermissionDenied => return error.SkipZigTest, |
| ... | @@ -748,7 +742,7 @@ test "accept/connect/recv/link_timeout" { | ... | @@ -748,7 +742,7 @@ test "accept/connect/recv/link_timeout" { |
| 748 | const sqe_recv = try ring.recv(0xffffffff, socket_test_harness.server, .{ .buffer = buffer_recv[0..] }, 0); | 742 | const sqe_recv = try ring.recv(0xffffffff, socket_test_harness.server, .{ .buffer = buffer_recv[0..] }, 0); |
| 749 | sqe_recv.flags |= linux.IOSQE_IO_LINK; | 743 | sqe_recv.flags |= linux.IOSQE_IO_LINK; |
| 750 | 744 | ||
| 751 | const ts = linux.kernel_timespec{ .sec = 0, .nsec = 1000000 }; | 745 | const ts: linux.kernel_timespec = .{ .sec = 0, .nsec = std.time.ns_per_ms }; |
| 752 | _ = try ring.link_timeout(0x22222222, &ts, 0); | 746 | _ = try ring.link_timeout(0x22222222, &ts, 0); |
| 753 | 747 | ||
| 754 | const nr_wait = try ring.submit(); | 748 | const nr_wait = try ring.submit(); |
| ... | @@ -883,9 +877,6 @@ test "statx" { | ... | @@ -883,9 +877,6 @@ test "statx" { |
| 883 | } | 877 | } |
| 884 | 878 | ||
| 885 | test "accept/connect/recv/cancel" { | 879 | test "accept/connect/recv/cancel" { |
| 886 | const io = testing.io; | ||
| 887 | _ = io; | ||
| 888 | |||
| 889 | var ring = IoUring.init(16, 0) catch |err| switch (err) { | 880 | var ring = IoUring.init(16, 0) catch |err| switch (err) { |
| 890 | error.SystemOutdated => return error.SkipZigTest, | 881 | error.SystemOutdated => return error.SkipZigTest, |
| 891 | error.PermissionDenied => return error.SkipZigTest, | 882 | error.PermissionDenied => return error.SkipZigTest, |
| ... | @@ -1568,9 +1559,6 @@ test "remove_buffers" { | ... | @@ -1568,9 +1559,6 @@ test "remove_buffers" { |
| 1568 | } | 1559 | } |
| 1569 | 1560 | ||
| 1570 | test "provide_buffers: accept/connect/send/recv" { | 1561 | test "provide_buffers: accept/connect/send/recv" { |
| 1571 | const io = testing.io; | ||
| 1572 | _ = io; | ||
| 1573 | |||
| 1574 | var ring = IoUring.init(16, 0) catch |err| switch (err) { | 1562 | var ring = IoUring.init(16, 0) catch |err| switch (err) { |
| 1575 | error.SystemOutdated => return error.SkipZigTest, | 1563 | error.SystemOutdated => return error.SkipZigTest, |
| 1576 | error.PermissionDenied => return error.SkipZigTest, | 1564 | error.PermissionDenied => return error.SkipZigTest, |
| ... | @@ -1777,11 +1765,6 @@ test "accept multishot" { | ... | @@ -1777,11 +1765,6 @@ test "accept multishot" { |
| 1777 | } | 1765 | } |
| 1778 | 1766 | ||
| 1779 | test "accept/connect/send_zc/recv" { | 1767 | test "accept/connect/send_zc/recv" { |
| 1780 | try skipKernelLessThan(.{ .major = 6, .minor = 0, .patch = 0 }); | ||
| 1781 | |||
| 1782 | const io = testing.io; | ||
| 1783 | _ = io; | ||
| 1784 | |||
| 1785 | var ring = IoUring.init(16, 0) catch |err| switch (err) { | 1768 | var ring = IoUring.init(16, 0) catch |err| switch (err) { |
| 1786 | error.SystemOutdated => return error.SkipZigTest, | 1769 | error.SystemOutdated => return error.SkipZigTest, |
| 1787 | error.PermissionDenied => return error.SkipZigTest, | 1770 | error.PermissionDenied => return error.SkipZigTest, |
| ... | @@ -1789,6 +1772,13 @@ test "accept/connect/send_zc/recv" { | ... | @@ -1789,6 +1772,13 @@ test "accept/connect/send_zc/recv" { |
| 1789 | }; | 1772 | }; |
| 1790 | defer ring.deinit(); | 1773 | defer ring.deinit(); |
| 1791 | 1774 | ||
| 1775 | const probe = ring.get_probe() catch return error.SkipZigTest; | ||
| 1776 | const ops_not_supported = !probe.is_supported(.ACCEPT) or | ||
| 1777 | !probe.is_supported(.CONNECT) or | ||
| 1778 | !probe.is_supported(.SEND_ZC) or | ||
| 1779 | !probe.is_supported(.RECV); | ||
| 1780 | if (ops_not_supported) return error.SkipZigTest; | ||
| 1781 | |||
| 1792 | const socket_test_harness = try createSocketTestHarness(&ring); | 1782 | const socket_test_harness = try createSocketTestHarness(&ring); |
| 1793 | defer socket_test_harness.close(); | 1783 | defer socket_test_harness.close(); |
| 1794 | 1784 | ||
| ... | @@ -1836,16 +1826,16 @@ test "accept/connect/send_zc/recv" { | ... | @@ -1836,16 +1826,16 @@ test "accept/connect/send_zc/recv" { |
| 1836 | } | 1826 | } |
| 1837 | 1827 | ||
| 1838 | test "accept_direct" { | 1828 | test "accept_direct" { |
| 1839 | if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30854 | ||
| 1840 | |||
| 1841 | try skipKernelLessThan(.{ .major = 5, .minor = 19, .patch = 0 }); | ||
| 1842 | |||
| 1843 | var ring = IoUring.init(1, 0) catch |err| switch (err) { | 1829 | var ring = IoUring.init(1, 0) catch |err| switch (err) { |
| 1844 | error.SystemOutdated => return error.SkipZigTest, | 1830 | error.SystemOutdated => return error.SkipZigTest, |
| 1845 | error.PermissionDenied => return error.SkipZigTest, | 1831 | error.PermissionDenied => return error.SkipZigTest, |
| 1846 | else => return err, | 1832 | else => return err, |
| 1847 | }; | 1833 | }; |
| 1848 | defer ring.deinit(); | 1834 | defer ring.deinit(); |
| 1835 | |||
| 1836 | const probe = ring.get_probe() catch return error.SkipZigTest; | ||
| 1837 | if (!probe.is_supported(.ACCEPT)) return error.SkipZigTest; | ||
| 1838 | |||
| 1849 | var address: linux.sockaddr.in = .{ | 1839 | var address: linux.sockaddr.in = .{ |
| 1850 | .port = 0, | 1840 | .port = 0, |
| 1851 | .addr = @as(*align(1) const u32, @ptrCast( | 1841 | .addr = @as(*align(1) const u32, @ptrCast( |
| ... | @@ -1923,13 +1913,6 @@ test "accept_direct" { | ... | @@ -1923,13 +1913,6 @@ test "accept_direct" { |
| 1923 | } | 1913 | } |
| 1924 | 1914 | ||
| 1925 | test "accept_multishot_direct" { | 1915 | test "accept_multishot_direct" { |
| 1926 | try skipKernelLessThan(.{ .major = 5, .minor = 19, .patch = 0 }); | ||
| 1927 | |||
| 1928 | if (builtin.cpu.arch == .riscv64) { | ||
| 1929 | // https://github.com/ziglang/zig/issues/25734 | ||
| 1930 | return error.SkipZigTest; | ||
| 1931 | } | ||
| 1932 | |||
| 1933 | var ring = IoUring.init(1, 0) catch |err| switch (err) { | 1916 | var ring = IoUring.init(1, 0) catch |err| switch (err) { |
| 1934 | error.SystemOutdated => return error.SkipZigTest, | 1917 | error.SystemOutdated => return error.SkipZigTest, |
| 1935 | error.PermissionDenied => return error.SkipZigTest, | 1918 | error.PermissionDenied => return error.SkipZigTest, |
| ... | @@ -1937,6 +1920,9 @@ test "accept_multishot_direct" { | ... | @@ -1937,6 +1920,9 @@ test "accept_multishot_direct" { |
| 1937 | }; | 1920 | }; |
| 1938 | defer ring.deinit(); | 1921 | defer ring.deinit(); |
| 1939 | 1922 | ||
| 1923 | const probe = ring.get_probe() catch return error.SkipZigTest; | ||
| 1924 | if (!probe.is_supported(.ACCEPT)) return error.SkipZigTest; | ||
| 1925 | |||
| 1940 | var address: linux.sockaddr.in = .{ | 1926 | var address: linux.sockaddr.in = .{ |
| 1941 | .port = 0, | 1927 | .port = 0, |
| 1942 | .addr = @as(*align(1) const u32, @ptrCast( | 1928 | .addr = @as(*align(1) const u32, @ptrCast( |
| ... | @@ -1991,8 +1977,6 @@ test "accept_multishot_direct" { | ... | @@ -1991,8 +1977,6 @@ test "accept_multishot_direct" { |
| 1991 | } | 1977 | } |
| 1992 | 1978 | ||
| 1993 | test "socket" { | 1979 | test "socket" { |
| 1994 | try skipKernelLessThan(.{ .major = 5, .minor = 19, .patch = 0 }); | ||
| 1995 | |||
| 1996 | var ring = IoUring.init(1, 0) catch |err| switch (err) { | 1980 | var ring = IoUring.init(1, 0) catch |err| switch (err) { |
| 1997 | error.SystemOutdated => return error.SkipZigTest, | 1981 | error.SystemOutdated => return error.SkipZigTest, |
| 1998 | error.PermissionDenied => return error.SkipZigTest, | 1982 | error.PermissionDenied => return error.SkipZigTest, |
| ... | @@ -2000,6 +1984,9 @@ test "socket" { | ... | @@ -2000,6 +1984,9 @@ test "socket" { |
| 2000 | }; | 1984 | }; |
| 2001 | defer ring.deinit(); | 1985 | defer ring.deinit(); |
| 2002 | 1986 | ||
| 1987 | const probe = ring.get_probe() catch return error.SkipZigTest; | ||
| 1988 | if (!probe.is_supported(.SOCKET)) return error.SkipZigTest; | ||
| 1989 | |||
| 2003 | // prepare, submit socket operation | 1990 | // prepare, submit socket operation |
| 2004 | _ = try ring.socket(0, linux.AF.INET, posix.SOCK.STREAM, 0, 0); | 1991 | _ = try ring.socket(0, linux.AF.INET, posix.SOCK.STREAM, 0, 0); |
| 2005 | try testing.expectEqual(@as(u32, 1), try ring.submit()); | 1992 | try testing.expectEqual(@as(u32, 1), try ring.submit()); |
| ... | @@ -2014,8 +2001,6 @@ test "socket" { | ... | @@ -2014,8 +2001,6 @@ test "socket" { |
| 2014 | } | 2001 | } |
| 2015 | 2002 | ||
| 2016 | test "socket_direct/socket_direct_alloc/close_direct" { | 2003 | test "socket_direct/socket_direct_alloc/close_direct" { |
| 2017 | try skipKernelLessThan(.{ .major = 5, .minor = 19, .patch = 0 }); | ||
| 2018 | |||
| 2019 | var ring = IoUring.init(2, 0) catch |err| switch (err) { | 2004 | var ring = IoUring.init(2, 0) catch |err| switch (err) { |
| 2020 | error.SystemOutdated => return error.SkipZigTest, | 2005 | error.SystemOutdated => return error.SkipZigTest, |
| 2021 | error.PermissionDenied => return error.SkipZigTest, | 2006 | error.PermissionDenied => return error.SkipZigTest, |
| ... | @@ -2023,6 +2008,9 @@ test "socket_direct/socket_direct_alloc/close_direct" { | ... | @@ -2023,6 +2008,9 @@ test "socket_direct/socket_direct_alloc/close_direct" { |
| 2023 | }; | 2008 | }; |
| 2024 | defer ring.deinit(); | 2009 | defer ring.deinit(); |
| 2025 | 2010 | ||
| 2011 | const probe = ring.get_probe() catch return error.SkipZigTest; | ||
| 2012 | if (!probe.is_supported(.SOCKET) or !probe.is_supported(.CLOSE)) return error.SkipZigTest; | ||
| 2013 | |||
| 2026 | var registered_fds: [3]linux.fd_t = @splat(-1); | 2014 | var registered_fds: [3]linux.fd_t = @splat(-1); |
| 2027 | try ring.register_files(registered_fds[0..]); | 2015 | try ring.register_files(registered_fds[0..]); |
| 2028 | 2016 | ||
| ... | @@ -2097,8 +2085,6 @@ test "socket_direct/socket_direct_alloc/close_direct" { | ... | @@ -2097,8 +2085,6 @@ test "socket_direct/socket_direct_alloc/close_direct" { |
| 2097 | } | 2085 | } |
| 2098 | 2086 | ||
| 2099 | test "openat_direct/close_direct" { | 2087 | test "openat_direct/close_direct" { |
| 2100 | try skipKernelLessThan(.{ .major = 5, .minor = 19, .patch = 0 }); | ||
| 2101 | |||
| 2102 | var ring = IoUring.init(2, 0) catch |err| switch (err) { | 2088 | var ring = IoUring.init(2, 0) catch |err| switch (err) { |
| 2103 | error.SystemOutdated => return error.SkipZigTest, | 2089 | error.SystemOutdated => return error.SkipZigTest, |
| 2104 | error.PermissionDenied => return error.SkipZigTest, | 2090 | error.PermissionDenied => return error.SkipZigTest, |
| ... | @@ -2106,6 +2092,9 @@ test "openat_direct/close_direct" { | ... | @@ -2106,6 +2092,9 @@ test "openat_direct/close_direct" { |
| 2106 | }; | 2092 | }; |
| 2107 | defer ring.deinit(); | 2093 | defer ring.deinit(); |
| 2108 | 2094 | ||
| 2095 | const probe = ring.get_probe() catch return error.SkipZigTest; | ||
| 2096 | if (!probe.is_supported(.OPENAT) or !probe.is_supported(.CLOSE)) return error.SkipZigTest; | ||
| 2097 | |||
| 2109 | var registered_fds: [3]linux.fd_t = @splat(-1); | 2098 | var registered_fds: [3]linux.fd_t = @splat(-1); |
| 2110 | try ring.register_files(registered_fds[0..]); | 2099 | try ring.register_files(registered_fds[0..]); |
| 2111 | 2100 | ||
| ... | @@ -2148,9 +2137,6 @@ test "openat_direct/close_direct" { | ... | @@ -2148,9 +2137,6 @@ test "openat_direct/close_direct" { |
| 2148 | } | 2137 | } |
| 2149 | 2138 | ||
| 2150 | test "ring mapped buffers recv" { | 2139 | test "ring mapped buffers recv" { |
| 2151 | const io = testing.io; | ||
| 2152 | _ = io; | ||
| 2153 | |||
| 2154 | var ring = IoUring.init(16, 0) catch |err| switch (err) { | 2140 | var ring = IoUring.init(16, 0) catch |err| switch (err) { |
| 2155 | error.SystemOutdated => return error.SkipZigTest, | 2141 | error.SystemOutdated => return error.SkipZigTest, |
| 2156 | error.PermissionDenied => return error.SkipZigTest, | 2142 | error.PermissionDenied => return error.SkipZigTest, |
| ... | @@ -2238,9 +2224,6 @@ test "ring mapped buffers recv" { | ... | @@ -2238,9 +2224,6 @@ test "ring mapped buffers recv" { |
| 2238 | } | 2224 | } |
| 2239 | 2225 | ||
| 2240 | test "ring mapped buffers multishot recv" { | 2226 | test "ring mapped buffers multishot recv" { |
| 2241 | const io = testing.io; | ||
| 2242 | _ = io; | ||
| 2243 | |||
| 2244 | var ring = IoUring.init(16, 0) catch |err| switch (err) { | 2227 | var ring = IoUring.init(16, 0) catch |err| switch (err) { |
| 2245 | error.SystemOutdated => return error.SkipZigTest, | 2228 | error.SystemOutdated => return error.SkipZigTest, |
| 2246 | error.PermissionDenied => return error.SkipZigTest, | 2229 | error.PermissionDenied => return error.SkipZigTest, |
| ... | @@ -2672,7 +2655,7 @@ pub fn createSocketTestHarness(ring: *IoUring) !SocketTestHarness { | ... | @@ -2672,7 +2655,7 @@ pub fn createSocketTestHarness(ring: *IoUring) !SocketTestHarness { |
| 2672 | 2655 | ||
| 2673 | // All good | 2656 | // All good |
| 2674 | 2657 | ||
| 2675 | return SocketTestHarness{ | 2658 | return .{ |
| 2676 | .listener = listener_socket, | 2659 | .listener = listener_socket, |
| 2677 | .server = cqe_accept.res, | 2660 | .server = cqe_accept.res, |
| 2678 | .client = client, | 2661 | .client = client, |
| ... | @@ -2695,27 +2678,6 @@ fn createListenerSocket(address: *linux.sockaddr.in) !posix.socket_t { | ... | @@ -2695,27 +2678,6 @@ fn createListenerSocket(address: *linux.sockaddr.in) !posix.socket_t { |
| 2695 | return listener_socket; | 2678 | return listener_socket; |
| 2696 | } | 2679 | } |
| 2697 | 2680 | ||
| 2698 | /// For use in tests. Returns SkipZigTest if kernel version is less than required. | ||
| 2699 | inline fn skipKernelLessThan(required: std.SemanticVersion) !void { | ||
| 2700 | var uts: linux.utsname = undefined; | ||
| 2701 | const res = linux.uname(&uts); | ||
| 2702 | switch (linux.errno(res)) { | ||
| 2703 | .SUCCESS => {}, | ||
| 2704 | else => |errno| return posix.unexpectedErrno(errno), | ||
| 2705 | } | ||
| 2706 | |||
| 2707 | const release = mem.sliceTo(&uts.release, 0); | ||
| 2708 | // Strips potential extra, as kernel version might not be semver compliant, example "6.8.9-300.fc40.x86_64" | ||
| 2709 | const extra_index = std.mem.indexOfAny(u8, release, "-+"); | ||
| 2710 | const stripped = release[0..(extra_index orelse release.len)]; | ||
| 2711 | // Make sure the input don't rely on the extra we just stripped | ||
| 2712 | try testing.expect(required.pre == null and required.build == null); | ||
| 2713 | |||
| 2714 | var current = try std.SemanticVersion.parse(stripped); | ||
| 2715 | current.pre = null; // don't check pre field | ||
| 2716 | if (required.order(current) == .gt) return error.SkipZigTest; | ||
| 2717 | } | ||
| 2718 | |||
| 2719 | fn addrAny(addr: *linux.sockaddr.in) *linux.sockaddr { | 2681 | fn addrAny(addr: *linux.sockaddr.in) *linux.sockaddr { |
| 2720 | return @ptrCast(addr); | 2682 | return @ptrCast(addr); |
| 2721 | } | 2683 | } |
lib/std/os/linux/aarch64.zig+1-1| ... | @@ -154,7 +154,7 @@ pub const restore = restore_rt; | ... | @@ -154,7 +154,7 @@ pub const restore = restore_rt; |
| 154 | pub fn restore_rt() callconv(.naked) noreturn { | 154 | pub fn restore_rt() callconv(.naked) noreturn { |
| 155 | switch (builtin.zig_backend) { | 155 | switch (builtin.zig_backend) { |
| 156 | .stage2_c => asm volatile ( | 156 | .stage2_c => asm volatile ( |
| 157 | \\ mov x8, %[number] | 157 | \\ mov w8, %[number] |
| 158 | \\ svc #0 | 158 | \\ svc #0 |
| 159 | : | 159 | : |
| 160 | : [number] "i" (@backingInt(SYS.rt_sigreturn)), | 160 | : [number] "i" (@backingInt(SYS.rt_sigreturn)), |
lib/std/os/linux/s390x.zig+26-10| ... | @@ -174,19 +174,35 @@ pub fn clone() callconv(.naked) u64 { | ... | @@ -174,19 +174,35 @@ pub fn clone() callconv(.naked) u64 { |
| 174 | } | 174 | } |
| 175 | 175 | ||
| 176 | pub fn restore() callconv(.naked) noreturn { | 176 | pub fn restore() callconv(.naked) noreturn { |
| 177 | asm volatile ( | 177 | switch (builtin.zig_backend) { |
| 178 | \\svc 0 | 178 | .stage2_c => asm volatile ( |
| 179 | : | 179 | \\lghi %%r1, %[number] |
| 180 | : [number] "{r1}" (@backingInt(SYS.sigreturn)), | 180 | \\svc 0 |
| 181 | ); | 181 | : |
| 182 | : [number] "K" (@backingInt(SYS.sigreturn)), | ||
| 183 | ), | ||
| 184 | else => asm volatile ( | ||
| 185 | \\svc 0 | ||
| 186 | : | ||
| 187 | : [number] "{r1}" (@backingInt(SYS.sigreturn)), | ||
| 188 | ), | ||
| 189 | } | ||
| 182 | } | 190 | } |
| 183 | 191 | ||
| 184 | pub fn restore_rt() callconv(.naked) noreturn { | 192 | pub fn restore_rt() callconv(.naked) noreturn { |
| 185 | asm volatile ( | 193 | switch (builtin.zig_backend) { |
| 186 | \\svc 0 | 194 | .stage2_c => asm volatile ( |
| 187 | : | 195 | \\lghi %%r1, %[number] |
| 188 | : [number] "{r1}" (@backingInt(SYS.rt_sigreturn)), | 196 | \\svc 0 |
| 189 | ); | 197 | : |
| 198 | : [number] "K" (@backingInt(SYS.rt_sigreturn)), | ||
| 199 | ), | ||
| 200 | else => asm volatile ( | ||
| 201 | \\svc 0 | ||
| 202 | : | ||
| 203 | : [number] "{r1}" (@backingInt(SYS.rt_sigreturn)), | ||
| 204 | ), | ||
| 205 | } | ||
| 190 | } | 206 | } |
| 191 | 207 | ||
| 192 | pub const time_t = i64; | 208 | pub const time_t = i64; |
lib/std/os/linux/sparc.zig+8-5| ... | @@ -260,13 +260,16 @@ pub fn clone() callconv(.naked) u32 { | ... | @@ -260,13 +260,16 @@ pub fn clone() callconv(.naked) u32 { |
| 260 | 260 | ||
| 261 | pub const restore = restore_rt; | 261 | pub const restore = restore_rt; |
| 262 | 262 | ||
| 263 | // Need to use C ABI here instead of naked | 263 | pub fn restore_rt() callconv(.naked) noreturn { |
| 264 | // to prevent an infinite loop when calling rt_sigreturn. | 264 | asm volatile ( |
| 265 | pub fn restore_rt() callconv(.c) void { | 265 | \\ nop |
| 266 | return asm volatile ("t 0x10" | 266 | \\ nop |
| 267 | ); | ||
| 268 | asm volatile ( | ||
| 269 | \\ t 0x10 | ||
| 267 | : | 270 | : |
| 268 | : [number] "{g1}" (@backingInt(SYS.rt_sigreturn)), | 271 | : [number] "{g1}" (@backingInt(SYS.rt_sigreturn)), |
| 269 | : .{ .memory = true, .xcc = true, .o0 = true, .o1 = true, .o2 = true, .o3 = true, .o4 = true, .o5 = true, .o7 = true }); | 272 | ); |
| 270 | } | 273 | } |
| 271 | 274 | ||
| 272 | pub const VDSO = struct { | 275 | pub const VDSO = struct { |
lib/std/os/linux/sparc64.zig+8-5| ... | @@ -259,13 +259,16 @@ pub fn clone() callconv(.naked) u64 { | ... | @@ -259,13 +259,16 @@ pub fn clone() callconv(.naked) u64 { |
| 259 | 259 | ||
| 260 | pub const restore = restore_rt; | 260 | pub const restore = restore_rt; |
| 261 | 261 | ||
| 262 | // Need to use C ABI here instead of naked | 262 | pub fn restore_rt() callconv(.naked) noreturn { |
| 263 | // to prevent an infinite loop when calling rt_sigreturn. | 263 | asm volatile ( |
| 264 | pub fn restore_rt() callconv(.c) void { | 264 | \\ nop |
| 265 | return asm volatile ("t 0x6d" | 265 | \\ nop |
| 266 | ); | ||
| 267 | asm volatile ( | ||
| 268 | \\ t 0x6d | ||
| 266 | : | 269 | : |
| 267 | : [number] "{g1}" (@backingInt(SYS.rt_sigreturn)), | 270 | : [number] "{g1}" (@backingInt(SYS.rt_sigreturn)), |
| 268 | : .{ .memory = true, .xcc = true, .o0 = true, .o1 = true, .o2 = true, .o3 = true, .o4 = true, .o5 = true, .o7 = true }); | 271 | ); |
| 269 | } | 272 | } |
| 270 | 273 | ||
| 271 | pub const VDSO = struct { | 274 | pub const VDSO = struct { |
lib/std/os/linux/tls.zig+35-14| ... | @@ -22,7 +22,7 @@ const page_size_min = std.heap.page_size_min; | ... | @@ -22,7 +22,7 @@ const page_size_min = std.heap.page_size_min; |
| 22 | /// Represents an ELF TLS variant. | 22 | /// Represents an ELF TLS variant. |
| 23 | /// | 23 | /// |
| 24 | /// In all variants, the TP and the TLS blocks must be aligned to the `p_align` value in the | 24 | /// In all variants, the TP and the TLS blocks must be aligned to the `p_align` value in the |
| 25 | /// `PT_TLS` ELF program header. Everything else has natural alignment. | 25 | /// `PT.TLS` ELF program header. Everything else has natural alignment. |
| 26 | /// | 26 | /// |
| 27 | /// The location of the DTV does not actually matter. For simplicity, we put it in the TLS area, but | 27 | /// The location of the DTV does not actually matter. For simplicity, we put it in the TLS area, but |
| 28 | /// there is no actual ABI requirement that it reside there. | 28 | /// there is no actual ABI requirement that it reside there. |
| ... | @@ -480,17 +480,17 @@ pub fn getThreadPointer() usize { | ... | @@ -480,17 +480,17 @@ pub fn getThreadPointer() usize { |
| 480 | }; | 480 | }; |
| 481 | } | 481 | } |
| 482 | 482 | ||
| 483 | fn computeAreaDesc(phdrs: []elf.Phdr) void { | 483 | fn computeAreaDesc(phdrs: []elf.ElfN.Phdr) void { |
| 484 | @setRuntimeSafety(false); | 484 | @setRuntimeSafety(false); |
| 485 | @disableInstrumentation(); | 485 | @disableInstrumentation(); |
| 486 | 486 | ||
| 487 | var tls_phdr: ?*elf.Phdr = null; | 487 | var tls_phdr: ?*elf.ElfN.Phdr = null; |
| 488 | var img_base: usize = 0; | 488 | var img_base: usize = 0; |
| 489 | 489 | ||
| 490 | for (phdrs) |*phdr| { | 490 | for (phdrs) |*phdr| { |
| 491 | switch (phdr.p_type) { | 491 | switch (phdr.type) { |
| 492 | elf.PT_PHDR => img_base = @intFromPtr(phdrs.ptr) - phdr.p_vaddr, | 492 | .PHDR => img_base = @intFromPtr(phdrs.ptr) - phdr.vaddr, |
| 493 | elf.PT_TLS => tls_phdr = phdr, | 493 | .TLS => tls_phdr = phdr, |
| 494 | else => {}, | 494 | else => {}, |
| 495 | } | 495 | } |
| 496 | } | 496 | } |
| ... | @@ -500,12 +500,12 @@ fn computeAreaDesc(phdrs: []elf.Phdr) void { | ... | @@ -500,12 +500,12 @@ fn computeAreaDesc(phdrs: []elf.Phdr) void { |
| 500 | var block_size: usize = undefined; | 500 | var block_size: usize = undefined; |
| 501 | 501 | ||
| 502 | if (tls_phdr) |phdr| { | 502 | if (tls_phdr) |phdr| { |
| 503 | align_factor = phdr.p_align; | 503 | align_factor = phdr.@"align"; |
| 504 | 504 | ||
| 505 | // The effective size in memory is represented by `p_memsz`; the length of the data stored | 505 | // The effective size in memory is represented by `memsz`; the length of the data stored |
| 506 | // in the `PT_TLS` segment is `p_filesz` and may be less than the former. | 506 | // in the `PT.TLS` segment is `filesz` and may be less than the former. |
| 507 | block_init = @as([*]u8, @ptrFromInt(img_base + phdr.p_vaddr))[0..phdr.p_filesz]; | 507 | block_init = @as([*]u8, @ptrFromInt(img_base + phdr.vaddr))[0..phdr.filesz]; |
| 508 | block_size = phdr.p_memsz; | 508 | block_size = phdr.memsz; |
| 509 | } else { | 509 | } else { |
| 510 | align_factor = @alignOf(usize); | 510 | align_factor = @alignOf(usize); |
| 511 | 511 | ||
| ... | @@ -651,7 +651,7 @@ var main_thread_area_buffer: [0x1000]u8 align(page_size_min) = undefined; | ... | @@ -651,7 +651,7 @@ var main_thread_area_buffer: [0x1000]u8 align(page_size_min) = undefined; |
| 651 | 651 | ||
| 652 | /// Computes the layout of the static TLS area, allocates the area, initializes all of its fields, | 652 | /// Computes the layout of the static TLS area, allocates the area, initializes all of its fields, |
| 653 | /// and assigns the architecture-specific value to the TP register. | 653 | /// and assigns the architecture-specific value to the TP register. |
| 654 | pub fn initStatic(phdrs: []elf.Phdr) void { | 654 | pub fn initStatic(phdrs: []elf.ElfN.Phdr) void { |
| 655 | @setRuntimeSafety(false); | 655 | @setRuntimeSafety(false); |
| 656 | @disableInstrumentation(); | 656 | @disableInstrumentation(); |
| 657 | 657 | ||
| ... | @@ -726,12 +726,14 @@ comptime { | ... | @@ -726,12 +726,14 @@ comptime { |
| 726 | // function for the GD and LD models. This function is unlikely to actually be used, since | 726 | // function for the GD and LD models. This function is unlikely to actually be used, since |
| 727 | // the linker should be able to relax every TLS access to the LE model and therefore | 727 | // the linker should be able to relax every TLS access to the LE model and therefore |
| 728 | // eliminate all calls to this function, but that isn't guaranteed. | 728 | // eliminate all calls to this function, but that isn't guaranteed. |
| 729 | _ = struct { | 729 | const Fns = struct { |
| 730 | const TlsIndex = switch (native_arch) { | 730 | const TlsIndex = switch (native_arch) { |
| 731 | .x86_64 => extern struct { module: u64, offset: u64 }, // Even for x32... | 731 | .x86_64 => extern struct { module: u64, offset: u64 }, // Even for x32... |
| 732 | else => extern struct { module: usize, offset: usize }, // ...but not MIPS N32! | 732 | else => extern struct { module: usize, offset: usize }, // ...but not MIPS N32! |
| 733 | }; | 733 | }; |
| 734 | export fn __tls_get_addr(ti: *const TlsIndex) *anyopaque { | 734 | fn __tls_get_addr(ti: *const TlsIndex) callconv(.c) *anyopaque { |
| 735 | comptime assert(native_arch != .s390x); | ||
| 736 | |||
| 735 | assert(ti.module == 1); // The executable's module ID is always 1 | 737 | assert(ti.module == 1); // The executable's module ID is always 1 |
| 736 | const tp = getThreadPointer(); | 738 | const tp = getThreadPointer(); |
| 737 | const block: [*]u8 = switch (current_variant) { | 739 | const block: [*]u8 = switch (current_variant) { |
| ... | @@ -743,6 +745,25 @@ comptime { | ... | @@ -743,6 +745,25 @@ comptime { |
| 743 | }; | 745 | }; |
| 744 | return block[@intCast(ti.offset)..]; | 746 | return block[@intCast(ti.offset)..]; |
| 745 | } | 747 | } |
| 748 | fn __tls_get_offset() callconv(.naked) noreturn { | ||
| 749 | comptime assert(native_arch == .s390x); | ||
| 750 | |||
| 751 | // We receive the module's GOT pointer in r12 and the GOT offset in r2. | ||
| 752 | asm volatile ( | ||
| 753 | \\ la %%r1, 0(%%r12, %%r2) | ||
| 754 | \\ lg %%r2, 8(%%r1) | ||
| 755 | \\ lgrl %%r0, %[block_size] | ||
| 756 | \\ sgr %%r2, %%r0 | ||
| 757 | \\ br %%r14 | ||
| 758 | : | ||
| 759 | : [block_size] "s" (&area_desc.block.size), | ||
| 760 | ); | ||
| 761 | } | ||
| 746 | }; | 762 | }; |
| 763 | |||
| 764 | if (native_arch == .s390x) | ||
| 765 | @export(&Fns.__tls_get_offset, .{ .name = "__tls_get_offset" }) | ||
| 766 | else | ||
| 767 | @export(&Fns.__tls_get_addr, .{ .name = "__tls_get_addr" }); | ||
| 747 | } | 768 | } |
| 748 | } | 769 | } |
lib/std/os/linux/vdso.zig+5-5| ... | @@ -19,14 +19,14 @@ pub fn lookup(vername: []const u8, name: []const u8) usize { | ... | @@ -19,14 +19,14 @@ pub fn lookup(vername: []const u8, name: []const u8) usize { |
| 19 | i += 1; | 19 | i += 1; |
| 20 | ph_addr += eh.e_phentsize; | 20 | ph_addr += eh.e_phentsize; |
| 21 | }) { | 21 | }) { |
| 22 | const this_ph = @as(*elf.Phdr, @ptrFromInt(ph_addr)); | 22 | const this_ph = @as(*elf.ElfN.Phdr, @ptrFromInt(ph_addr)); |
| 23 | switch (this_ph.p_type) { | 23 | switch (this_ph.type) { |
| 24 | // On WSL1 as well as older kernels, the VDSO ELF image is pre-linked in the upper half | 24 | // On WSL1 as well as older kernels, the VDSO ELF image is pre-linked in the upper half |
| 25 | // of the memory space (e.g. p_vaddr = 0xffffffffff700000 on WSL1). | 25 | // of the memory space (e.g. vaddr = 0xffffffffff700000 on WSL1). |
| 26 | // Wrapping operations are used on this line as well as subsequent calculations relative to base | 26 | // Wrapping operations are used on this line as well as subsequent calculations relative to base |
| 27 | // (lines 47, 78) to ensure no overflow check is tripped. | 27 | // (lines 47, 78) to ensure no overflow check is tripped. |
| 28 | elf.PT_LOAD => base = vdso_addr +% this_ph.p_offset -% this_ph.p_vaddr, | 28 | .LOAD => base = vdso_addr +% this_ph.offset -% this_ph.vaddr, |
| 29 | elf.PT_DYNAMIC => maybe_dynv = @as([*]usize, @ptrFromInt(vdso_addr + this_ph.p_offset)), | 29 | .DYNAMIC => maybe_dynv = @as([*]usize, @ptrFromInt(vdso_addr + this_ph.offset)), |
| 30 | else => {}, | 30 | else => {}, |
| 31 | } | 31 | } |
| 32 | } | 32 | } |
lib/std/pie.zig+3-3| ... | @@ -293,7 +293,7 @@ inline fn getDynamicSymbol() [*]const elf.Dyn { | ... | @@ -293,7 +293,7 @@ inline fn getDynamicSymbol() [*]const elf.Dyn { |
| 293 | }; | 293 | }; |
| 294 | } | 294 | } |
| 295 | 295 | ||
| 296 | pub fn relocate(phdrs: []const elf.Phdr) void { | 296 | pub fn relocate(phdrs: []const elf.ElfN.Phdr) void { |
| 297 | @setRuntimeSafety(false); | 297 | @setRuntimeSafety(false); |
| 298 | @disableInstrumentation(); | 298 | @disableInstrumentation(); |
| 299 | 299 | ||
| ... | @@ -303,8 +303,8 @@ pub fn relocate(phdrs: []const elf.Phdr) void { | ... | @@ -303,8 +303,8 @@ pub fn relocate(phdrs: []const elf.Phdr) void { |
| 303 | // the theoretical load addresses for the `_DYNAMIC` symbol. | 303 | // the theoretical load addresses for the `_DYNAMIC` symbol. |
| 304 | const base_addr = base: { | 304 | const base_addr = base: { |
| 305 | for (phdrs) |*phdr| { | 305 | for (phdrs) |*phdr| { |
| 306 | if (phdr.p_type != elf.PT_DYNAMIC) continue; | 306 | if (phdr.type != .DYNAMIC) continue; |
| 307 | break :base @intFromPtr(dynv) - phdr.p_vaddr; | 307 | break :base @intFromPtr(dynv) - phdr.vaddr; |
| 308 | } | 308 | } |
| 309 | // This is not supposed to happen for well-formed binaries. | 309 | // This is not supposed to happen for well-formed binaries. |
| 310 | @trap(); | 310 | @trap(); |
lib/std/posix/test.zig+1-1| ... | @@ -75,7 +75,7 @@ fn iter_fn(info: *dl_phdr_info, size: usize, counter: *usize) IterFnError!void { | ... | @@ -75,7 +75,7 @@ fn iter_fn(info: *dl_phdr_info, size: usize, counter: *usize) IterFnError!void { |
| 75 | // Count how many libraries are loaded | 75 | // Count how many libraries are loaded |
| 76 | counter.* += @as(usize, 1); | 76 | counter.* += @as(usize, 1); |
| 77 | 77 | ||
| 78 | // The image should contain at least a PT_LOAD segment | 78 | // The image should contain at least a PT.LOAD segment |
| 79 | if (info.phnum < 1) return error.MissingPtLoadSegment; | 79 | if (info.phnum < 1) return error.MissingPtLoadSegment; |
| 80 | 80 | ||
| 81 | // Quick & dirty validation of the phdr pointers, make sure we're not | 81 | // Quick & dirty validation of the phdr pointers, make sure we're not |
lib/std/process.zig+5-5| ... | @@ -100,7 +100,7 @@ pub const UserInfo = struct { | ... | @@ -100,7 +100,7 @@ pub const UserInfo = struct { |
| 100 | }; | 100 | }; |
| 101 | 101 | ||
| 102 | /// POSIX function which gets a uid from username. | 102 | /// POSIX function which gets a uid from username. |
| 103 | pub fn getUserInfo(name: []const u8) !UserInfo { | 103 | pub fn getUserInfo(io: Io, name: []const u8) !UserInfo { |
| 104 | return switch (native_os) { | 104 | return switch (native_os) { |
| 105 | .linux, | 105 | .linux, |
| 106 | .driverkit, | 106 | .driverkit, |
| ... | @@ -116,7 +116,7 @@ pub fn getUserInfo(name: []const u8) !UserInfo { | ... | @@ -116,7 +116,7 @@ pub fn getUserInfo(name: []const u8) !UserInfo { |
| 116 | .haiku, | 116 | .haiku, |
| 117 | .illumos, | 117 | .illumos, |
| 118 | .serenity, | 118 | .serenity, |
| 119 | => posixGetUserInfo(name), | 119 | => posixGetUserInfo(io, name), |
| 120 | else => @compileError("Unsupported OS"), | 120 | else => @compileError("Unsupported OS"), |
| 121 | }; | 121 | }; |
| 122 | } | 122 | } |
| ... | @@ -127,7 +127,7 @@ pub fn posixGetUserInfo(io: Io, name: []const u8) !UserInfo { | ... | @@ -127,7 +127,7 @@ pub fn posixGetUserInfo(io: Io, name: []const u8) !UserInfo { |
| 127 | const file = try Io.Dir.openFileAbsolute(io, "/etc/passwd", .{}); | 127 | const file = try Io.Dir.openFileAbsolute(io, "/etc/passwd", .{}); |
| 128 | defer file.close(io); | 128 | defer file.close(io); |
| 129 | var buffer: [4096]u8 = undefined; | 129 | var buffer: [4096]u8 = undefined; |
| 130 | var file_reader = file.reader(&buffer); | 130 | var file_reader = file.reader(io, &buffer); |
| 131 | return posixGetUserInfoPasswdStream(name, &file_reader.interface) catch |err| switch (err) { | 131 | return posixGetUserInfoPasswdStream(name, &file_reader.interface) catch |err| switch (err) { |
| 132 | error.ReadFailed => return file_reader.err.?, | 132 | error.ReadFailed => return file_reader.err.?, |
| 133 | error.EndOfStream => return error.UserNotFound, | 133 | error.EndOfStream => return error.UserNotFound, |
| ... | @@ -644,7 +644,7 @@ pub fn totalSystemMemory() TotalSystemMemoryError!u64 { | ... | @@ -644,7 +644,7 @@ pub fn totalSystemMemory() TotalSystemMemoryError!u64 { |
| 644 | /// leaks can be accurate. In release builds, this calls `exit` with code zero, | 644 | /// leaks can be accurate. In release builds, this calls `exit` with code zero, |
| 645 | /// and does not return. | 645 | /// and does not return. |
| 646 | pub fn cleanExit(io: Io) void { | 646 | pub fn cleanExit(io: Io) void { |
| 647 | if (builtin.mode == .Debug) return; | 647 | if (builtin.mode == .debug) return; |
| 648 | _ = io.lockStderr(&.{}, .no_color) catch {}; | 648 | _ = io.lockStderr(&.{}, .no_color) catch {}; |
| 649 | exit(0); | 649 | exit(0); |
| 650 | } | 650 | } |
| ... | @@ -809,7 +809,7 @@ pub fn abort() noreturn { | ... | @@ -809,7 +809,7 @@ pub fn abort() noreturn { |
| 809 | // even when linking libc on Windows we use our own abort implementation. | 809 | // even when linking libc on Windows we use our own abort implementation. |
| 810 | // See https://github.com/ziglang/zig/issues/2071 for more details. | 810 | // See https://github.com/ziglang/zig/issues/2071 for more details. |
| 811 | if (native_os == .windows) { | 811 | if (native_os == .windows) { |
| 812 | if (builtin.mode == .Debug and windows.peb().BeingDebugged.toBool()) { | 812 | if (builtin.mode == .debug and windows.peb().BeingDebugged.toBool()) { |
| 813 | @breakpoint(); | 813 | @breakpoint(); |
| 814 | } | 814 | } |
| 815 | windows.ntdll.RtlExitUserProcess(3); | 815 | windows.ntdll.RtlExitUserProcess(3); |
lib/std/process/Args.zig+1-1| ... | @@ -752,7 +752,7 @@ pub fn IteratorGeneral(comptime options: IteratorGeneralOptions) type { | ... | @@ -752,7 +752,7 @@ pub fn IteratorGeneral(comptime options: IteratorGeneralOptions) type { |
| 752 | start: usize = 0, | 752 | start: usize = 0, |
| 753 | end: usize = 0, | 753 | end: usize = 0, |
| 754 | 754 | ||
| 755 | pub const Self = @This(); | 755 | const Self = @This(); |
| 756 | 756 | ||
| 757 | pub const InitError = error{OutOfMemory}; | 757 | pub const InitError = error{OutOfMemory}; |
| 758 | 758 |
lib/std/sort/block.zig+1-1| ... | @@ -103,7 +103,7 @@ pub fn block( | ... | @@ -103,7 +103,7 @@ pub fn block( |
| 103 | context: anytype, | 103 | context: anytype, |
| 104 | comptime lessThanFn: fn (@TypeOf(context), lhs: T, rhs: T) bool, | 104 | comptime lessThanFn: fn (@TypeOf(context), lhs: T, rhs: T) bool, |
| 105 | ) void { | 105 | ) void { |
| 106 | const lessThan = if (builtin.mode == .Debug) struct { | 106 | const lessThan = if (builtin.mode == .debug) struct { |
| 107 | fn lessThan(ctx: @TypeOf(context), lhs: T, rhs: T) bool { | 107 | fn lessThan(ctx: @TypeOf(context), lhs: T, rhs: T) bool { |
| 108 | const lt = lessThanFn(ctx, lhs, rhs); | 108 | const lt = lessThanFn(ctx, lhs, rhs); |
| 109 | const gt = lessThanFn(ctx, rhs, lhs); | 109 | const gt = lessThanFn(ctx, rhs, lhs); |
lib/std/spirv.zig+1-1| ... | @@ -97,7 +97,7 @@ pub fn specConst(T: type, comptime default_value: T, comptime spec_id: u32) T { | ... | @@ -97,7 +97,7 @@ pub fn specConst(T: type, comptime default_value: T, comptime spec_id: u32) T { |
| 97 | }, | 97 | }, |
| 98 | .int, .float => return asm ( | 98 | .int, .float => return asm ( |
| 99 | \\%ret = OpSpecConstant %ty $default_value | 99 | \\%ret = OpSpecConstant %ty $default_value |
| 100 | \\ OpDecorate %ret SpecId $spec_id" | 100 | \\ OpDecorate %ret SpecId $spec_id |
| 101 | : [ret] "" (-> T), | 101 | : [ret] "" (-> T), |
| 102 | : [ty] "t" (T), | 102 | : [ty] "t" (T), |
| 103 | [default_value] "c" (default_value), | 103 | [default_value] "c" (default_value), |
lib/std/start.zig+11-11| ... | @@ -589,7 +589,7 @@ fn posixCallMainAndExit(argc_argv_ptr: [*]usize) callconv(.c) noreturn { | ... | @@ -589,7 +589,7 @@ fn posixCallMainAndExit(argc_argv_ptr: [*]usize) callconv(.c) noreturn { |
| 589 | else => continue, | 589 | else => continue, |
| 590 | } | 590 | } |
| 591 | } | 591 | } |
| 592 | break :init @as([*]elf.Phdr, @ptrFromInt(at_phdr))[0..at_phnum]; | 592 | break :init @as([*]elf.ElfN.Phdr, @ptrFromInt(at_phdr))[0..at_phnum]; |
| 593 | }; | 593 | }; |
| 594 | 594 | ||
| 595 | // Apply the initial relocations as early as possible in the startup process. We cannot | 595 | // Apply the initial relocations as early as possible in the startup process. We cannot |
| ... | @@ -621,7 +621,7 @@ fn posixCallMainAndExit(argc_argv_ptr: [*]usize) callconv(.c) noreturn { | ... | @@ -621,7 +621,7 @@ fn posixCallMainAndExit(argc_argv_ptr: [*]usize) callconv(.c) noreturn { |
| 621 | std.os.linux.tls.initStatic(phdrs); | 621 | std.os.linux.tls.initStatic(phdrs); |
| 622 | } | 622 | } |
| 623 | 623 | ||
| 624 | // The way Linux executables represent stack size is via the PT_GNU_STACK | 624 | // The way Linux executables represent stack size is via the PT.GNU_STACK |
| 625 | // program header. However the kernel does not recognize it; it always gives 8 MiB. | 625 | // program header. However the kernel does not recognize it; it always gives 8 MiB. |
| 626 | // Here we look for the stack size in our program headers and use setrlimit | 626 | // Here we look for the stack size in our program headers and use setrlimit |
| 627 | // to ask for more stack space. | 627 | // to ask for more stack space. |
| ... | @@ -645,19 +645,19 @@ fn posixCallMainAndExit(argc_argv_ptr: [*]usize) callconv(.c) noreturn { | ... | @@ -645,19 +645,19 @@ fn posixCallMainAndExit(argc_argv_ptr: [*]usize) callconv(.c) noreturn { |
| 645 | std.process.exit(callMainWithArgs(argc, argv, envp)); | 645 | std.process.exit(callMainWithArgs(argc, argv, envp)); |
| 646 | } | 646 | } |
| 647 | 647 | ||
| 648 | fn expandStackSize(phdrs: []elf.Phdr) void { | 648 | fn expandStackSize(phdrs: []elf.ElfN.Phdr) void { |
| 649 | @disableInstrumentation(); | 649 | @disableInstrumentation(); |
| 650 | for (phdrs) |*phdr| { | 650 | for (phdrs) |*phdr| { |
| 651 | switch (phdr.p_type) { | 651 | switch (phdr.type) { |
| 652 | elf.PT_GNU_STACK => { | 652 | .GNU_STACK => { |
| 653 | if (phdr.p_memsz == 0) break; | 653 | if (phdr.memsz == 0) break; |
| 654 | assert(phdr.p_memsz % std.heap.page_size_min == 0); | 654 | assert(phdr.memsz % std.heap.page_size_min == 0); |
| 655 | 655 | ||
| 656 | // Silently fail if we are unable to get limits. | 656 | // Silently fail if we are unable to get limits. |
| 657 | const limits = std.posix.getrlimit(.STACK) catch break; | 657 | const limits = std.posix.getrlimit(.STACK) catch break; |
| 658 | 658 | ||
| 659 | // Clamp to limits.max . | 659 | // Clamp to limits.max . |
| 660 | const wanted_stack_size = @min(phdr.p_memsz, limits.max); | 660 | const wanted_stack_size = @min(phdr.memsz, limits.max); |
| 661 | 661 | ||
| 662 | if (wanted_stack_size > limits.cur) { | 662 | if (wanted_stack_size > limits.cur) { |
| 663 | std.posix.setrlimit(.STACK, .{ | 663 | std.posix.setrlimit(.STACK, .{ |
| ... | @@ -702,7 +702,7 @@ fn main(c_argc: c_int, c_argv: [*][*:0]c_char, c_envp: [*:null]?[*:0]c_char) cal | ... | @@ -702,7 +702,7 @@ fn main(c_argc: c_int, c_argv: [*][*:0]c_char, c_envp: [*:null]?[*:0]c_char) cal |
| 702 | .linux => { | 702 | .linux => { |
| 703 | const at_phdr = std.c.getauxval(elf.AT_PHDR); | 703 | const at_phdr = std.c.getauxval(elf.AT_PHDR); |
| 704 | const at_phnum = std.c.getauxval(elf.AT_PHNUM); | 704 | const at_phnum = std.c.getauxval(elf.AT_PHNUM); |
| 705 | const phdrs = (@as([*]elf.Phdr, @ptrFromInt(at_phdr)))[0..at_phnum]; | 705 | const phdrs = (@as([*]elf.ElfN.Phdr, @ptrFromInt(at_phdr)))[0..at_phnum]; |
| 706 | expandStackSize(phdrs); | 706 | expandStackSize(phdrs); |
| 707 | }, | 707 | }, |
| 708 | .windows => { | 708 | .windows => { |
| ... | @@ -742,8 +742,8 @@ fn mainWithoutEnv(c_argc: c_int, c_argv: [*][*:0]c_char) callconv(.c) c_int { | ... | @@ -742,8 +742,8 @@ fn mainWithoutEnv(c_argc: c_int, c_argv: [*][*:0]c_char) callconv(.c) c_int { |
| 742 | const bad_main_ret = "expected return type of main to be 'void', '!void', 'noreturn', 'u8', or '!u8'"; | 742 | const bad_main_ret = "expected return type of main to be 'void', '!void', 'noreturn', 'u8', or '!u8'"; |
| 743 | 743 | ||
| 744 | const use_safe_allocator = !is_wasm and switch (builtin.mode) { | 744 | const use_safe_allocator = !is_wasm and switch (builtin.mode) { |
| 745 | .Debug, .ReleaseSafe => true, | 745 | .debug, .safe => true, |
| 746 | .ReleaseFast, .ReleaseSmall => !builtin.link_libc and builtin.single_threaded, // Also not ideal. | 746 | .fast, .small => !builtin.link_libc and builtin.single_threaded, // Also not ideal. |
| 747 | }; | 747 | }; |
| 748 | var safe_allocator: std.heap.SafeAllocator = .init(std.heap.page_allocator, .{}); | 748 | var safe_allocator: std.heap.SafeAllocator = .init(std.heap.page_allocator, .{}); |
| 749 | 749 |
lib/std/std.zig+2-2| ... | @@ -162,7 +162,7 @@ pub const Options = struct { | ... | @@ -162,7 +162,7 @@ pub const Options = struct { |
| 162 | /// This enables `std.http.Client` to log ssl secrets to the file specified by the SSLKEYLOGFILE | 162 | /// This enables `std.http.Client` to log ssl secrets to the file specified by the SSLKEYLOGFILE |
| 163 | /// env var. Creating such a log file allows other programs with access to that file to decrypt | 163 | /// env var. Creating such a log file allows other programs with access to that file to decrypt |
| 164 | /// all `std.http.Client` traffic made by this program. | 164 | /// all `std.http.Client` traffic made by this program. |
| 165 | http_enable_ssl_key_log_file: bool = @import("builtin").mode == .Debug, | 165 | http_enable_ssl_key_log_file: bool = @import("builtin").mode == .debug, |
| 166 | 166 | ||
| 167 | side_channels_mitigations: crypto.SideChannelsMitigations = crypto.default_side_channels_mitigations, | 167 | side_channels_mitigations: crypto.SideChannelsMitigations = crypto.default_side_channels_mitigations, |
| 168 | 168 | ||
| ... | @@ -192,7 +192,7 @@ pub const Options = struct { | ... | @@ -192,7 +192,7 @@ pub const Options = struct { |
| 192 | /// If this happens the fix is to add the error code to the corresponding | 192 | /// If this happens the fix is to add the error code to the corresponding |
| 193 | /// switch expression, possibly introduce a new error in the error set, and | 193 | /// switch expression, possibly introduce a new error in the error set, and |
| 194 | /// send a patch to Zig. | 194 | /// send a patch to Zig. |
| 195 | unexpected_error_tracing: bool = @import("builtin").mode == .Debug and switch (@import("builtin").zig_backend) { | 195 | unexpected_error_tracing: bool = @import("builtin").mode == .debug and switch (@import("builtin").zig_backend) { |
| 196 | .stage2_llvm, .stage2_x86_64 => true, | 196 | .stage2_llvm, .stage2_x86_64 => true, |
| 197 | else => false, | 197 | else => false, |
| 198 | }, | 198 | }, |
lib/std/tar/Writer.zig+1-1| ... | @@ -312,7 +312,7 @@ pub const Header = extern struct { | ... | @@ -312,7 +312,7 @@ pub const Header = extern struct { |
| 312 | 312 | ||
| 313 | // add as much to prefix as you can, must split at / | 313 | // add as much to prefix as you can, must split at / |
| 314 | const prefix_remaining = max_prefix - prefix_pos; | 314 | const prefix_remaining = max_prefix - prefix_pos; |
| 315 | if (std.mem.lastIndexOf(u8, sub_path[0..@min(prefix_remaining, sub_path.len)], &.{'/'})) |sep_pos| { | 315 | if (std.mem.findLast(u8, sub_path[0..@min(prefix_remaining, sub_path.len)], &.{'/'})) |sep_pos| { |
| 316 | @memcpy(w.prefix[prefix_pos..][0..sep_pos], sub_path[0..sep_pos]); | 316 | @memcpy(w.prefix[prefix_pos..][0..sep_pos], sub_path[0..sep_pos]); |
| 317 | if ((sub_path.len - sep_pos - 1) > max_name) return error.NameTooLong; | 317 | if ((sub_path.len - sep_pos - 1) > max_name) return error.NameTooLong; |
| 318 | @memcpy(w.name[0..][0 .. sub_path.len - sep_pos - 1], sub_path[sep_pos + 1 ..]); | 318 | @memcpy(w.name[0..][0 .. sub_path.len - sep_pos - 1], sub_path[sep_pos + 1 ..]); |
lib/std/tar/test.zig+3-3| ... | @@ -474,14 +474,14 @@ test "should not overwrite existing file" { | ... | @@ -474,14 +474,14 @@ test "should not overwrite existing file" { |
| 474 | defer root.cleanup(); | 474 | defer root.cleanup(); |
| 475 | try testing.expectError( | 475 | try testing.expectError( |
| 476 | error.PathAlreadyExists, | 476 | error.PathAlreadyExists, |
| 477 | tar.pipeToFileSystem(io, root.dir, &r, .{ .mode_mode = .ignore, .strip_components = 1 }), | 477 | tar.extract(io, root.dir, &r, .{ .mode_mode = .ignore, .strip_components = 1 }), |
| 478 | ); | 478 | ); |
| 479 | 479 | ||
| 480 | // Unpack with strip_components = 0 should pass | 480 | // Unpack with strip_components = 0 should pass |
| 481 | r = .fixed(data); | 481 | r = .fixed(data); |
| 482 | var root2 = std.testing.tmpDir(.{}); | 482 | var root2 = std.testing.tmpDir(.{}); |
| 483 | defer root2.cleanup(); | 483 | defer root2.cleanup(); |
| 484 | try tar.pipeToFileSystem(io, root2.dir, &r, .{ .mode_mode = .ignore, .strip_components = 0 }); | 484 | try tar.extract(io, root2.dir, &r, .{ .mode_mode = .ignore, .strip_components = 0 }); |
| 485 | } | 485 | } |
| 486 | 486 | ||
| 487 | test "case sensitivity" { | 487 | test "case sensitivity" { |
| ... | @@ -501,7 +501,7 @@ test "case sensitivity" { | ... | @@ -501,7 +501,7 @@ test "case sensitivity" { |
| 501 | var root = std.testing.tmpDir(.{}); | 501 | var root = std.testing.tmpDir(.{}); |
| 502 | defer root.cleanup(); | 502 | defer root.cleanup(); |
| 503 | 503 | ||
| 504 | tar.pipeToFileSystem(io, root.dir, &r, .{ .mode_mode = .ignore, .strip_components = 1 }) catch |err| { | 504 | tar.extract(io, root.dir, &r, .{ .mode_mode = .ignore, .strip_components = 1 }) catch |err| { |
| 505 | // on case insensitive fs we fail on overwrite existing file | 505 | // on case insensitive fs we fail on overwrite existing file |
| 506 | try testing.expectEqual(error.PathAlreadyExists, err); | 506 | try testing.expectEqual(error.PathAlreadyExists, err); |
| 507 | return; | 507 | return; |
lib/std/testing.zig+1-1| ... | @@ -999,7 +999,7 @@ test "expectEqualDeep composite type" { | ... | @@ -999,7 +999,7 @@ test "expectEqualDeep composite type" { |
| 999 | } | 999 | } |
| 1000 | 1000 | ||
| 1001 | fn printIndicatorLine(source: []const u8, indicator_index: usize) void { | 1001 | fn printIndicatorLine(source: []const u8, indicator_index: usize) void { |
| 1002 | const line_begin_index = if (std.mem.lastIndexOfScalar(u8, source[0..indicator_index], '\n')) |line_begin| | 1002 | const line_begin_index = if (std.mem.findScalarLast(u8, source[0..indicator_index], '\n')) |line_begin| |
| 1003 | line_begin + 1 | 1003 | line_begin + 1 |
| 1004 | else | 1004 | else |
| 1005 | 0; | 1005 | 0; |
lib/std/testing/Smith.zig+2-2| ... | @@ -52,7 +52,7 @@ pub inline fn baselineWeights(T: type) []const Weight { | ... | @@ -52,7 +52,7 @@ pub inline fn baselineWeights(T: type) []const Weight { |
| 52 | .bool, .int, .float => i: { | 52 | .bool, .int, .float => i: { |
| 53 | // Reject types that don't have a fixed bitsize (esp. usize) | 53 | // Reject types that don't have a fixed bitsize (esp. usize) |
| 54 | // since they are not gauraunteed to fit in a u64 across targets. | 54 | // since they are not gauraunteed to fit in a u64 across targets. |
| 55 | if (std.mem.indexOfScalar(type, &.{ | 55 | if (std.mem.findScalar(type, &.{ |
| 56 | isize, usize, | 56 | isize, usize, |
| 57 | c_char, c_longdouble, | 57 | c_char, c_longdouble, |
| 58 | c_short, c_ushort, | 58 | c_short, c_ushort, |
| ... | @@ -708,7 +708,7 @@ fn constructInput(comptime values: []const union(enum) { | ... | @@ -708,7 +708,7 @@ fn constructInput(comptime values: []const union(enum) { |
| 708 | } | 708 | } |
| 709 | 709 | ||
| 710 | test value { | 710 | test value { |
| 711 | if (@import("builtin").zig_backend == .stage2_c) return error.SkipZigTest; // TODO | 711 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; |
| 712 | 712 | ||
| 713 | const S = struct { | 713 | const S = struct { |
| 714 | v: void = {}, | 714 | v: void = {}, |
lib/std/unicode.zig+35| ... | @@ -425,6 +425,15 @@ pub const Utf8Iterator = struct { | ... | @@ -425,6 +425,15 @@ pub const Utf8Iterator = struct { |
| 425 | 425 | ||
| 426 | return it.bytes[original_i..end_ix]; | 426 | return it.bytes[original_i..end_ix]; |
| 427 | } | 427 | } |
| 428 | |||
| 429 | /// Look ahead at the next codepoint without advancing the iterator. | ||
| 430 | /// If no codepoints exist, then returns null. | ||
| 431 | pub fn peekCodepoint(it: *Utf8Iterator) ?u21 { | ||
| 432 | const original_i = it.i; | ||
| 433 | defer it.i = original_i; | ||
| 434 | |||
| 435 | return it.nextCodepoint(); | ||
| 436 | } | ||
| 428 | }; | 437 | }; |
| 429 | 438 | ||
| 430 | pub fn utf16IsHighSurrogate(c: u16) bool { | 439 | pub fn utf16IsHighSurrogate(c: u16) bool { |
| ... | @@ -768,6 +777,9 @@ fn testMiscInvalidUtf8() !void { | ... | @@ -768,6 +777,9 @@ fn testMiscInvalidUtf8() !void { |
| 768 | test "utf8 iterator peeking" { | 777 | test "utf8 iterator peeking" { |
| 769 | try comptime testUtf8Peeking(); | 778 | try comptime testUtf8Peeking(); |
| 770 | try testUtf8Peeking(); | 779 | try testUtf8Peeking(); |
| 780 | |||
| 781 | comptime try testUtf8PeekCodepoint(); | ||
| 782 | try testUtf8PeekCodepoint(); | ||
| 771 | } | 783 | } |
| 772 | 784 | ||
| 773 | fn testUtf8Peeking() !void { | 785 | fn testUtf8Peeking() !void { |
| ... | @@ -790,6 +802,20 @@ fn testUtf8Peeking() !void { | ... | @@ -790,6 +802,20 @@ fn testUtf8Peeking() !void { |
| 790 | try testing.expect(mem.eql(u8, &[_]u8{}, it.peek(1))); | 802 | try testing.expect(mem.eql(u8, &[_]u8{}, it.peek(1))); |
| 791 | } | 803 | } |
| 792 | 804 | ||
| 805 | fn testUtf8PeekCodepoint() !void { | ||
| 806 | const s = Utf8View.initComptime("東京市"); | ||
| 807 | var it = s.iterator(); | ||
| 808 | |||
| 809 | try testing.expect(it.peekCodepoint().? == 0x6771); | ||
| 810 | try testing.expect(it.peekCodepoint().? == 0x6771); | ||
| 811 | _ = it.nextCodepoint(); | ||
| 812 | try testing.expect(it.peekCodepoint().? == 0x4eac); | ||
| 813 | _ = it.nextCodepoint(); | ||
| 814 | try testing.expect(it.peekCodepoint().? == 0x5e02); | ||
| 815 | _ = it.nextCodepoint(); | ||
| 816 | try testing.expect(it.peekCodepoint() == null); | ||
| 817 | } | ||
| 818 | |||
| 793 | fn testError(bytes: []const u8, expected_err: anyerror) !void { | 819 | fn testError(bytes: []const u8, expected_err: anyerror) !void { |
| 794 | try testing.expectError(expected_err, testDecode(bytes)); | 820 | try testing.expectError(expected_err, testDecode(bytes)); |
| 795 | } | 821 | } |
| ... | @@ -1758,6 +1784,15 @@ pub const Wtf8Iterator = struct { | ... | @@ -1758,6 +1784,15 @@ pub const Wtf8Iterator = struct { |
| 1758 | 1784 | ||
| 1759 | return it.bytes[original_i..end_ix]; | 1785 | return it.bytes[original_i..end_ix]; |
| 1760 | } | 1786 | } |
| 1787 | |||
| 1788 | /// Look ahead at the next codepoint without advancing the iterator. | ||
| 1789 | /// If no codepoints exist, then returns null. | ||
| 1790 | pub fn peekCodepoint(it: *Wtf8Iterator) ?u21 { | ||
| 1791 | const original_i = it.i; | ||
| 1792 | defer it.i = original_i; | ||
| 1793 | |||
| 1794 | return it.nextCodepoint(); | ||
| 1795 | } | ||
| 1761 | }; | 1796 | }; |
| 1762 | 1797 | ||
| 1763 | pub fn wtf16LeToWtf8ArrayList(result: *std.array_list.Managed(u8), utf16le: []const u16) Allocator.Error!void { | 1798 | pub fn wtf16LeToWtf8ArrayList(result: *std.array_list.Managed(u8), utf16le: []const u16) Allocator.Error!void { |
lib/std/zig.zig+47-77| ... | @@ -386,23 +386,6 @@ pub const Subsystem = enum { | ... | @@ -386,23 +386,6 @@ pub const Subsystem = enum { |
| 386 | efi_boot_service_driver, | 386 | efi_boot_service_driver, |
| 387 | efi_rom, | 387 | efi_rom, |
| 388 | efi_runtime_driver, | 388 | efi_runtime_driver, |
| 389 | |||
| 390 | /// Deprecated; use '.console' instead. To be removed after 0.16.0 is tagged. | ||
| 391 | pub const Console: Subsystem = .console; | ||
| 392 | /// Deprecated; use '.windows' instead. To be removed after 0.16.0 is tagged. | ||
| 393 | pub const Windows: Subsystem = .windows; | ||
| 394 | /// Deprecated; use '.posix' instead. To be removed after 0.16.0 is tagged. | ||
| 395 | pub const Posix: Subsystem = .posix; | ||
| 396 | /// Deprecated; use '.native' instead. To be removed after 0.16.0 is tagged. | ||
| 397 | pub const Native: Subsystem = .native; | ||
| 398 | /// Deprecated; use '.efi_application' instead. To be removed after 0.16.0 is tagged. | ||
| 399 | pub const EfiApplication: Subsystem = .efi_application; | ||
| 400 | /// Deprecated; use '.efi_boot_service_driver' instead. To be removed after 0.16.0 is tagged. | ||
| 401 | pub const EfiBootServiceDriver: Subsystem = .efi_boot_service_driver; | ||
| 402 | /// Deprecated; use '.efi_rom' instead. To be removed after 0.16.0 is tagged. | ||
| 403 | pub const EfiRom: Subsystem = .efi_rom; | ||
| 404 | /// Deprecated; use '.efi_runtime_driver' instead. To be removed after 0.16.0 is tagged. | ||
| 405 | pub const EfiRuntimeDriver: Subsystem = .efi_runtime_driver; | ||
| 406 | }; | 389 | }; |
| 407 | 390 | ||
| 408 | pub const CompressDebugSections = enum(u2) { none, zlib, zstd }; | 391 | pub const CompressDebugSections = enum(u2) { none, zlib, zstd }; |
| ... | @@ -562,8 +545,7 @@ pub fn stringEscape(bytes: []const u8, w: *Writer) Writer.Error!void { | ... | @@ -562,8 +545,7 @@ pub fn stringEscape(bytes: []const u8, w: *Writer) Writer.Error!void { |
| 562 | '\t' => try w.writeAll("\\t"), | 545 | '\t' => try w.writeAll("\\t"), |
| 563 | '\\' => try w.writeAll("\\\\"), | 546 | '\\' => try w.writeAll("\\\\"), |
| 564 | '"' => try w.writeAll("\\\""), | 547 | '"' => try w.writeAll("\\\""), |
| 565 | '\'' => try w.writeByte('\''), | 548 | ' ', '!', '#'...'[', ']'...'~' => try w.writeByte(byte), |
| 566 | ' ', '!', '#'...'&', '('...'[', ']'...'~' => try w.writeByte(byte), | ||
| 567 | else => { | 549 | else => { |
| 568 | try w.writeAll("\\x"); | 550 | try w.writeAll("\\x"); |
| 569 | try w.printInt(byte, 16, .lower, .{ .width = 2, .fill = '0' }); | 551 | try w.printInt(byte, 16, .lower, .{ .width = 2, .fill = '0' }); |
| ... | @@ -780,11 +762,11 @@ pub const EnvVar = enum { | ... | @@ -780,11 +762,11 @@ pub const EnvVar = enum { |
| 780 | ZIG_LIBC, | 762 | ZIG_LIBC, |
| 781 | ZIG_BUILD_ERROR_STYLE, | 763 | ZIG_BUILD_ERROR_STYLE, |
| 782 | ZIG_BUILD_MULTILINE_ERRORS, | 764 | ZIG_BUILD_MULTILINE_ERRORS, |
| 765 | ZIG_BUILD_SUMMARY, | ||
| 783 | ZIG_VERBOSE_LINK, | 766 | ZIG_VERBOSE_LINK, |
| 784 | ZIG_VERBOSE_CC, | 767 | ZIG_VERBOSE_CC, |
| 785 | ZIG_VERBOSE_CMD, | 768 | ZIG_VERBOSE_CMD, |
| 786 | ZIG_DEBUG_CMD, | 769 | ZIG_DEBUG_CMD, |
| 787 | ZIG_DEBUG_MAKER, | ||
| 788 | ZIG_IS_DETECTING_LIBC_PATHS, | 770 | ZIG_IS_DETECTING_LIBC_PATHS, |
| 789 | ZIG_IS_AVOIDING_CALLING_ITSELF, | 771 | ZIG_IS_AVOIDING_CALLING_ITSELF, |
| 790 | 772 | ||
| ... | @@ -1577,7 +1559,7 @@ pub fn resolvePath( | ... | @@ -1577,7 +1559,7 @@ pub fn resolvePath( |
| 1577 | // Heuristic for a fast path: if no component is absolute and ".." never appears, we just need to resolve `paths`. | 1559 | // Heuristic for a fast path: if no component is absolute and ".." never appears, we just need to resolve `paths`. |
| 1578 | for (paths) |p| { | 1560 | for (paths) |p| { |
| 1579 | if (Dir.path.isAbsolute(p)) break; // absolute path | 1561 | if (Dir.path.isAbsolute(p)) break; // absolute path |
| 1580 | if (mem.indexOf(u8, p, "..") != null) break; // may contain up-dir | 1562 | if (mem.find(u8, p, "..") != null) break; // may contain up-dir |
| 1581 | } else { | 1563 | } else { |
| 1582 | // no absolute path, no "..". | 1564 | // no absolute path, no "..". |
| 1583 | const res = try Dir.path.resolve(gpa, paths); | 1565 | const res = try Dir.path.resolve(gpa, paths); |
| ... | @@ -1675,31 +1657,32 @@ pub fn buildExeSubprocess( | ... | @@ -1675,31 +1657,32 @@ pub fn buildExeSubprocess( |
| 1675 | }; | 1657 | }; |
| 1676 | defer child.kill(io); | 1658 | defer child.kill(io); |
| 1677 | 1659 | ||
| 1678 | var stderr_task = io.concurrent(readStreamAlloc, .{ gpa, io, child.stderr.?, .unlimited }) catch | 1660 | var multi_reader_buffer: Io.File.MultiReader.Buffer(2) = undefined; |
| 1679 | @panic("TODO use multireader instead"); | 1661 | var multi_reader: Io.File.MultiReader = undefined; |
| 1680 | defer if (stderr_task.cancel(io)) |slice| gpa.free(slice) else |_| {}; | 1662 | multi_reader.init(gpa, io, multi_reader_buffer.toStreams(), &.{ child.stdout.?, child.stderr.? }); |
| 1663 | defer multi_reader.deinit(); | ||
| 1664 | const stdout = multi_reader.reader(0); | ||
| 1665 | const stderr = multi_reader.reader(1); | ||
| 1681 | 1666 | ||
| 1682 | var stdout_buffer: [512]u8 = undefined; | 1667 | var stdin_buffer: [8]u8 = undefined; |
| 1683 | var stdout_reader: Io.File.Reader = .initStreaming(child.stdout.?, io, &stdout_buffer); | 1668 | var stdin_writer = child.stdin.?.writerStreaming(io, &stdin_buffer); |
| 1684 | const stdout = &stdout_reader.interface; | ||
| 1685 | 1669 | ||
| 1686 | { | 1670 | var client: Client = .{ |
| 1687 | var w = child.stdin.?.writer(io, &.{}); | 1671 | .in = stdout, |
| 1688 | w.interface.writeStruct(Client.Message.Header{ .tag = .update, .bytes_len = 0 }, .little) catch |err| switch (err) { | 1672 | .out = &stdin_writer.interface, |
| 1689 | error.WriteFailed => { | 1673 | }; |
| 1690 | log.err("{t} writing to command: {f}", .{ w.err.?, cmd }); | ||
| 1691 | return error.AlreadyReported; | ||
| 1692 | }, | ||
| 1693 | }; | ||
| 1694 | w.interface.writeStruct(Client.Message.Header{ .tag = .exit, .bytes_len = 0 }, .little) catch |err| switch (err) { | ||
| 1695 | error.WriteFailed => { | ||
| 1696 | log.err("{t} writing to command: {f}", .{ w.err.?, cmd }); | ||
| 1697 | return error.AlreadyReported; | ||
| 1698 | }, | ||
| 1699 | }; | ||
| 1700 | } | ||
| 1701 | 1674 | ||
| 1702 | const Header = Server.Message.Header; | 1675 | (blk: { |
| 1676 | client.serveMessageHeader(.{ .tag = .update, .bytes_len = 0 }) catch |err| break :blk err; | ||
| 1677 | client.serveMessageHeader(.{ .tag = .exit, .bytes_len = 0 }) catch |err| break :blk err; | ||
| 1678 | client.out.flush() catch |err| break :blk err; | ||
| 1679 | }) catch |err| switch (err) { | ||
| 1680 | error.WriteFailed => { | ||
| 1681 | if (stdin_writer.err.? == error.Canceled) return error.Canceled; | ||
| 1682 | log.err("{t} writing to command: {f}", .{ stdin_writer.err.?, cmd }); | ||
| 1683 | return error.AlreadyReported; | ||
| 1684 | }, | ||
| 1685 | }; | ||
| 1703 | 1686 | ||
| 1704 | var result: ?Cache.Path = null; | 1687 | var result: ?Cache.Path = null; |
| 1705 | defer if (result) |r| gpa.free(r.sub_path); | 1688 | defer if (result) |r| gpa.free(r.sub_path); |
| ... | @@ -1707,33 +1690,29 @@ pub fn buildExeSubprocess( | ... | @@ -1707,33 +1690,29 @@ pub fn buildExeSubprocess( |
| 1707 | var result_error_bundle: ErrorBundle = .empty; | 1690 | var result_error_bundle: ErrorBundle = .empty; |
| 1708 | defer result_error_bundle.deinit(gpa); | 1691 | defer result_error_bundle.deinit(gpa); |
| 1709 | 1692 | ||
| 1710 | var body_buffer: std.ArrayList(u8) = .empty; | ||
| 1711 | defer body_buffer.deinit(gpa); | ||
| 1712 | |||
| 1713 | var received_fs_inputs = false; | 1693 | var received_fs_inputs = false; |
| 1714 | var cache_hit = false; | 1694 | var cache_hit = false; |
| 1715 | 1695 | ||
| 1696 | var eos_err: error{EndOfStream}!void = {}; | ||
| 1697 | |||
| 1716 | while (true) { | 1698 | while (true) { |
| 1717 | const header = stdout.takeStruct(Header, .little) catch |err| switch (err) { | 1699 | const header = client.receiveMessageWithMultiReader(&multi_reader, .none) catch |err| switch (err) { |
| 1718 | error.ReadFailed => { | 1700 | error.Timeout => unreachable, |
| 1719 | log.err("{t} reading from command: {f}", .{ stdout_reader.err.?, cmd }); | 1701 | error.EndOfStream => |e| { |
| 1720 | return error.AlreadyReported; | 1702 | if (client.in.bufferedLen() == 0) break; |
| 1721 | }, | 1703 | // Better to report the crash with stderr below, but we set |
| 1722 | error.EndOfStream => break, | 1704 | // this in case the child exits successfully while violating |
| 1723 | }; | 1705 | // this protocol. |
| 1724 | body_buffer.clearRetainingCapacity(); | 1706 | eos_err = e; |
| 1725 | stdout.appendExact(gpa, &body_buffer, header.bytes_len) catch |err| switch (err) { | 1707 | break; |
| 1726 | error.ReadFailed => { | ||
| 1727 | log.err("{t} reading from command: {f}", .{ stdout_reader.err.?, cmd }); | ||
| 1728 | return error.AlreadyReported; | ||
| 1729 | }, | 1708 | }, |
| 1730 | error.OutOfMemory => |e| return e, | 1709 | error.Canceled, error.OutOfMemory => |e| return e, |
| 1731 | error.EndOfStream => { | 1710 | else => |e| { |
| 1732 | log.err("unexpected end of stream from command: {f}", .{cmd}); | 1711 | log.err("{t} reading from command: {f}", .{ e, cmd }); |
| 1733 | return error.AlreadyReported; | 1712 | return error.AlreadyReported; |
| 1734 | }, | 1713 | }, |
| 1735 | }; | 1714 | }; |
| 1736 | const body = body_buffer.items; | 1715 | const body = stdout.take(header.bytes_len) catch unreachable; |
| 1737 | 1716 | ||
| 1738 | switch (header.tag) { | 1717 | switch (header.tag) { |
| 1739 | .zig_version => { | 1718 | .zig_version => { |
| ... | @@ -1784,16 +1763,15 @@ pub fn buildExeSubprocess( | ... | @@ -1784,16 +1763,15 @@ pub fn buildExeSubprocess( |
| 1784 | } | 1763 | } |
| 1785 | } | 1764 | } |
| 1786 | 1765 | ||
| 1787 | const stderr_contents = stderr_task.await(io) catch |err| switch (err) { | 1766 | const stderr_contents = stderr.buffered(); |
| 1788 | error.Canceled, error.OutOfMemory => |e| return e, | ||
| 1789 | else => |e| c: { | ||
| 1790 | log.warn("{t} reading stderr from command: {f}", .{ e, cmd }); | ||
| 1791 | break :c ""; | ||
| 1792 | }, | ||
| 1793 | }; | ||
| 1794 | if (stderr_contents.len > 0) | 1767 | if (stderr_contents.len > 0) |
| 1795 | log.warn("unexpected stderr from {s} command:\n{s}", .{ options.argv[0], stderr_contents }); | 1768 | log.warn("unexpected stderr from {s} command:\n{s}", .{ options.argv[0], stderr_contents }); |
| 1796 | 1769 | ||
| 1770 | eos_err catch { | ||
| 1771 | log.err("unexpected end of stream from command: {f}", .{cmd}); | ||
| 1772 | return error.AlreadyReported; | ||
| 1773 | }; | ||
| 1774 | |||
| 1797 | // Send EOF to stdin. | 1775 | // Send EOF to stdin. |
| 1798 | child.stdin.?.close(io); | 1776 | child.stdin.?.close(io); |
| 1799 | child.stdin = null; | 1777 | child.stdin = null; |
| ... | @@ -1851,14 +1829,6 @@ pub fn buildExeSubprocess( | ... | @@ -1851,14 +1829,6 @@ pub fn buildExeSubprocess( |
| 1851 | }; | 1829 | }; |
| 1852 | } | 1830 | } |
| 1853 | 1831 | ||
| 1854 | fn readStreamAlloc(gpa: Allocator, io: Io, file: Io.File, limit: Io.Limit) ![]u8 { | ||
| 1855 | var file_reader: Io.File.Reader = .initStreaming(file, io, &.{}); | ||
| 1856 | return file_reader.interface.allocRemaining(gpa, limit) catch |err| switch (err) { | ||
| 1857 | error.ReadFailed => return file_reader.err.?, | ||
| 1858 | else => |e| return e, | ||
| 1859 | }; | ||
| 1860 | } | ||
| 1861 | |||
| 1862 | test { | 1832 | test { |
| 1863 | _ = Ast; | 1833 | _ = Ast; |
| 1864 | _ = AstRlAnnotate; | 1834 | _ = AstRlAnnotate; |
lib/std/zig/Ast/Render.zig+7-7| ... | @@ -941,20 +941,20 @@ fn renderExpressionFixup(r: *Render, node: Ast.Node.Index, space: Space) Error!v | ... | @@ -941,20 +941,20 @@ fn renderExpressionFixup(r: *Render, node: Ast.Node.Index, space: Space) Error!v |
| 941 | } | 941 | } |
| 942 | 942 | ||
| 943 | fn drainNoNewline(w: *Writer, data: []const []const u8, splat: usize) Writer.Error!usize { | 943 | fn drainNoNewline(w: *Writer, data: []const []const u8, splat: usize) Writer.Error!usize { |
| 944 | if (std.mem.indexOfScalar(u8, w.buffered(), '\n') != null) { | 944 | if (std.mem.findScalar(u8, w.buffered(), '\n') != null) { |
| 945 | return error.WriteFailed; | 945 | return error.WriteFailed; |
| 946 | } | 946 | } |
| 947 | 947 | ||
| 948 | var n: usize = 0; | 948 | var n: usize = 0; |
| 949 | for (data[0 .. data.len - 1]) |v| { | 949 | for (data[0 .. data.len - 1]) |v| { |
| 950 | if (std.mem.indexOfScalar(u8, v, '\n') != null) { | 950 | if (std.mem.findScalar(u8, v, '\n') != null) { |
| 951 | return error.WriteFailed; | 951 | return error.WriteFailed; |
| 952 | } | 952 | } |
| 953 | n += v.len; | 953 | n += v.len; |
| 954 | } | 954 | } |
| 955 | 955 | ||
| 956 | const pattern = data[data.len - 1]; | 956 | const pattern = data[data.len - 1]; |
| 957 | if (splat != 0 and std.mem.indexOfScalar(u8, pattern, '\n') != null) { | 957 | if (splat != 0 and std.mem.findScalar(u8, pattern, '\n') != null) { |
| 958 | return error.WriteFailed; | 958 | return error.WriteFailed; |
| 959 | } | 959 | } |
| 960 | n += pattern.len * splat; | 960 | n += pattern.len * splat; |
| ... | @@ -990,7 +990,7 @@ fn rendersMultiline(r: *const Render, node: Ast.Node.Index) error{OutOfMemory}!b | ... | @@ -990,7 +990,7 @@ fn rendersMultiline(r: *const Render, node: Ast.Node.Index) error{OutOfMemory}!b |
| 990 | error.WriteFailed => return true, | 990 | error.WriteFailed => return true, |
| 991 | }; | 991 | }; |
| 992 | if (sub_ais.disabled_offset != null) return true; | 992 | if (sub_ais.disabled_offset != null) return true; |
| 993 | if (std.mem.indexOfScalar(u8, no_nl_w.buffered(), '\n') != null) { | 993 | if (std.mem.findScalar(u8, no_nl_w.buffered(), '\n') != null) { |
| 994 | return true; | 994 | return true; |
| 995 | } | 995 | } |
| 996 | 996 | ||
| ... | @@ -2993,7 +2993,7 @@ fn hasMultilineString(tree: Ast, start_token: Ast.TokenIndex, end_token: Ast.Tok | ... | @@ -2993,7 +2993,7 @@ fn hasMultilineString(tree: Ast, start_token: Ast.TokenIndex, end_token: Ast.Tok |
| 2993 | /// Returns true if there exists a doc comment between the start | 2993 | /// Returns true if there exists a doc comment between the start |
| 2994 | /// of token `start_token` and the start of token `end_token`. | 2994 | /// of token `start_token` and the start of token `end_token`. |
| 2995 | fn hasDocComment(tree: Ast, start_token: Ast.TokenIndex, end_token: Ast.TokenIndex) bool { | 2995 | fn hasDocComment(tree: Ast, start_token: Ast.TokenIndex, end_token: Ast.TokenIndex) bool { |
| 2996 | return std.mem.indexOfScalar( | 2996 | return std.mem.findScalar( |
| 2997 | Token.Tag, | 2997 | Token.Tag, |
| 2998 | tree.tokens.items(.tag)[start_token..end_token], | 2998 | tree.tokens.items(.tag)[start_token..end_token], |
| 2999 | .doc_comment, | 2999 | .doc_comment, |
| ... | @@ -3459,7 +3459,7 @@ const AutoIndentingStream = struct { | ... | @@ -3459,7 +3459,7 @@ const AutoIndentingStream = struct { |
| 3459 | /// Sets current indentation level to be the same as that of the last pushSpace. | 3459 | /// Sets current indentation level to be the same as that of the last pushSpace. |
| 3460 | pub fn enableSpaceMode(ais: *AutoIndentingStream, space: Space) void { | 3460 | pub fn enableSpaceMode(ais: *AutoIndentingStream, space: Space) void { |
| 3461 | if (ais.space_stack.items.len == 0) return; | 3461 | if (ais.space_stack.items.len == 0) return; |
| 3462 | const curr = ais.space_stack.getLast().?; | 3462 | const curr = ais.space_stack.last().?; |
| 3463 | if (curr.space != space) return; | 3463 | if (curr.space != space) return; |
| 3464 | ais.space_mode = curr.indent_count; | 3464 | ais.space_mode = curr.indent_count; |
| 3465 | } | 3465 | } |
| ... | @@ -3470,7 +3470,7 @@ const AutoIndentingStream = struct { | ... | @@ -3470,7 +3470,7 @@ const AutoIndentingStream = struct { |
| 3470 | 3470 | ||
| 3471 | pub fn lastSpaceModeIndent(ais: *AutoIndentingStream) usize { | 3471 | pub fn lastSpaceModeIndent(ais: *AutoIndentingStream) usize { |
| 3472 | if (ais.space_stack.items.len == 0) return 0; | 3472 | if (ais.space_stack.items.len == 0) return 0; |
| 3473 | return ais.space_stack.getLast().?.indent_count * ais.indent_delta; | 3473 | return ais.space_stack.last().?.indent_count * ais.indent_delta; |
| 3474 | } | 3474 | } |
| 3475 | 3475 | ||
| 3476 | /// Push default indentation | 3476 | /// Push default indentation |
lib/std/zig/AstGen.zig+3-2| ... | @@ -74,13 +74,13 @@ src_hasher: std.zig.SrcHasher, | ... | @@ -74,13 +74,13 @@ src_hasher: std.zig.SrcHasher, |
| 74 | const InnerError = error{ OutOfMemory, AnalysisFail }; | 74 | const InnerError = error{ OutOfMemory, AnalysisFail }; |
| 75 | 75 | ||
| 76 | fn addExtra(astgen: *AstGen, extra: anytype) Allocator.Error!u32 { | 76 | fn addExtra(astgen: *AstGen, extra: anytype) Allocator.Error!u32 { |
| 77 | const field_count = std.meta.fieldNames(@TypeOf(extra)).len; | 77 | const field_count = @typeInfo(@TypeOf(extra)).@"struct".field_names.len; |
| 78 | try astgen.extra.ensureUnusedCapacity(astgen.gpa, field_count); | 78 | try astgen.extra.ensureUnusedCapacity(astgen.gpa, field_count); |
| 79 | return addExtraAssumeCapacity(astgen, extra); | 79 | return addExtraAssumeCapacity(astgen, extra); |
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | fn addExtraAssumeCapacity(astgen: *AstGen, extra: anytype) u32 { | 82 | fn addExtraAssumeCapacity(astgen: *AstGen, extra: anytype) u32 { |
| 83 | const field_count = std.meta.fieldNames(@TypeOf(extra)).len; | 83 | const field_count = @typeInfo(@TypeOf(extra)).@"struct".field_names.len; |
| 84 | const extra_index: u32 = @intCast(astgen.extra.items.len); | 84 | const extra_index: u32 = @intCast(astgen.extra.items.len); |
| 85 | astgen.extra.items.len += field_count; | 85 | astgen.extra.items.len += field_count; |
| 86 | setExtra(astgen, extra_index, extra); | 86 | setExtra(astgen, extra_index, extra); |
| ... | @@ -7453,6 +7453,7 @@ fn switchExpr( | ... | @@ -7453,6 +7453,7 @@ fn switchExpr( |
| 7453 | const ident_name = try astgen.identAsString(ident_token); | 7453 | const ident_name = try astgen.identAsString(ident_token); |
| 7454 | const ident_name_str = tree.tokenSlice(ident_token); | 7454 | const ident_name_str = tree.tokenSlice(ident_token); |
| 7455 | if (mem.eql(u8, "_", ident_name_str)) { | 7455 | if (mem.eql(u8, "_", ident_name_str)) { |
| 7456 | if (non_err_is_ref != .no) return astgen.failTok(payload_token, "pointer modifier invalid on discard", .{}); | ||
| 7456 | break :scope &scratch_scope.base; | 7457 | break :scope &scratch_scope.base; |
| 7457 | } | 7458 | } |
| 7458 | non_err_capture = if (non_err_is_ref != .no) .by_ref else .by_val; | 7459 | non_err_capture = if (non_err_is_ref != .no) .by_ref else .by_val; |
lib/std/zig/Client.zig+126-2| ... | @@ -1,3 +1,18 @@ | ... | @@ -1,3 +1,18 @@ |
| 1 | const Client = @This(); | ||
| 2 | |||
| 3 | const std = @import("std"); | ||
| 4 | const Io = std.Io; | ||
| 5 | const Allocator = std.mem.Allocator; | ||
| 6 | const assert = std.debug.assert; | ||
| 7 | const Configuration = std.Build.Configuration; | ||
| 8 | const OutMessage = std.zig.Client.Message; | ||
| 9 | const InMessage = std.zig.Server.Message; | ||
| 10 | const Reader = Io.Reader; | ||
| 11 | const Writer = Io.Writer; | ||
| 12 | |||
| 13 | in: *Reader, | ||
| 14 | out: *Writer, | ||
| 15 | |||
| 1 | pub const Message = struct { | 16 | pub const Message = struct { |
| 2 | pub const Header = extern struct { | 17 | pub const Header = extern struct { |
| 3 | tag: Tag, | 18 | tag: Tag, |
| ... | @@ -46,11 +61,120 @@ pub const Message = struct { | ... | @@ -46,11 +61,120 @@ pub const Message = struct { |
| 46 | /// The message body has the same format as in Server. | 61 | /// The message body has the same format as in Server. |
| 47 | new_fuzz_input, | 62 | new_fuzz_input, |
| 48 | 63 | ||
| 64 | /// Asks the server to run a list of steps. | ||
| 65 | /// Body is a `BuildSteps`. | ||
| 66 | /// This message only applies to the build system protocol. | ||
| 67 | bsp_build_steps = 0x80000000, | ||
| 68 | |||
| 49 | _, | 69 | _, |
| 50 | }; | 70 | }; |
| 51 | 71 | ||
| 72 | /// Trailing: | ||
| 73 | /// * step_indices: [step_count]std.Build.Configuration.Step.Index, | ||
| 74 | pub const BuildSteps = extern struct { | ||
| 75 | step_count: u32, | ||
| 76 | flags: Flags, | ||
| 77 | |||
| 78 | pub const Flags = packed struct(u32) { | ||
| 79 | /// Can only be enabled when the server declared support for file | ||
| 80 | /// watching. | ||
| 81 | watch: bool, | ||
| 82 | reserved: u31 = 0, | ||
| 83 | }; | ||
| 84 | }; | ||
| 85 | |||
| 52 | comptime { | 86 | comptime { |
| 53 | const std = @import("std"); | 87 | assert(@sizeOf(std.Build.abi.fuzz.LimitKind) == 1); |
| 54 | std.debug.assert(@sizeOf(std.Build.abi.fuzz.LimitKind) == 1); | ||
| 55 | } | 88 | } |
| 56 | }; | 89 | }; |
| 90 | |||
| 91 | pub fn receiveMessage(c: *const Client) Reader.Error!InMessage.Header { | ||
| 92 | return c.in.takeStruct(InMessage.Header, .little); | ||
| 93 | } | ||
| 94 | |||
| 95 | /// Assumes that `c.in` is a reader in `multi_reader`. | ||
| 96 | /// Guarantees that the response body will be buffered in `c.in` on success. | ||
| 97 | pub fn receiveMessageWithMultiReader( | ||
| 98 | c: *Client, | ||
| 99 | multi_reader: *Io.File.MultiReader, | ||
| 100 | timeout: Io.Timeout, | ||
| 101 | ) (Io.File.MultiReader.Error || Io.Timeout.Error)!InMessage.Header { | ||
| 102 | while (c.in.bufferedLen() < @sizeOf(InMessage.Header)) { | ||
| 103 | multi_reader.fill(64, timeout) catch |err| switch (err) { | ||
| 104 | error.Canceled, | ||
| 105 | error.Timeout, | ||
| 106 | error.ConcurrencyUnavailable, | ||
| 107 | error.EndOfStream, | ||
| 108 | => |e| return e, | ||
| 109 | }; | ||
| 110 | } | ||
| 111 | const header = c.in.takeStruct(InMessage.Header, .little) catch unreachable; | ||
| 112 | while (c.in.bufferedLen() < header.bytes_len) { | ||
| 113 | try multi_reader.fill(header.bytes_len - c.in.bufferedLen(), timeout); | ||
| 114 | } | ||
| 115 | try multi_reader.checkAnyError(); | ||
| 116 | return header; | ||
| 117 | } | ||
| 118 | |||
| 119 | /// Don't forget to flush! | ||
| 120 | pub fn serveMessageHeader(c: *const Client, header: OutMessage.Header) Writer.Error!void { | ||
| 121 | try c.out.writeStruct(header, .little); | ||
| 122 | } | ||
| 123 | |||
| 124 | pub fn serveBodylessMessage(c: *const Client, tag: OutMessage.Tag) Writer.Error!void { | ||
| 125 | try c.serveMessageHeader(.{ .tag = tag, .bytes_len = 0 }); | ||
| 126 | try c.out.flush(); | ||
| 127 | } | ||
| 128 | |||
| 129 | pub fn serveRunTest(c: *const Client, index: u32) !void { | ||
| 130 | try c.serveMessageHeader(.{ | ||
| 131 | .tag = .run_test, | ||
| 132 | .bytes_len = @sizeOf(u32), | ||
| 133 | }); | ||
| 134 | try c.out.writeInt(u32, index, .little); | ||
| 135 | try c.out.flush(); | ||
| 136 | } | ||
| 137 | |||
| 138 | pub fn serveRunFuzzTestMessage( | ||
| 139 | c: *const Client, | ||
| 140 | test_names: []const []const u8, | ||
| 141 | kind: std.Build.abi.fuzz.LimitKind, | ||
| 142 | amount_or_instance: u64, | ||
| 143 | ) !void { | ||
| 144 | try c.serveMessageHeader(.{ | ||
| 145 | .tag = .start_fuzzing, | ||
| 146 | .bytes_len = 1 + 8 + 4 + count: { | ||
| 147 | var bytes_len: u32 = @intCast(test_names.len * 4); | ||
| 148 | for (test_names) |name| { | ||
| 149 | bytes_len += @intCast(name.len); | ||
| 150 | } | ||
| 151 | break :count bytes_len; | ||
| 152 | }, | ||
| 153 | }); | ||
| 154 | try c.out.writeByte(@backingInt(kind)); | ||
| 155 | try c.out.writeInt(u64, amount_or_instance, .little); | ||
| 156 | try c.out.writeInt(u32, @intCast(test_names.len), .little); | ||
| 157 | for (test_names) |test_name| { | ||
| 158 | try c.out.writeInt(u32, @intCast(test_name.len), .little); | ||
| 159 | try c.out.writeAll(test_name); | ||
| 160 | } | ||
| 161 | try c.out.flush(); | ||
| 162 | } | ||
| 163 | |||
| 164 | pub fn serveBuildSteps( | ||
| 165 | c: *const Client, | ||
| 166 | steps: []const Configuration.Step.Index, | ||
| 167 | flags: OutMessage.BuildSteps.Flags, | ||
| 168 | ) !void { | ||
| 169 | try c.serveMessageHeader(.{ | ||
| 170 | .tag = .bsp_build_steps, | ||
| 171 | .bytes_len = @intCast(@sizeOf(OutMessage.BuildSteps) + steps.len * @sizeOf(Configuration.Step.Index)), | ||
| 172 | }); | ||
| 173 | const body: OutMessage.BuildSteps = .{ | ||
| 174 | .step_count = @intCast(steps.len), | ||
| 175 | .flags = flags, | ||
| 176 | }; | ||
| 177 | try c.out.writeStruct(body, .little); | ||
| 178 | try c.out.writeSliceEndian(Configuration.Step.Index, steps, .little); | ||
| 179 | try c.out.flush(); | ||
| 180 | } |
lib/std/zig/LibCInstallation.zig+1-1| ... | @@ -43,7 +43,7 @@ pub const FindError = error{ | ... | @@ -43,7 +43,7 @@ pub const FindError = error{ |
| 43 | pub fn parse(allocator: Allocator, io: Io, libc_file: []const u8, target: *const std.Target) !LibCInstallation { | 43 | pub fn parse(allocator: Allocator, io: Io, libc_file: []const u8, target: *const std.Target) !LibCInstallation { |
| 44 | var self: LibCInstallation = .{}; | 44 | var self: LibCInstallation = .{}; |
| 45 | 45 | ||
| 46 | const field_names = comptime std.meta.fieldNames(LibCInstallation); | 46 | const field_names = @typeInfo(LibCInstallation).@"struct".field_names; |
| 47 | const FoundKey = struct { | 47 | const FoundKey = struct { |
| 48 | found: bool, | 48 | found: bool, |
| 49 | allocated: ?[]u8, | 49 | allocated: ?[]u8, |
lib/std/zig/Server.zig+66-19| ... | @@ -1,12 +1,8 @@ | ... | @@ -1,12 +1,8 @@ |
| 1 | const Server = @This(); | 1 | const Server = @This(); |
| 2 | 2 | ||
| 3 | const builtin = @import("builtin"); | ||
| 4 | |||
| 5 | const std = @import("std"); | 3 | const std = @import("std"); |
| 6 | const Allocator = std.mem.Allocator; | 4 | const Allocator = std.mem.Allocator; |
| 7 | const assert = std.debug.assert; | 5 | const assert = std.debug.assert; |
| 8 | const native_endian = builtin.target.cpu.arch.endian(); | ||
| 9 | const need_bswap = native_endian != .little; | ||
| 10 | const Cache = std.Build.Cache; | 6 | const Cache = std.Build.Cache; |
| 11 | const OutMessage = std.zig.Server.Message; | 7 | const OutMessage = std.zig.Server.Message; |
| 12 | const InMessage = std.zig.Client.Message; | 8 | const InMessage = std.zig.Client.Message; |
| ... | @@ -16,6 +12,14 @@ const Writer = std.Io.Writer; | ... | @@ -16,6 +12,14 @@ const Writer = std.Io.Writer; |
| 16 | in: *Reader, | 12 | in: *Reader, |
| 17 | out: *Writer, | 13 | out: *Writer, |
| 18 | 14 | ||
| 15 | /// The ABI version of the build system protocol. Will be bumped whenever a | ||
| 16 | /// backwards incompatible changes to the protocol is made. | ||
| 17 | /// | ||
| 18 | /// Does not apply to the internal compiler protocol or test runner. | ||
| 19 | /// | ||
| 20 | /// See `version` in `Message.Handshake`. | ||
| 21 | pub const build_system_version: u32 = 1; | ||
| 22 | |||
| 19 | pub const Message = struct { | 23 | pub const Message = struct { |
| 20 | pub const Header = extern struct { | 24 | pub const Header = extern struct { |
| 21 | tag: Tag, | 25 | tag: Tag, |
| ... | @@ -70,9 +74,62 @@ pub const Message = struct { | ... | @@ -70,9 +74,62 @@ pub const Message = struct { |
| 70 | /// Body is a TimeReport. | 74 | /// Body is a TimeReport. |
| 71 | time_report, | 75 | time_report, |
| 72 | 76 | ||
| 77 | /// The first message sent by the server over the build system protocol. | ||
| 78 | /// Body is a `Handshake`. | ||
| 79 | /// This message only applies to the build system protocol. | ||
| 80 | bsp_handshake = 0x80000000, | ||
| 81 | /// Notifies that a new configuration file is available. | ||
| 82 | /// Body is a cwd relative path to the configuration file. | ||
| 83 | /// This message only applies to the build system protocol. | ||
| 84 | bsp_configuration, | ||
| 85 | /// Does not have a body. | ||
| 86 | /// This message only applies to the build system protocol. | ||
| 87 | bsp_build_started, | ||
| 88 | /// Does not have a body. | ||
| 89 | /// This message only applies to the build system protocol. | ||
| 90 | bsp_build_completed, | ||
| 91 | /// Body is a `Configuration.Step.Index`. | ||
| 92 | /// This message only applies to the build system protocol. | ||
| 93 | bsp_step_started, | ||
| 94 | /// Body is a `BuildStepCompleted`. | ||
| 95 | /// This message only applies to the build system protocol. | ||
| 96 | bsp_step_completed, | ||
| 97 | |||
| 73 | _, | 98 | _, |
| 74 | }; | 99 | }; |
| 75 | 100 | ||
| 101 | /// Trailing: | ||
| 102 | /// * base_paths: BasePaths, | ||
| 103 | pub const Handshake = extern struct { | ||
| 104 | /// See `build_system_version`. | ||
| 105 | version: u32, | ||
| 106 | flags: Flags, | ||
| 107 | |||
| 108 | pub const Flags = packed struct(u32) { | ||
| 109 | file_system_watch_supported: bool, | ||
| 110 | _: u31 = 0, | ||
| 111 | }; | ||
| 112 | }; | ||
| 113 | |||
| 114 | /// Trailing: | ||
| 115 | /// * error_bundle: ErrorBundle, | ||
| 116 | pub const BuildStepCompleted = extern struct { | ||
| 117 | step_index: std.Build.Configuration.Step.Index, | ||
| 118 | status: Status, | ||
| 119 | error_bundle: ErrorBundle, | ||
| 120 | // TODO result_error_msgs | ||
| 121 | // TODO result_stderr | ||
| 122 | // TODO result_peak_rss | ||
| 123 | // TODO result_duration_ns | ||
| 124 | |||
| 125 | pub const Status = enum(u32) { | ||
| 126 | success, | ||
| 127 | failure, | ||
| 128 | skipped, | ||
| 129 | skipped_oom, | ||
| 130 | }; | ||
| 131 | }; | ||
| 132 | |||
| 76 | pub const PathPrefix = enum(u8) { | 133 | pub const PathPrefix = enum(u8) { |
| 77 | cwd, | 134 | cwd, |
| 78 | zig_lib, | 135 | zig_lib, |
| ... | @@ -140,21 +197,6 @@ pub const Message = struct { | ... | @@ -140,21 +197,6 @@ pub const Message = struct { |
| 140 | }; | 197 | }; |
| 141 | }; | 198 | }; |
| 142 | 199 | ||
| 143 | pub const Options = struct { | ||
| 144 | in: *Reader, | ||
| 145 | out: *Writer, | ||
| 146 | zig_version: []const u8, | ||
| 147 | }; | ||
| 148 | |||
| 149 | pub fn init(options: Options) !Server { | ||
| 150 | var s: Server = .{ | ||
| 151 | .in = options.in, | ||
| 152 | .out = options.out, | ||
| 153 | }; | ||
| 154 | try s.serveStringMessage(.zig_version, options.zig_version); | ||
| 155 | return s; | ||
| 156 | } | ||
| 157 | |||
| 158 | pub fn receiveMessage(s: *Server) !InMessage.Header { | 200 | pub fn receiveMessage(s: *Server) !InMessage.Header { |
| 159 | return s.in.takeStruct(InMessage.Header, .little); | 201 | return s.in.takeStruct(InMessage.Header, .little); |
| 160 | } | 202 | } |
| ... | @@ -183,6 +225,11 @@ pub fn serveMessageHeader(s: *const Server, header: OutMessage.Header) !void { | ... | @@ -183,6 +225,11 @@ pub fn serveMessageHeader(s: *const Server, header: OutMessage.Header) !void { |
| 183 | try s.out.writeStruct(header, .little); | 225 | try s.out.writeStruct(header, .little); |
| 184 | } | 226 | } |
| 185 | 227 | ||
| 228 | pub fn serveBodylessMessage(s: *const Server, tag: OutMessage.Tag) Writer.Error!void { | ||
| 229 | try s.serveMessageHeader(.{ .tag = tag, .bytes_len = 0 }); | ||
| 230 | try s.out.flush(); | ||
| 231 | } | ||
| 232 | |||
| 186 | pub fn serveU32Message(s: *const Server, tag: OutMessage.Tag, int: u32) !void { | 233 | pub fn serveU32Message(s: *const Server, tag: OutMessage.Tag, int: u32) !void { |
| 187 | try serveMessageHeader(s, .{ | 234 | try serveMessageHeader(s, .{ |
| 188 | .tag = tag, | 235 | .tag = tag, |
lib/std/zig/WindowsSdk.zig+4-4| ... | @@ -891,7 +891,7 @@ const MsvcLibDir = struct { | ... | @@ -891,7 +891,7 @@ const MsvcLibDir = struct { |
| 891 | 891 | ||
| 892 | lib_dir_buf.appendSliceAssumeCapacity(installation_path); | 892 | lib_dir_buf.appendSliceAssumeCapacity(installation_path); |
| 893 | 893 | ||
| 894 | if (!Dir.path.isSep(lib_dir_buf.getLast().?)) { | 894 | if (!Dir.path.isSep(lib_dir_buf.last().?)) { |
| 895 | try lib_dir_buf.append('\\'); | 895 | try lib_dir_buf.append('\\'); |
| 896 | } | 896 | } |
| 897 | const installation_path_with_trailing_sep_len = lib_dir_buf.items.len; | 897 | const installation_path_with_trailing_sep_len = lib_dir_buf.items.len; |
| ... | @@ -1064,7 +1064,7 @@ const MsvcLibDir = struct { | ... | @@ -1064,7 +1064,7 @@ const MsvcLibDir = struct { |
| 1064 | errdefer msvc_dir.deinit(); | 1064 | errdefer msvc_dir.deinit(); |
| 1065 | 1065 | ||
| 1066 | // String might contain trailing slash, so trim it here | 1066 | // String might contain trailing slash, so trim it here |
| 1067 | if (msvc_dir.items.len > "C:\\".len and msvc_dir.getLast().? == '\\') _ = msvc_dir.pop(); | 1067 | if (msvc_dir.items.len > "C:\\".len and msvc_dir.last().? == '\\') _ = msvc_dir.pop(); |
| 1068 | 1068 | ||
| 1069 | // Remove `\include` at the end of path | 1069 | // Remove `\include` at the end of path |
| 1070 | if (std.mem.endsWith(u8, msvc_dir.items, "\\include")) { | 1070 | if (std.mem.endsWith(u8, msvc_dir.items, "\\include")) { |
| ... | @@ -1108,7 +1108,7 @@ const MsvcLibDir = struct { | ... | @@ -1108,7 +1108,7 @@ const MsvcLibDir = struct { |
| 1108 | 1108 | ||
| 1109 | try list.appendSlice(VS140COMNTOOLS); // C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools | 1109 | try list.appendSlice(VS140COMNTOOLS); // C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools |
| 1110 | // String might contain trailing slash, so trim it here | 1110 | // String might contain trailing slash, so trim it here |
| 1111 | if (list.items.len > "C:\\".len and list.getLast().? == '\\') _ = list.pop(); | 1111 | if (list.items.len > "C:\\".len and list.last().? == '\\') _ = list.pop(); |
| 1112 | list.shrinkRetainingCapacity(list.items.len - "\\Common7\\Tools".len); // C:\Program Files (x86)\Microsoft Visual Studio 14.0 | 1112 | list.shrinkRetainingCapacity(list.items.len - "\\Common7\\Tools".len); // C:\Program Files (x86)\Microsoft Visual Studio 14.0 |
| 1113 | break :base_path list; | 1113 | break :base_path list; |
| 1114 | } | 1114 | } |
| ... | @@ -1131,7 +1131,7 @@ const MsvcLibDir = struct { | ... | @@ -1131,7 +1131,7 @@ const MsvcLibDir = struct { |
| 1131 | errdefer path.deinit(); | 1131 | errdefer path.deinit(); |
| 1132 | 1132 | ||
| 1133 | // String might contain trailing slash, so trim it here | 1133 | // String might contain trailing slash, so trim it here |
| 1134 | if (path.items.len > "C:\\".len and path.getLast().? == '\\') _ = path.pop(); | 1134 | if (path.items.len > "C:\\".len and path.last().? == '\\') _ = path.pop(); |
| 1135 | break :base_path path; | 1135 | break :base_path path; |
| 1136 | } | 1136 | } |
| 1137 | return error.PathNotFound; | 1137 | return error.PathNotFound; |
lib/std/zig/Zir.zig+2-2| ... | @@ -584,7 +584,7 @@ pub const Inst = struct { | ... | @@ -584,7 +584,7 @@ pub const Inst = struct { |
| 584 | /// containing the instruction. | 584 | /// containing the instruction. |
| 585 | /// Uses the `un_tok` union field. | 585 | /// Uses the `un_tok` union field. |
| 586 | ref, | 586 | ref, |
| 587 | /// Implements the dereference operand (`.*`). Checks that operand is a pointer | 587 | /// Implements the dereference operator (`.*`). Checks that operand is a pointer |
| 588 | /// that supports being directly dereferenced. | 588 | /// that supports being directly dereferenced. |
| 589 | /// Uses the `un_node` union field. | 589 | /// Uses the `un_node` union field. |
| 590 | deref, | 590 | deref, |
| ... | @@ -2522,7 +2522,7 @@ pub const Inst = struct { | ... | @@ -2522,7 +2522,7 @@ pub const Inst = struct { |
| 2522 | // bigger than expected. Note that in Debug builds, Zig is allowed | 2522 | // bigger than expected. Note that in Debug builds, Zig is allowed |
| 2523 | // to insert a secret field for safety checks. | 2523 | // to insert a secret field for safety checks. |
| 2524 | comptime { | 2524 | comptime { |
| 2525 | if (builtin.mode != .Debug and builtin.mode != .ReleaseSafe) { | 2525 | if (builtin.mode != .debug and builtin.mode != .safe) { |
| 2526 | assert(@sizeOf(Data) == 8); | 2526 | assert(@sizeOf(Data) == 8); |
| 2527 | } | 2527 | } |
| 2528 | } | 2528 | } |
lib/std/zig/llvm/Builder.zig+1320-479| ... | @@ -17,7 +17,7 @@ gpa: Allocator, | ... | @@ -17,7 +17,7 @@ gpa: Allocator, |
| 17 | strip: bool, | 17 | strip: bool, |
| 18 | 18 | ||
| 19 | source_filename: String, | 19 | source_filename: String, |
| 20 | data_layout: String, | 20 | data_layout: DataLayout, |
| 21 | target_triple: String, | 21 | target_triple: String, |
| 22 | module_asm: std.ArrayList(u8), | 22 | module_asm: std.ArrayList(u8), |
| 23 | 23 | ||
| ... | @@ -87,6 +87,455 @@ pub const Options = struct { | ... | @@ -87,6 +87,455 @@ pub const Options = struct { |
| 87 | triple: []const u8 = &.{}, | 87 | triple: []const u8 = &.{}, |
| 88 | }; | 88 | }; |
| 89 | 89 | ||
| 90 | pub const DataLayout = struct { | ||
| 91 | endian: ?std.lang.Endian, | ||
| 92 | int_specs: PrimitiveSpec.Map, | ||
| 93 | float_specs: PrimitiveSpec.Map, | ||
| 94 | vector_specs: PrimitiveSpec.Map, | ||
| 95 | pointer_specs: PointerSpec.Map, | ||
| 96 | string_repr: String, | ||
| 97 | |||
| 98 | const PrimitiveSpec = packed struct(u32) { | ||
| 99 | bit_width: BitWidth, | ||
| 100 | abi_align: Alignment, | ||
| 101 | pref_align: Alignment, | ||
| 102 | |||
| 103 | const BitWidth = u20; | ||
| 104 | |||
| 105 | const Map = std.array_hash_map.Custom(PrimitiveSpec, void, Context, false); | ||
| 106 | |||
| 107 | const Context = struct { | ||
| 108 | pub fn hash(_: Context, spec: PrimitiveSpec) u32 { | ||
| 109 | return std.hash.int(spec.bit_width); | ||
| 110 | } | ||
| 111 | |||
| 112 | pub fn eql(_: Context, lhs_spec: PrimitiveSpec, rhs_spec: PrimitiveSpec, _: usize) bool { | ||
| 113 | return lhs_spec.bit_width == rhs_spec.bit_width; | ||
| 114 | } | ||
| 115 | }; | ||
| 116 | }; | ||
| 117 | |||
| 118 | const PointerSpec = struct { | ||
| 119 | bit_width: BitWidth, | ||
| 120 | index_bit_width: BitWidth, | ||
| 121 | flags: packed struct(u32) { | ||
| 122 | abi_align: Alignment, | ||
| 123 | pref_align: Alignment, | ||
| 124 | has_unstable_repr: bool, | ||
| 125 | has_external_state: bool, | ||
| 126 | null_ptr_repr: NullPtrRepr, | ||
| 127 | unused: u17 = 0, | ||
| 128 | }, | ||
| 129 | addr_space_name: String, | ||
| 130 | |||
| 131 | const BitWidth = u32; | ||
| 132 | |||
| 133 | const NullPtrRepr = enum(u1) { all_zeros, all_ones }; | ||
| 134 | |||
| 135 | const Map = std.array_hash_map.Auto(AddrSpace, PointerSpec); | ||
| 136 | }; | ||
| 137 | |||
| 138 | pub fn stringForTarget(target: *const std.Target) []const u8 { | ||
| 139 | // These data layouts should match Clang. | ||
| 140 | return switch (target.cpu.arch) { | ||
| 141 | .arc => "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-f32:32:32-i64:32-f64:32-a:0:32-n32", | ||
| 142 | .xcore => "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:32-f64:32-a:0:32-n32", | ||
| 143 | .hexagon => "e-m:e-p:32:32:32-a:0-n16:32-i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048", | ||
| 144 | .lanai => "E-m:e-p:32:32-i64:64-a:0:32-n32-S64", | ||
| 145 | .aarch64 => if (target.ofmt == .macho) | ||
| 146 | if (target.os.tag == .windows or target.os.tag == .uefi) | ||
| 147 | "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32" | ||
| 148 | else if (target.abi == .ilp32) | ||
| 149 | "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32" | ||
| 150 | else | ||
| 151 | "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32" | ||
| 152 | else if (target.os.tag == .windows or target.os.tag == .uefi) | ||
| 153 | "e-m:w-p270:32:32-p271:32:32-p272:64:64-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32" | ||
| 154 | else | ||
| 155 | "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32", | ||
| 156 | .aarch64_be => "E-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32", | ||
| 157 | .arm => if (target.ofmt == .macho) | ||
| 158 | "e-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" | ||
| 159 | else | ||
| 160 | "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64", | ||
| 161 | .armeb, .thumbeb => if (target.ofmt == .macho) | ||
| 162 | "E-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" | ||
| 163 | else | ||
| 164 | "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64", | ||
| 165 | .thumb => if (target.ofmt == .macho) | ||
| 166 | "e-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" | ||
| 167 | else if (target.os.tag == .windows or target.os.tag == .uefi) | ||
| 168 | "e-m:w-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" | ||
| 169 | else | ||
| 170 | "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64", | ||
| 171 | .avr => "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8:16-a:8", | ||
| 172 | .bpfeb => "E-m:e-p:64:64-i64:64-i128:128-n32:64-S128", | ||
| 173 | .bpfel => "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128", | ||
| 174 | .msp430 => "e-m:e-p:16:16-i32:16-i64:16-f32:16-f64:16-a:8-n8:16-S16", | ||
| 175 | .mips => "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64", | ||
| 176 | .mipsel => "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64", | ||
| 177 | .mips64 => switch (target.abi) { | ||
| 178 | .gnuabin32, .muslabin32, .abin32 => "E-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128", | ||
| 179 | else => "E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128", | ||
| 180 | }, | ||
| 181 | .mips64el => switch (target.abi) { | ||
| 182 | .gnuabin32, .muslabin32, .abin32 => "e-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128", | ||
| 183 | else => "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128", | ||
| 184 | }, | ||
| 185 | .m68k => "E-m:e-p:32:16:32-i8:8:8-i16:16:16-i32:16:32-n8:16:32-a:0:16-S16", | ||
| 186 | .powerpc => "E-m:e-p:32:32-Fn32-i64:64-n32", | ||
| 187 | .powerpcle => "e-m:e-p:32:32-Fn32-i64:64-n32", | ||
| 188 | .powerpc64 => switch (target.os.tag) { | ||
| 189 | .linux => "E-m:e-Fn32-i64:64-i128:128-n32:64-S128-v256:256:256-v512:512:512", | ||
| 190 | .ps3 => "E-m:e-p:32:32-Fi64-i64:64-i128:128-n32:64", | ||
| 191 | else => "E-m:e-Fn32-i64:64-i128:128-n32:64", | ||
| 192 | }, | ||
| 193 | .powerpc64le => if (target.os.tag == .linux) | ||
| 194 | "e-m:e-Fn32-i64:64-i128:128-n32:64-S128-v256:256:256-v512:512:512" | ||
| 195 | else | ||
| 196 | "e-m:e-Fn32-i64:64-i128:128-n32:64", | ||
| 197 | .nvptx => "e-p:32:32-p6:32:32-p7:32:32-i64:64-i128:128-i256:256-v16:16-v32:32-n16:32:64", | ||
| 198 | .nvptx64 => "e-p6:32:32-i64:64-i128:128-i256:256-v16:16-v32:32-n16:32:64", | ||
| 199 | .amdgcn => "e-m:e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128:128:48-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9", | ||
| 200 | .riscv32 => if (target.cpu.has(.riscv, .e)) | ||
| 201 | "e-m:e-p:32:32-i64:64-n32-S32" | ||
| 202 | else | ||
| 203 | "e-m:e-p:32:32-i64:64-n32-S128", | ||
| 204 | .riscv32be => if (target.cpu.has(.riscv, .e)) | ||
| 205 | "E-m:e-p:32:32-i64:64-n32-S32" | ||
| 206 | else | ||
| 207 | "E-m:e-p:32:32-i64:64-n32-S128", | ||
| 208 | .riscv64 => if (target.cpu.has(.riscv, .e)) | ||
| 209 | "e-m:e-p:64:64-i64:64-i128:128-n32:64-S64" | ||
| 210 | else | ||
| 211 | "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128", | ||
| 212 | .riscv64be => if (target.cpu.has(.riscv, .e)) | ||
| 213 | "E-m:e-p:64:64-i64:64-i128:128-n32:64-S64" | ||
| 214 | else | ||
| 215 | "E-m:e-p:64:64-i64:64-i128:128-n32:64-S128", | ||
| 216 | .sparc => "E-m:e-p:32:32-i64:64-i128:128-f128:64-n32-S64", | ||
| 217 | .sparc64 => "E-m:e-i64:64-i128:128-n32:64-S128", | ||
| 218 | .s390x => "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64", | ||
| 219 | .x86 => if (target.os.tag == .windows or target.os.tag == .uefi) switch (target.abi) { | ||
| 220 | .gnu => if (target.ofmt == .coff) | ||
| 221 | "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:32-n8:16:32-a:0:32-S32" | ||
| 222 | else | ||
| 223 | "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:32-n8:16:32-a:0:32-S32", | ||
| 224 | else => blk: { | ||
| 225 | const msvc = switch (target.abi) { | ||
| 226 | .none, .msvc => true, | ||
| 227 | else => false, | ||
| 228 | }; | ||
| 229 | |||
| 230 | break :blk if (target.ofmt == .coff) | ||
| 231 | if (msvc) | ||
| 232 | "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32-a:0:32-S32" | ||
| 233 | else | ||
| 234 | "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:32-n8:16:32-a:0:32-S32" | ||
| 235 | else if (msvc) | ||
| 236 | "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32-a:0:32-S32" | ||
| 237 | else | ||
| 238 | "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:32-n8:16:32-a:0:32-S32"; | ||
| 239 | }, | ||
| 240 | } else if (target.ofmt == .macho) | ||
| 241 | "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:128-f64:32:64-f80:32-n8:16:32-S128" | ||
| 242 | else | ||
| 243 | "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:128-f64:32:64-f80:32-n8:16:32-S128", | ||
| 244 | .x86_64 => if (target.os.tag.isDarwin() or target.ofmt == .macho) | ||
| 245 | "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" | ||
| 246 | else switch (target.abi) { | ||
| 247 | .gnux32, .muslx32, .x32 => "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", | ||
| 248 | else => if ((target.os.tag == .windows or target.os.tag == .uefi) and target.ofmt == .coff) | ||
| 249 | "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" | ||
| 250 | else | ||
| 251 | "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", | ||
| 252 | }, | ||
| 253 | .spirv32 => switch (target.os.tag) { | ||
| 254 | .vulkan, .opengl => "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1", | ||
| 255 | else => "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1", | ||
| 256 | }, | ||
| 257 | .spirv64 => "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1", | ||
| 258 | .wasm32 => if (target.os.tag == .emscripten) | ||
| 259 | "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-f128:64-n32:64-S128-ni:1:10:20" | ||
| 260 | else | ||
| 261 | "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20", | ||
| 262 | .wasm64 => if (target.os.tag == .emscripten) | ||
| 263 | "e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-i128:128-f128:64-n32:64-S128-ni:1:10:20" | ||
| 264 | else | ||
| 265 | "e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20", | ||
| 266 | .ve => "e-m:e-i64:64-n32:64-S128-v64:64:64-v128:64:64-v256:64:64-v512:64:64-v1024:64:64-v2048:64:64-v4096:64:64-v8192:64:64-v16384:64:64", | ||
| 267 | .csky => "e-m:e-S32-p:32:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:32-v128:32:32-a:0:32-Fi32-n32", | ||
| 268 | .loongarch32 => "e-m:e-p:32:32-i64:64-n32-S128", | ||
| 269 | .loongarch64 => "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128", | ||
| 270 | .xtensa => "e-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-n32", | ||
| 271 | |||
| 272 | .alpha, | ||
| 273 | .arceb, | ||
| 274 | .ez80, | ||
| 275 | .hppa, | ||
| 276 | .hppa64, | ||
| 277 | .kalimba, | ||
| 278 | .kvx, | ||
| 279 | .m88k, | ||
| 280 | .microblaze, | ||
| 281 | .microblazeel, | ||
| 282 | .or1k, | ||
| 283 | .propeller, | ||
| 284 | .sh, | ||
| 285 | .sheb, | ||
| 286 | .x86_16, | ||
| 287 | .xtensaeb, | ||
| 288 | => unreachable, | ||
| 289 | }; | ||
| 290 | } | ||
| 291 | |||
| 292 | const default_int_specs: []const PrimitiveSpec = &.{ | ||
| 293 | .{ .bit_width = 8, .abi_align = .fromByteUnits(1), .pref_align = .fromByteUnits(1) }, // i8:8:8 | ||
| 294 | .{ .bit_width = 16, .abi_align = .fromByteUnits(2), .pref_align = .fromByteUnits(2) }, // i16:16:16 | ||
| 295 | .{ .bit_width = 32, .abi_align = .fromByteUnits(4), .pref_align = .fromByteUnits(4) }, // i32:32:32 | ||
| 296 | .{ .bit_width = 64, .abi_align = .fromByteUnits(4), .pref_align = .fromByteUnits(8) }, // i64:32:64 | ||
| 297 | }; | ||
| 298 | const default_float_specs: []const PrimitiveSpec = &.{ | ||
| 299 | .{ .bit_width = 16, .abi_align = .fromByteUnits(2), .pref_align = .fromByteUnits(2) }, // f16:16:16 | ||
| 300 | .{ .bit_width = 32, .abi_align = .fromByteUnits(4), .pref_align = .fromByteUnits(4) }, // f32:32:32 | ||
| 301 | .{ .bit_width = 64, .abi_align = .fromByteUnits(8), .pref_align = .fromByteUnits(8) }, // f64:64:64 | ||
| 302 | .{ .bit_width = 128, .abi_align = .fromByteUnits(16), .pref_align = .fromByteUnits(16) }, // f128:128:128 | ||
| 303 | }; | ||
| 304 | const default_vector_specs: []const PrimitiveSpec = &.{ | ||
| 305 | .{ .bit_width = 64, .abi_align = .fromByteUnits(8), .pref_align = .fromByteUnits(8) }, // v64:64:64 | ||
| 306 | .{ .bit_width = 128, .abi_align = .fromByteUnits(16), .pref_align = .fromByteUnits(16) }, // v128:128:128 | ||
| 307 | }; | ||
| 308 | |||
| 309 | pub fn parseString(string_repr: String, builder: *Builder) Allocator.Error!DataLayout { | ||
| 310 | const gpa = builder.gpa; | ||
| 311 | |||
| 312 | var int_specs: PrimitiveSpec.Map = .empty; | ||
| 313 | defer int_specs.deinit(gpa); | ||
| 314 | var float_specs: PrimitiveSpec.Map = .empty; | ||
| 315 | defer float_specs.deinit(gpa); | ||
| 316 | var vector_specs: PrimitiveSpec.Map = .empty; | ||
| 317 | defer vector_specs.deinit(gpa); | ||
| 318 | var pointer_specs: PointerSpec.Map = .empty; | ||
| 319 | defer pointer_specs.deinit(gpa); | ||
| 320 | var non_integral_addr_spaces: std.ArrayList(AddrSpace) = .empty; | ||
| 321 | defer non_integral_addr_spaces.deinit(gpa); | ||
| 322 | |||
| 323 | try int_specs.ensureTotalCapacity(gpa, default_int_specs.len); | ||
| 324 | for (default_int_specs) |int_spec| int_specs.putAssumeCapacityNoClobber(int_spec, {}); | ||
| 325 | try float_specs.ensureTotalCapacity(gpa, default_float_specs.len); | ||
| 326 | for (default_float_specs) |float_spec| float_specs.putAssumeCapacityNoClobber(float_spec, {}); | ||
| 327 | try vector_specs.ensureTotalCapacity(gpa, default_vector_specs.len); | ||
| 328 | for (default_vector_specs) |vector_spec| vector_specs.putAssumeCapacityNoClobber(vector_spec, {}); | ||
| 329 | try pointer_specs.putNoClobber(gpa, .default, comptime .{ | ||
| 330 | .bit_width = 64, | ||
| 331 | .index_bit_width = 64, | ||
| 332 | .flags = .{ | ||
| 333 | .abi_align = .fromByteUnits(8), | ||
| 334 | .pref_align = .fromByteUnits(8), | ||
| 335 | .has_unstable_repr = false, | ||
| 336 | .has_external_state = false, | ||
| 337 | .null_ptr_repr = .all_zeros, | ||
| 338 | }, | ||
| 339 | .addr_space_name = .none, | ||
| 340 | }); | ||
| 341 | |||
| 342 | var endian: ?std.lang.Endian = null; | ||
| 343 | var spec_it = std.mem.splitScalar(u8, string_repr.slice(builder).?, '-'); | ||
| 344 | while (spec_it.next()) |spec| switch (spec[0]) { | ||
| 345 | else => {}, | ||
| 346 | 'E' => { | ||
| 347 | assert(spec.len == 1); | ||
| 348 | assert(endian == null); | ||
| 349 | endian = .big; | ||
| 350 | }, | ||
| 351 | 'e' => { | ||
| 352 | assert(spec.len == 1); | ||
| 353 | assert(endian == null); | ||
| 354 | endian = .little; | ||
| 355 | }, | ||
| 356 | 'p' => { | ||
| 357 | var field_it = std.mem.splitScalar(u8, spec[1..], ':'); | ||
| 358 | |||
| 359 | const first = field_it.first(); | ||
| 360 | var has_unstable_repr = false; | ||
| 361 | var has_external_state = false; | ||
| 362 | var null_ptr_repr: ?PointerSpec.NullPtrRepr = null; | ||
| 363 | var addr_space_name: String = .none; | ||
| 364 | const addr_space = for (first, 0..) |flag, as_start| switch (flag) { | ||
| 365 | 'u' => has_unstable_repr = true, | ||
| 366 | 'e' => has_external_state = true, | ||
| 367 | 'z' => { | ||
| 368 | assert(null_ptr_repr == null); | ||
| 369 | null_ptr_repr = .all_zeros; | ||
| 370 | }, | ||
| 371 | 'o' => { | ||
| 372 | assert(null_ptr_repr == null); | ||
| 373 | null_ptr_repr = .all_ones; | ||
| 374 | }, | ||
| 375 | else => { | ||
| 376 | if (first[first.len - ")".len] != ')') break first[as_start..]; | ||
| 377 | const name_start = std.mem.findScalarPos(u8, first, as_start, '(').?; | ||
| 378 | addr_space_name = try builder.string(first[name_start + "(".len .. first.len - ")".len]); | ||
| 379 | break first[as_start..name_start]; | ||
| 380 | }, | ||
| 381 | } else first[first.len..]; | ||
| 382 | const bit_width = std.fmt.parseInt(PointerSpec.BitWidth, field_it.next().?, 10) catch unreachable; | ||
| 383 | const abi_align: Alignment = .fromByteUnits(std.fmt.parseInt(u64, field_it.next().?, 10) catch unreachable); | ||
| 384 | const pref_align: Alignment = if (field_it.next()) |pref_align| | ||
| 385 | .fromByteUnits(std.fmt.parseInt(u64, pref_align, 10) catch unreachable) | ||
| 386 | else | ||
| 387 | abi_align; | ||
| 388 | const index_bit_width = if (field_it.next()) |index_bit_width| | ||
| 389 | std.fmt.parseInt(PointerSpec.BitWidth, index_bit_width, 10) catch unreachable | ||
| 390 | else | ||
| 391 | bit_width; | ||
| 392 | assert(field_it.peek() == null); | ||
| 393 | |||
| 394 | try pointer_specs.put(gpa, switch (addr_space.len) { | ||
| 395 | 0 => .default, | ||
| 396 | else => @fromBackingInt(std.fmt.parseInt(u24, addr_space, 10) catch unreachable), | ||
| 397 | }, .{ | ||
| 398 | .bit_width = bit_width, | ||
| 399 | .index_bit_width = index_bit_width, | ||
| 400 | .flags = .{ | ||
| 401 | .abi_align = abi_align, | ||
| 402 | .pref_align = pref_align, | ||
| 403 | .has_unstable_repr = has_unstable_repr, | ||
| 404 | .has_external_state = has_external_state, | ||
| 405 | .null_ptr_repr = null_ptr_repr orelse .all_zeros, | ||
| 406 | }, | ||
| 407 | .addr_space_name = addr_space_name, | ||
| 408 | }); | ||
| 409 | }, | ||
| 410 | 'i', 'f', 'v' => |kind| { | ||
| 411 | if (std.mem.eql(u8, spec, "ve")) { | ||
| 412 | vector_specs.clearRetainingCapacity(); | ||
| 413 | continue; | ||
| 414 | } | ||
| 415 | var field_it = std.mem.splitScalar(u8, spec[1..], ':'); | ||
| 416 | const bit_width = std.fmt.parseInt(PrimitiveSpec.BitWidth, field_it.first(), 10) catch unreachable; | ||
| 417 | const abi_align: Alignment = .fromByteUnits(std.fmt.parseInt(u64, field_it.next().?, 10) catch unreachable); | ||
| 418 | const pref_align: Alignment = if (field_it.next()) |pref_align| | ||
| 419 | .fromByteUnits(std.fmt.parseInt(u64, pref_align, 10) catch unreachable) | ||
| 420 | else | ||
| 421 | abi_align; | ||
| 422 | assert(field_it.peek() == null); | ||
| 423 | const specs = switch (kind) { | ||
| 424 | else => unreachable, | ||
| 425 | 'i' => &int_specs, | ||
| 426 | 'f' => &float_specs, | ||
| 427 | 'v' => &vector_specs, | ||
| 428 | }; | ||
| 429 | try specs.put(gpa, .{ .bit_width = bit_width, .abi_align = abi_align, .pref_align = pref_align }, {}); | ||
| 430 | }, | ||
| 431 | 'n' => { | ||
| 432 | var field_it = std.mem.splitScalar(u8, spec[1..], ':'); | ||
| 433 | if (std.mem.eql(u8, field_it.first(), "i")) { | ||
| 434 | while (field_it.next()) |non_integral_addr_space| try non_integral_addr_spaces.append( | ||
| 435 | gpa, | ||
| 436 | @fromBackingInt(std.fmt.parseInt(u24, non_integral_addr_space, 10) catch unreachable), | ||
| 437 | ); | ||
| 438 | } else { | ||
| 439 | field_it.reset(); | ||
| 440 | while (field_it.next()) |native_bit_width| { | ||
| 441 | _ = std.fmt.parseInt(PrimitiveSpec.BitWidth, native_bit_width, 10) catch unreachable; | ||
| 442 | } | ||
| 443 | } | ||
| 444 | }, | ||
| 445 | }; | ||
| 446 | |||
| 447 | for (non_integral_addr_spaces.items) |non_integral_addr_space| { | ||
| 448 | const pointer_spec_gop = try pointer_specs.getOrPut(gpa, non_integral_addr_space); | ||
| 449 | if (!pointer_spec_gop.found_existing) pointer_spec_gop.value_ptr.* = pointer_specs.get(.default).?; | ||
| 450 | pointer_spec_gop.value_ptr.flags.has_unstable_repr = true; | ||
| 451 | pointer_spec_gop.value_ptr.flags.has_external_state = false; | ||
| 452 | } | ||
| 453 | |||
| 454 | { | ||
| 455 | const SortContext = struct { | ||
| 456 | specs: []const PrimitiveSpec, | ||
| 457 | pub fn lessThan(ctx: @This(), lhs_index: usize, rhs_index: usize) bool { | ||
| 458 | return ctx.specs[lhs_index].bit_width < ctx.specs[rhs_index].bit_width; | ||
| 459 | } | ||
| 460 | }; | ||
| 461 | int_specs.sortUnstable(SortContext{ .specs = int_specs.keys() }); | ||
| 462 | float_specs.sortUnstable(SortContext{ .specs = float_specs.keys() }); | ||
| 463 | vector_specs.sortUnstable(SortContext{ .specs = vector_specs.keys() }); | ||
| 464 | } | ||
| 465 | { | ||
| 466 | const SortContext = struct { | ||
| 467 | addr_spaces: []const AddrSpace, | ||
| 468 | pub fn lessThan(ctx: @This(), lhs_index: usize, rhs_index: usize) bool { | ||
| 469 | return @backingInt(ctx.addr_spaces[lhs_index]) < @backingInt(ctx.addr_spaces[rhs_index]); | ||
| 470 | } | ||
| 471 | }; | ||
| 472 | pointer_specs.sortUnstable(SortContext{ .addr_spaces = pointer_specs.keys() }); | ||
| 473 | assert(pointer_specs.keys()[0] == .default); | ||
| 474 | } | ||
| 475 | |||
| 476 | return .{ | ||
| 477 | .endian = endian, | ||
| 478 | .int_specs = int_specs.move(), | ||
| 479 | .float_specs = float_specs.move(), | ||
| 480 | .vector_specs = vector_specs.move(), | ||
| 481 | .pointer_specs = pointer_specs.move(), | ||
| 482 | .string_repr = string_repr, | ||
| 483 | }; | ||
| 484 | } | ||
| 485 | |||
| 486 | pub fn deinit(data_layout: *DataLayout, gpa: Allocator) void { | ||
| 487 | data_layout.int_specs.deinit(gpa); | ||
| 488 | data_layout.float_specs.deinit(gpa); | ||
| 489 | data_layout.vector_specs.deinit(gpa); | ||
| 490 | data_layout.pointer_specs.deinit(gpa); | ||
| 491 | } | ||
| 492 | |||
| 493 | pub fn getIntegerSpec(data_layout: *const DataLayout, bit_width: PrimitiveSpec.BitWidth) PrimitiveSpec { | ||
| 494 | const specs = data_layout.int_specs.keys(); | ||
| 495 | return specs[ | ||
| 496 | @min(std.sort.lowerBound(PrimitiveSpec, specs, bit_width, struct { | ||
| 497 | fn order(ctx: PrimitiveSpec.BitWidth, spec: PrimitiveSpec) std.math.Order { | ||
| 498 | return std.math.order(ctx, spec.bit_width); | ||
| 499 | } | ||
| 500 | }.order), specs.len - 1) | ||
| 501 | ]; | ||
| 502 | } | ||
| 503 | |||
| 504 | pub fn getFloatSpec(data_layout: *const DataLayout, bit_width: PrimitiveSpec.BitWidth) PrimitiveSpec { | ||
| 505 | if (data_layout.float_specs.getEntry(.{ | ||
| 506 | .bit_width = bit_width, | ||
| 507 | .abi_align = .default, | ||
| 508 | .pref_align = .default, | ||
| 509 | })) |entry| return entry.key_ptr.*; | ||
| 510 | const default_align: Alignment = .fromByteUnits( | ||
| 511 | std.math.ceilPowerOfTwoAssert(PrimitiveSpec.BitWidth, bit_width / 8), | ||
| 512 | ); | ||
| 513 | return .{ .bit_width = bit_width, .abi_align = default_align, .pref_align = default_align }; | ||
| 514 | } | ||
| 515 | |||
| 516 | pub fn getVectorSpec( | ||
| 517 | data_layout: *const DataLayout, | ||
| 518 | bit_width: PrimitiveSpec.BitWidth, | ||
| 519 | store_size: Type.Size, | ||
| 520 | ) PrimitiveSpec { | ||
| 521 | if (data_layout.float_specs.getEntry(.{ | ||
| 522 | .bit_width = bit_width, | ||
| 523 | .abi_align = .default, | ||
| 524 | .pref_align = .default, | ||
| 525 | })) |entry| return entry.key_ptr.*; | ||
| 526 | const default_align: Alignment = .fromByteUnits( | ||
| 527 | std.math.ceilPowerOfTwoAssert(PrimitiveSpec.BitWidth, switch (store_size) { | ||
| 528 | .fixed, .scalable => |known_min| known_min, | ||
| 529 | }), | ||
| 530 | ); | ||
| 531 | return .{ .bit_width = bit_width, .abi_align = default_align, .pref_align = default_align }; | ||
| 532 | } | ||
| 533 | |||
| 534 | pub fn getPointerSpec(data_layout: *const DataLayout, addr_space: AddrSpace) PointerSpec { | ||
| 535 | return data_layout.pointer_specs.get(addr_space) orelse data_layout.pointer_specs.values()[0]; | ||
| 536 | } | ||
| 537 | }; | ||
| 538 | |||
| 90 | pub const String = enum(u32) { | 539 | pub const String = enum(u32) { |
| 91 | none = maxInt(u31), | 540 | none = maxInt(u31), |
| 92 | empty, | 541 | empty, |
| ... | @@ -142,8 +591,8 @@ pub const String = enum(u32) { | ... | @@ -142,8 +591,8 @@ pub const String = enum(u32) { |
| 142 | } | 591 | } |
| 143 | 592 | ||
| 144 | fn fromIndex(index: ?usize) String { | 593 | fn fromIndex(index: ?usize) String { |
| 145 | return @fromBackingInt(@intCast(@as(u32, @intCast((index orelse return .none) + | 594 | return @fromBackingInt(@as(u32, @intCast((index orelse return .none) + |
| 146 | @backingInt(String.empty))))); | 595 | @backingInt(String.empty)))); |
| 147 | } | 596 | } |
| 148 | 597 | ||
| 149 | fn toIndex(self: String) ?usize { | 598 | fn toIndex(self: String) ?usize { |
| ... | @@ -489,7 +938,10 @@ pub const Type = enum(u32) { | ... | @@ -489,7 +938,10 @@ pub const Type = enum(u32) { |
| 489 | .double, .i64, .x86_mmx => 64, | 938 | .double, .i64, .x86_mmx => 64, |
| 490 | .x86_fp80, .i80 => 80, | 939 | .x86_fp80, .i80 => 80, |
| 491 | .fp128, .ppc_fp128, .i128 => 128, | 940 | .fp128, .ppc_fp128, .i128 => 128, |
| 492 | .ptr, .@"ptr addrspace(4)" => @panic("TODO: query data layout"), | 941 | .ptr => @intCast(builder.data_layout.getPointerSpec(.default).bit_width), |
| 942 | .@"ptr addrspace(4)" => @intCast( | ||
| 943 | builder.data_layout.getPointerSpec(@fromBackingInt(@intCast(4))).bit_width, | ||
| 944 | ), | ||
| 493 | _ => { | 945 | _ => { |
| 494 | const item = builder.type_items.items[@backingInt(self)]; | 946 | const item = builder.type_items.items[@backingInt(self)]; |
| 495 | return switch (item.tag) { | 947 | return switch (item.tag) { |
| ... | @@ -498,7 +950,9 @@ pub const Type = enum(u32) { | ... | @@ -498,7 +950,9 @@ pub const Type = enum(u32) { |
| 498 | .vararg_function, | 950 | .vararg_function, |
| 499 | => unreachable, | 951 | => unreachable, |
| 500 | .integer => @intCast(item.data), | 952 | .integer => @intCast(item.data), |
| 501 | .pointer => @panic("TODO: query data layout"), | 953 | .pointer => @intCast( |
| 954 | builder.data_layout.getPointerSpec(@fromBackingInt(@intCast(item.data))).bit_width, | ||
| 955 | ), | ||
| 502 | .target => unreachable, | 956 | .target => unreachable, |
| 503 | .vector, | 957 | .vector, |
| 504 | .scalable_vector, | 958 | .scalable_vector, |
| ... | @@ -931,12 +1385,74 @@ pub const Type = enum(u32) { | ... | @@ -931,12 +1385,74 @@ pub const Type = enum(u32) { |
| 931 | }, | 1385 | }, |
| 932 | }; | 1386 | }; |
| 933 | } | 1387 | } |
| 1388 | |||
| 1389 | const Size = union(enum) { fixed: u64, scalable: u64 }; | ||
| 1390 | pub fn bits(ty: Type, builder: *const Builder) Size { | ||
| 1391 | const item = builder.type_items.items[@backingInt(ty)]; | ||
| 1392 | return switch (item.tag) { | ||
| 1393 | else => unreachable, | ||
| 1394 | .simple => switch (@as(Simple, @fromBackingInt(@intCast(item.data)))) { | ||
| 1395 | else => unreachable, | ||
| 1396 | .label => .{ .fixed = builder.data_layout.getPointerSpec(.default).bit_width }, | ||
| 1397 | .half, .bfloat => .{ .fixed = 16 }, | ||
| 1398 | .float => .{ .fixed = 32 }, | ||
| 1399 | .double => .{ .fixed = 64 }, | ||
| 1400 | .ppc_fp128, .fp128 => .{ .fixed = 128 }, | ||
| 1401 | .x86_amx => .{ .fixed = 8192 }, | ||
| 1402 | .x86_fp80 => .{ .fixed = 80 }, | ||
| 1403 | }, | ||
| 1404 | .integer => .{ .fixed = item.data }, | ||
| 1405 | .pointer => .{ | ||
| 1406 | .fixed = builder.data_layout.getPointerSpec(@fromBackingInt(@intCast(item.data))).bit_width, | ||
| 1407 | }, | ||
| 1408 | }; | ||
| 1409 | } | ||
| 1410 | |||
| 1411 | pub fn alignment(ty: Type, kind: enum { abi, pref }, builder: *const Builder) Alignment { | ||
| 1412 | const item = builder.type_items.items[@backingInt(ty)]; | ||
| 1413 | switch (item.tag) { | ||
| 1414 | else => unreachable, | ||
| 1415 | .simple => switch (@as(Simple, @fromBackingInt(@intCast(item.data)))) { | ||
| 1416 | else => unreachable, | ||
| 1417 | .label => { | ||
| 1418 | const spec = builder.data_layout.getPointerSpec(.default); | ||
| 1419 | return switch (kind) { | ||
| 1420 | .abi => spec.flags.abi_align, | ||
| 1421 | .pref => spec.flags.pref_align, | ||
| 1422 | }; | ||
| 1423 | }, | ||
| 1424 | .half, .bfloat, .float, .double, .ppc_fp128, .fp128, .x86_fp80 => { | ||
| 1425 | const spec = builder.data_layout.getFloatSpec(@intCast(ty.bits(builder).fixed)); | ||
| 1426 | return switch (kind) { | ||
| 1427 | .abi => spec.abi_align, | ||
| 1428 | .pref => spec.pref_align, | ||
| 1429 | }; | ||
| 1430 | }, | ||
| 1431 | .x86_amx => return comptime .fromByteUnits(64), | ||
| 1432 | }, | ||
| 1433 | .integer => { | ||
| 1434 | const spec = builder.data_layout.getIntegerSpec(@intCast(item.data)); | ||
| 1435 | return switch (kind) { | ||
| 1436 | .abi => spec.abi_align, | ||
| 1437 | .pref => spec.pref_align, | ||
| 1438 | }; | ||
| 1439 | }, | ||
| 1440 | .pointer => { | ||
| 1441 | const spec = builder.data_layout.getPointerSpec(@fromBackingInt(@intCast(item.data))); | ||
| 1442 | return switch (kind) { | ||
| 1443 | .abi => spec.flags.abi_align, | ||
| 1444 | .pref => spec.flags.pref_align, | ||
| 1445 | }; | ||
| 1446 | }, | ||
| 1447 | } | ||
| 1448 | } | ||
| 934 | }; | 1449 | }; |
| 935 | 1450 | ||
| 936 | pub const Attribute = union(Kind) { | 1451 | pub const Attribute = union(Kind) { |
| 937 | // Parameter Attributes | 1452 | // Parameter Attributes |
| 938 | zeroext, | 1453 | zeroext, |
| 939 | signext, | 1454 | signext, |
| 1455 | noext, | ||
| 940 | inreg, | 1456 | inreg, |
| 941 | byval: Type, | 1457 | byval: Type, |
| 942 | byref: Type, | 1458 | byref: Type, |
| ... | @@ -947,6 +1463,7 @@ pub const Attribute = union(Kind) { | ... | @@ -947,6 +1463,7 @@ pub const Attribute = union(Kind) { |
| 947 | @"align": Alignment.Lazy, | 1463 | @"align": Alignment.Lazy, |
| 948 | @"noalias", | 1464 | @"noalias", |
| 949 | nocapture, | 1465 | nocapture, |
| 1466 | captures: Captures, | ||
| 950 | nofree, | 1467 | nofree, |
| 951 | nest, | 1468 | nest, |
| 952 | returned, | 1469 | returned, |
| ... | @@ -965,6 +1482,11 @@ pub const Attribute = union(Kind) { | ... | @@ -965,6 +1482,11 @@ pub const Attribute = union(Kind) { |
| 965 | readnone, | 1482 | readnone, |
| 966 | readonly, | 1483 | readonly, |
| 967 | writeonly, | 1484 | writeonly, |
| 1485 | writable, | ||
| 1486 | initializes: []const [2]u64, | ||
| 1487 | dead_on_unwind, | ||
| 1488 | dead_on_return: ?u32, | ||
| 1489 | range: [2]Constant, | ||
| 968 | 1490 | ||
| 969 | // Function Attributes | 1491 | // Function Attributes |
| 970 | //alignstack: Alignment.Lazy, | 1492 | //alignstack: Alignment.Lazy, |
| ... | @@ -974,7 +1496,7 @@ pub const Attribute = union(Kind) { | ... | @@ -974,7 +1496,7 @@ pub const Attribute = union(Kind) { |
| 974 | builtin, | 1496 | builtin, |
| 975 | cold, | 1497 | cold, |
| 976 | convergent, | 1498 | convergent, |
| 977 | disable_sanitizer_information, | 1499 | disable_sanitizer_instrumentation, |
| 978 | fn_ret_thunk_extern, | 1500 | fn_ret_thunk_extern, |
| 979 | hot, | 1501 | hot, |
| 980 | inlinehint, | 1502 | inlinehint, |
| ... | @@ -984,6 +1506,7 @@ pub const Attribute = union(Kind) { | ... | @@ -984,6 +1506,7 @@ pub const Attribute = union(Kind) { |
| 984 | naked, | 1506 | naked, |
| 985 | nobuiltin, | 1507 | nobuiltin, |
| 986 | nocallback, | 1508 | nocallback, |
| 1509 | nodivergencesource, | ||
| 987 | noduplicate, | 1510 | noduplicate, |
| 988 | //nofree, | 1511 | //nofree, |
| 989 | noimplicitfloat, | 1512 | noimplicitfloat, |
| ... | @@ -1001,6 +1524,7 @@ pub const Attribute = union(Kind) { | ... | @@ -1001,6 +1524,7 @@ pub const Attribute = union(Kind) { |
| 1001 | nosanitize_bounds, | 1524 | nosanitize_bounds, |
| 1002 | nosanitize_coverage, | 1525 | nosanitize_coverage, |
| 1003 | null_pointer_is_valid, | 1526 | null_pointer_is_valid, |
| 1527 | optdebug, | ||
| 1004 | optforfuzzing, | 1528 | optforfuzzing, |
| 1005 | optnone, | 1529 | optnone, |
| 1006 | optsize, | 1530 | optsize, |
| ... | @@ -1012,23 +1536,23 @@ pub const Attribute = union(Kind) { | ... | @@ -1012,23 +1536,23 @@ pub const Attribute = union(Kind) { |
| 1012 | sanitize_thread, | 1536 | sanitize_thread, |
| 1013 | sanitize_hwaddress, | 1537 | sanitize_hwaddress, |
| 1014 | sanitize_memtag, | 1538 | sanitize_memtag, |
| 1539 | sanitize_realtime, | ||
| 1540 | sanitize_realtime_blocking, | ||
| 1541 | sanitize_alloc_token, | ||
| 1015 | speculative_load_hardening, | 1542 | speculative_load_hardening, |
| 1016 | speculatable, | 1543 | speculatable, |
| 1017 | ssp, | 1544 | ssp, |
| 1018 | sspstrong, | 1545 | sspstrong, |
| 1019 | sspreq, | 1546 | sspreq, |
| 1020 | strictfp, | 1547 | strictfp, |
| 1548 | denormal_fpenv, | ||
| 1021 | uwtable: UwTable, | 1549 | uwtable: UwTable, |
| 1022 | nocf_check, | 1550 | nocf_check, |
| 1023 | shadowcallstack, | 1551 | shadowcallstack, |
| 1024 | mustprogress, | 1552 | mustprogress, |
| 1025 | vscale_range: VScaleRange, | 1553 | vscale_range: VScaleRange, |
| 1026 | 1554 | nooutline, | |
| 1027 | // Global Attributes | 1555 | nocreateundeforpoison, |
| 1028 | no_sanitize_address, | ||
| 1029 | no_sanitize_hwaddress, | ||
| 1030 | //sanitize_memtag, | ||
| 1031 | sanitize_address_dyninit, | ||
| 1032 | 1556 | ||
| 1033 | string: struct { kind: String, value: String }, | 1557 | string: struct { kind: String, value: String }, |
| 1034 | none: noreturn, | 1558 | none: noreturn, |
| ... | @@ -1045,100 +1569,11 @@ pub const Attribute = union(Kind) { | ... | @@ -1045,100 +1569,11 @@ pub const Attribute = union(Kind) { |
| 1045 | const storage = self.toStorage(builder); | 1569 | const storage = self.toStorage(builder); |
| 1046 | if (storage.kind.toString()) |kind| return .{ .string = .{ | 1570 | if (storage.kind.toString()) |kind| return .{ .string = .{ |
| 1047 | .kind = kind, | 1571 | .kind = kind, |
| 1048 | .value = @fromBackingInt(@intCast(storage.value)), | 1572 | .value = @fromBackingInt(storage.value), |
| 1049 | } } else return switch (storage.kind) { | 1573 | } } else return switch (storage.kind) { |
| 1050 | inline .zeroext, | 1574 | inline else => |kind| { |
| 1051 | .signext, | ||
| 1052 | .inreg, | ||
| 1053 | .byval, | ||
| 1054 | .byref, | ||
| 1055 | .preallocated, | ||
| 1056 | .inalloca, | ||
| 1057 | .sret, | ||
| 1058 | .elementtype, | ||
| 1059 | .@"align", | ||
| 1060 | .@"noalias", | ||
| 1061 | .nocapture, | ||
| 1062 | .nofree, | ||
| 1063 | .nest, | ||
| 1064 | .returned, | ||
| 1065 | .nonnull, | ||
| 1066 | .dereferenceable, | ||
| 1067 | .dereferenceable_or_null, | ||
| 1068 | .swiftself, | ||
| 1069 | .swiftasync, | ||
| 1070 | .swifterror, | ||
| 1071 | .immarg, | ||
| 1072 | .noundef, | ||
| 1073 | .nofpclass, | ||
| 1074 | .alignstack, | ||
| 1075 | .allocalign, | ||
| 1076 | .allocptr, | ||
| 1077 | .readnone, | ||
| 1078 | .readonly, | ||
| 1079 | .writeonly, | ||
| 1080 | //.alignstack, | ||
| 1081 | .allockind, | ||
| 1082 | .allocsize, | ||
| 1083 | .alwaysinline, | ||
| 1084 | .builtin, | ||
| 1085 | .cold, | ||
| 1086 | .convergent, | ||
| 1087 | .disable_sanitizer_information, | ||
| 1088 | .fn_ret_thunk_extern, | ||
| 1089 | .hot, | ||
| 1090 | .inlinehint, | ||
| 1091 | .jumptable, | ||
| 1092 | .memory, | ||
| 1093 | .minsize, | ||
| 1094 | .naked, | ||
| 1095 | .nobuiltin, | ||
| 1096 | .nocallback, | ||
| 1097 | .noduplicate, | ||
| 1098 | //.nofree, | ||
| 1099 | .noimplicitfloat, | ||
| 1100 | .@"noinline", | ||
| 1101 | .nomerge, | ||
| 1102 | .nonlazybind, | ||
| 1103 | .noprofile, | ||
| 1104 | .skipprofile, | ||
| 1105 | .noredzone, | ||
| 1106 | .noreturn, | ||
| 1107 | .norecurse, | ||
| 1108 | .willreturn, | ||
| 1109 | .nosync, | ||
| 1110 | .nounwind, | ||
| 1111 | .nosanitize_bounds, | ||
| 1112 | .nosanitize_coverage, | ||
| 1113 | .null_pointer_is_valid, | ||
| 1114 | .optforfuzzing, | ||
| 1115 | .optnone, | ||
| 1116 | .optsize, | ||
| 1117 | //.preallocated, | ||
| 1118 | .returns_twice, | ||
| 1119 | .safestack, | ||
| 1120 | .sanitize_address, | ||
| 1121 | .sanitize_memory, | ||
| 1122 | .sanitize_thread, | ||
| 1123 | .sanitize_hwaddress, | ||
| 1124 | .sanitize_memtag, | ||
| 1125 | .speculative_load_hardening, | ||
| 1126 | .speculatable, | ||
| 1127 | .ssp, | ||
| 1128 | .sspstrong, | ||
| 1129 | .sspreq, | ||
| 1130 | .strictfp, | ||
| 1131 | .uwtable, | ||
| 1132 | .nocf_check, | ||
| 1133 | .shadowcallstack, | ||
| 1134 | .mustprogress, | ||
| 1135 | .vscale_range, | ||
| 1136 | .no_sanitize_address, | ||
| 1137 | .no_sanitize_hwaddress, | ||
| 1138 | .sanitize_address_dyninit, | ||
| 1139 | => |kind| { | ||
| 1140 | const field_name, const field_type = comptime blk: { | 1575 | const field_name, const field_type = comptime blk: { |
| 1141 | @setEvalBranchQuota(10_000); | 1576 | @setEvalBranchQuota(12_000); |
| 1142 | const info = @typeInfo(Attribute).@"union"; | 1577 | const info = @typeInfo(Attribute).@"union"; |
| 1143 | for (info.field_names, info.field_types) |field_name, field_type| { | 1578 | for (info.field_names, info.field_types) |field_name, field_type| { |
| 1144 | if (std.mem.eql(u8, field_name, @tagName(kind))) break :blk .{ field_name, field_type }; | 1579 | if (std.mem.eql(u8, field_name, @tagName(kind))) break :blk .{ field_name, field_type }; |
| ... | @@ -1149,14 +1584,17 @@ pub const Attribute = union(Kind) { | ... | @@ -1149,14 +1584,17 @@ pub const Attribute = union(Kind) { |
| 1149 | return @unionInit(Attribute, field_name, switch (field_type) { | 1584 | return @unionInit(Attribute, field_name, switch (field_type) { |
| 1150 | void => {}, | 1585 | void => {}, |
| 1151 | u32 => storage.value, | 1586 | u32 => storage.value, |
| 1152 | Alignment.Lazy, String, Type, UwTable => @fromBackingInt(@intCast(storage.value)), | 1587 | Alignment.Lazy, String, Type, UwTable => @fromBackingInt(storage.value), |
| 1153 | AllocKind, AllocSize, FpClass, Memory, VScaleRange => @bitCast(storage.value), | 1588 | AllocKind, AllocSize, Captures, FpClass, Memory, VScaleRange => @bitCast(storage.value), |
| 1154 | else => @compileError("bad payload type: " ++ field_name ++ ": " ++ | 1589 | else => @compileError("bad payload type: " ++ field_name ++ ": " ++ |
| 1155 | @typeName(field_type)), | 1590 | @typeName(field_type)), |
| 1156 | }); | 1591 | }); |
| 1157 | }, | 1592 | }, |
| 1158 | .string, .none => unreachable, | 1593 | .initializes, |
| 1159 | _ => unreachable, | 1594 | .dead_on_return, |
| 1595 | .range, | ||
| 1596 | => @panic("TODO"), | ||
| 1597 | .string, .none, _ => unreachable, | ||
| 1160 | }; | 1598 | }; |
| 1161 | } | 1599 | } |
| 1162 | 1600 | ||
| ... | @@ -1174,6 +1612,7 @@ pub const Attribute = union(Kind) { | ... | @@ -1174,6 +1612,7 @@ pub const Attribute = union(Kind) { |
| 1174 | switch (attribute) { | 1612 | switch (attribute) { |
| 1175 | .zeroext, | 1613 | .zeroext, |
| 1176 | .signext, | 1614 | .signext, |
| 1615 | .noext, | ||
| 1177 | .inreg, | 1616 | .inreg, |
| 1178 | .@"noalias", | 1617 | .@"noalias", |
| 1179 | .nocapture, | 1618 | .nocapture, |
| ... | @@ -1191,11 +1630,13 @@ pub const Attribute = union(Kind) { | ... | @@ -1191,11 +1630,13 @@ pub const Attribute = union(Kind) { |
| 1191 | .readnone, | 1630 | .readnone, |
| 1192 | .readonly, | 1631 | .readonly, |
| 1193 | .writeonly, | 1632 | .writeonly, |
| 1633 | .writable, | ||
| 1634 | .dead_on_unwind, | ||
| 1194 | .alwaysinline, | 1635 | .alwaysinline, |
| 1195 | .builtin, | 1636 | .builtin, |
| 1196 | .cold, | 1637 | .cold, |
| 1197 | .convergent, | 1638 | .convergent, |
| 1198 | .disable_sanitizer_information, | 1639 | .disable_sanitizer_instrumentation, |
| 1199 | .fn_ret_thunk_extern, | 1640 | .fn_ret_thunk_extern, |
| 1200 | .hot, | 1641 | .hot, |
| 1201 | .inlinehint, | 1642 | .inlinehint, |
| ... | @@ -1204,6 +1645,7 @@ pub const Attribute = union(Kind) { | ... | @@ -1204,6 +1645,7 @@ pub const Attribute = union(Kind) { |
| 1204 | .naked, | 1645 | .naked, |
| 1205 | .nobuiltin, | 1646 | .nobuiltin, |
| 1206 | .nocallback, | 1647 | .nocallback, |
| 1648 | .nodivergencesource, | ||
| 1207 | .noduplicate, | 1649 | .noduplicate, |
| 1208 | .noimplicitfloat, | 1650 | .noimplicitfloat, |
| 1209 | .@"noinline", | 1651 | .@"noinline", |
| ... | @@ -1220,6 +1662,7 @@ pub const Attribute = union(Kind) { | ... | @@ -1220,6 +1662,7 @@ pub const Attribute = union(Kind) { |
| 1220 | .nosanitize_bounds, | 1662 | .nosanitize_bounds, |
| 1221 | .nosanitize_coverage, | 1663 | .nosanitize_coverage, |
| 1222 | .null_pointer_is_valid, | 1664 | .null_pointer_is_valid, |
| 1665 | .optdebug, | ||
| 1223 | .optforfuzzing, | 1666 | .optforfuzzing, |
| 1224 | .optnone, | 1667 | .optnone, |
| 1225 | .optsize, | 1668 | .optsize, |
| ... | @@ -1230,18 +1673,21 @@ pub const Attribute = union(Kind) { | ... | @@ -1230,18 +1673,21 @@ pub const Attribute = union(Kind) { |
| 1230 | .sanitize_thread, | 1673 | .sanitize_thread, |
| 1231 | .sanitize_hwaddress, | 1674 | .sanitize_hwaddress, |
| 1232 | .sanitize_memtag, | 1675 | .sanitize_memtag, |
| 1676 | .sanitize_realtime, | ||
| 1677 | .sanitize_realtime_blocking, | ||
| 1678 | .sanitize_alloc_token, | ||
| 1233 | .speculative_load_hardening, | 1679 | .speculative_load_hardening, |
| 1234 | .speculatable, | 1680 | .speculatable, |
| 1235 | .ssp, | 1681 | .ssp, |
| 1236 | .sspstrong, | 1682 | .sspstrong, |
| 1237 | .sspreq, | 1683 | .sspreq, |
| 1238 | .strictfp, | 1684 | .strictfp, |
| 1685 | .denormal_fpenv, | ||
| 1239 | .nocf_check, | 1686 | .nocf_check, |
| 1240 | .shadowcallstack, | 1687 | .shadowcallstack, |
| 1241 | .mustprogress, | 1688 | .mustprogress, |
| 1242 | .no_sanitize_address, | 1689 | .nooutline, |
| 1243 | .no_sanitize_hwaddress, | 1690 | .nocreateundeforpoison, |
| 1244 | .sanitize_address_dyninit, | ||
| 1245 | => try w.print(" {s}", .{@tagName(attribute)}), | 1691 | => try w.print(" {s}", .{@tagName(attribute)}), |
| 1246 | .byval, | 1692 | .byval, |
| 1247 | .byref, | 1693 | .byref, |
| ... | @@ -1254,6 +1700,45 @@ pub const Attribute = union(Kind) { | ... | @@ -1254,6 +1700,45 @@ pub const Attribute = union(Kind) { |
| 1254 | .dereferenceable, | 1700 | .dereferenceable, |
| 1255 | .dereferenceable_or_null, | 1701 | .dereferenceable_or_null, |
| 1256 | => |size| try w.print(" {s}({d})", .{ @tagName(attribute), size }), | 1702 | => |size| try w.print(" {s}({d})", .{ @tagName(attribute), size }), |
| 1703 | .captures => |captures| { | ||
| 1704 | try w.print(" {s}(", .{@tagName(attribute)}); | ||
| 1705 | var need_comma = false; | ||
| 1706 | if (captures == Captures.none) { | ||
| 1707 | if (need_comma) try w.writeAll(", "); | ||
| 1708 | try w.writeAll("none"); | ||
| 1709 | need_comma = true; | ||
| 1710 | } | ||
| 1711 | inline for (@typeInfo(Captures).@"struct".field_names) |field_name| { | ||
| 1712 | if (comptime std.mem.eql(u8, field_name, "_")) continue; | ||
| 1713 | const components = @field(captures, field_name); | ||
| 1714 | if (components != Captures.Components.none) { | ||
| 1715 | if (!comptime std.mem.eql(u8, field_name, "other")) { | ||
| 1716 | if (need_comma) try w.writeAll(", "); | ||
| 1717 | try w.writeAll(field_name ++ ": "); | ||
| 1718 | need_comma = false; | ||
| 1719 | } | ||
| 1720 | if (components.address) { | ||
| 1721 | if (need_comma) try w.writeAll(", "); | ||
| 1722 | try w.writeAll("address"); | ||
| 1723 | need_comma = true; | ||
| 1724 | } else if (components.address_is_null) { | ||
| 1725 | if (need_comma) try w.writeAll(", "); | ||
| 1726 | try w.writeAll("address_is_null"); | ||
| 1727 | need_comma = true; | ||
| 1728 | } | ||
| 1729 | if (components.provenance) { | ||
| 1730 | if (need_comma) try w.writeAll(", "); | ||
| 1731 | try w.writeAll("provenance"); | ||
| 1732 | need_comma = true; | ||
| 1733 | } else if (components.read_provenance) { | ||
| 1734 | if (need_comma) try w.writeAll(", "); | ||
| 1735 | try w.writeAll("read_provenance"); | ||
| 1736 | need_comma = true; | ||
| 1737 | } | ||
| 1738 | } | ||
| 1739 | } | ||
| 1740 | try w.writeByte(')'); | ||
| 1741 | }, | ||
| 1257 | .nofpclass => |fpclass| { | 1742 | .nofpclass => |fpclass| { |
| 1258 | const Int = @typeInfo(FpClass).@"struct".backing_integer.?; | 1743 | const Int = @typeInfo(FpClass).@"struct".backing_integer.?; |
| 1259 | try w.print(" {s}(", .{@tagName(attribute)}); | 1744 | try w.print(" {s}(", .{@tagName(attribute)}); |
| ... | @@ -1281,6 +1766,9 @@ pub const Attribute = union(Kind) { | ... | @@ -1281,6 +1766,9 @@ pub const Attribute = union(Kind) { |
| 1281 | try w.print("({d})", .{alignment_bytes}); | 1766 | try w.print("({d})", .{alignment_bytes}); |
| 1282 | } | 1767 | } |
| 1283 | }, | 1768 | }, |
| 1769 | .initializes => @panic("TODO"), | ||
| 1770 | .dead_on_return => @panic("TODO"), | ||
| 1771 | .range => @panic("TODO"), | ||
| 1284 | .allockind => |allockind| { | 1772 | .allockind => |allockind| { |
| 1285 | try w.print(" {t}(\"", .{attribute}); | 1773 | try w.print(" {t}(\"", .{attribute}); |
| 1286 | var any = false; | 1774 | var any = false; |
| ... | @@ -1344,100 +1832,109 @@ pub const Attribute = union(Kind) { | ... | @@ -1344,100 +1832,109 @@ pub const Attribute = union(Kind) { |
| 1344 | 1832 | ||
| 1345 | pub const Kind = enum(u32) { | 1833 | pub const Kind = enum(u32) { |
| 1346 | // Parameter Attributes | 1834 | // Parameter Attributes |
| 1347 | zeroext = 34, | 1835 | zeroext = @backingInt(ATTR_KIND.Z_EXT), |
| 1348 | signext = 24, | 1836 | signext = @backingInt(ATTR_KIND.S_EXT), |
| 1349 | inreg = 5, | 1837 | noext = @backingInt(ATTR_KIND.NO_EXT), |
| 1350 | byval = 3, | 1838 | inreg = @backingInt(ATTR_KIND.IN_REG), |
| 1351 | byref = 69, | 1839 | byval = @backingInt(ATTR_KIND.BY_VAL), |
| 1352 | preallocated = 65, | 1840 | byref = @backingInt(ATTR_KIND.BYREF), |
| 1353 | inalloca = 38, | 1841 | preallocated = @backingInt(ATTR_KIND.PREALLOCATED), |
| 1354 | sret = 29, // TODO: ? | 1842 | inalloca = @backingInt(ATTR_KIND.IN_ALLOCA), |
| 1355 | elementtype = 77, | 1843 | sret = @backingInt(ATTR_KIND.STRUCT_RET), |
| 1356 | @"align" = 1, | 1844 | elementtype = @backingInt(ATTR_KIND.ELEMENTTYPE), |
| 1357 | @"noalias" = 9, | 1845 | @"align" = @backingInt(ATTR_KIND.ALIGNMENT), |
| 1358 | nocapture = 11, | 1846 | @"noalias" = @backingInt(ATTR_KIND.NO_ALIAS), |
| 1359 | nofree = 62, | 1847 | nocapture = @backingInt(ATTR_KIND.NO_CAPTURE), |
| 1360 | nest = 8, | 1848 | captures = @backingInt(ATTR_KIND.CAPTURES), |
| 1361 | returned = 22, | 1849 | nofree = @backingInt(ATTR_KIND.NOFREE), |
| 1362 | nonnull = 39, | 1850 | nest = @backingInt(ATTR_KIND.NEST), |
| 1363 | dereferenceable = 41, | 1851 | returned = @backingInt(ATTR_KIND.RETURNED), |
| 1364 | dereferenceable_or_null = 42, | 1852 | nonnull = @backingInt(ATTR_KIND.NON_NULL), |
| 1365 | swiftself = 46, | 1853 | dereferenceable = @backingInt(ATTR_KIND.DEREFERENCEABLE), |
| 1366 | swiftasync = 75, | 1854 | dereferenceable_or_null = @backingInt(ATTR_KIND.DEREFERENCEABLE_OR_NULL), |
| 1367 | swifterror = 47, | 1855 | swiftself = @backingInt(ATTR_KIND.SWIFT_SELF), |
| 1368 | immarg = 60, | 1856 | swiftasync = @backingInt(ATTR_KIND.SWIFT_ASYNC), |
| 1369 | noundef = 68, | 1857 | swifterror = @backingInt(ATTR_KIND.SWIFT_ERROR), |
| 1370 | nofpclass = 87, | 1858 | immarg = @backingInt(ATTR_KIND.IMMARG), |
| 1371 | alignstack = 25, | 1859 | noundef = @backingInt(ATTR_KIND.NOUNDEF), |
| 1372 | allocalign = 80, | 1860 | nofpclass = @backingInt(ATTR_KIND.NOFPCLASS), |
| 1373 | allocptr = 81, | 1861 | alignstack = @backingInt(ATTR_KIND.STACK_ALIGNMENT), |
| 1374 | readnone = 20, | 1862 | allocalign = @backingInt(ATTR_KIND.ALLOC_ALIGN), |
| 1375 | readonly = 21, | 1863 | allocptr = @backingInt(ATTR_KIND.ALLOCATED_POINTER), |
| 1376 | writeonly = 52, | 1864 | readnone = @backingInt(ATTR_KIND.READ_NONE), |
| 1865 | readonly = @backingInt(ATTR_KIND.READ_ONLY), | ||
| 1866 | writeonly = @backingInt(ATTR_KIND.WRITEONLY), | ||
| 1867 | writable = @backingInt(ATTR_KIND.WRITABLE), | ||
| 1868 | initializes = @backingInt(ATTR_KIND.INITIALIZES), | ||
| 1869 | dead_on_unwind = @backingInt(ATTR_KIND.DEAD_ON_UNWIND), | ||
| 1870 | dead_on_return = @backingInt(ATTR_KIND.DEAD_ON_RETURN), | ||
| 1871 | range = @backingInt(ATTR_KIND.RANGE), | ||
| 1377 | 1872 | ||
| 1378 | // Function Attributes | 1873 | // Function Attributes |
| 1379 | //alignstack, | 1874 | //alignstack = @intFromEnum(ATTR_KIND.STACK_ALIGNMENT), |
| 1380 | allockind = 82, | 1875 | allockind = @backingInt(ATTR_KIND.ALLOC_KIND), |
| 1381 | allocsize = 51, | 1876 | allocsize = @backingInt(ATTR_KIND.ALLOC_SIZE), |
| 1382 | alwaysinline = 2, | 1877 | alwaysinline = @backingInt(ATTR_KIND.ALWAYS_INLINE), |
| 1383 | builtin = 35, | 1878 | builtin = @backingInt(ATTR_KIND.BUILTIN), |
| 1384 | cold = 36, | 1879 | cold = @backingInt(ATTR_KIND.COLD), |
| 1385 | convergent = 43, | 1880 | convergent = @backingInt(ATTR_KIND.CONVERGENT), |
| 1386 | disable_sanitizer_information = 78, | 1881 | disable_sanitizer_instrumentation = @backingInt(ATTR_KIND.DISABLE_SANITIZER_INSTRUMENTATION), |
| 1387 | fn_ret_thunk_extern = 84, | 1882 | fn_ret_thunk_extern = @backingInt(ATTR_KIND.FNRETTHUNK_EXTERN), |
| 1388 | hot = 72, | 1883 | hot = @backingInt(ATTR_KIND.HOT), |
| 1389 | inlinehint = 4, | 1884 | inlinehint = @backingInt(ATTR_KIND.INLINE_HINT), |
| 1390 | jumptable = 40, | 1885 | jumptable = @backingInt(ATTR_KIND.JUMP_TABLE), |
| 1391 | memory = 86, | 1886 | memory = @backingInt(ATTR_KIND.MEMORY), |
| 1392 | minsize = 6, | 1887 | minsize = @backingInt(ATTR_KIND.MIN_SIZE), |
| 1393 | naked = 7, | 1888 | naked = @backingInt(ATTR_KIND.NAKED), |
| 1394 | nobuiltin = 10, | 1889 | nobuiltin = @backingInt(ATTR_KIND.NO_BUILTIN), |
| 1395 | nocallback = 71, | 1890 | nocallback = @backingInt(ATTR_KIND.NO_CALLBACK), |
| 1396 | noduplicate = 12, | 1891 | nodivergencesource = @backingInt(ATTR_KIND.NO_DIVERGENCE_SOURCE), |
| 1397 | //nofree, | 1892 | noduplicate = @backingInt(ATTR_KIND.NO_DUPLICATE), |
| 1398 | noimplicitfloat = 13, | 1893 | //nofree = @intFromEnum(ATTR_KIND.NOFREE), |
| 1399 | @"noinline" = 14, | 1894 | noimplicitfloat = @backingInt(ATTR_KIND.NO_IMPLICIT_FLOAT), |
| 1400 | nomerge = 66, | 1895 | @"noinline" = @backingInt(ATTR_KIND.NO_INLINE), |
| 1401 | nonlazybind = 15, | 1896 | nomerge = @backingInt(ATTR_KIND.NO_MERGE), |
| 1402 | noprofile = 73, | 1897 | nonlazybind = @backingInt(ATTR_KIND.NON_LAZY_BIND), |
| 1403 | skipprofile = 85, | 1898 | noprofile = @backingInt(ATTR_KIND.NO_PROFILE), |
| 1404 | noredzone = 16, | 1899 | skipprofile = @backingInt(ATTR_KIND.SKIP_PROFILE), |
| 1405 | noreturn = 17, | 1900 | noredzone = @backingInt(ATTR_KIND.NO_RED_ZONE), |
| 1406 | norecurse = 48, | 1901 | noreturn = @backingInt(ATTR_KIND.NO_RETURN), |
| 1407 | willreturn = 61, | 1902 | norecurse = @backingInt(ATTR_KIND.NO_RECURSE), |
| 1408 | nosync = 63, | 1903 | willreturn = @backingInt(ATTR_KIND.WILLRETURN), |
| 1409 | nounwind = 18, | 1904 | nosync = @backingInt(ATTR_KIND.NOSYNC), |
| 1410 | nosanitize_bounds = 79, | 1905 | nounwind = @backingInt(ATTR_KIND.NO_UNWIND), |
| 1411 | nosanitize_coverage = 76, | 1906 | nosanitize_bounds = @backingInt(ATTR_KIND.NO_SANITIZE_BOUNDS), |
| 1412 | null_pointer_is_valid = 67, | 1907 | nosanitize_coverage = @backingInt(ATTR_KIND.NO_SANITIZE_COVERAGE), |
| 1413 | optforfuzzing = 57, | 1908 | null_pointer_is_valid = @backingInt(ATTR_KIND.NULL_POINTER_IS_VALID), |
| 1414 | optnone = 37, | 1909 | optdebug = @backingInt(ATTR_KIND.OPTIMIZE_FOR_DEBUGGING), |
| 1415 | optsize = 19, | 1910 | optforfuzzing = @backingInt(ATTR_KIND.OPT_FOR_FUZZING), |
| 1416 | //preallocated, | 1911 | optnone = @backingInt(ATTR_KIND.OPTIMIZE_NONE), |
| 1417 | returns_twice = 23, | 1912 | optsize = @backingInt(ATTR_KIND.OPTIMIZE_FOR_SIZE), |
| 1418 | safestack = 44, | 1913 | //preallocated = @intFromEnum(ATTR_KIND.PREALLOCATED), |
| 1419 | sanitize_address = 30, | 1914 | returns_twice = @backingInt(ATTR_KIND.RETURNS_TWICE), |
| 1420 | sanitize_memory = 32, | 1915 | safestack = @backingInt(ATTR_KIND.SAFESTACK), |
| 1421 | sanitize_thread = 31, | 1916 | sanitize_address = @backingInt(ATTR_KIND.SANITIZE_ADDRESS), |
| 1422 | sanitize_hwaddress = 55, | 1917 | sanitize_memory = @backingInt(ATTR_KIND.SANITIZE_MEMORY), |
| 1423 | sanitize_memtag = 64, | 1918 | sanitize_thread = @backingInt(ATTR_KIND.SANITIZE_THREAD), |
| 1424 | speculative_load_hardening = 59, | 1919 | sanitize_hwaddress = @backingInt(ATTR_KIND.SANITIZE_HWADDRESS), |
| 1425 | speculatable = 53, | 1920 | sanitize_memtag = @backingInt(ATTR_KIND.SANITIZE_MEMTAG), |
| 1426 | ssp = 26, | 1921 | sanitize_realtime = @backingInt(ATTR_KIND.SANITIZE_REALTIME), |
| 1427 | sspstrong = 28, | 1922 | sanitize_realtime_blocking = @backingInt(ATTR_KIND.SANITIZE_REALTIME_BLOCKING), |
| 1428 | sspreq = 27, | 1923 | sanitize_alloc_token = @backingInt(ATTR_KIND.SANITIZE_ALLOC_TOKEN), |
| 1429 | strictfp = 54, | 1924 | speculative_load_hardening = @backingInt(ATTR_KIND.SPECULATIVE_LOAD_HARDENING), |
| 1430 | uwtable = 33, | 1925 | speculatable = @backingInt(ATTR_KIND.SPECULATABLE), |
| 1431 | nocf_check = 56, | 1926 | ssp = @backingInt(ATTR_KIND.STACK_PROTECT), |
| 1432 | shadowcallstack = 58, | 1927 | sspstrong = @backingInt(ATTR_KIND.STACK_PROTECT_STRONG), |
| 1433 | mustprogress = 70, | 1928 | sspreq = @backingInt(ATTR_KIND.STACK_PROTECT_REQ), |
| 1434 | vscale_range = 74, | 1929 | strictfp = @backingInt(ATTR_KIND.STRICT_FP), |
| 1435 | 1930 | denormal_fpenv = @backingInt(ATTR_KIND.DENORMAL_FPENV), | |
| 1436 | // Global Attributes | 1931 | uwtable = @backingInt(ATTR_KIND.UW_TABLE), |
| 1437 | no_sanitize_address = 100, | 1932 | nocf_check = @backingInt(ATTR_KIND.NOCF_CHECK), |
| 1438 | no_sanitize_hwaddress = 101, | 1933 | shadowcallstack = @backingInt(ATTR_KIND.SHADOWCALLSTACK), |
| 1439 | //sanitize_memtag, | 1934 | mustprogress = @backingInt(ATTR_KIND.MUSTPROGRESS), |
| 1440 | sanitize_address_dyninit = 102, | 1935 | vscale_range = @backingInt(ATTR_KIND.VSCALE_RANGE), |
| 1936 | nooutline = @backingInt(ATTR_KIND.NOOUTLINE), | ||
| 1937 | nocreateundeforpoison = @backingInt(ATTR_KIND.NO_CREATE_UNDEF_OR_POISON), | ||
| 1441 | 1938 | ||
| 1442 | string = maxInt(u31), | 1939 | string = maxInt(u31), |
| 1443 | none = maxInt(u32), | 1940 | none = maxInt(u32), |
| ... | @@ -1447,16 +1944,128 @@ pub const Attribute = union(Kind) { | ... | @@ -1447,16 +1944,128 @@ pub const Attribute = union(Kind) { |
| 1447 | 1944 | ||
| 1448 | pub fn fromString(str: String) Kind { | 1945 | pub fn fromString(str: String) Kind { |
| 1449 | assert(!str.isAnon()); | 1946 | assert(!str.isAnon()); |
| 1450 | const kind: Kind = @fromBackingInt(@intCast(@backingInt(str))); | 1947 | const kind: Kind = @fromBackingInt(@backingInt(str)); |
| 1451 | assert(kind != .none); | 1948 | assert(kind != .none); |
| 1452 | return kind; | 1949 | return kind; |
| 1453 | } | 1950 | } |
| 1454 | 1951 | ||
| 1455 | fn toString(self: Kind) ?String { | 1952 | fn toString(self: Kind) ?String { |
| 1456 | assert(self != .none); | 1953 | assert(self != .none); |
| 1457 | const str: String = @fromBackingInt(@intCast(@backingInt(self))); | 1954 | const str: String = @fromBackingInt(@backingInt(self)); |
| 1458 | return if (str.isAnon()) null else str; | 1955 | return if (str.isAnon()) null else str; |
| 1459 | } | 1956 | } |
| 1957 | |||
| 1958 | /// enum AttributeKindCodes | ||
| 1959 | const ATTR_KIND = enum(u32) { | ||
| 1960 | ALIGNMENT = 1, | ||
| 1961 | ALWAYS_INLINE = 2, | ||
| 1962 | BY_VAL = 3, | ||
| 1963 | INLINE_HINT = 4, | ||
| 1964 | IN_REG = 5, | ||
| 1965 | MIN_SIZE = 6, | ||
| 1966 | NAKED = 7, | ||
| 1967 | NEST = 8, | ||
| 1968 | NO_ALIAS = 9, | ||
| 1969 | NO_BUILTIN = 10, | ||
| 1970 | NO_CAPTURE = 11, | ||
| 1971 | NO_DUPLICATE = 12, | ||
| 1972 | NO_IMPLICIT_FLOAT = 13, | ||
| 1973 | NO_INLINE = 14, | ||
| 1974 | NON_LAZY_BIND = 15, | ||
| 1975 | NO_RED_ZONE = 16, | ||
| 1976 | NO_RETURN = 17, | ||
| 1977 | NO_UNWIND = 18, | ||
| 1978 | OPTIMIZE_FOR_SIZE = 19, | ||
| 1979 | READ_NONE = 20, | ||
| 1980 | READ_ONLY = 21, | ||
| 1981 | RETURNED = 22, | ||
| 1982 | RETURNS_TWICE = 23, | ||
| 1983 | S_EXT = 24, | ||
| 1984 | STACK_ALIGNMENT = 25, | ||
| 1985 | STACK_PROTECT = 26, | ||
| 1986 | STACK_PROTECT_REQ = 27, | ||
| 1987 | STACK_PROTECT_STRONG = 28, | ||
| 1988 | STRUCT_RET = 29, | ||
| 1989 | SANITIZE_ADDRESS = 30, | ||
| 1990 | SANITIZE_THREAD = 31, | ||
| 1991 | SANITIZE_MEMORY = 32, | ||
| 1992 | UW_TABLE = 33, | ||
| 1993 | Z_EXT = 34, | ||
| 1994 | BUILTIN = 35, | ||
| 1995 | COLD = 36, | ||
| 1996 | OPTIMIZE_NONE = 37, | ||
| 1997 | IN_ALLOCA = 38, | ||
| 1998 | NON_NULL = 39, | ||
| 1999 | JUMP_TABLE = 40, | ||
| 2000 | DEREFERENCEABLE = 41, | ||
| 2001 | DEREFERENCEABLE_OR_NULL = 42, | ||
| 2002 | CONVERGENT = 43, | ||
| 2003 | SAFESTACK = 44, | ||
| 2004 | ARGMEMONLY = 45, | ||
| 2005 | SWIFT_SELF = 46, | ||
| 2006 | SWIFT_ERROR = 47, | ||
| 2007 | NO_RECURSE = 48, | ||
| 2008 | INACCESSIBLEMEM_ONLY = 49, | ||
| 2009 | INACCESSIBLEMEM_OR_ARGMEMONLY = 50, | ||
| 2010 | ALLOC_SIZE = 51, | ||
| 2011 | WRITEONLY = 52, | ||
| 2012 | SPECULATABLE = 53, | ||
| 2013 | STRICT_FP = 54, | ||
| 2014 | SANITIZE_HWADDRESS = 55, | ||
| 2015 | NOCF_CHECK = 56, | ||
| 2016 | OPT_FOR_FUZZING = 57, | ||
| 2017 | SHADOWCALLSTACK = 58, | ||
| 2018 | SPECULATIVE_LOAD_HARDENING = 59, | ||
| 2019 | IMMARG = 60, | ||
| 2020 | WILLRETURN = 61, | ||
| 2021 | NOFREE = 62, | ||
| 2022 | NOSYNC = 63, | ||
| 2023 | SANITIZE_MEMTAG = 64, | ||
| 2024 | PREALLOCATED = 65, | ||
| 2025 | NO_MERGE = 66, | ||
| 2026 | NULL_POINTER_IS_VALID = 67, | ||
| 2027 | NOUNDEF = 68, | ||
| 2028 | BYREF = 69, | ||
| 2029 | MUSTPROGRESS = 70, | ||
| 2030 | NO_CALLBACK = 71, | ||
| 2031 | HOT = 72, | ||
| 2032 | NO_PROFILE = 73, | ||
| 2033 | VSCALE_RANGE = 74, | ||
| 2034 | SWIFT_ASYNC = 75, | ||
| 2035 | NO_SANITIZE_COVERAGE = 76, | ||
| 2036 | ELEMENTTYPE = 77, | ||
| 2037 | DISABLE_SANITIZER_INSTRUMENTATION = 78, | ||
| 2038 | NO_SANITIZE_BOUNDS = 79, | ||
| 2039 | ALLOC_ALIGN = 80, | ||
| 2040 | ALLOCATED_POINTER = 81, | ||
| 2041 | ALLOC_KIND = 82, | ||
| 2042 | PRESPLIT_COROUTINE = 83, | ||
| 2043 | FNRETTHUNK_EXTERN = 84, | ||
| 2044 | SKIP_PROFILE = 85, | ||
| 2045 | MEMORY = 86, | ||
| 2046 | NOFPCLASS = 87, | ||
| 2047 | OPTIMIZE_FOR_DEBUGGING = 88, | ||
| 2048 | WRITABLE = 89, | ||
| 2049 | CORO_ONLY_DESTROY_WHEN_COMPLETE = 90, | ||
| 2050 | DEAD_ON_UNWIND = 91, | ||
| 2051 | RANGE = 92, | ||
| 2052 | SANITIZE_NUMERICAL_STABILITY = 93, | ||
| 2053 | INITIALIZES = 94, | ||
| 2054 | HYBRID_PATCHABLE = 95, | ||
| 2055 | SANITIZE_REALTIME = 96, | ||
| 2056 | SANITIZE_REALTIME_BLOCKING = 97, | ||
| 2057 | CORO_ELIDE_SAFE = 98, | ||
| 2058 | NO_EXT = 99, | ||
| 2059 | NO_DIVERGENCE_SOURCE = 100, | ||
| 2060 | SANITIZE_TYPE = 101, | ||
| 2061 | CAPTURES = 102, | ||
| 2062 | DEAD_ON_RETURN = 103, | ||
| 2063 | SANITIZE_ALLOC_TOKEN = 104, | ||
| 2064 | NO_CREATE_UNDEF_OR_POISON = 105, | ||
| 2065 | DENORMAL_FPENV = 106, | ||
| 2066 | NOOUTLINE = 107, | ||
| 2067 | FLATTEN = 108, | ||
| 2068 | }; | ||
| 1460 | }; | 2069 | }; |
| 1461 | 2070 | ||
| 1462 | pub const FpClass = packed struct(u32) { | 2071 | pub const FpClass = packed struct(u32) { |
| ... | @@ -1506,6 +2115,29 @@ pub const Attribute = union(Kind) { | ... | @@ -1506,6 +2115,29 @@ pub const Attribute = union(Kind) { |
| 1506 | pub const pnorm = FpClass{ .positive_normal = true }; | 2115 | pub const pnorm = FpClass{ .positive_normal = true }; |
| 1507 | }; | 2116 | }; |
| 1508 | 2117 | ||
| 2118 | pub const Captures = packed struct(u32) { | ||
| 2119 | other: Components = .none, | ||
| 2120 | ret: Components = .none, | ||
| 2121 | _: u24 = 0, | ||
| 2122 | |||
| 2123 | pub const none: Captures = .{}; | ||
| 2124 | |||
| 2125 | pub const Components = packed struct(u4) { | ||
| 2126 | address_is_null: bool = false, | ||
| 2127 | address: bool = false, | ||
| 2128 | read_provenance: bool = false, | ||
| 2129 | provenance: bool = false, | ||
| 2130 | |||
| 2131 | pub const none: Components = .{}; | ||
| 2132 | pub const all: Components = .{ | ||
| 2133 | .address_is_null = true, | ||
| 2134 | .address = true, | ||
| 2135 | .read_provenance = true, | ||
| 2136 | .provenance = true, | ||
| 2137 | }; | ||
| 2138 | }; | ||
| 2139 | }; | ||
| 2140 | |||
| 1509 | pub const AllocKind = packed struct(u32) { | 2141 | pub const AllocKind = packed struct(u32) { |
| 1510 | alloc: bool, | 2142 | alloc: bool, |
| 1511 | realloc: bool, | 2143 | realloc: bool, |
| ... | @@ -1582,9 +2214,13 @@ pub const Attribute = union(Kind) { | ... | @@ -1582,9 +2214,13 @@ pub const Attribute = union(Kind) { |
| 1582 | void => 0, | 2214 | void => 0, |
| 1583 | u32 => value, | 2215 | u32 => value, |
| 1584 | Alignment.Lazy, String, Type, UwTable => @backingInt(value), | 2216 | Alignment.Lazy, String, Type, UwTable => @backingInt(value), |
| 1585 | AllocKind, AllocSize, FpClass, Memory, VScaleRange => @bitCast(value), | 2217 | AllocKind, AllocSize, Captures, FpClass, Memory, VScaleRange => @bitCast(value), |
| 1586 | else => @compileError("bad payload type: " ++ @tagName(tag) ++ @typeName(@TypeOf(value))), | 2218 | else => @compileError("bad payload type: " ++ @tagName(tag) ++ ": " ++ @typeName(@TypeOf(value))), |
| 1587 | } }, | 2219 | } }, |
| 2220 | .initializes, | ||
| 2221 | .dead_on_return, | ||
| 2222 | .range, | ||
| 2223 | => @panic("TODO"), | ||
| 1588 | .string => |string_attr| .{ | 2224 | .string => |string_attr| .{ |
| 1589 | .kind = Kind.fromString(string_attr.kind), | 2225 | .kind = Kind.fromString(string_attr.kind), |
| 1590 | .value = @backingInt(string_attr.value), | 2226 | .value = @backingInt(string_attr.value), |
| ... | @@ -1907,87 +2543,87 @@ pub const AddrSpace = enum(u24) { | ... | @@ -1907,87 +2543,87 @@ pub const AddrSpace = enum(u24) { |
| 1907 | 2543 | ||
| 1908 | // See llvm/lib/Target/X86/X86.h | 2544 | // See llvm/lib/Target/X86/X86.h |
| 1909 | pub const x86 = struct { | 2545 | pub const x86 = struct { |
| 1910 | pub const gs: AddrSpace = @fromBackingInt(@intCast(256)); | 2546 | pub const gs: AddrSpace = @fromBackingInt(256); |
| 1911 | pub const fs: AddrSpace = @fromBackingInt(@intCast(257)); | 2547 | pub const fs: AddrSpace = @fromBackingInt(257); |
| 1912 | pub const ss: AddrSpace = @fromBackingInt(@intCast(258)); | 2548 | pub const ss: AddrSpace = @fromBackingInt(258); |
| 1913 | 2549 | ||
| 1914 | pub const ptr32_sptr: AddrSpace = @fromBackingInt(@intCast(270)); | 2550 | pub const ptr32_sptr: AddrSpace = @fromBackingInt(270); |
| 1915 | pub const ptr32_uptr: AddrSpace = @fromBackingInt(@intCast(271)); | 2551 | pub const ptr32_uptr: AddrSpace = @fromBackingInt(271); |
| 1916 | pub const ptr64: AddrSpace = @fromBackingInt(@intCast(272)); | 2552 | pub const ptr64: AddrSpace = @fromBackingInt(272); |
| 1917 | }; | 2553 | }; |
| 1918 | pub const x86_64 = x86; | 2554 | pub const x86_64 = x86; |
| 1919 | 2555 | ||
| 1920 | // See llvm/lib/Target/AVR/AVR.h | 2556 | // See llvm/lib/Target/AVR/AVR.h |
| 1921 | pub const avr = struct { | 2557 | pub const avr = struct { |
| 1922 | pub const data: AddrSpace = @fromBackingInt(@intCast(0)); | 2558 | pub const data: AddrSpace = @fromBackingInt(0); |
| 1923 | pub const program: AddrSpace = @fromBackingInt(@intCast(1)); | 2559 | pub const program: AddrSpace = @fromBackingInt(1); |
| 1924 | pub const program1: AddrSpace = @fromBackingInt(@intCast(2)); | 2560 | pub const program1: AddrSpace = @fromBackingInt(2); |
| 1925 | pub const program2: AddrSpace = @fromBackingInt(@intCast(3)); | 2561 | pub const program2: AddrSpace = @fromBackingInt(3); |
| 1926 | pub const program3: AddrSpace = @fromBackingInt(@intCast(4)); | 2562 | pub const program3: AddrSpace = @fromBackingInt(4); |
| 1927 | pub const program4: AddrSpace = @fromBackingInt(@intCast(5)); | 2563 | pub const program4: AddrSpace = @fromBackingInt(5); |
| 1928 | pub const program5: AddrSpace = @fromBackingInt(@intCast(6)); | 2564 | pub const program5: AddrSpace = @fromBackingInt(6); |
| 1929 | }; | 2565 | }; |
| 1930 | 2566 | ||
| 1931 | // See llvm/lib/Target/NVPTX/NVPTX.h | 2567 | // See llvm/lib/Target/NVPTX/NVPTX.h |
| 1932 | pub const nvptx = struct { | 2568 | pub const nvptx = struct { |
| 1933 | pub const generic: AddrSpace = @fromBackingInt(@intCast(0)); | 2569 | pub const generic: AddrSpace = @fromBackingInt(0); |
| 1934 | pub const global: AddrSpace = @fromBackingInt(@intCast(1)); | 2570 | pub const global: AddrSpace = @fromBackingInt(1); |
| 1935 | pub const constant: AddrSpace = @fromBackingInt(@intCast(2)); | 2571 | pub const constant: AddrSpace = @fromBackingInt(2); |
| 1936 | pub const shared: AddrSpace = @fromBackingInt(@intCast(3)); | 2572 | pub const shared: AddrSpace = @fromBackingInt(3); |
| 1937 | pub const param: AddrSpace = @fromBackingInt(@intCast(4)); | 2573 | pub const param: AddrSpace = @fromBackingInt(4); |
| 1938 | pub const local: AddrSpace = @fromBackingInt(@intCast(5)); | 2574 | pub const local: AddrSpace = @fromBackingInt(5); |
| 1939 | }; | 2575 | }; |
| 1940 | 2576 | ||
| 1941 | // See llvm/lib/Target/AMDGPU/AMDGPU.h | 2577 | // See llvm/lib/Target/AMDGPU/AMDGPU.h |
| 1942 | pub const amdgpu = struct { | 2578 | pub const amdgpu = struct { |
| 1943 | pub const flat: AddrSpace = @fromBackingInt(@intCast(0)); | 2579 | pub const flat: AddrSpace = @fromBackingInt(0); |
| 1944 | pub const global: AddrSpace = @fromBackingInt(@intCast(1)); | 2580 | pub const global: AddrSpace = @fromBackingInt(1); |
| 1945 | pub const region: AddrSpace = @fromBackingInt(@intCast(2)); | 2581 | pub const region: AddrSpace = @fromBackingInt(2); |
| 1946 | pub const local: AddrSpace = @fromBackingInt(@intCast(3)); | 2582 | pub const local: AddrSpace = @fromBackingInt(3); |
| 1947 | pub const constant: AddrSpace = @fromBackingInt(@intCast(4)); | 2583 | pub const constant: AddrSpace = @fromBackingInt(4); |
| 1948 | pub const private: AddrSpace = @fromBackingInt(@intCast(5)); | 2584 | pub const private: AddrSpace = @fromBackingInt(5); |
| 1949 | pub const constant_32bit: AddrSpace = @fromBackingInt(@intCast(6)); | 2585 | pub const constant_32bit: AddrSpace = @fromBackingInt(6); |
| 1950 | pub const buffer_fat_pointer: AddrSpace = @fromBackingInt(@intCast(7)); | 2586 | pub const buffer_fat_pointer: AddrSpace = @fromBackingInt(7); |
| 1951 | pub const buffer_resource: AddrSpace = @fromBackingInt(@intCast(8)); | 2587 | pub const buffer_resource: AddrSpace = @fromBackingInt(8); |
| 1952 | pub const buffer_strided_pointer: AddrSpace = @fromBackingInt(@intCast(9)); | 2588 | pub const buffer_strided_pointer: AddrSpace = @fromBackingInt(9); |
| 1953 | pub const param_d: AddrSpace = @fromBackingInt(@intCast(6)); | 2589 | pub const param_d: AddrSpace = @fromBackingInt(6); |
| 1954 | pub const param_i: AddrSpace = @fromBackingInt(@intCast(7)); | 2590 | pub const param_i: AddrSpace = @fromBackingInt(7); |
| 1955 | pub const constant_buffer_0: AddrSpace = @fromBackingInt(@intCast(8)); | 2591 | pub const constant_buffer_0: AddrSpace = @fromBackingInt(8); |
| 1956 | pub const constant_buffer_1: AddrSpace = @fromBackingInt(@intCast(9)); | 2592 | pub const constant_buffer_1: AddrSpace = @fromBackingInt(9); |
| 1957 | pub const constant_buffer_2: AddrSpace = @fromBackingInt(@intCast(10)); | 2593 | pub const constant_buffer_2: AddrSpace = @fromBackingInt(10); |
| 1958 | pub const constant_buffer_3: AddrSpace = @fromBackingInt(@intCast(11)); | 2594 | pub const constant_buffer_3: AddrSpace = @fromBackingInt(11); |
| 1959 | pub const constant_buffer_4: AddrSpace = @fromBackingInt(@intCast(12)); | 2595 | pub const constant_buffer_4: AddrSpace = @fromBackingInt(12); |
| 1960 | pub const constant_buffer_5: AddrSpace = @fromBackingInt(@intCast(13)); | 2596 | pub const constant_buffer_5: AddrSpace = @fromBackingInt(13); |
| 1961 | pub const constant_buffer_6: AddrSpace = @fromBackingInt(@intCast(14)); | 2597 | pub const constant_buffer_6: AddrSpace = @fromBackingInt(14); |
| 1962 | pub const constant_buffer_7: AddrSpace = @fromBackingInt(@intCast(15)); | 2598 | pub const constant_buffer_7: AddrSpace = @fromBackingInt(15); |
| 1963 | pub const constant_buffer_8: AddrSpace = @fromBackingInt(@intCast(16)); | 2599 | pub const constant_buffer_8: AddrSpace = @fromBackingInt(16); |
| 1964 | pub const constant_buffer_9: AddrSpace = @fromBackingInt(@intCast(17)); | 2600 | pub const constant_buffer_9: AddrSpace = @fromBackingInt(17); |
| 1965 | pub const constant_buffer_10: AddrSpace = @fromBackingInt(@intCast(18)); | 2601 | pub const constant_buffer_10: AddrSpace = @fromBackingInt(18); |
| 1966 | pub const constant_buffer_11: AddrSpace = @fromBackingInt(@intCast(19)); | 2602 | pub const constant_buffer_11: AddrSpace = @fromBackingInt(19); |
| 1967 | pub const constant_buffer_12: AddrSpace = @fromBackingInt(@intCast(20)); | 2603 | pub const constant_buffer_12: AddrSpace = @fromBackingInt(20); |
| 1968 | pub const constant_buffer_13: AddrSpace = @fromBackingInt(@intCast(21)); | 2604 | pub const constant_buffer_13: AddrSpace = @fromBackingInt(21); |
| 1969 | pub const constant_buffer_14: AddrSpace = @fromBackingInt(@intCast(22)); | 2605 | pub const constant_buffer_14: AddrSpace = @fromBackingInt(22); |
| 1970 | pub const constant_buffer_15: AddrSpace = @fromBackingInt(@intCast(23)); | 2606 | pub const constant_buffer_15: AddrSpace = @fromBackingInt(23); |
| 1971 | pub const streamout_register: AddrSpace = @fromBackingInt(@intCast(128)); | 2607 | pub const streamout_register: AddrSpace = @fromBackingInt(128); |
| 1972 | }; | 2608 | }; |
| 1973 | 2609 | ||
| 1974 | pub const spirv = struct { | 2610 | pub const spirv = struct { |
| 1975 | pub const function: AddrSpace = @fromBackingInt(@intCast(0)); | 2611 | pub const function: AddrSpace = @fromBackingInt(0); |
| 1976 | pub const cross_workgroup: AddrSpace = @fromBackingInt(@intCast(1)); | 2612 | pub const cross_workgroup: AddrSpace = @fromBackingInt(1); |
| 1977 | pub const uniform_constant: AddrSpace = @fromBackingInt(@intCast(2)); | 2613 | pub const uniform_constant: AddrSpace = @fromBackingInt(2); |
| 1978 | pub const workgroup: AddrSpace = @fromBackingInt(@intCast(3)); | 2614 | pub const workgroup: AddrSpace = @fromBackingInt(3); |
| 1979 | pub const generic: AddrSpace = @fromBackingInt(@intCast(4)); | 2615 | pub const generic: AddrSpace = @fromBackingInt(4); |
| 1980 | pub const device_only_intel: AddrSpace = @fromBackingInt(@intCast(5)); | 2616 | pub const device_only_intel: AddrSpace = @fromBackingInt(5); |
| 1981 | pub const host_only_intel: AddrSpace = @fromBackingInt(@intCast(6)); | 2617 | pub const host_only_intel: AddrSpace = @fromBackingInt(6); |
| 1982 | pub const input: AddrSpace = @fromBackingInt(@intCast(7)); | 2618 | pub const input: AddrSpace = @fromBackingInt(7); |
| 1983 | }; | 2619 | }; |
| 1984 | 2620 | ||
| 1985 | // See llvm/include/llvm/CodeGen/WasmAddressSpaces.h | 2621 | // See llvm/include/llvm/CodeGen/WasmAddressSpaces.h |
| 1986 | pub const wasm = struct { | 2622 | pub const wasm = struct { |
| 1987 | pub const default: AddrSpace = @fromBackingInt(@intCast(0)); | 2623 | pub const default: AddrSpace = @fromBackingInt(0); |
| 1988 | pub const variable: AddrSpace = @fromBackingInt(@intCast(1)); | 2624 | pub const variable: AddrSpace = @fromBackingInt(1); |
| 1989 | pub const externref: AddrSpace = @fromBackingInt(@intCast(10)); | 2625 | pub const externref: AddrSpace = @fromBackingInt(10); |
| 1990 | pub const funcref: AddrSpace = @fromBackingInt(@intCast(20)); | 2626 | pub const funcref: AddrSpace = @fromBackingInt(20); |
| 1991 | }; | 2627 | }; |
| 1992 | 2628 | ||
| 1993 | pub fn format(addr_space: AddrSpace, w: *Writer) Writer.Error!void { | 2629 | pub fn format(addr_space: AddrSpace, w: *Writer) Writer.Error!void { |
| ... | @@ -2030,7 +2666,7 @@ pub const Alignment = enum(u6) { | ... | @@ -2030,7 +2666,7 @@ pub const Alignment = enum(u6) { |
| 2030 | _, | 2666 | _, |
| 2031 | 2667 | ||
| 2032 | pub fn wrap(a: Alignment) Lazy { | 2668 | pub fn wrap(a: Alignment) Lazy { |
| 2033 | return @fromBackingInt(@intCast(@backingInt(a))); | 2669 | return @fromBackingInt(@backingInt(a)); |
| 2034 | } | 2670 | } |
| 2035 | pub fn resolve(l: Lazy, b: *const Builder) Alignment { | 2671 | pub fn resolve(l: Lazy, b: *const Builder) Alignment { |
| 2036 | return switch (@backingInt(l)) { | 2672 | return switch (@backingInt(l)) { |
| ... | @@ -2061,11 +2697,18 @@ pub const Alignment = enum(u6) { | ... | @@ -2061,11 +2697,18 @@ pub const Alignment = enum(u6) { |
| 2061 | }; | 2697 | }; |
| 2062 | } | 2698 | } |
| 2063 | 2699 | ||
| 2064 | /// Asserts that neither `a` nor `b` is `.default`. | 2700 | /// Asserts that neither `lhs` nor `rhs` is `.default`. |
| 2065 | pub fn max(a: Alignment, b: Alignment) Alignment { | 2701 | pub fn max(lhs: Alignment, rhs: Alignment) Alignment { |
| 2066 | assert(a != .default); | 2702 | assert(lhs != .default); |
| 2067 | assert(b != .default); | 2703 | assert(rhs != .default); |
| 2068 | return @fromBackingInt(@intCast(@max(@backingInt(a), @backingInt(b)))); | 2704 | return @fromBackingInt(@max(@backingInt(lhs), @backingInt(rhs))); |
| 2705 | } | ||
| 2706 | |||
| 2707 | /// Asserts that neither `lhs` nor `rhs` is `.default`. | ||
| 2708 | pub fn order(lhs: Alignment, rhs: Alignment) std.math.Order { | ||
| 2709 | assert(lhs != .default); | ||
| 2710 | assert(rhs != .default); | ||
| 2711 | return std.math.order(@backingInt(lhs), @backingInt(rhs)); | ||
| 2069 | } | 2712 | } |
| 2070 | 2713 | ||
| 2071 | pub fn toLlvm(self: Alignment) u6 { | 2714 | pub fn toLlvm(self: Alignment) u6 { |
| ... | @@ -2106,6 +2749,7 @@ pub const CallConv = enum(u10) { | ... | @@ -2106,6 +2749,7 @@ pub const CallConv = enum(u10) { |
| 2106 | tailcc, | 2749 | tailcc, |
| 2107 | cfguard_checkcc, | 2750 | cfguard_checkcc, |
| 2108 | swifttailcc, | 2751 | swifttailcc, |
| 2752 | preserve_nonecc, | ||
| 2109 | 2753 | ||
| 2110 | x86_stdcallcc = 64, | 2754 | x86_stdcallcc = 64, |
| 2111 | x86_fastcallcc, | 2755 | x86_fastcallcc, |
| ... | @@ -2174,6 +2818,7 @@ pub const CallConv = enum(u10) { | ... | @@ -2174,6 +2818,7 @@ pub const CallConv = enum(u10) { |
| 2174 | .tailcc, | 2818 | .tailcc, |
| 2175 | .cfguard_checkcc, | 2819 | .cfguard_checkcc, |
| 2176 | .swifttailcc, | 2820 | .swifttailcc, |
| 2821 | .preserve_nonecc, | ||
| 2177 | .x86_stdcallcc, | 2822 | .x86_stdcallcc, |
| 2178 | .x86_fastcallcc, | 2823 | .x86_fastcallcc, |
| 2179 | .arm_apcscc, | 2824 | .arm_apcscc, |
| ... | @@ -2261,8 +2906,7 @@ pub const StrtabString = enum(u32) { | ... | @@ -2261,8 +2906,7 @@ pub const StrtabString = enum(u32) { |
| 2261 | } | 2906 | } |
| 2262 | 2907 | ||
| 2263 | fn fromIndex(index: ?usize) StrtabString { | 2908 | fn fromIndex(index: ?usize) StrtabString { |
| 2264 | return @fromBackingInt(@intCast(@as(u32, @intCast((index orelse return .none) + | 2909 | return @fromBackingInt(@intCast((index orelse return .none) + @backingInt(StrtabString.empty))); |
| 2265 | @backingInt(StrtabString.empty))))); | ||
| 2266 | } | 2910 | } |
| 2267 | 2911 | ||
| 2268 | fn toIndex(self: StrtabString) ?usize { | 2912 | fn toIndex(self: StrtabString) ?usize { |
| ... | @@ -2318,7 +2962,7 @@ pub fn trailingStrtabString(self: *Builder) Allocator.Error!StrtabString { | ... | @@ -2318,7 +2962,7 @@ pub fn trailingStrtabString(self: *Builder) Allocator.Error!StrtabString { |
| 2318 | } | 2962 | } |
| 2319 | 2963 | ||
| 2320 | pub fn trailingStrtabStringAssumeCapacity(self: *Builder) StrtabString { | 2964 | pub fn trailingStrtabStringAssumeCapacity(self: *Builder) StrtabString { |
| 2321 | const start = self.strtab_string_indices.getLast().?; | 2965 | const start = self.strtab_string_indices.last().?; |
| 2322 | const bytes: []const u8 = self.strtab_string_bytes.items[start..]; | 2966 | const bytes: []const u8 = self.strtab_string_bytes.items[start..]; |
| 2323 | const gop = self.strtab_string_map.getOrPutAssumeCapacityAdapted(bytes, StrtabString.Adapter{ .builder = self }); | 2967 | const gop = self.strtab_string_map.getOrPutAssumeCapacityAdapted(bytes, StrtabString.Adapter{ .builder = self }); |
| 2324 | if (gop.found_existing) { | 2968 | if (gop.found_existing) { |
| ... | @@ -2398,7 +3042,7 @@ pub const Global = struct { | ... | @@ -2398,7 +3042,7 @@ pub const Global = struct { |
| 2398 | } | 3042 | } |
| 2399 | 3043 | ||
| 2400 | pub fn toConst(global: Index) Constant { | 3044 | pub fn toConst(global: Index) Constant { |
| 2401 | return @fromBackingInt(@intCast(@backingInt(Constant.first_global) + @backingInt(global))); | 3045 | return @fromBackingInt(@backingInt(Constant.first_global) + @backingInt(global)); |
| 2402 | } | 3046 | } |
| 2403 | 3047 | ||
| 2404 | pub fn toValue(global: Index) Value { | 3048 | pub fn toValue(global: Index) Value { |
| ... | @@ -2526,7 +3170,7 @@ pub const Global = struct { | ... | @@ -2526,7 +3170,7 @@ pub const Global = struct { |
| 2526 | _ = builder.addGlobalAssumeCapacity(new_name, builder.globals.values()[index]); | 3170 | _ = builder.addGlobalAssumeCapacity(new_name, builder.globals.values()[index]); |
| 2527 | builder.globals.swapRemoveAt(index); | 3171 | builder.globals.swapRemoveAt(index); |
| 2528 | if (!old_name.isAnon()) return; | 3172 | if (!old_name.isAnon()) return; |
| 2529 | builder.next_unnamed_global = @fromBackingInt(@intCast(@backingInt(builder.next_unnamed_global) - 1)); | 3173 | builder.next_unnamed_global = @fromBackingInt(@backingInt(builder.next_unnamed_global) - 1); |
| 2530 | if (builder.next_unnamed_global == old_name) return; | 3174 | if (builder.next_unnamed_global == old_name) return; |
| 2531 | builder.getGlobal(builder.next_unnamed_global).?.renameAssumeCapacity(old_name, builder); | 3175 | builder.getGlobal(builder.next_unnamed_global).?.renameAssumeCapacity(old_name, builder); |
| 2532 | } | 3176 | } |
| ... | @@ -2539,7 +3183,7 @@ pub const Global = struct { | ... | @@ -2539,7 +3183,7 @@ pub const Global = struct { |
| 2539 | 3183 | ||
| 2540 | fn replaceAssumeCapacity(self: Index, other: Index, builder: *Builder) void { | 3184 | fn replaceAssumeCapacity(self: Index, other: Index, builder: *Builder) void { |
| 2541 | if (self.eql(other, builder)) return; | 3185 | if (self.eql(other, builder)) return; |
| 2542 | builder.next_replaced_global = @fromBackingInt(@intCast(@backingInt(builder.next_replaced_global) - 1)); | 3186 | builder.next_replaced_global = @fromBackingInt(@backingInt(builder.next_replaced_global) - 1); |
| 2543 | self.renameAssumeCapacity(builder.next_replaced_global, builder); | 3187 | self.renameAssumeCapacity(builder.next_replaced_global, builder); |
| 2544 | self.ptr(builder).kind = .{ .replaced = other.unwrap(builder) }; | 3188 | self.ptr(builder).kind = .{ .replaced = other.unwrap(builder) }; |
| 2545 | } | 3189 | } |
| ... | @@ -2699,6 +3343,8 @@ pub const Intrinsic = enum { | ... | @@ -2699,6 +3343,8 @@ pub const Intrinsic = enum { |
| 2699 | smin, | 3343 | smin, |
| 2700 | umax, | 3344 | umax, |
| 2701 | umin, | 3345 | umin, |
| 3346 | scmp, | ||
| 3347 | ucmp, | ||
| 2702 | memcpy, | 3348 | memcpy, |
| 2703 | @"memcpy.inline", | 3349 | @"memcpy.inline", |
| 2704 | memmove, | 3350 | memmove, |
| ... | @@ -2708,10 +3354,21 @@ pub const Intrinsic = enum { | ... | @@ -2708,10 +3354,21 @@ pub const Intrinsic = enum { |
| 2708 | powi, | 3354 | powi, |
| 2709 | sin, | 3355 | sin, |
| 2710 | cos, | 3356 | cos, |
| 3357 | tan, | ||
| 3358 | asin, | ||
| 3359 | acos, | ||
| 3360 | atan, | ||
| 3361 | atan2, | ||
| 3362 | sinh, | ||
| 3363 | cosh, | ||
| 3364 | tanh, | ||
| 3365 | sincos, | ||
| 3366 | sincospi, | ||
| 3367 | modf, | ||
| 2711 | pow, | 3368 | pow, |
| 2712 | exp, | 3369 | exp, |
| 2713 | exp10, | ||
| 2714 | exp2, | 3370 | exp2, |
| 3371 | exp10, | ||
| 2715 | ldexp, | 3372 | ldexp, |
| 2716 | frexp, | 3373 | frexp, |
| 2717 | log, | 3374 | log, |
| ... | @@ -2723,6 +3380,8 @@ pub const Intrinsic = enum { | ... | @@ -2723,6 +3380,8 @@ pub const Intrinsic = enum { |
| 2723 | maxnum, | 3380 | maxnum, |
| 2724 | minimum, | 3381 | minimum, |
| 2725 | maximum, | 3382 | maximum, |
| 3383 | minimumnum, | ||
| 3384 | maximumnum, | ||
| 2726 | copysign, | 3385 | copysign, |
| 2727 | floor, | 3386 | floor, |
| 2728 | ceil, | 3387 | ceil, |
| ... | @@ -2744,6 +3403,7 @@ pub const Intrinsic = enum { | ... | @@ -2744,6 +3403,7 @@ pub const Intrinsic = enum { |
| 2744 | cttz, | 3403 | cttz, |
| 2745 | fshl, | 3404 | fshl, |
| 2746 | fshr, | 3405 | fshr, |
| 3406 | clmul, | ||
| 2747 | 3407 | ||
| 2748 | // Arithmetic with Overflow | 3408 | // Arithmetic with Overflow |
| 2749 | @"sadd.with.overflow", | 3409 | @"sadd.with.overflow", |
| ... | @@ -2904,21 +3564,21 @@ pub const Intrinsic = enum { | ... | @@ -2904,21 +3564,21 @@ pub const Intrinsic = enum { |
| 2904 | .{ .kind = .{ .type = .ptr } }, | 3564 | .{ .kind = .{ .type = .ptr } }, |
| 2905 | .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} }, | 3565 | .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} }, |
| 2906 | }, | 3566 | }, |
| 2907 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 3567 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .all(.none) } }, |
| 2908 | }, | 3568 | }, |
| 2909 | .addressofreturnaddress = .{ | 3569 | .addressofreturnaddress = .{ |
| 2910 | .ret_len = 1, | 3570 | .ret_len = 1, |
| 2911 | .params = &.{ | 3571 | .params = &.{ |
| 2912 | .{ .kind = .overloaded }, | 3572 | .{ .kind = .overloaded }, |
| 2913 | }, | 3573 | }, |
| 2914 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 3574 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .all(.none) } }, |
| 2915 | }, | 3575 | }, |
| 2916 | .sponentry = .{ | 3576 | .sponentry = .{ |
| 2917 | .ret_len = 1, | 3577 | .ret_len = 1, |
| 2918 | .params = &.{ | 3578 | .params = &.{ |
| 2919 | .{ .kind = .overloaded }, | 3579 | .{ .kind = .overloaded }, |
| 2920 | }, | 3580 | }, |
| 2921 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 3581 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .all(.none) } }, |
| 2922 | }, | 3582 | }, |
| 2923 | .frameaddress = .{ | 3583 | .frameaddress = .{ |
| 2924 | .ret_len = 1, | 3584 | .ret_len = 1, |
| ... | @@ -2926,7 +3586,7 @@ pub const Intrinsic = enum { | ... | @@ -2926,7 +3586,7 @@ pub const Intrinsic = enum { |
| 2926 | .{ .kind = .overloaded }, | 3586 | .{ .kind = .overloaded }, |
| 2927 | .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} }, | 3587 | .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} }, |
| 2928 | }, | 3588 | }, |
| 2929 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 3589 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .all(.none) } }, |
| 2930 | }, | 3590 | }, |
| 2931 | .prefetch = .{ | 3591 | .prefetch = .{ |
| 2932 | .ret_len = 0, | 3592 | .ret_len = 0, |
| ... | @@ -2936,14 +3596,14 @@ pub const Intrinsic = enum { | ... | @@ -2936,14 +3596,14 @@ pub const Intrinsic = enum { |
| 2936 | .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} }, | 3596 | .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} }, |
| 2937 | .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} }, | 3597 | .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} }, |
| 2938 | }, | 3598 | }, |
| 2939 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.readwrite) } }, | 3599 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .all(.readwrite) } }, |
| 2940 | }, | 3600 | }, |
| 2941 | .@"thread.pointer" = .{ | 3601 | .@"thread.pointer" = .{ |
| 2942 | .ret_len = 1, | 3602 | .ret_len = 1, |
| 2943 | .params = &.{ | 3603 | .params = &.{ |
| 2944 | .{ .kind = .{ .type = .ptr } }, | 3604 | .{ .kind = .{ .type = .ptr } }, |
| 2945 | }, | 3605 | }, |
| 2946 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 3606 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .all(.none) } }, |
| 2947 | }, | 3607 | }, |
| 2948 | 3608 | ||
| 2949 | .abs = .{ | 3609 | .abs = .{ |
| ... | @@ -2953,7 +3613,7 @@ pub const Intrinsic = enum { | ... | @@ -2953,7 +3613,7 @@ pub const Intrinsic = enum { |
| 2953 | .{ .kind = .{ .matches = 0 } }, | 3613 | .{ .kind = .{ .matches = 0 } }, |
| 2954 | .{ .kind = .{ .type = .i1 }, .attrs = &.{.immarg} }, | 3614 | .{ .kind = .{ .type = .i1 }, .attrs = &.{.immarg} }, |
| 2955 | }, | 3615 | }, |
| 2956 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 3616 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 2957 | }, | 3617 | }, |
| 2958 | .smax = .{ | 3618 | .smax = .{ |
| 2959 | .ret_len = 1, | 3619 | .ret_len = 1, |
| ... | @@ -2962,7 +3622,7 @@ pub const Intrinsic = enum { | ... | @@ -2962,7 +3622,7 @@ pub const Intrinsic = enum { |
| 2962 | .{ .kind = .{ .matches = 0 } }, | 3622 | .{ .kind = .{ .matches = 0 } }, |
| 2963 | .{ .kind = .{ .matches = 0 } }, | 3623 | .{ .kind = .{ .matches = 0 } }, |
| 2964 | }, | 3624 | }, |
| 2965 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 3625 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 2966 | }, | 3626 | }, |
| 2967 | .smin = .{ | 3627 | .smin = .{ |
| 2968 | .ret_len = 1, | 3628 | .ret_len = 1, |
| ... | @@ -2971,7 +3631,7 @@ pub const Intrinsic = enum { | ... | @@ -2971,7 +3631,7 @@ pub const Intrinsic = enum { |
| 2971 | .{ .kind = .{ .matches = 0 } }, | 3631 | .{ .kind = .{ .matches = 0 } }, |
| 2972 | .{ .kind = .{ .matches = 0 } }, | 3632 | .{ .kind = .{ .matches = 0 } }, |
| 2973 | }, | 3633 | }, |
| 2974 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 3634 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 2975 | }, | 3635 | }, |
| 2976 | .umax = .{ | 3636 | .umax = .{ |
| 2977 | .ret_len = 1, | 3637 | .ret_len = 1, |
| ... | @@ -2980,7 +3640,7 @@ pub const Intrinsic = enum { | ... | @@ -2980,7 +3640,7 @@ pub const Intrinsic = enum { |
| 2980 | .{ .kind = .{ .matches = 0 } }, | 3640 | .{ .kind = .{ .matches = 0 } }, |
| 2981 | .{ .kind = .{ .matches = 0 } }, | 3641 | .{ .kind = .{ .matches = 0 } }, |
| 2982 | }, | 3642 | }, |
| 2983 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 3643 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 2984 | }, | 3644 | }, |
| 2985 | .umin = .{ | 3645 | .umin = .{ |
| 2986 | .ret_len = 1, | 3646 | .ret_len = 1, |
| ... | @@ -2989,7 +3649,25 @@ pub const Intrinsic = enum { | ... | @@ -2989,7 +3649,25 @@ pub const Intrinsic = enum { |
| 2989 | .{ .kind = .{ .matches = 0 } }, | 3649 | .{ .kind = .{ .matches = 0 } }, |
| 2990 | .{ .kind = .{ .matches = 0 } }, | 3650 | .{ .kind = .{ .matches = 0 } }, |
| 2991 | }, | 3651 | }, |
| 2992 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 3652 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3653 | }, | ||
| 3654 | .scmp = .{ | ||
| 3655 | .ret_len = 1, | ||
| 3656 | .params = &.{ | ||
| 3657 | .{ .kind = .overloaded }, | ||
| 3658 | .{ .kind = .overloaded }, | ||
| 3659 | .{ .kind = .{ .matches = 1 } }, | ||
| 3660 | }, | ||
| 3661 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, | ||
| 3662 | }, | ||
| 3663 | .ucmp = .{ | ||
| 3664 | .ret_len = 1, | ||
| 3665 | .params = &.{ | ||
| 3666 | .{ .kind = .overloaded }, | ||
| 3667 | .{ .kind = .overloaded }, | ||
| 3668 | .{ .kind = .{ .matches = 1 } }, | ||
| 3669 | }, | ||
| 3670 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, | ||
| 2993 | }, | 3671 | }, |
| 2994 | .memcpy = .{ | 3672 | .memcpy = .{ |
| 2995 | .ret_len = 0, | 3673 | .ret_len = 0, |
| ... | @@ -3047,7 +3725,7 @@ pub const Intrinsic = enum { | ... | @@ -3047,7 +3725,7 @@ pub const Intrinsic = enum { |
| 3047 | .{ .kind = .overloaded }, | 3725 | .{ .kind = .overloaded }, |
| 3048 | .{ .kind = .{ .matches = 0 } }, | 3726 | .{ .kind = .{ .matches = 0 } }, |
| 3049 | }, | 3727 | }, |
| 3050 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 3728 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3051 | }, | 3729 | }, |
| 3052 | .powi = .{ | 3730 | .powi = .{ |
| 3053 | .ret_len = 1, | 3731 | .ret_len = 1, |
| ... | @@ -3056,7 +3734,7 @@ pub const Intrinsic = enum { | ... | @@ -3056,7 +3734,7 @@ pub const Intrinsic = enum { |
| 3056 | .{ .kind = .{ .matches = 0 } }, | 3734 | .{ .kind = .{ .matches = 0 } }, |
| 3057 | .{ .kind = .overloaded }, | 3735 | .{ .kind = .overloaded }, |
| 3058 | }, | 3736 | }, |
| 3059 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 3737 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3060 | }, | 3738 | }, |
| 3061 | .sin = .{ | 3739 | .sin = .{ |
| 3062 | .ret_len = 1, | 3740 | .ret_len = 1, |
| ... | @@ -3064,7 +3742,7 @@ pub const Intrinsic = enum { | ... | @@ -3064,7 +3742,7 @@ pub const Intrinsic = enum { |
| 3064 | .{ .kind = .overloaded }, | 3742 | .{ .kind = .overloaded }, |
| 3065 | .{ .kind = .{ .matches = 0 } }, | 3743 | .{ .kind = .{ .matches = 0 } }, |
| 3066 | }, | 3744 | }, |
| 3067 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 3745 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3068 | }, | 3746 | }, |
| 3069 | .cos = .{ | 3747 | .cos = .{ |
| 3070 | .ret_len = 1, | 3748 | .ret_len = 1, |
| ... | @@ -3072,7 +3750,99 @@ pub const Intrinsic = enum { | ... | @@ -3072,7 +3750,99 @@ pub const Intrinsic = enum { |
| 3072 | .{ .kind = .overloaded }, | 3750 | .{ .kind = .overloaded }, |
| 3073 | .{ .kind = .{ .matches = 0 } }, | 3751 | .{ .kind = .{ .matches = 0 } }, |
| 3074 | }, | 3752 | }, |
| 3075 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 3753 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3754 | }, | ||
| 3755 | .tan = .{ | ||
| 3756 | .ret_len = 1, | ||
| 3757 | .params = &.{ | ||
| 3758 | .{ .kind = .overloaded }, | ||
| 3759 | .{ .kind = .{ .matches = 0 } }, | ||
| 3760 | }, | ||
| 3761 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, | ||
| 3762 | }, | ||
| 3763 | .asin = .{ | ||
| 3764 | .ret_len = 1, | ||
| 3765 | .params = &.{ | ||
| 3766 | .{ .kind = .overloaded }, | ||
| 3767 | .{ .kind = .{ .matches = 0 } }, | ||
| 3768 | }, | ||
| 3769 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, | ||
| 3770 | }, | ||
| 3771 | .acos = .{ | ||
| 3772 | .ret_len = 1, | ||
| 3773 | .params = &.{ | ||
| 3774 | .{ .kind = .overloaded }, | ||
| 3775 | .{ .kind = .{ .matches = 0 } }, | ||
| 3776 | }, | ||
| 3777 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, | ||
| 3778 | }, | ||
| 3779 | .atan = .{ | ||
| 3780 | .ret_len = 1, | ||
| 3781 | .params = &.{ | ||
| 3782 | .{ .kind = .overloaded }, | ||
| 3783 | .{ .kind = .{ .matches = 0 } }, | ||
| 3784 | }, | ||
| 3785 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, | ||
| 3786 | }, | ||
| 3787 | .atan2 = .{ | ||
| 3788 | .ret_len = 1, | ||
| 3789 | .params = &.{ | ||
| 3790 | .{ .kind = .overloaded }, | ||
| 3791 | .{ .kind = .{ .matches = 0 } }, | ||
| 3792 | .{ .kind = .{ .matches = 0 } }, | ||
| 3793 | }, | ||
| 3794 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, | ||
| 3795 | }, | ||
| 3796 | .sinh = .{ | ||
| 3797 | .ret_len = 1, | ||
| 3798 | .params = &.{ | ||
| 3799 | .{ .kind = .overloaded }, | ||
| 3800 | .{ .kind = .{ .matches = 0 } }, | ||
| 3801 | }, | ||
| 3802 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, | ||
| 3803 | }, | ||
| 3804 | .cosh = .{ | ||
| 3805 | .ret_len = 1, | ||
| 3806 | .params = &.{ | ||
| 3807 | .{ .kind = .overloaded }, | ||
| 3808 | .{ .kind = .{ .matches = 0 } }, | ||
| 3809 | }, | ||
| 3810 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, | ||
| 3811 | }, | ||
| 3812 | .tanh = .{ | ||
| 3813 | .ret_len = 1, | ||
| 3814 | .params = &.{ | ||
| 3815 | .{ .kind = .overloaded }, | ||
| 3816 | .{ .kind = .{ .matches = 0 } }, | ||
| 3817 | }, | ||
| 3818 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, | ||
| 3819 | }, | ||
| 3820 | .sincos = .{ | ||
| 3821 | .ret_len = 2, | ||
| 3822 | .params = &.{ | ||
| 3823 | .{ .kind = .overloaded }, | ||
| 3824 | .{ .kind = .{ .matches = 0 } }, | ||
| 3825 | .{ .kind = .{ .matches = 0 } }, | ||
| 3826 | }, | ||
| 3827 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, | ||
| 3828 | }, | ||
| 3829 | .sincospi = .{ | ||
| 3830 | .ret_len = 2, | ||
| 3831 | .params = &.{ | ||
| 3832 | .{ .kind = .overloaded }, | ||
| 3833 | .{ .kind = .{ .matches = 0 } }, | ||
| 3834 | .{ .kind = .{ .matches = 0 } }, | ||
| 3835 | }, | ||
| 3836 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, | ||
| 3837 | }, | ||
| 3838 | .modf = .{ | ||
| 3839 | .ret_len = 2, | ||
| 3840 | .params = &.{ | ||
| 3841 | .{ .kind = .overloaded }, | ||
| 3842 | .{ .kind = .{ .matches = 0 } }, | ||
| 3843 | .{ .kind = .{ .matches = 0 } }, | ||
| 3844 | }, | ||
| 3845 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, | ||
| 3076 | }, | 3846 | }, |
| 3077 | .pow = .{ | 3847 | .pow = .{ |
| 3078 | .ret_len = 1, | 3848 | .ret_len = 1, |
| ... | @@ -3081,7 +3851,7 @@ pub const Intrinsic = enum { | ... | @@ -3081,7 +3851,7 @@ pub const Intrinsic = enum { |
| 3081 | .{ .kind = .{ .matches = 0 } }, | 3851 | .{ .kind = .{ .matches = 0 } }, |
| 3082 | .{ .kind = .{ .matches = 0 } }, | 3852 | .{ .kind = .{ .matches = 0 } }, |
| 3083 | }, | 3853 | }, |
| 3084 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 3854 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3085 | }, | 3855 | }, |
| 3086 | .exp = .{ | 3856 | .exp = .{ |
| 3087 | .ret_len = 1, | 3857 | .ret_len = 1, |
| ... | @@ -3089,7 +3859,7 @@ pub const Intrinsic = enum { | ... | @@ -3089,7 +3859,7 @@ pub const Intrinsic = enum { |
| 3089 | .{ .kind = .overloaded }, | 3859 | .{ .kind = .overloaded }, |
| 3090 | .{ .kind = .{ .matches = 0 } }, | 3860 | .{ .kind = .{ .matches = 0 } }, |
| 3091 | }, | 3861 | }, |
| 3092 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 3862 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3093 | }, | 3863 | }, |
| 3094 | .exp2 = .{ | 3864 | .exp2 = .{ |
| 3095 | .ret_len = 1, | 3865 | .ret_len = 1, |
| ... | @@ -3097,7 +3867,7 @@ pub const Intrinsic = enum { | ... | @@ -3097,7 +3867,7 @@ pub const Intrinsic = enum { |
| 3097 | .{ .kind = .overloaded }, | 3867 | .{ .kind = .overloaded }, |
| 3098 | .{ .kind = .{ .matches = 0 } }, | 3868 | .{ .kind = .{ .matches = 0 } }, |
| 3099 | }, | 3869 | }, |
| 3100 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 3870 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3101 | }, | 3871 | }, |
| 3102 | .exp10 = .{ | 3872 | .exp10 = .{ |
| 3103 | .ret_len = 1, | 3873 | .ret_len = 1, |
| ... | @@ -3105,7 +3875,7 @@ pub const Intrinsic = enum { | ... | @@ -3105,7 +3875,7 @@ pub const Intrinsic = enum { |
| 3105 | .{ .kind = .overloaded }, | 3875 | .{ .kind = .overloaded }, |
| 3106 | .{ .kind = .{ .matches = 0 } }, | 3876 | .{ .kind = .{ .matches = 0 } }, |
| 3107 | }, | 3877 | }, |
| 3108 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 3878 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3109 | }, | 3879 | }, |
| 3110 | .ldexp = .{ | 3880 | .ldexp = .{ |
| 3111 | .ret_len = 1, | 3881 | .ret_len = 1, |
| ... | @@ -3114,7 +3884,7 @@ pub const Intrinsic = enum { | ... | @@ -3114,7 +3884,7 @@ pub const Intrinsic = enum { |
| 3114 | .{ .kind = .{ .matches = 0 } }, | 3884 | .{ .kind = .{ .matches = 0 } }, |
| 3115 | .{ .kind = .overloaded }, | 3885 | .{ .kind = .overloaded }, |
| 3116 | }, | 3886 | }, |
| 3117 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 3887 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3118 | }, | 3888 | }, |
| 3119 | .frexp = .{ | 3889 | .frexp = .{ |
| 3120 | .ret_len = 2, | 3890 | .ret_len = 2, |
| ... | @@ -3123,7 +3893,7 @@ pub const Intrinsic = enum { | ... | @@ -3123,7 +3893,7 @@ pub const Intrinsic = enum { |
| 3123 | .{ .kind = .overloaded }, | 3893 | .{ .kind = .overloaded }, |
| 3124 | .{ .kind = .{ .matches = 0 } }, | 3894 | .{ .kind = .{ .matches = 0 } }, |
| 3125 | }, | 3895 | }, |
| 3126 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 3896 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3127 | }, | 3897 | }, |
| 3128 | .log = .{ | 3898 | .log = .{ |
| 3129 | .ret_len = 1, | 3899 | .ret_len = 1, |
| ... | @@ -3131,7 +3901,7 @@ pub const Intrinsic = enum { | ... | @@ -3131,7 +3901,7 @@ pub const Intrinsic = enum { |
| 3131 | .{ .kind = .overloaded }, | 3901 | .{ .kind = .overloaded }, |
| 3132 | .{ .kind = .{ .matches = 0 } }, | 3902 | .{ .kind = .{ .matches = 0 } }, |
| 3133 | }, | 3903 | }, |
| 3134 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 3904 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3135 | }, | 3905 | }, |
| 3136 | .log10 = .{ | 3906 | .log10 = .{ |
| 3137 | .ret_len = 1, | 3907 | .ret_len = 1, |
| ... | @@ -3139,7 +3909,7 @@ pub const Intrinsic = enum { | ... | @@ -3139,7 +3909,7 @@ pub const Intrinsic = enum { |
| 3139 | .{ .kind = .overloaded }, | 3909 | .{ .kind = .overloaded }, |
| 3140 | .{ .kind = .{ .matches = 0 } }, | 3910 | .{ .kind = .{ .matches = 0 } }, |
| 3141 | }, | 3911 | }, |
| 3142 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 3912 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3143 | }, | 3913 | }, |
| 3144 | .log2 = .{ | 3914 | .log2 = .{ |
| 3145 | .ret_len = 1, | 3915 | .ret_len = 1, |
| ... | @@ -3147,7 +3917,7 @@ pub const Intrinsic = enum { | ... | @@ -3147,7 +3917,7 @@ pub const Intrinsic = enum { |
| 3147 | .{ .kind = .overloaded }, | 3917 | .{ .kind = .overloaded }, |
| 3148 | .{ .kind = .{ .matches = 0 } }, | 3918 | .{ .kind = .{ .matches = 0 } }, |
| 3149 | }, | 3919 | }, |
| 3150 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 3920 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3151 | }, | 3921 | }, |
| 3152 | .fma = .{ | 3922 | .fma = .{ |
| 3153 | .ret_len = 1, | 3923 | .ret_len = 1, |
| ... | @@ -3157,7 +3927,7 @@ pub const Intrinsic = enum { | ... | @@ -3157,7 +3927,7 @@ pub const Intrinsic = enum { |
| 3157 | .{ .kind = .{ .matches = 0 } }, | 3927 | .{ .kind = .{ .matches = 0 } }, |
| 3158 | .{ .kind = .{ .matches = 0 } }, | 3928 | .{ .kind = .{ .matches = 0 } }, |
| 3159 | }, | 3929 | }, |
| 3160 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 3930 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3161 | }, | 3931 | }, |
| 3162 | .fabs = .{ | 3932 | .fabs = .{ |
| 3163 | .ret_len = 1, | 3933 | .ret_len = 1, |
| ... | @@ -3165,7 +3935,7 @@ pub const Intrinsic = enum { | ... | @@ -3165,7 +3935,7 @@ pub const Intrinsic = enum { |
| 3165 | .{ .kind = .overloaded }, | 3935 | .{ .kind = .overloaded }, |
| 3166 | .{ .kind = .{ .matches = 0 } }, | 3936 | .{ .kind = .{ .matches = 0 } }, |
| 3167 | }, | 3937 | }, |
| 3168 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 3938 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3169 | }, | 3939 | }, |
| 3170 | .minnum = .{ | 3940 | .minnum = .{ |
| 3171 | .ret_len = 1, | 3941 | .ret_len = 1, |
| ... | @@ -3174,7 +3944,7 @@ pub const Intrinsic = enum { | ... | @@ -3174,7 +3944,7 @@ pub const Intrinsic = enum { |
| 3174 | .{ .kind = .{ .matches = 0 } }, | 3944 | .{ .kind = .{ .matches = 0 } }, |
| 3175 | .{ .kind = .{ .matches = 0 } }, | 3945 | .{ .kind = .{ .matches = 0 } }, |
| 3176 | }, | 3946 | }, |
| 3177 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 3947 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3178 | }, | 3948 | }, |
| 3179 | .maxnum = .{ | 3949 | .maxnum = .{ |
| 3180 | .ret_len = 1, | 3950 | .ret_len = 1, |
| ... | @@ -3183,7 +3953,7 @@ pub const Intrinsic = enum { | ... | @@ -3183,7 +3953,7 @@ pub const Intrinsic = enum { |
| 3183 | .{ .kind = .{ .matches = 0 } }, | 3953 | .{ .kind = .{ .matches = 0 } }, |
| 3184 | .{ .kind = .{ .matches = 0 } }, | 3954 | .{ .kind = .{ .matches = 0 } }, |
| 3185 | }, | 3955 | }, |
| 3186 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 3956 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3187 | }, | 3957 | }, |
| 3188 | .minimum = .{ | 3958 | .minimum = .{ |
| 3189 | .ret_len = 1, | 3959 | .ret_len = 1, |
| ... | @@ -3192,7 +3962,7 @@ pub const Intrinsic = enum { | ... | @@ -3192,7 +3962,7 @@ pub const Intrinsic = enum { |
| 3192 | .{ .kind = .{ .matches = 0 } }, | 3962 | .{ .kind = .{ .matches = 0 } }, |
| 3193 | .{ .kind = .{ .matches = 0 } }, | 3963 | .{ .kind = .{ .matches = 0 } }, |
| 3194 | }, | 3964 | }, |
| 3195 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 3965 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3196 | }, | 3966 | }, |
| 3197 | .maximum = .{ | 3967 | .maximum = .{ |
| 3198 | .ret_len = 1, | 3968 | .ret_len = 1, |
| ... | @@ -3201,7 +3971,25 @@ pub const Intrinsic = enum { | ... | @@ -3201,7 +3971,25 @@ pub const Intrinsic = enum { |
| 3201 | .{ .kind = .{ .matches = 0 } }, | 3971 | .{ .kind = .{ .matches = 0 } }, |
| 3202 | .{ .kind = .{ .matches = 0 } }, | 3972 | .{ .kind = .{ .matches = 0 } }, |
| 3203 | }, | 3973 | }, |
| 3204 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 3974 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3975 | }, | ||
| 3976 | .minimumnum = .{ | ||
| 3977 | .ret_len = 1, | ||
| 3978 | .params = &.{ | ||
| 3979 | .{ .kind = .overloaded }, | ||
| 3980 | .{ .kind = .{ .matches = 0 } }, | ||
| 3981 | .{ .kind = .{ .matches = 0 } }, | ||
| 3982 | }, | ||
| 3983 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, | ||
| 3984 | }, | ||
| 3985 | .maximumnum = .{ | ||
| 3986 | .ret_len = 1, | ||
| 3987 | .params = &.{ | ||
| 3988 | .{ .kind = .overloaded }, | ||
| 3989 | .{ .kind = .{ .matches = 0 } }, | ||
| 3990 | .{ .kind = .{ .matches = 0 } }, | ||
| 3991 | }, | ||
| 3992 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, | ||
| 3205 | }, | 3993 | }, |
| 3206 | .copysign = .{ | 3994 | .copysign = .{ |
| 3207 | .ret_len = 1, | 3995 | .ret_len = 1, |
| ... | @@ -3210,7 +3998,7 @@ pub const Intrinsic = enum { | ... | @@ -3210,7 +3998,7 @@ pub const Intrinsic = enum { |
| 3210 | .{ .kind = .{ .matches = 0 } }, | 3998 | .{ .kind = .{ .matches = 0 } }, |
| 3211 | .{ .kind = .{ .matches = 0 } }, | 3999 | .{ .kind = .{ .matches = 0 } }, |
| 3212 | }, | 4000 | }, |
| 3213 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4001 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3214 | }, | 4002 | }, |
| 3215 | .floor = .{ | 4003 | .floor = .{ |
| 3216 | .ret_len = 1, | 4004 | .ret_len = 1, |
| ... | @@ -3218,7 +4006,7 @@ pub const Intrinsic = enum { | ... | @@ -3218,7 +4006,7 @@ pub const Intrinsic = enum { |
| 3218 | .{ .kind = .overloaded }, | 4006 | .{ .kind = .overloaded }, |
| 3219 | .{ .kind = .{ .matches = 0 } }, | 4007 | .{ .kind = .{ .matches = 0 } }, |
| 3220 | }, | 4008 | }, |
| 3221 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4009 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3222 | }, | 4010 | }, |
| 3223 | .ceil = .{ | 4011 | .ceil = .{ |
| 3224 | .ret_len = 1, | 4012 | .ret_len = 1, |
| ... | @@ -3226,7 +4014,7 @@ pub const Intrinsic = enum { | ... | @@ -3226,7 +4014,7 @@ pub const Intrinsic = enum { |
| 3226 | .{ .kind = .overloaded }, | 4014 | .{ .kind = .overloaded }, |
| 3227 | .{ .kind = .{ .matches = 0 } }, | 4015 | .{ .kind = .{ .matches = 0 } }, |
| 3228 | }, | 4016 | }, |
| 3229 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4017 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3230 | }, | 4018 | }, |
| 3231 | .trunc = .{ | 4019 | .trunc = .{ |
| 3232 | .ret_len = 1, | 4020 | .ret_len = 1, |
| ... | @@ -3234,7 +4022,7 @@ pub const Intrinsic = enum { | ... | @@ -3234,7 +4022,7 @@ pub const Intrinsic = enum { |
| 3234 | .{ .kind = .overloaded }, | 4022 | .{ .kind = .overloaded }, |
| 3235 | .{ .kind = .{ .matches = 0 } }, | 4023 | .{ .kind = .{ .matches = 0 } }, |
| 3236 | }, | 4024 | }, |
| 3237 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4025 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3238 | }, | 4026 | }, |
| 3239 | .rint = .{ | 4027 | .rint = .{ |
| 3240 | .ret_len = 1, | 4028 | .ret_len = 1, |
| ... | @@ -3242,7 +4030,7 @@ pub const Intrinsic = enum { | ... | @@ -3242,7 +4030,7 @@ pub const Intrinsic = enum { |
| 3242 | .{ .kind = .overloaded }, | 4030 | .{ .kind = .overloaded }, |
| 3243 | .{ .kind = .{ .matches = 0 } }, | 4031 | .{ .kind = .{ .matches = 0 } }, |
| 3244 | }, | 4032 | }, |
| 3245 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4033 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3246 | }, | 4034 | }, |
| 3247 | .nearbyint = .{ | 4035 | .nearbyint = .{ |
| 3248 | .ret_len = 1, | 4036 | .ret_len = 1, |
| ... | @@ -3250,7 +4038,7 @@ pub const Intrinsic = enum { | ... | @@ -3250,7 +4038,7 @@ pub const Intrinsic = enum { |
| 3250 | .{ .kind = .overloaded }, | 4038 | .{ .kind = .overloaded }, |
| 3251 | .{ .kind = .{ .matches = 0 } }, | 4039 | .{ .kind = .{ .matches = 0 } }, |
| 3252 | }, | 4040 | }, |
| 3253 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4041 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3254 | }, | 4042 | }, |
| 3255 | .round = .{ | 4043 | .round = .{ |
| 3256 | .ret_len = 1, | 4044 | .ret_len = 1, |
| ... | @@ -3258,7 +4046,7 @@ pub const Intrinsic = enum { | ... | @@ -3258,7 +4046,7 @@ pub const Intrinsic = enum { |
| 3258 | .{ .kind = .overloaded }, | 4046 | .{ .kind = .overloaded }, |
| 3259 | .{ .kind = .{ .matches = 0 } }, | 4047 | .{ .kind = .{ .matches = 0 } }, |
| 3260 | }, | 4048 | }, |
| 3261 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4049 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3262 | }, | 4050 | }, |
| 3263 | .roundeven = .{ | 4051 | .roundeven = .{ |
| 3264 | .ret_len = 1, | 4052 | .ret_len = 1, |
| ... | @@ -3266,7 +4054,7 @@ pub const Intrinsic = enum { | ... | @@ -3266,7 +4054,7 @@ pub const Intrinsic = enum { |
| 3266 | .{ .kind = .overloaded }, | 4054 | .{ .kind = .overloaded }, |
| 3267 | .{ .kind = .{ .matches = 0 } }, | 4055 | .{ .kind = .{ .matches = 0 } }, |
| 3268 | }, | 4056 | }, |
| 3269 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4057 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3270 | }, | 4058 | }, |
| 3271 | .lround = .{ | 4059 | .lround = .{ |
| 3272 | .ret_len = 1, | 4060 | .ret_len = 1, |
| ... | @@ -3274,7 +4062,7 @@ pub const Intrinsic = enum { | ... | @@ -3274,7 +4062,7 @@ pub const Intrinsic = enum { |
| 3274 | .{ .kind = .overloaded }, | 4062 | .{ .kind = .overloaded }, |
| 3275 | .{ .kind = .overloaded }, | 4063 | .{ .kind = .overloaded }, |
| 3276 | }, | 4064 | }, |
| 3277 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4065 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3278 | }, | 4066 | }, |
| 3279 | .llround = .{ | 4067 | .llround = .{ |
| 3280 | .ret_len = 1, | 4068 | .ret_len = 1, |
| ... | @@ -3282,7 +4070,7 @@ pub const Intrinsic = enum { | ... | @@ -3282,7 +4070,7 @@ pub const Intrinsic = enum { |
| 3282 | .{ .kind = .overloaded }, | 4070 | .{ .kind = .overloaded }, |
| 3283 | .{ .kind = .overloaded }, | 4071 | .{ .kind = .overloaded }, |
| 3284 | }, | 4072 | }, |
| 3285 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4073 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3286 | }, | 4074 | }, |
| 3287 | .lrint = .{ | 4075 | .lrint = .{ |
| 3288 | .ret_len = 1, | 4076 | .ret_len = 1, |
| ... | @@ -3290,7 +4078,7 @@ pub const Intrinsic = enum { | ... | @@ -3290,7 +4078,7 @@ pub const Intrinsic = enum { |
| 3290 | .{ .kind = .overloaded }, | 4078 | .{ .kind = .overloaded }, |
| 3291 | .{ .kind = .overloaded }, | 4079 | .{ .kind = .overloaded }, |
| 3292 | }, | 4080 | }, |
| 3293 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4081 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3294 | }, | 4082 | }, |
| 3295 | .llrint = .{ | 4083 | .llrint = .{ |
| 3296 | .ret_len = 1, | 4084 | .ret_len = 1, |
| ... | @@ -3298,7 +4086,7 @@ pub const Intrinsic = enum { | ... | @@ -3298,7 +4086,7 @@ pub const Intrinsic = enum { |
| 3298 | .{ .kind = .overloaded }, | 4086 | .{ .kind = .overloaded }, |
| 3299 | .{ .kind = .overloaded }, | 4087 | .{ .kind = .overloaded }, |
| 3300 | }, | 4088 | }, |
| 3301 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4089 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3302 | }, | 4090 | }, |
| 3303 | 4091 | ||
| 3304 | .bitreverse = .{ | 4092 | .bitreverse = .{ |
| ... | @@ -3307,7 +4095,7 @@ pub const Intrinsic = enum { | ... | @@ -3307,7 +4095,7 @@ pub const Intrinsic = enum { |
| 3307 | .{ .kind = .overloaded }, | 4095 | .{ .kind = .overloaded }, |
| 3308 | .{ .kind = .{ .matches = 0 } }, | 4096 | .{ .kind = .{ .matches = 0 } }, |
| 3309 | }, | 4097 | }, |
| 3310 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4098 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3311 | }, | 4099 | }, |
| 3312 | .bswap = .{ | 4100 | .bswap = .{ |
| 3313 | .ret_len = 1, | 4101 | .ret_len = 1, |
| ... | @@ -3315,7 +4103,7 @@ pub const Intrinsic = enum { | ... | @@ -3315,7 +4103,7 @@ pub const Intrinsic = enum { |
| 3315 | .{ .kind = .overloaded }, | 4103 | .{ .kind = .overloaded }, |
| 3316 | .{ .kind = .{ .matches = 0 } }, | 4104 | .{ .kind = .{ .matches = 0 } }, |
| 3317 | }, | 4105 | }, |
| 3318 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4106 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3319 | }, | 4107 | }, |
| 3320 | .ctpop = .{ | 4108 | .ctpop = .{ |
| 3321 | .ret_len = 1, | 4109 | .ret_len = 1, |
| ... | @@ -3323,7 +4111,7 @@ pub const Intrinsic = enum { | ... | @@ -3323,7 +4111,7 @@ pub const Intrinsic = enum { |
| 3323 | .{ .kind = .overloaded }, | 4111 | .{ .kind = .overloaded }, |
| 3324 | .{ .kind = .{ .matches = 0 } }, | 4112 | .{ .kind = .{ .matches = 0 } }, |
| 3325 | }, | 4113 | }, |
| 3326 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4114 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3327 | }, | 4115 | }, |
| 3328 | .ctlz = .{ | 4116 | .ctlz = .{ |
| 3329 | .ret_len = 1, | 4117 | .ret_len = 1, |
| ... | @@ -3332,7 +4120,7 @@ pub const Intrinsic = enum { | ... | @@ -3332,7 +4120,7 @@ pub const Intrinsic = enum { |
| 3332 | .{ .kind = .{ .matches = 0 } }, | 4120 | .{ .kind = .{ .matches = 0 } }, |
| 3333 | .{ .kind = .{ .type = .i1 }, .attrs = &.{.immarg} }, | 4121 | .{ .kind = .{ .type = .i1 }, .attrs = &.{.immarg} }, |
| 3334 | }, | 4122 | }, |
| 3335 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4123 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3336 | }, | 4124 | }, |
| 3337 | .cttz = .{ | 4125 | .cttz = .{ |
| 3338 | .ret_len = 1, | 4126 | .ret_len = 1, |
| ... | @@ -3341,7 +4129,7 @@ pub const Intrinsic = enum { | ... | @@ -3341,7 +4129,7 @@ pub const Intrinsic = enum { |
| 3341 | .{ .kind = .{ .matches = 0 } }, | 4129 | .{ .kind = .{ .matches = 0 } }, |
| 3342 | .{ .kind = .{ .type = .i1 }, .attrs = &.{.immarg} }, | 4130 | .{ .kind = .{ .type = .i1 }, .attrs = &.{.immarg} }, |
| 3343 | }, | 4131 | }, |
| 3344 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4132 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3345 | }, | 4133 | }, |
| 3346 | .fshl = .{ | 4134 | .fshl = .{ |
| 3347 | .ret_len = 1, | 4135 | .ret_len = 1, |
| ... | @@ -3351,7 +4139,7 @@ pub const Intrinsic = enum { | ... | @@ -3351,7 +4139,7 @@ pub const Intrinsic = enum { |
| 3351 | .{ .kind = .{ .matches = 0 } }, | 4139 | .{ .kind = .{ .matches = 0 } }, |
| 3352 | .{ .kind = .{ .matches = 0 } }, | 4140 | .{ .kind = .{ .matches = 0 } }, |
| 3353 | }, | 4141 | }, |
| 3354 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4142 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3355 | }, | 4143 | }, |
| 3356 | .fshr = .{ | 4144 | .fshr = .{ |
| 3357 | .ret_len = 1, | 4145 | .ret_len = 1, |
| ... | @@ -3361,7 +4149,16 @@ pub const Intrinsic = enum { | ... | @@ -3361,7 +4149,16 @@ pub const Intrinsic = enum { |
| 3361 | .{ .kind = .{ .matches = 0 } }, | 4149 | .{ .kind = .{ .matches = 0 } }, |
| 3362 | .{ .kind = .{ .matches = 0 } }, | 4150 | .{ .kind = .{ .matches = 0 } }, |
| 3363 | }, | 4151 | }, |
| 3364 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4152 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 4153 | }, | ||
| 4154 | .clmul = .{ | ||
| 4155 | .ret_len = 1, | ||
| 4156 | .params = &.{ | ||
| 4157 | .{ .kind = .overloaded }, | ||
| 4158 | .{ .kind = .{ .matches = 0 } }, | ||
| 4159 | .{ .kind = .{ .matches = 0 } }, | ||
| 4160 | }, | ||
| 4161 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, | ||
| 3365 | }, | 4162 | }, |
| 3366 | 4163 | ||
| 3367 | .@"sadd.with.overflow" = .{ | 4164 | .@"sadd.with.overflow" = .{ |
| ... | @@ -3372,7 +4169,7 @@ pub const Intrinsic = enum { | ... | @@ -3372,7 +4169,7 @@ pub const Intrinsic = enum { |
| 3372 | .{ .kind = .{ .matches = 0 } }, | 4169 | .{ .kind = .{ .matches = 0 } }, |
| 3373 | .{ .kind = .{ .matches = 0 } }, | 4170 | .{ .kind = .{ .matches = 0 } }, |
| 3374 | }, | 4171 | }, |
| 3375 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4172 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3376 | }, | 4173 | }, |
| 3377 | .@"uadd.with.overflow" = .{ | 4174 | .@"uadd.with.overflow" = .{ |
| 3378 | .ret_len = 2, | 4175 | .ret_len = 2, |
| ... | @@ -3382,7 +4179,7 @@ pub const Intrinsic = enum { | ... | @@ -3382,7 +4179,7 @@ pub const Intrinsic = enum { |
| 3382 | .{ .kind = .{ .matches = 0 } }, | 4179 | .{ .kind = .{ .matches = 0 } }, |
| 3383 | .{ .kind = .{ .matches = 0 } }, | 4180 | .{ .kind = .{ .matches = 0 } }, |
| 3384 | }, | 4181 | }, |
| 3385 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4182 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3386 | }, | 4183 | }, |
| 3387 | .@"ssub.with.overflow" = .{ | 4184 | .@"ssub.with.overflow" = .{ |
| 3388 | .ret_len = 2, | 4185 | .ret_len = 2, |
| ... | @@ -3392,7 +4189,7 @@ pub const Intrinsic = enum { | ... | @@ -3392,7 +4189,7 @@ pub const Intrinsic = enum { |
| 3392 | .{ .kind = .{ .matches = 0 } }, | 4189 | .{ .kind = .{ .matches = 0 } }, |
| 3393 | .{ .kind = .{ .matches = 0 } }, | 4190 | .{ .kind = .{ .matches = 0 } }, |
| 3394 | }, | 4191 | }, |
| 3395 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4192 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3396 | }, | 4193 | }, |
| 3397 | .@"usub.with.overflow" = .{ | 4194 | .@"usub.with.overflow" = .{ |
| 3398 | .ret_len = 2, | 4195 | .ret_len = 2, |
| ... | @@ -3402,7 +4199,7 @@ pub const Intrinsic = enum { | ... | @@ -3402,7 +4199,7 @@ pub const Intrinsic = enum { |
| 3402 | .{ .kind = .{ .matches = 0 } }, | 4199 | .{ .kind = .{ .matches = 0 } }, |
| 3403 | .{ .kind = .{ .matches = 0 } }, | 4200 | .{ .kind = .{ .matches = 0 } }, |
| 3404 | }, | 4201 | }, |
| 3405 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4202 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3406 | }, | 4203 | }, |
| 3407 | .@"smul.with.overflow" = .{ | 4204 | .@"smul.with.overflow" = .{ |
| 3408 | .ret_len = 2, | 4205 | .ret_len = 2, |
| ... | @@ -3412,7 +4209,7 @@ pub const Intrinsic = enum { | ... | @@ -3412,7 +4209,7 @@ pub const Intrinsic = enum { |
| 3412 | .{ .kind = .{ .matches = 0 } }, | 4209 | .{ .kind = .{ .matches = 0 } }, |
| 3413 | .{ .kind = .{ .matches = 0 } }, | 4210 | .{ .kind = .{ .matches = 0 } }, |
| 3414 | }, | 4211 | }, |
| 3415 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4212 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3416 | }, | 4213 | }, |
| 3417 | .@"umul.with.overflow" = .{ | 4214 | .@"umul.with.overflow" = .{ |
| 3418 | .ret_len = 2, | 4215 | .ret_len = 2, |
| ... | @@ -3422,7 +4219,7 @@ pub const Intrinsic = enum { | ... | @@ -3422,7 +4219,7 @@ pub const Intrinsic = enum { |
| 3422 | .{ .kind = .{ .matches = 0 } }, | 4219 | .{ .kind = .{ .matches = 0 } }, |
| 3423 | .{ .kind = .{ .matches = 0 } }, | 4220 | .{ .kind = .{ .matches = 0 } }, |
| 3424 | }, | 4221 | }, |
| 3425 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4222 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3426 | }, | 4223 | }, |
| 3427 | 4224 | ||
| 3428 | .@"sadd.sat" = .{ | 4225 | .@"sadd.sat" = .{ |
| ... | @@ -3432,7 +4229,7 @@ pub const Intrinsic = enum { | ... | @@ -3432,7 +4229,7 @@ pub const Intrinsic = enum { |
| 3432 | .{ .kind = .{ .matches = 0 } }, | 4229 | .{ .kind = .{ .matches = 0 } }, |
| 3433 | .{ .kind = .{ .matches = 0 } }, | 4230 | .{ .kind = .{ .matches = 0 } }, |
| 3434 | }, | 4231 | }, |
| 3435 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4232 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3436 | }, | 4233 | }, |
| 3437 | .@"uadd.sat" = .{ | 4234 | .@"uadd.sat" = .{ |
| 3438 | .ret_len = 1, | 4235 | .ret_len = 1, |
| ... | @@ -3441,7 +4238,7 @@ pub const Intrinsic = enum { | ... | @@ -3441,7 +4238,7 @@ pub const Intrinsic = enum { |
| 3441 | .{ .kind = .{ .matches = 0 } }, | 4238 | .{ .kind = .{ .matches = 0 } }, |
| 3442 | .{ .kind = .{ .matches = 0 } }, | 4239 | .{ .kind = .{ .matches = 0 } }, |
| 3443 | }, | 4240 | }, |
| 3444 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4241 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3445 | }, | 4242 | }, |
| 3446 | .@"ssub.sat" = .{ | 4243 | .@"ssub.sat" = .{ |
| 3447 | .ret_len = 1, | 4244 | .ret_len = 1, |
| ... | @@ -3450,7 +4247,7 @@ pub const Intrinsic = enum { | ... | @@ -3450,7 +4247,7 @@ pub const Intrinsic = enum { |
| 3450 | .{ .kind = .{ .matches = 0 } }, | 4247 | .{ .kind = .{ .matches = 0 } }, |
| 3451 | .{ .kind = .{ .matches = 0 } }, | 4248 | .{ .kind = .{ .matches = 0 } }, |
| 3452 | }, | 4249 | }, |
| 3453 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4250 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3454 | }, | 4251 | }, |
| 3455 | .@"usub.sat" = .{ | 4252 | .@"usub.sat" = .{ |
| 3456 | .ret_len = 1, | 4253 | .ret_len = 1, |
| ... | @@ -3459,7 +4256,7 @@ pub const Intrinsic = enum { | ... | @@ -3459,7 +4256,7 @@ pub const Intrinsic = enum { |
| 3459 | .{ .kind = .{ .matches = 0 } }, | 4256 | .{ .kind = .{ .matches = 0 } }, |
| 3460 | .{ .kind = .{ .matches = 0 } }, | 4257 | .{ .kind = .{ .matches = 0 } }, |
| 3461 | }, | 4258 | }, |
| 3462 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4259 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3463 | }, | 4260 | }, |
| 3464 | .@"sshl.sat" = .{ | 4261 | .@"sshl.sat" = .{ |
| 3465 | .ret_len = 1, | 4262 | .ret_len = 1, |
| ... | @@ -3468,7 +4265,7 @@ pub const Intrinsic = enum { | ... | @@ -3468,7 +4265,7 @@ pub const Intrinsic = enum { |
| 3468 | .{ .kind = .{ .matches = 0 } }, | 4265 | .{ .kind = .{ .matches = 0 } }, |
| 3469 | .{ .kind = .{ .matches = 0 } }, | 4266 | .{ .kind = .{ .matches = 0 } }, |
| 3470 | }, | 4267 | }, |
| 3471 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4268 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3472 | }, | 4269 | }, |
| 3473 | .@"ushl.sat" = .{ | 4270 | .@"ushl.sat" = .{ |
| 3474 | .ret_len = 1, | 4271 | .ret_len = 1, |
| ... | @@ -3477,7 +4274,7 @@ pub const Intrinsic = enum { | ... | @@ -3477,7 +4274,7 @@ pub const Intrinsic = enum { |
| 3477 | .{ .kind = .{ .matches = 0 } }, | 4274 | .{ .kind = .{ .matches = 0 } }, |
| 3478 | .{ .kind = .{ .matches = 0 } }, | 4275 | .{ .kind = .{ .matches = 0 } }, |
| 3479 | }, | 4276 | }, |
| 3480 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4277 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3481 | }, | 4278 | }, |
| 3482 | 4279 | ||
| 3483 | .@"smul.fix" = .{ | 4280 | .@"smul.fix" = .{ |
| ... | @@ -3488,7 +4285,7 @@ pub const Intrinsic = enum { | ... | @@ -3488,7 +4285,7 @@ pub const Intrinsic = enum { |
| 3488 | .{ .kind = .{ .matches = 0 } }, | 4285 | .{ .kind = .{ .matches = 0 } }, |
| 3489 | .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} }, | 4286 | .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} }, |
| 3490 | }, | 4287 | }, |
| 3491 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4288 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3492 | }, | 4289 | }, |
| 3493 | .@"umul.fix" = .{ | 4290 | .@"umul.fix" = .{ |
| 3494 | .ret_len = 1, | 4291 | .ret_len = 1, |
| ... | @@ -3498,7 +4295,7 @@ pub const Intrinsic = enum { | ... | @@ -3498,7 +4295,7 @@ pub const Intrinsic = enum { |
| 3498 | .{ .kind = .{ .matches = 0 } }, | 4295 | .{ .kind = .{ .matches = 0 } }, |
| 3499 | .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} }, | 4296 | .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} }, |
| 3500 | }, | 4297 | }, |
| 3501 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4298 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3502 | }, | 4299 | }, |
| 3503 | .@"smul.fix.sat" = .{ | 4300 | .@"smul.fix.sat" = .{ |
| 3504 | .ret_len = 1, | 4301 | .ret_len = 1, |
| ... | @@ -3508,7 +4305,7 @@ pub const Intrinsic = enum { | ... | @@ -3508,7 +4305,7 @@ pub const Intrinsic = enum { |
| 3508 | .{ .kind = .{ .matches = 0 } }, | 4305 | .{ .kind = .{ .matches = 0 } }, |
| 3509 | .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} }, | 4306 | .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} }, |
| 3510 | }, | 4307 | }, |
| 3511 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4308 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3512 | }, | 4309 | }, |
| 3513 | .@"umul.fix.sat" = .{ | 4310 | .@"umul.fix.sat" = .{ |
| 3514 | .ret_len = 1, | 4311 | .ret_len = 1, |
| ... | @@ -3518,7 +4315,7 @@ pub const Intrinsic = enum { | ... | @@ -3518,7 +4315,7 @@ pub const Intrinsic = enum { |
| 3518 | .{ .kind = .{ .matches = 0 } }, | 4315 | .{ .kind = .{ .matches = 0 } }, |
| 3519 | .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} }, | 4316 | .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} }, |
| 3520 | }, | 4317 | }, |
| 3521 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4318 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3522 | }, | 4319 | }, |
| 3523 | .@"sdiv.fix" = .{ | 4320 | .@"sdiv.fix" = .{ |
| 3524 | .ret_len = 1, | 4321 | .ret_len = 1, |
| ... | @@ -3528,7 +4325,7 @@ pub const Intrinsic = enum { | ... | @@ -3528,7 +4325,7 @@ pub const Intrinsic = enum { |
| 3528 | .{ .kind = .{ .matches = 0 } }, | 4325 | .{ .kind = .{ .matches = 0 } }, |
| 3529 | .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} }, | 4326 | .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} }, |
| 3530 | }, | 4327 | }, |
| 3531 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4328 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .all(.none) } }, |
| 3532 | }, | 4329 | }, |
| 3533 | .@"udiv.fix" = .{ | 4330 | .@"udiv.fix" = .{ |
| 3534 | .ret_len = 1, | 4331 | .ret_len = 1, |
| ... | @@ -3538,7 +4335,7 @@ pub const Intrinsic = enum { | ... | @@ -3538,7 +4335,7 @@ pub const Intrinsic = enum { |
| 3538 | .{ .kind = .{ .matches = 0 } }, | 4335 | .{ .kind = .{ .matches = 0 } }, |
| 3539 | .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} }, | 4336 | .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} }, |
| 3540 | }, | 4337 | }, |
| 3541 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4338 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .all(.none) } }, |
| 3542 | }, | 4339 | }, |
| 3543 | .@"sdiv.fix.sat" = .{ | 4340 | .@"sdiv.fix.sat" = .{ |
| 3544 | .ret_len = 1, | 4341 | .ret_len = 1, |
| ... | @@ -3548,7 +4345,7 @@ pub const Intrinsic = enum { | ... | @@ -3548,7 +4345,7 @@ pub const Intrinsic = enum { |
| 3548 | .{ .kind = .{ .matches = 0 } }, | 4345 | .{ .kind = .{ .matches = 0 } }, |
| 3549 | .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} }, | 4346 | .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} }, |
| 3550 | }, | 4347 | }, |
| 3551 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4348 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .all(.none) } }, |
| 3552 | }, | 4349 | }, |
| 3553 | .@"udiv.fix.sat" = .{ | 4350 | .@"udiv.fix.sat" = .{ |
| 3554 | .ret_len = 1, | 4351 | .ret_len = 1, |
| ... | @@ -3558,7 +4355,7 @@ pub const Intrinsic = enum { | ... | @@ -3558,7 +4355,7 @@ pub const Intrinsic = enum { |
| 3558 | .{ .kind = .{ .matches = 0 } }, | 4355 | .{ .kind = .{ .matches = 0 } }, |
| 3559 | .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} }, | 4356 | .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} }, |
| 3560 | }, | 4357 | }, |
| 3561 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4358 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .all(.none) } }, |
| 3562 | }, | 4359 | }, |
| 3563 | 4360 | ||
| 3564 | .canonicalize = .{ | 4361 | .canonicalize = .{ |
| ... | @@ -3567,7 +4364,7 @@ pub const Intrinsic = enum { | ... | @@ -3567,7 +4364,7 @@ pub const Intrinsic = enum { |
| 3567 | .{ .kind = .overloaded }, | 4364 | .{ .kind = .overloaded }, |
| 3568 | .{ .kind = .{ .matches = 0 } }, | 4365 | .{ .kind = .{ .matches = 0 } }, |
| 3569 | }, | 4366 | }, |
| 3570 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4367 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3571 | }, | 4368 | }, |
| 3572 | .fmuladd = .{ | 4369 | .fmuladd = .{ |
| 3573 | .ret_len = 1, | 4370 | .ret_len = 1, |
| ... | @@ -3577,7 +4374,7 @@ pub const Intrinsic = enum { | ... | @@ -3577,7 +4374,7 @@ pub const Intrinsic = enum { |
| 3577 | .{ .kind = .{ .matches = 0 } }, | 4374 | .{ .kind = .{ .matches = 0 } }, |
| 3578 | .{ .kind = .{ .matches = 0 } }, | 4375 | .{ .kind = .{ .matches = 0 } }, |
| 3579 | }, | 4376 | }, |
| 3580 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4377 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3581 | }, | 4378 | }, |
| 3582 | 4379 | ||
| 3583 | .@"vector.reduce.add" = .{ | 4380 | .@"vector.reduce.add" = .{ |
| ... | @@ -3586,7 +4383,7 @@ pub const Intrinsic = enum { | ... | @@ -3586,7 +4383,7 @@ pub const Intrinsic = enum { |
| 3586 | .{ .kind = .{ .matches_scalar = 1 } }, | 4383 | .{ .kind = .{ .matches_scalar = 1 } }, |
| 3587 | .{ .kind = .overloaded }, | 4384 | .{ .kind = .overloaded }, |
| 3588 | }, | 4385 | }, |
| 3589 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4386 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3590 | }, | 4387 | }, |
| 3591 | .@"vector.reduce.fadd" = .{ | 4388 | .@"vector.reduce.fadd" = .{ |
| 3592 | .ret_len = 1, | 4389 | .ret_len = 1, |
| ... | @@ -3595,7 +4392,7 @@ pub const Intrinsic = enum { | ... | @@ -3595,7 +4392,7 @@ pub const Intrinsic = enum { |
| 3595 | .{ .kind = .{ .matches_scalar = 2 } }, | 4392 | .{ .kind = .{ .matches_scalar = 2 } }, |
| 3596 | .{ .kind = .overloaded }, | 4393 | .{ .kind = .overloaded }, |
| 3597 | }, | 4394 | }, |
| 3598 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4395 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3599 | }, | 4396 | }, |
| 3600 | .@"vector.reduce.mul" = .{ | 4397 | .@"vector.reduce.mul" = .{ |
| 3601 | .ret_len = 1, | 4398 | .ret_len = 1, |
| ... | @@ -3603,7 +4400,7 @@ pub const Intrinsic = enum { | ... | @@ -3603,7 +4400,7 @@ pub const Intrinsic = enum { |
| 3603 | .{ .kind = .{ .matches_scalar = 1 } }, | 4400 | .{ .kind = .{ .matches_scalar = 1 } }, |
| 3604 | .{ .kind = .overloaded }, | 4401 | .{ .kind = .overloaded }, |
| 3605 | }, | 4402 | }, |
| 3606 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4403 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3607 | }, | 4404 | }, |
| 3608 | .@"vector.reduce.fmul" = .{ | 4405 | .@"vector.reduce.fmul" = .{ |
| 3609 | .ret_len = 1, | 4406 | .ret_len = 1, |
| ... | @@ -3612,7 +4409,7 @@ pub const Intrinsic = enum { | ... | @@ -3612,7 +4409,7 @@ pub const Intrinsic = enum { |
| 3612 | .{ .kind = .{ .matches_scalar = 2 } }, | 4409 | .{ .kind = .{ .matches_scalar = 2 } }, |
| 3613 | .{ .kind = .overloaded }, | 4410 | .{ .kind = .overloaded }, |
| 3614 | }, | 4411 | }, |
| 3615 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4412 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3616 | }, | 4413 | }, |
| 3617 | .@"vector.reduce.and" = .{ | 4414 | .@"vector.reduce.and" = .{ |
| 3618 | .ret_len = 1, | 4415 | .ret_len = 1, |
| ... | @@ -3620,7 +4417,7 @@ pub const Intrinsic = enum { | ... | @@ -3620,7 +4417,7 @@ pub const Intrinsic = enum { |
| 3620 | .{ .kind = .{ .matches_scalar = 1 } }, | 4417 | .{ .kind = .{ .matches_scalar = 1 } }, |
| 3621 | .{ .kind = .overloaded }, | 4418 | .{ .kind = .overloaded }, |
| 3622 | }, | 4419 | }, |
| 3623 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4420 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3624 | }, | 4421 | }, |
| 3625 | .@"vector.reduce.or" = .{ | 4422 | .@"vector.reduce.or" = .{ |
| 3626 | .ret_len = 1, | 4423 | .ret_len = 1, |
| ... | @@ -3628,7 +4425,7 @@ pub const Intrinsic = enum { | ... | @@ -3628,7 +4425,7 @@ pub const Intrinsic = enum { |
| 3628 | .{ .kind = .{ .matches_scalar = 1 } }, | 4425 | .{ .kind = .{ .matches_scalar = 1 } }, |
| 3629 | .{ .kind = .overloaded }, | 4426 | .{ .kind = .overloaded }, |
| 3630 | }, | 4427 | }, |
| 3631 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4428 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3632 | }, | 4429 | }, |
| 3633 | .@"vector.reduce.xor" = .{ | 4430 | .@"vector.reduce.xor" = .{ |
| 3634 | .ret_len = 1, | 4431 | .ret_len = 1, |
| ... | @@ -3636,7 +4433,7 @@ pub const Intrinsic = enum { | ... | @@ -3636,7 +4433,7 @@ pub const Intrinsic = enum { |
| 3636 | .{ .kind = .{ .matches_scalar = 1 } }, | 4433 | .{ .kind = .{ .matches_scalar = 1 } }, |
| 3637 | .{ .kind = .overloaded }, | 4434 | .{ .kind = .overloaded }, |
| 3638 | }, | 4435 | }, |
| 3639 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4436 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3640 | }, | 4437 | }, |
| 3641 | .@"vector.reduce.smax" = .{ | 4438 | .@"vector.reduce.smax" = .{ |
| 3642 | .ret_len = 1, | 4439 | .ret_len = 1, |
| ... | @@ -3644,7 +4441,7 @@ pub const Intrinsic = enum { | ... | @@ -3644,7 +4441,7 @@ pub const Intrinsic = enum { |
| 3644 | .{ .kind = .{ .matches_scalar = 1 } }, | 4441 | .{ .kind = .{ .matches_scalar = 1 } }, |
| 3645 | .{ .kind = .overloaded }, | 4442 | .{ .kind = .overloaded }, |
| 3646 | }, | 4443 | }, |
| 3647 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4444 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3648 | }, | 4445 | }, |
| 3649 | .@"vector.reduce.smin" = .{ | 4446 | .@"vector.reduce.smin" = .{ |
| 3650 | .ret_len = 1, | 4447 | .ret_len = 1, |
| ... | @@ -3652,7 +4449,7 @@ pub const Intrinsic = enum { | ... | @@ -3652,7 +4449,7 @@ pub const Intrinsic = enum { |
| 3652 | .{ .kind = .{ .matches_scalar = 1 } }, | 4449 | .{ .kind = .{ .matches_scalar = 1 } }, |
| 3653 | .{ .kind = .overloaded }, | 4450 | .{ .kind = .overloaded }, |
| 3654 | }, | 4451 | }, |
| 3655 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4452 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3656 | }, | 4453 | }, |
| 3657 | .@"vector.reduce.umax" = .{ | 4454 | .@"vector.reduce.umax" = .{ |
| 3658 | .ret_len = 1, | 4455 | .ret_len = 1, |
| ... | @@ -3660,7 +4457,7 @@ pub const Intrinsic = enum { | ... | @@ -3660,7 +4457,7 @@ pub const Intrinsic = enum { |
| 3660 | .{ .kind = .{ .matches_scalar = 1 } }, | 4457 | .{ .kind = .{ .matches_scalar = 1 } }, |
| 3661 | .{ .kind = .overloaded }, | 4458 | .{ .kind = .overloaded }, |
| 3662 | }, | 4459 | }, |
| 3663 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4460 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3664 | }, | 4461 | }, |
| 3665 | .@"vector.reduce.umin" = .{ | 4462 | .@"vector.reduce.umin" = .{ |
| 3666 | .ret_len = 1, | 4463 | .ret_len = 1, |
| ... | @@ -3668,7 +4465,7 @@ pub const Intrinsic = enum { | ... | @@ -3668,7 +4465,7 @@ pub const Intrinsic = enum { |
| 3668 | .{ .kind = .{ .matches_scalar = 1 } }, | 4465 | .{ .kind = .{ .matches_scalar = 1 } }, |
| 3669 | .{ .kind = .overloaded }, | 4466 | .{ .kind = .overloaded }, |
| 3670 | }, | 4467 | }, |
| 3671 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4468 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3672 | }, | 4469 | }, |
| 3673 | .@"vector.reduce.fmax" = .{ | 4470 | .@"vector.reduce.fmax" = .{ |
| 3674 | .ret_len = 1, | 4471 | .ret_len = 1, |
| ... | @@ -3676,7 +4473,7 @@ pub const Intrinsic = enum { | ... | @@ -3676,7 +4473,7 @@ pub const Intrinsic = enum { |
| 3676 | .{ .kind = .{ .matches_scalar = 1 } }, | 4473 | .{ .kind = .{ .matches_scalar = 1 } }, |
| 3677 | .{ .kind = .overloaded }, | 4474 | .{ .kind = .overloaded }, |
| 3678 | }, | 4475 | }, |
| 3679 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4476 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3680 | }, | 4477 | }, |
| 3681 | .@"vector.reduce.fmin" = .{ | 4478 | .@"vector.reduce.fmin" = .{ |
| 3682 | .ret_len = 1, | 4479 | .ret_len = 1, |
| ... | @@ -3684,7 +4481,7 @@ pub const Intrinsic = enum { | ... | @@ -3684,7 +4481,7 @@ pub const Intrinsic = enum { |
| 3684 | .{ .kind = .{ .matches_scalar = 1 } }, | 4481 | .{ .kind = .{ .matches_scalar = 1 } }, |
| 3685 | .{ .kind = .overloaded }, | 4482 | .{ .kind = .overloaded }, |
| 3686 | }, | 4483 | }, |
| 3687 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4484 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3688 | }, | 4485 | }, |
| 3689 | .@"vector.reduce.fmaximum" = .{ | 4486 | .@"vector.reduce.fmaximum" = .{ |
| 3690 | .ret_len = 1, | 4487 | .ret_len = 1, |
| ... | @@ -3692,7 +4489,7 @@ pub const Intrinsic = enum { | ... | @@ -3692,7 +4489,7 @@ pub const Intrinsic = enum { |
| 3692 | .{ .kind = .{ .matches_scalar = 1 } }, | 4489 | .{ .kind = .{ .matches_scalar = 1 } }, |
| 3693 | .{ .kind = .overloaded }, | 4490 | .{ .kind = .overloaded }, |
| 3694 | }, | 4491 | }, |
| 3695 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4492 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3696 | }, | 4493 | }, |
| 3697 | .@"vector.reduce.fminimum" = .{ | 4494 | .@"vector.reduce.fminimum" = .{ |
| 3698 | .ret_len = 1, | 4495 | .ret_len = 1, |
| ... | @@ -3700,7 +4497,7 @@ pub const Intrinsic = enum { | ... | @@ -3700,7 +4497,7 @@ pub const Intrinsic = enum { |
| 3700 | .{ .kind = .{ .matches_scalar = 1 } }, | 4497 | .{ .kind = .{ .matches_scalar = 1 } }, |
| 3701 | .{ .kind = .overloaded }, | 4498 | .{ .kind = .overloaded }, |
| 3702 | }, | 4499 | }, |
| 3703 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4500 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3704 | }, | 4501 | }, |
| 3705 | .@"vector.insert" = .{ | 4502 | .@"vector.insert" = .{ |
| 3706 | .ret_len = 1, | 4503 | .ret_len = 1, |
| ... | @@ -3710,7 +4507,7 @@ pub const Intrinsic = enum { | ... | @@ -3710,7 +4507,7 @@ pub const Intrinsic = enum { |
| 3710 | .{ .kind = .overloaded }, | 4507 | .{ .kind = .overloaded }, |
| 3711 | .{ .kind = .{ .type = .i64 } }, | 4508 | .{ .kind = .{ .type = .i64 } }, |
| 3712 | }, | 4509 | }, |
| 3713 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4510 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3714 | }, | 4511 | }, |
| 3715 | .@"vector.extract" = .{ | 4512 | .@"vector.extract" = .{ |
| 3716 | .ret_len = 1, | 4513 | .ret_len = 1, |
| ... | @@ -3719,7 +4516,7 @@ pub const Intrinsic = enum { | ... | @@ -3719,7 +4516,7 @@ pub const Intrinsic = enum { |
| 3719 | .{ .kind = .overloaded }, | 4516 | .{ .kind = .overloaded }, |
| 3720 | .{ .kind = .{ .type = .i64 } }, | 4517 | .{ .kind = .{ .type = .i64 } }, |
| 3721 | }, | 4518 | }, |
| 3722 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4519 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3723 | }, | 4520 | }, |
| 3724 | 4521 | ||
| 3725 | .@"is.fpclass" = .{ | 4522 | .@"is.fpclass" = .{ |
| ... | @@ -3729,7 +4526,7 @@ pub const Intrinsic = enum { | ... | @@ -3729,7 +4526,7 @@ pub const Intrinsic = enum { |
| 3729 | .{ .kind = .overloaded }, | 4526 | .{ .kind = .overloaded }, |
| 3730 | .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} }, | 4527 | .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} }, |
| 3731 | }, | 4528 | }, |
| 3732 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4529 | .attrs = &.{ .nocallback, .nocreateundeforpoison, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3733 | }, | 4530 | }, |
| 3734 | 4531 | ||
| 3735 | .@"var.annotation" = .{ | 4532 | .@"var.annotation" = .{ |
| ... | @@ -3814,7 +4611,7 @@ pub const Intrinsic = enum { | ... | @@ -3814,7 +4611,7 @@ pub const Intrinsic = enum { |
| 3814 | .{ .kind = .{ .type = .i1 }, .attrs = &.{.immarg} }, | 4611 | .{ .kind = .{ .type = .i1 }, .attrs = &.{.immarg} }, |
| 3815 | .{ .kind = .{ .type = .i1 }, .attrs = &.{.immarg} }, | 4612 | .{ .kind = .{ .type = .i1 }, .attrs = &.{.immarg} }, |
| 3816 | }, | 4613 | }, |
| 3817 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4614 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3818 | }, | 4615 | }, |
| 3819 | .expect = .{ | 4616 | .expect = .{ |
| 3820 | .ret_len = 1, | 4617 | .ret_len = 1, |
| ... | @@ -3823,7 +4620,7 @@ pub const Intrinsic = enum { | ... | @@ -3823,7 +4620,7 @@ pub const Intrinsic = enum { |
| 3823 | .{ .kind = .{ .matches = 0 } }, | 4620 | .{ .kind = .{ .matches = 0 } }, |
| 3824 | .{ .kind = .{ .matches = 0 } }, | 4621 | .{ .kind = .{ .matches = 0 } }, |
| 3825 | }, | 4622 | }, |
| 3826 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4623 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .all(.none) } }, |
| 3827 | }, | 4624 | }, |
| 3828 | .@"expect.with.probability" = .{ | 4625 | .@"expect.with.probability" = .{ |
| 3829 | .ret_len = 1, | 4626 | .ret_len = 1, |
| ... | @@ -3833,7 +4630,7 @@ pub const Intrinsic = enum { | ... | @@ -3833,7 +4630,7 @@ pub const Intrinsic = enum { |
| 3833 | .{ .kind = .{ .matches = 0 } }, | 4630 | .{ .kind = .{ .matches = 0 } }, |
| 3834 | .{ .kind = .{ .type = .double }, .attrs = &.{.immarg} }, | 4631 | .{ .kind = .{ .type = .double }, .attrs = &.{.immarg} }, |
| 3835 | }, | 4632 | }, |
| 3836 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4633 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .all(.none) } }, |
| 3837 | }, | 4634 | }, |
| 3838 | .assume = .{ | 4635 | .assume = .{ |
| 3839 | .ret_len = 0, | 4636 | .ret_len = 0, |
| ... | @@ -3848,7 +4645,7 @@ pub const Intrinsic = enum { | ... | @@ -3848,7 +4645,7 @@ pub const Intrinsic = enum { |
| 3848 | .{ .kind = .overloaded }, | 4645 | .{ .kind = .overloaded }, |
| 3849 | .{ .kind = .{ .matches = 0 }, .attrs = &.{.returned} }, | 4646 | .{ .kind = .{ .matches = 0 }, .attrs = &.{.returned} }, |
| 3850 | }, | 4647 | }, |
| 3851 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4648 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .all(.none) } }, |
| 3852 | }, | 4649 | }, |
| 3853 | .@"type.test" = .{ | 4650 | .@"type.test" = .{ |
| 3854 | .ret_len = 1, | 4651 | .ret_len = 1, |
| ... | @@ -3857,7 +4654,7 @@ pub const Intrinsic = enum { | ... | @@ -3857,7 +4654,7 @@ pub const Intrinsic = enum { |
| 3857 | .{ .kind = .{ .type = .ptr } }, | 4654 | .{ .kind = .{ .type = .ptr } }, |
| 3858 | .{ .kind = .{ .type = .metadata } }, | 4655 | .{ .kind = .{ .type = .metadata } }, |
| 3859 | }, | 4656 | }, |
| 3860 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4657 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3861 | }, | 4658 | }, |
| 3862 | .@"type.checked.load" = .{ | 4659 | .@"type.checked.load" = .{ |
| 3863 | .ret_len = 2, | 4660 | .ret_len = 2, |
| ... | @@ -3868,7 +4665,7 @@ pub const Intrinsic = enum { | ... | @@ -3868,7 +4665,7 @@ pub const Intrinsic = enum { |
| 3868 | .{ .kind = .{ .type = .i32 } }, | 4665 | .{ .kind = .{ .type = .i32 } }, |
| 3869 | .{ .kind = .{ .type = .metadata } }, | 4666 | .{ .kind = .{ .type = .metadata } }, |
| 3870 | }, | 4667 | }, |
| 3871 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4668 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .all(.none) } }, |
| 3872 | }, | 4669 | }, |
| 3873 | .@"type.checked.load.relative" = .{ | 4670 | .@"type.checked.load.relative" = .{ |
| 3874 | .ret_len = 2, | 4671 | .ret_len = 2, |
| ... | @@ -3879,7 +4676,7 @@ pub const Intrinsic = enum { | ... | @@ -3879,7 +4676,7 @@ pub const Intrinsic = enum { |
| 3879 | .{ .kind = .{ .type = .i32 } }, | 4676 | .{ .kind = .{ .type = .i32 } }, |
| 3880 | .{ .kind = .{ .type = .metadata } }, | 4677 | .{ .kind = .{ .type = .metadata } }, |
| 3881 | }, | 4678 | }, |
| 3882 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4679 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .all(.none) } }, |
| 3883 | }, | 4680 | }, |
| 3884 | .@"arithmetic.fence" = .{ | 4681 | .@"arithmetic.fence" = .{ |
| 3885 | .ret_len = 1, | 4682 | .ret_len = 1, |
| ... | @@ -3887,12 +4684,12 @@ pub const Intrinsic = enum { | ... | @@ -3887,12 +4684,12 @@ pub const Intrinsic = enum { |
| 3887 | .{ .kind = .overloaded }, | 4684 | .{ .kind = .overloaded }, |
| 3888 | .{ .kind = .{ .matches = 0 } }, | 4685 | .{ .kind = .{ .matches = 0 } }, |
| 3889 | }, | 4686 | }, |
| 3890 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4687 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3891 | }, | 4688 | }, |
| 3892 | .donothing = .{ | 4689 | .donothing = .{ |
| 3893 | .ret_len = 0, | 4690 | .ret_len = 0, |
| 3894 | .params = &.{}, | 4691 | .params = &.{}, |
| 3895 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4692 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .all(.none) } }, |
| 3896 | }, | 4693 | }, |
| 3897 | .@"load.relative" = .{ | 4694 | .@"load.relative" = .{ |
| 3898 | .ret_len = 1, | 4695 | .ret_len = 1, |
| ... | @@ -3914,7 +4711,7 @@ pub const Intrinsic = enum { | ... | @@ -3914,7 +4711,7 @@ pub const Intrinsic = enum { |
| 3914 | .{ .kind = .{ .type = .i1 } }, | 4711 | .{ .kind = .{ .type = .i1 } }, |
| 3915 | .{ .kind = .overloaded }, | 4712 | .{ .kind = .overloaded }, |
| 3916 | }, | 4713 | }, |
| 3917 | .attrs = &.{ .convergent, .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4714 | .attrs = &.{ .convergent, .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .all(.none) } }, |
| 3918 | }, | 4715 | }, |
| 3919 | .ptrmask = .{ | 4716 | .ptrmask = .{ |
| 3920 | .ret_len = 1, | 4717 | .ret_len = 1, |
| ... | @@ -3923,7 +4720,7 @@ pub const Intrinsic = enum { | ... | @@ -3923,7 +4720,7 @@ pub const Intrinsic = enum { |
| 3923 | .{ .kind = .{ .matches = 0 } }, | 4720 | .{ .kind = .{ .matches = 0 } }, |
| 3924 | .{ .kind = .overloaded }, | 4721 | .{ .kind = .overloaded }, |
| 3925 | }, | 4722 | }, |
| 3926 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4723 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3927 | }, | 4724 | }, |
| 3928 | .@"threadlocal.address" = .{ | 4725 | .@"threadlocal.address" = .{ |
| 3929 | .ret_len = 1, | 4726 | .ret_len = 1, |
| ... | @@ -3931,14 +4728,14 @@ pub const Intrinsic = enum { | ... | @@ -3931,14 +4728,14 @@ pub const Intrinsic = enum { |
| 3931 | .{ .kind = .overloaded, .attrs = &.{.nonnull} }, | 4728 | .{ .kind = .overloaded, .attrs = &.{.nonnull} }, |
| 3932 | .{ .kind = .{ .matches = 0 }, .attrs = &.{.nonnull} }, | 4729 | .{ .kind = .{ .matches = 0 }, .attrs = &.{.nonnull} }, |
| 3933 | }, | 4730 | }, |
| 3934 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4731 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3935 | }, | 4732 | }, |
| 3936 | .vscale = .{ | 4733 | .vscale = .{ |
| 3937 | .ret_len = 1, | 4734 | .ret_len = 1, |
| 3938 | .params = &.{ | 4735 | .params = &.{ |
| 3939 | .{ .kind = .overloaded }, | 4736 | .{ .kind = .overloaded }, |
| 3940 | }, | 4737 | }, |
| 3941 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4738 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .all(.none) } }, |
| 3942 | }, | 4739 | }, |
| 3943 | 4740 | ||
| 3944 | .@"dbg.declare" = .{ | 4741 | .@"dbg.declare" = .{ |
| ... | @@ -3948,7 +4745,7 @@ pub const Intrinsic = enum { | ... | @@ -3948,7 +4745,7 @@ pub const Intrinsic = enum { |
| 3948 | .{ .kind = .{ .type = .metadata } }, | 4745 | .{ .kind = .{ .type = .metadata } }, |
| 3949 | .{ .kind = .{ .type = .metadata } }, | 4746 | .{ .kind = .{ .type = .metadata } }, |
| 3950 | }, | 4747 | }, |
| 3951 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4748 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3952 | }, | 4749 | }, |
| 3953 | .@"dbg.value" = .{ | 4750 | .@"dbg.value" = .{ |
| 3954 | .ret_len = 0, | 4751 | .ret_len = 0, |
| ... | @@ -3957,7 +4754,7 @@ pub const Intrinsic = enum { | ... | @@ -3957,7 +4754,7 @@ pub const Intrinsic = enum { |
| 3957 | .{ .kind = .{ .type = .metadata } }, | 4754 | .{ .kind = .{ .type = .metadata } }, |
| 3958 | .{ .kind = .{ .type = .metadata } }, | 4755 | .{ .kind = .{ .type = .metadata } }, |
| 3959 | }, | 4756 | }, |
| 3960 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4757 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3961 | }, | 4758 | }, |
| 3962 | 4759 | ||
| 3963 | .@"amdgcn.workitem.id.x" = .{ | 4760 | .@"amdgcn.workitem.id.x" = .{ |
| ... | @@ -3965,42 +4762,42 @@ pub const Intrinsic = enum { | ... | @@ -3965,42 +4762,42 @@ pub const Intrinsic = enum { |
| 3965 | .params = &.{ | 4762 | .params = &.{ |
| 3966 | .{ .kind = .{ .type = .i32 } }, | 4763 | .{ .kind = .{ .type = .i32 } }, |
| 3967 | }, | 4764 | }, |
| 3968 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4765 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3969 | }, | 4766 | }, |
| 3970 | .@"amdgcn.workitem.id.y" = .{ | 4767 | .@"amdgcn.workitem.id.y" = .{ |
| 3971 | .ret_len = 1, | 4768 | .ret_len = 1, |
| 3972 | .params = &.{ | 4769 | .params = &.{ |
| 3973 | .{ .kind = .{ .type = .i32 } }, | 4770 | .{ .kind = .{ .type = .i32 } }, |
| 3974 | }, | 4771 | }, |
| 3975 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4772 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3976 | }, | 4773 | }, |
| 3977 | .@"amdgcn.workitem.id.z" = .{ | 4774 | .@"amdgcn.workitem.id.z" = .{ |
| 3978 | .ret_len = 1, | 4775 | .ret_len = 1, |
| 3979 | .params = &.{ | 4776 | .params = &.{ |
| 3980 | .{ .kind = .{ .type = .i32 } }, | 4777 | .{ .kind = .{ .type = .i32 } }, |
| 3981 | }, | 4778 | }, |
| 3982 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4779 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3983 | }, | 4780 | }, |
| 3984 | .@"amdgcn.workgroup.id.x" = .{ | 4781 | .@"amdgcn.workgroup.id.x" = .{ |
| 3985 | .ret_len = 1, | 4782 | .ret_len = 1, |
| 3986 | .params = &.{ | 4783 | .params = &.{ |
| 3987 | .{ .kind = .{ .type = .i32 } }, | 4784 | .{ .kind = .{ .type = .i32 } }, |
| 3988 | }, | 4785 | }, |
| 3989 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4786 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3990 | }, | 4787 | }, |
| 3991 | .@"amdgcn.workgroup.id.y" = .{ | 4788 | .@"amdgcn.workgroup.id.y" = .{ |
| 3992 | .ret_len = 1, | 4789 | .ret_len = 1, |
| 3993 | .params = &.{ | 4790 | .params = &.{ |
| 3994 | .{ .kind = .{ .type = .i32 } }, | 4791 | .{ .kind = .{ .type = .i32 } }, |
| 3995 | }, | 4792 | }, |
| 3996 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4793 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 3997 | }, | 4794 | }, |
| 3998 | .@"amdgcn.workgroup.id.z" = .{ | 4795 | .@"amdgcn.workgroup.id.z" = .{ |
| 3999 | .ret_len = 1, | 4796 | .ret_len = 1, |
| 4000 | .params = &.{ | 4797 | .params = &.{ |
| 4001 | .{ .kind = .{ .type = .i32 } }, | 4798 | .{ .kind = .{ .type = .i32 } }, |
| 4002 | }, | 4799 | }, |
| 4003 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4800 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 4004 | }, | 4801 | }, |
| 4005 | .@"amdgcn.dispatch.ptr" = .{ | 4802 | .@"amdgcn.dispatch.ptr" = .{ |
| 4006 | .ret_len = 1, | 4803 | .ret_len = 1, |
| ... | @@ -4010,7 +4807,7 @@ pub const Intrinsic = enum { | ... | @@ -4010,7 +4807,7 @@ pub const Intrinsic = enum { |
| 4010 | .attrs = &.{.{ .@"align" = .wrap(.fromByteUnits(4)) }}, | 4807 | .attrs = &.{.{ .@"align" = .wrap(.fromByteUnits(4)) }}, |
| 4011 | }, | 4808 | }, |
| 4012 | }, | 4809 | }, |
| 4013 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4810 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = .all(.none) } }, |
| 4014 | }, | 4811 | }, |
| 4015 | 4812 | ||
| 4016 | .@"nvvm.read.ptx.sreg.tid.x" = .{ | 4813 | .@"nvvm.read.ptx.sreg.tid.x" = .{ |
| ... | @@ -4085,7 +4882,7 @@ pub const Intrinsic = enum { | ... | @@ -4085,7 +4882,7 @@ pub const Intrinsic = enum { |
| 4085 | .{ .kind = .overloaded }, | 4882 | .{ .kind = .overloaded }, |
| 4086 | .{ .kind = .{ .type = .i32 } }, | 4883 | .{ .kind = .{ .type = .i32 } }, |
| 4087 | }, | 4884 | }, |
| 4088 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } }, | 4885 | .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .all(.none) } }, |
| 4089 | }, | 4886 | }, |
| 4090 | .@"wasm.memory.grow" = .{ | 4887 | .@"wasm.memory.grow" = .{ |
| 4091 | .ret_len = 1, | 4888 | .ret_len = 1, |
| ... | @@ -4166,6 +4963,10 @@ pub const Function = struct { | ... | @@ -4166,6 +4963,10 @@ pub const Function = struct { |
| 4166 | self.ptr(builder).attributes = new_function_attributes; | 4963 | self.ptr(builder).attributes = new_function_attributes; |
| 4167 | } | 4964 | } |
| 4168 | 4965 | ||
| 4966 | pub fn getAttributes(self: Index, builder: *Builder) FunctionAttributes { | ||
| 4967 | return self.ptr(builder).attributes; | ||
| 4968 | } | ||
| 4969 | |||
| 4169 | pub fn setSection(self: Index, section: String, builder: *Builder) void { | 4970 | pub fn setSection(self: Index, section: String, builder: *Builder) void { |
| 4170 | self.ptr(builder).section = section; | 4971 | self.ptr(builder).section = section; |
| 4171 | } | 4972 | } |
| ... | @@ -4487,7 +5288,7 @@ pub const Function = struct { | ... | @@ -4487,7 +5288,7 @@ pub const Function = struct { |
| 4487 | } | 5288 | } |
| 4488 | 5289 | ||
| 4489 | pub fn toValue(self: Instruction.Index) Value { | 5290 | pub fn toValue(self: Instruction.Index) Value { |
| 4490 | return @fromBackingInt(@intCast(@backingInt(self))); | 5291 | return @fromBackingInt(@backingInt(self)); |
| 4491 | } | 5292 | } |
| 4492 | 5293 | ||
| 4493 | pub fn isTerminatorWip(self: Instruction.Index, wip: *const WipFunction) bool { | 5294 | pub fn isTerminatorWip(self: Instruction.Index, wip: *const WipFunction) bool { |
| ... | @@ -4679,7 +5480,7 @@ pub const Function = struct { | ... | @@ -4679,7 +5480,7 @@ pub const Function = struct { |
| 4679 | .changeScalarAssumeCapacity(.i1, wip.builder), | 5480 | .changeScalarAssumeCapacity(.i1, wip.builder), |
| 4680 | .fneg, | 5481 | .fneg, |
| 4681 | .@"fneg fast", | 5482 | .@"fneg fast", |
| 4682 | => @as(Value, @fromBackingInt(@intCast(instruction.data))).typeOfWip(wip), | 5483 | => @as(Value, @fromBackingInt(instruction.data)).typeOfWip(wip), |
| 4683 | .getelementptr, | 5484 | .getelementptr, |
| 4684 | .@"getelementptr inbounds", | 5485 | .@"getelementptr inbounds", |
| 4685 | => { | 5486 | => { |
| ... | @@ -4871,7 +5672,7 @@ pub const Function = struct { | ... | @@ -4871,7 +5672,7 @@ pub const Function = struct { |
| 4871 | .changeScalarAssumeCapacity(.i1, builder), | 5672 | .changeScalarAssumeCapacity(.i1, builder), |
| 4872 | .fneg, | 5673 | .fneg, |
| 4873 | .@"fneg fast", | 5674 | .@"fneg fast", |
| 4874 | => @as(Value, @fromBackingInt(@intCast(instruction.data))).typeOf(function_index, builder), | 5675 | => @as(Value, @fromBackingInt(instruction.data)).typeOf(function_index, builder), |
| 4875 | .getelementptr, | 5676 | .getelementptr, |
| 4876 | .@"getelementptr inbounds", | 5677 | .@"getelementptr inbounds", |
| 4877 | => { | 5678 | => { |
| ... | @@ -4963,7 +5764,7 @@ pub const Function = struct { | ... | @@ -4963,7 +5764,7 @@ pub const Function = struct { |
| 4963 | 5764 | ||
| 4964 | pub fn fromMetadata(metadata: Metadata) Weights { | 5765 | pub fn fromMetadata(metadata: Metadata) Weights { |
| 4965 | assert(metadata.kind == .node); | 5766 | assert(metadata.kind == .node); |
| 4966 | return @fromBackingInt(@intCast(metadata.index)); | 5767 | return @fromBackingInt(metadata.index); |
| 4967 | } | 5768 | } |
| 4968 | 5769 | ||
| 4969 | pub fn toMetadata(weights: Weights) Metadata { | 5770 | pub fn toMetadata(weights: Weights) Metadata { |
| ... | @@ -5156,7 +5957,7 @@ pub const Function = struct { | ... | @@ -5156,7 +5957,7 @@ pub const Function = struct { |
| 5156 | assert(argument.tag == .arg); | 5957 | assert(argument.tag == .arg); |
| 5157 | assert(argument.data == index); | 5958 | assert(argument.data == index); |
| 5158 | 5959 | ||
| 5159 | const argument_index: Instruction.Index = @fromBackingInt(@intCast(index)); | 5960 | const argument_index: Instruction.Index = @fromBackingInt(index); |
| 5160 | return argument_index.toValue(); | 5961 | return argument_index.toValue(); |
| 5161 | } | 5962 | } |
| 5162 | 5963 | ||
| ... | @@ -5202,7 +6003,7 @@ pub const Function = struct { | ... | @@ -5202,7 +6003,7 @@ pub const Function = struct { |
| 5202 | Type, | 6003 | Type, |
| 5203 | Value, | 6004 | Value, |
| 5204 | Instruction.BrCond.Weights, | 6005 | Instruction.BrCond.Weights, |
| 5205 | => @fromBackingInt(@intCast(value)), | 6006 | => @fromBackingInt(value), |
| 5206 | MemoryAccessInfo, | 6007 | MemoryAccessInfo, |
| 5207 | Instruction.Alloca.Info, | 6008 | Instruction.Alloca.Info, |
| 5208 | Instruction.Call.Info, | 6009 | Instruction.Call.Info, |
| ... | @@ -5327,7 +6128,7 @@ pub const WipFunction = struct { | ... | @@ -5327,7 +6128,7 @@ pub const WipFunction = struct { |
| 5327 | assert(argument.tag == .arg); | 6128 | assert(argument.tag == .arg); |
| 5328 | assert(argument.data == index); | 6129 | assert(argument.data == index); |
| 5329 | 6130 | ||
| 5330 | const argument_index: Instruction.Index = @fromBackingInt(@intCast(index)); | 6131 | const argument_index: Instruction.Index = @fromBackingInt(index); |
| 5331 | return argument_index.toValue(); | 6132 | return argument_index.toValue(); |
| 5332 | } | 6133 | } |
| 5333 | 6134 | ||
| ... | @@ -5722,7 +6523,7 @@ pub const WipFunction = struct { | ... | @@ -5722,7 +6523,7 @@ pub const WipFunction = struct { |
| 5722 | alignment: Alignment, | 6523 | alignment: Alignment, |
| 5723 | name: []const u8, | 6524 | name: []const u8, |
| 5724 | ) Allocator.Error!Value { | 6525 | ) Allocator.Error!Value { |
| 5725 | return self.loadAtomic(access_kind, ty, ptr, .system, .none, alignment, name); | 6526 | return self.loadAtomic(access_kind, ty, ptr, undefined, .none, alignment, name); |
| 5726 | } | 6527 | } |
| 5727 | 6528 | ||
| 5728 | pub fn loadAtomic( | 6529 | pub fn loadAtomic( |
| ... | @@ -5766,7 +6567,7 @@ pub const WipFunction = struct { | ... | @@ -5766,7 +6567,7 @@ pub const WipFunction = struct { |
| 5766 | ptr: Value, | 6567 | ptr: Value, |
| 5767 | alignment: Alignment, | 6568 | alignment: Alignment, |
| 5768 | ) Allocator.Error!Instruction.Index { | 6569 | ) Allocator.Error!Instruction.Index { |
| 5769 | return self.storeAtomic(kind, val, ptr, .system, .none, alignment); | 6570 | return self.storeAtomic(kind, val, ptr, undefined, .none, alignment); |
| 5770 | } | 6571 | } |
| 5771 | 6572 | ||
| 5772 | pub fn storeAtomic( | 6573 | pub fn storeAtomic( |
| ... | @@ -6414,24 +7215,24 @@ pub const WipFunction = struct { | ... | @@ -6414,24 +7215,24 @@ pub const WipFunction = struct { |
| 6414 | errdefer function.instructions.shrinkRetainingCapacity(0); | 7215 | errdefer function.instructions.shrinkRetainingCapacity(0); |
| 6415 | 7216 | ||
| 6416 | { | 7217 | { |
| 6417 | var final_instruction_index: Instruction.Index = @fromBackingInt(@intCast(0)); | 7218 | var final_instruction_index: Instruction.Index = @fromBackingInt(0); |
| 6418 | for (0..params_len) |param_index| { | 7219 | for (0..params_len) |param_index| { |
| 6419 | instructions.items[param_index] = final_instruction_index; | 7220 | instructions.items[param_index] = final_instruction_index; |
| 6420 | final_instruction_index = @fromBackingInt(@intCast(@backingInt(final_instruction_index) + 1)); | 7221 | final_instruction_index = @fromBackingInt(@backingInt(final_instruction_index) + 1); |
| 6421 | } | 7222 | } |
| 6422 | for (blocks, self.blocks.items) |*final_block, current_block| { | 7223 | for (blocks, self.blocks.items) |*final_block, current_block| { |
| 6423 | assert(current_block.incoming == current_block.branches); | 7224 | assert(current_block.incoming == current_block.branches); |
| 6424 | final_block.instruction = final_instruction_index; | 7225 | final_block.instruction = final_instruction_index; |
| 6425 | final_instruction_index = @fromBackingInt(@intCast(@backingInt(final_instruction_index) + 1)); | 7226 | final_instruction_index = @fromBackingInt(@backingInt(final_instruction_index) + 1); |
| 6426 | for (current_block.instructions.items) |instruction| { | 7227 | for (current_block.instructions.items) |instruction| { |
| 6427 | instructions.items[@backingInt(instruction)] = final_instruction_index; | 7228 | instructions.items[@backingInt(instruction)] = final_instruction_index; |
| 6428 | final_instruction_index = @fromBackingInt(@intCast(@backingInt(final_instruction_index) + 1)); | 7229 | final_instruction_index = @fromBackingInt(@backingInt(final_instruction_index) + 1); |
| 6429 | } | 7230 | } |
| 6430 | } | 7231 | } |
| 6431 | } | 7232 | } |
| 6432 | 7233 | ||
| 6433 | var wip_name: struct { | 7234 | var wip_name: struct { |
| 6434 | next_name: String = @fromBackingInt(@intCast(0)), | 7235 | next_name: String = @fromBackingInt(0), |
| 6435 | next_unique_name: std.AutoHashMap(String, String), | 7236 | next_unique_name: std.AutoHashMap(String, String), |
| 6436 | builder: *Builder, | 7237 | builder: *Builder, |
| 6437 | 7238 | ||
| ... | @@ -6440,19 +7241,19 @@ pub const WipFunction = struct { | ... | @@ -6440,19 +7241,19 @@ pub const WipFunction = struct { |
| 6440 | .none => return .none, | 7241 | .none => return .none, |
| 6441 | .empty => { | 7242 | .empty => { |
| 6442 | assert(wip_name.next_name != .none); | 7243 | assert(wip_name.next_name != .none); |
| 6443 | defer wip_name.next_name = @fromBackingInt(@intCast(@backingInt(wip_name.next_name) + 1)); | 7244 | defer wip_name.next_name = @fromBackingInt(@backingInt(wip_name.next_name) + 1); |
| 6444 | return wip_name.next_name; | 7245 | return wip_name.next_name; |
| 6445 | }, | 7246 | }, |
| 6446 | _ => { | 7247 | _ => { |
| 6447 | assert(!name.isAnon()); | 7248 | assert(!name.isAnon()); |
| 6448 | const gop = try wip_name.next_unique_name.getOrPut(name); | 7249 | const gop = try wip_name.next_unique_name.getOrPut(name); |
| 6449 | if (!gop.found_existing) { | 7250 | if (!gop.found_existing) { |
| 6450 | gop.value_ptr.* = @fromBackingInt(@intCast(0)); | 7251 | gop.value_ptr.* = @fromBackingInt(0); |
| 6451 | return name; | 7252 | return name; |
| 6452 | } | 7253 | } |
| 6453 | 7254 | ||
| 6454 | while (true) { | 7255 | while (true) { |
| 6455 | gop.value_ptr.* = @fromBackingInt(@intCast(@backingInt(gop.value_ptr.*) + 1)); | 7256 | gop.value_ptr.* = @fromBackingInt(@backingInt(gop.value_ptr.*) + 1); |
| 6456 | const unique_name = try wip_name.builder.fmt("{f}{s}{f}", .{ | 7257 | const unique_name = try wip_name.builder.fmt("{f}{s}{f}", .{ |
| 6457 | name.fmtRaw(wip_name.builder), | 7258 | name.fmtRaw(wip_name.builder), |
| 6458 | sep, | 7259 | sep, |
| ... | @@ -6460,7 +7261,7 @@ pub const WipFunction = struct { | ... | @@ -6460,7 +7261,7 @@ pub const WipFunction = struct { |
| 6460 | }); | 7261 | }); |
| 6461 | const unique_gop = try wip_name.next_unique_name.getOrPut(unique_name); | 7262 | const unique_gop = try wip_name.next_unique_name.getOrPut(unique_name); |
| 6462 | if (!unique_gop.found_existing) { | 7263 | if (!unique_gop.found_existing) { |
| 6463 | unique_gop.value_ptr.* = @fromBackingInt(@intCast(0)); | 7264 | unique_gop.value_ptr.* = @fromBackingInt(0); |
| 6464 | return unique_name; | 7265 | return unique_name; |
| 6465 | } | 7266 | } |
| 6466 | } | 7267 | } |
| ... | @@ -6702,7 +7503,7 @@ pub const WipFunction = struct { | ... | @@ -6702,7 +7503,7 @@ pub const WipFunction = struct { |
| 6702 | .fneg, | 7503 | .fneg, |
| 6703 | .@"fneg fast", | 7504 | .@"fneg fast", |
| 6704 | .ret, | 7505 | .ret, |
| 6705 | => instruction.data = @backingInt(instructions.map(@fromBackingInt(@intCast(instruction.data)))), | 7506 | => instruction.data = @backingInt(instructions.map(@fromBackingInt(instruction.data))), |
| 6706 | .getelementptr, | 7507 | .getelementptr, |
| 6707 | .@"getelementptr inbounds", | 7508 | .@"getelementptr inbounds", |
| 6708 | => { | 7509 | => { |
| ... | @@ -7079,7 +7880,7 @@ pub const WipFunction = struct { | ... | @@ -7079,7 +7880,7 @@ pub const WipFunction = struct { |
| 7079 | Type, | 7880 | Type, |
| 7080 | Value, | 7881 | Value, |
| 7081 | Instruction.BrCond.Weights, | 7882 | Instruction.BrCond.Weights, |
| 7082 | => @fromBackingInt(@intCast(value)), | 7883 | => @fromBackingInt(value), |
| 7083 | MemoryAccessInfo, | 7884 | MemoryAccessInfo, |
| 7084 | Instruction.Alloca.Info, | 7885 | Instruction.Alloca.Info, |
| 7085 | Instruction.Call.Info, | 7886 | Instruction.Call.Info, |
| ... | @@ -7268,7 +8069,7 @@ pub const Constant = enum(u32) { | ... | @@ -7268,7 +8069,7 @@ pub const Constant = enum(u32) { |
| 7268 | no_init = (1 << 30) - 1, | 8069 | no_init = (1 << 30) - 1, |
| 7269 | _, | 8070 | _, |
| 7270 | 8071 | ||
| 7271 | const first_global: Constant = @fromBackingInt(@intCast(1 << 29)); | 8072 | const first_global: Constant = @fromBackingInt(1 << 29); |
| 7272 | 8073 | ||
| 7273 | pub const Tag = enum(u7) { | 8074 | pub const Tag = enum(u7) { |
| 7274 | positive_integer, | 8075 | positive_integer, |
| ... | @@ -7405,7 +8206,18 @@ pub const Constant = enum(u32) { | ... | @@ -7405,7 +8206,18 @@ pub const Constant = enum(u32) { |
| 7405 | val: Constant, | 8206 | val: Constant, |
| 7406 | type: Type, | 8207 | type: Type, |
| 7407 | 8208 | ||
| 7408 | pub const Signedness = enum { unsigned, signed, unneeded }; | 8209 | pub const Signedness = enum { |
| 8210 | unsigned, | ||
| 8211 | signed, | ||
| 8212 | unneeded, | ||
| 8213 | |||
| 8214 | pub fn fromStdLang(signedness: std.lang.Signedness) Signedness { | ||
| 8215 | return switch (signedness) { | ||
| 8216 | .unsigned => .unsigned, | ||
| 8217 | .signed => .signed, | ||
| 8218 | }; | ||
| 8219 | } | ||
| 8220 | }; | ||
| 7409 | }; | 8221 | }; |
| 7410 | 8222 | ||
| 7411 | pub const GetElementPtr = struct { | 8223 | pub const GetElementPtr = struct { |
| ... | @@ -7444,11 +8256,11 @@ pub const Constant = enum(u32) { | ... | @@ -7444,11 +8256,11 @@ pub const Constant = enum(u32) { |
| 7444 | return if (@backingInt(self) < @backingInt(first_global)) | 8256 | return if (@backingInt(self) < @backingInt(first_global)) |
| 7445 | .{ .constant = @intCast(@backingInt(self)) } | 8257 | .{ .constant = @intCast(@backingInt(self)) } |
| 7446 | else | 8258 | else |
| 7447 | .{ .global = @fromBackingInt(@intCast(@backingInt(self) - @backingInt(first_global))) }; | 8259 | .{ .global = @fromBackingInt(@backingInt(self) - @backingInt(first_global)) }; |
| 7448 | } | 8260 | } |
| 7449 | 8261 | ||
| 7450 | pub fn toValue(self: Constant) Value { | 8262 | pub fn toValue(self: Constant) Value { |
| 7451 | return @fromBackingInt(@intCast(Value.first_constant + @backingInt(self))); | 8263 | return @fromBackingInt(Value.first_constant + @backingInt(self)); |
| 7452 | } | 8264 | } |
| 7453 | 8265 | ||
| 7454 | pub fn typeOf(self: Constant, builder: *Builder) Type { | 8266 | pub fn typeOf(self: Constant, builder: *Builder) Type { |
| ... | @@ -7474,7 +8286,7 @@ pub const Constant = enum(u32) { | ... | @@ -7474,7 +8286,7 @@ pub const Constant = enum(u32) { |
| 7474 | .zeroinitializer, | 8286 | .zeroinitializer, |
| 7475 | .undef, | 8287 | .undef, |
| 7476 | .poison, | 8288 | .poison, |
| 7477 | => @fromBackingInt(@intCast(item.data)), | 8289 | => @fromBackingInt(item.data), |
| 7478 | .structure, | 8290 | .structure, |
| 7479 | .packed_structure, | 8291 | .packed_structure, |
| 7480 | .array, | 8292 | .array, |
| ... | @@ -7482,7 +8294,7 @@ pub const Constant = enum(u32) { | ... | @@ -7482,7 +8294,7 @@ pub const Constant = enum(u32) { |
| 7482 | => builder.constantExtraData(Aggregate, item.data).type, | 8294 | => builder.constantExtraData(Aggregate, item.data).type, |
| 7483 | .splat => builder.constantExtraData(Splat, item.data).type, | 8295 | .splat => builder.constantExtraData(Splat, item.data).type, |
| 7484 | .string => builder.arrayTypeAssumeCapacity( | 8296 | .string => builder.arrayTypeAssumeCapacity( |
| 7485 | @as(String, @fromBackingInt(@intCast(item.data))).slice(builder).?.len, | 8297 | @as(String, @fromBackingInt(item.data)).slice(builder).?.len, |
| 7486 | .i8, | 8298 | .i8, |
| 7487 | ), | 8299 | ), |
| 7488 | .blockaddress => builder.ptrTypeAssumeCapacity( | 8300 | .blockaddress => builder.ptrTypeAssumeCapacity( |
| ... | @@ -7491,7 +8303,7 @@ pub const Constant = enum(u32) { | ... | @@ -7491,7 +8303,7 @@ pub const Constant = enum(u32) { |
| 7491 | ), | 8303 | ), |
| 7492 | .dso_local_equivalent, | 8304 | .dso_local_equivalent, |
| 7493 | .no_cfi, | 8305 | .no_cfi, |
| 7494 | => builder.ptrTypeAssumeCapacity(@as(Function.Index, @fromBackingInt(@intCast(item.data))) | 8306 | => builder.ptrTypeAssumeCapacity(@as(Function.Index, @fromBackingInt(item.data)) |
| 7495 | .ptrConst(builder).global.ptrConst(builder).addr_space), | 8307 | .ptrConst(builder).global.ptrConst(builder).addr_space), |
| 7496 | .trunc, | 8308 | .trunc, |
| 7497 | .ptrtoint, | 8309 | .ptrtoint, |
| ... | @@ -7802,7 +8614,7 @@ pub const Constant = enum(u32) { | ... | @@ -7802,7 +8614,7 @@ pub const Constant = enum(u32) { |
| 7802 | try w.writeByte('>'); | 8614 | try w.writeByte('>'); |
| 7803 | }, | 8615 | }, |
| 7804 | .string => try w.print("c{f}", .{ | 8616 | .string => try w.print("c{f}", .{ |
| 7805 | @as(String, @fromBackingInt(@intCast(item.data))).fmtQ(data.builder), | 8617 | @as(String, @fromBackingInt(item.data)).fmtQ(data.builder), |
| 7806 | }), | 8618 | }), |
| 7807 | .blockaddress => |tag| { | 8619 | .blockaddress => |tag| { |
| 7808 | const extra = data.builder.constantExtraData(BlockAddress, item.data); | 8620 | const extra = data.builder.constantExtraData(BlockAddress, item.data); |
| ... | @@ -7816,7 +8628,7 @@ pub const Constant = enum(u32) { | ... | @@ -7816,7 +8628,7 @@ pub const Constant = enum(u32) { |
| 7816 | .dso_local_equivalent, | 8628 | .dso_local_equivalent, |
| 7817 | .no_cfi, | 8629 | .no_cfi, |
| 7818 | => |tag| { | 8630 | => |tag| { |
| 7819 | const function: Function.Index = @fromBackingInt(@intCast(item.data)); | 8631 | const function: Function.Index = @fromBackingInt(item.data); |
| 7820 | try w.print("{s} {f}", .{ | 8632 | try w.print("{s} {f}", .{ |
| 7821 | @tagName(tag), | 8633 | @tagName(tag), |
| 7822 | function.ptrConst(data.builder).global.fmt(data.builder), | 8634 | function.ptrConst(data.builder).global.fmt(data.builder), |
| ... | @@ -7920,9 +8732,9 @@ pub const Value = enum(u32) { | ... | @@ -7920,9 +8732,9 @@ pub const Value = enum(u32) { |
| 7920 | metadata: Metadata, | 8732 | metadata: Metadata, |
| 7921 | } { | 8733 | } { |
| 7922 | return if (@backingInt(self) < first_constant) | 8734 | return if (@backingInt(self) < first_constant) |
| 7923 | .{ .instruction = @fromBackingInt(@intCast(@backingInt(self))) } | 8735 | .{ .instruction = @fromBackingInt(@backingInt(self)) } |
| 7924 | else if (@backingInt(self) < first_metadata) | 8736 | else if (@backingInt(self) < first_metadata) |
| 7925 | .{ .constant = @fromBackingInt(@intCast(@backingInt(self) - first_constant)) } | 8737 | .{ .constant = @fromBackingInt(@backingInt(self) - first_constant) } |
| 7926 | else | 8738 | else |
| 7927 | .{ .metadata = @bitCast(@backingInt(self) - first_metadata) }; | 8739 | .{ .metadata = @bitCast(@backingInt(self) - first_metadata) }; |
| 7928 | } | 8740 | } |
| ... | @@ -8016,7 +8828,7 @@ pub const Metadata = packed struct(u32) { | ... | @@ -8016,7 +8828,7 @@ pub const Metadata = packed struct(u32) { |
| 8016 | return .{ .index = metadata.index, .kind = metadata.kind, .is_none = false }; | 8828 | return .{ .index = metadata.index, .kind = metadata.kind, .is_none = false }; |
| 8017 | } | 8829 | } |
| 8018 | pub fn toValue(metadata: Metadata) Value { | 8830 | pub fn toValue(metadata: Metadata) Value { |
| 8019 | return @fromBackingInt(@intCast(Value.first_metadata + @as(u32, @bitCast(metadata)))); | 8831 | return @fromBackingInt(Value.first_metadata + @as(u32, @bitCast(metadata))); |
| 8020 | } | 8832 | } |
| 8021 | 8833 | ||
| 8022 | pub const String = enum(u32) { | 8834 | pub const String = enum(u32) { |
| ... | @@ -8032,7 +8844,7 @@ pub const Metadata = packed struct(u32) { | ... | @@ -8032,7 +8844,7 @@ pub const Metadata = packed struct(u32) { |
| 8032 | pub fn unwrap(metadata: Metadata.String.Optional) ?Metadata.String { | 8844 | pub fn unwrap(metadata: Metadata.String.Optional) ?Metadata.String { |
| 8033 | return switch (metadata) { | 8845 | return switch (metadata) { |
| 8034 | .none => null, | 8846 | .none => null, |
| 8035 | else => @fromBackingInt(@intCast(@backingInt(metadata))), | 8847 | else => @fromBackingInt(@backingInt(metadata)), |
| 8036 | }; | 8848 | }; |
| 8037 | } | 8849 | } |
| 8038 | pub fn toMetadata(metadata: Metadata.String.Optional) Metadata.Optional { | 8850 | pub fn toMetadata(metadata: Metadata.String.Optional) Metadata.Optional { |
| ... | @@ -8040,7 +8852,7 @@ pub const Metadata = packed struct(u32) { | ... | @@ -8040,7 +8852,7 @@ pub const Metadata = packed struct(u32) { |
| 8040 | } | 8852 | } |
| 8041 | }; | 8853 | }; |
| 8042 | pub fn toOptional(metadata: Metadata.String) Metadata.String.Optional { | 8854 | pub fn toOptional(metadata: Metadata.String) Metadata.String.Optional { |
| 8043 | return @fromBackingInt(@intCast(@backingInt(metadata))); | 8855 | return @fromBackingInt(@backingInt(metadata)); |
| 8044 | } | 8856 | } |
| 8045 | pub fn toMetadata(metadata: Metadata.String) Metadata { | 8857 | pub fn toMetadata(metadata: Metadata.String) Metadata { |
| 8046 | return .{ .index = @intCast(@backingInt(metadata)), .kind = .string }; | 8858 | return .{ .index = @intCast(@backingInt(metadata)), .kind = .string }; |
| ... | @@ -8077,7 +8889,7 @@ pub const Metadata = packed struct(u32) { | ... | @@ -8077,7 +8889,7 @@ pub const Metadata = packed struct(u32) { |
| 8077 | }; | 8889 | }; |
| 8078 | pub fn toString(metadata: Metadata) Metadata.String { | 8890 | pub fn toString(metadata: Metadata) Metadata.String { |
| 8079 | assert(metadata.kind == .string); | 8891 | assert(metadata.kind == .string); |
| 8080 | return @fromBackingInt(@intCast(metadata.index)); | 8892 | return @fromBackingInt(metadata.index); |
| 8081 | } | 8893 | } |
| 8082 | 8894 | ||
| 8083 | pub const Tag = enum(u6) { | 8895 | pub const Tag = enum(u6) { |
| ... | @@ -8542,7 +9354,7 @@ pub const Metadata = packed struct(u32) { | ... | @@ -8542,7 +9354,7 @@ pub const Metadata = packed struct(u32) { |
| 8542 | try w.writeByte(')'); | 9354 | try w.writeByte(')'); |
| 8543 | }, | 9355 | }, |
| 8544 | .constant => try Constant.format(.{ | 9356 | .constant => try Constant.format(.{ |
| 8545 | .constant = @fromBackingInt(@intCast(node_item.data)), | 9357 | .constant = @fromBackingInt(node_item.data), |
| 8546 | .builder = builder, | 9358 | .builder = builder, |
| 8547 | .flags = data.specialized orelse .{}, | 9359 | .flags = data.specialized orelse .{}, |
| 8548 | }, w), | 9360 | }, w), |
| ... | @@ -8705,7 +9517,7 @@ pub const Metadata = packed struct(u32) { | ... | @@ -8705,7 +9517,7 @@ pub const Metadata = packed struct(u32) { |
| 8705 | nodes: anytype, | 9517 | nodes: anytype, |
| 8706 | w: *Writer, | 9518 | w: *Writer, |
| 8707 | ) !void { | 9519 | ) !void { |
| 8708 | const names = comptime std.meta.fieldNames(@TypeOf(nodes)); | 9520 | const names = @typeInfo(@TypeOf(nodes)).@"struct".field_names; |
| 8709 | 9521 | ||
| 8710 | comptime var fmt_str: []const u8 = "{[distinct]s}{[node]s}("; | 9522 | comptime var fmt_str: []const u8 = "{[distinct]s}{[node]s}("; |
| 8711 | inline for (names) |name| fmt_str = fmt_str ++ "{[" ++ name ++ "]f}"; | 9523 | inline for (names) |name| fmt_str = fmt_str ++ "{[" ++ name ++ "]f}"; |
| ... | @@ -8735,7 +9547,14 @@ pub fn init(options: Options) Allocator.Error!Builder { | ... | @@ -8735,7 +9547,14 @@ pub fn init(options: Options) Allocator.Error!Builder { |
| 8735 | .strip = options.strip, | 9547 | .strip = options.strip, |
| 8736 | 9548 | ||
| 8737 | .source_filename = .none, | 9549 | .source_filename = .none, |
| 8738 | .data_layout = .none, | 9550 | .data_layout = .{ |
| 9551 | .endian = null, | ||
| 9552 | .int_specs = .empty, | ||
| 9553 | .float_specs = .empty, | ||
| 9554 | .vector_specs = .empty, | ||
| 9555 | .pointer_specs = .empty, | ||
| 9556 | .string_repr = .none, | ||
| 9557 | }, | ||
| 8739 | .target_triple = .none, | 9558 | .target_triple = .none, |
| 8740 | .module_asm = .empty, | 9559 | .module_asm = .empty, |
| 8741 | 9560 | ||
| ... | @@ -8744,7 +9563,7 @@ pub fn init(options: Options) Allocator.Error!Builder { | ... | @@ -8744,7 +9563,7 @@ pub fn init(options: Options) Allocator.Error!Builder { |
| 8744 | .string_bytes = .empty, | 9563 | .string_bytes = .empty, |
| 8745 | 9564 | ||
| 8746 | .types = .empty, | 9565 | .types = .empty, |
| 8747 | .next_unnamed_type = @fromBackingInt(@intCast(0)), | 9566 | .next_unnamed_type = @fromBackingInt(0), |
| 8748 | .next_unique_type_id = .empty, | 9567 | .next_unique_type_id = .empty, |
| 8749 | .type_map = .empty, | 9568 | .type_map = .empty, |
| 8750 | .type_items = .empty, | 9569 | .type_items = .empty, |
| ... | @@ -8758,7 +9577,7 @@ pub fn init(options: Options) Allocator.Error!Builder { | ... | @@ -8758,7 +9577,7 @@ pub fn init(options: Options) Allocator.Error!Builder { |
| 8758 | .function_attributes_set = .empty, | 9577 | .function_attributes_set = .empty, |
| 8759 | 9578 | ||
| 8760 | .globals = .empty, | 9579 | .globals = .empty, |
| 8761 | .next_unnamed_global = @fromBackingInt(@intCast(0)), | 9580 | .next_unnamed_global = @fromBackingInt(0), |
| 8762 | .next_replaced_global = .none, | 9581 | .next_replaced_global = .none, |
| 8763 | .next_unique_global_id = .empty, | 9582 | .next_unique_global_id = .empty, |
| 8764 | .aliases = .empty, | 9583 | .aliases = .empty, |
| ... | @@ -8791,14 +9610,14 @@ pub fn init(options: Options) Allocator.Error!Builder { | ... | @@ -8791,14 +9610,14 @@ pub fn init(options: Options) Allocator.Error!Builder { |
| 8791 | try self.string_indices.append(self.gpa, 0); | 9610 | try self.string_indices.append(self.gpa, 0); |
| 8792 | assert(try self.string("") == .empty); | 9611 | assert(try self.string("") == .empty); |
| 8793 | 9612 | ||
| 9613 | self.data_layout = try .parseString(try self.string(DataLayout.stringForTarget(options.target)), &self); | ||
| 9614 | |||
| 8794 | try self.strtab_string_indices.append(self.gpa, 0); | 9615 | try self.strtab_string_indices.append(self.gpa, 0); |
| 8795 | assert(try self.strtabString("") == .empty); | 9616 | assert(try self.strtabString("") == .empty); |
| 8796 | 9617 | ||
| 8797 | if (options.name.len > 0) self.source_filename = try self.string(options.name); | 9618 | if (options.name.len > 0) self.source_filename = try self.string(options.name); |
| 8798 | 9619 | ||
| 8799 | if (options.triple.len > 0) { | 9620 | if (options.triple.len > 0) self.target_triple = try self.string(options.triple); |
| 8800 | self.target_triple = try self.string(options.triple); | ||
| 8801 | } | ||
| 8802 | 9621 | ||
| 8803 | { | 9622 | { |
| 8804 | const static_len = @typeInfo(Type).@"enum".field_names.len - 1; | 9623 | const static_len = @typeInfo(Type).@"enum".field_names.len - 1; |
| ... | @@ -8815,7 +9634,7 @@ pub fn init(options: Options) Allocator.Error!Builder { | ... | @@ -8815,7 +9634,7 @@ pub fn init(options: Options) Allocator.Error!Builder { |
| 8815 | assert(self.intTypeAssumeCapacity(bits) == | 9634 | assert(self.intTypeAssumeCapacity(bits) == |
| 8816 | @field(Type, std.fmt.comptimePrint("i{d}", .{bits}))); | 9635 | @field(Type, std.fmt.comptimePrint("i{d}", .{bits}))); |
| 8817 | inline for (.{ 0, 4 }) |addr_space_index| { | 9636 | inline for (.{ 0, 4 }) |addr_space_index| { |
| 8818 | const addr_space: AddrSpace = @fromBackingInt(@intCast(addr_space_index)); | 9637 | const addr_space: AddrSpace = @fromBackingInt(addr_space_index); |
| 8819 | assert(self.ptrTypeAssumeCapacity(addr_space) == | 9638 | assert(self.ptrTypeAssumeCapacity(addr_space) == |
| 8820 | @field(Type, std.fmt.comptimePrint("ptr{f}", .{addr_space.fmt(" ")}))); | 9639 | @field(Type, std.fmt.comptimePrint("ptr{f}", .{addr_space.fmt(" ")}))); |
| 8821 | } | 9640 | } |
| ... | @@ -8891,6 +9710,8 @@ pub fn clearAndFree(self: *Builder) void { | ... | @@ -8891,6 +9710,8 @@ pub fn clearAndFree(self: *Builder) void { |
| 8891 | pub fn deinit(self: *Builder) void { | 9710 | pub fn deinit(self: *Builder) void { |
| 8892 | const gpa = self.gpa; | 9711 | const gpa = self.gpa; |
| 8893 | 9712 | ||
| 9713 | self.data_layout.deinit(gpa); | ||
| 9714 | |||
| 8894 | self.module_asm.deinit(gpa); | 9715 | self.module_asm.deinit(gpa); |
| 8895 | 9716 | ||
| 8896 | self.string_map.deinit(gpa); | 9717 | self.string_map.deinit(gpa); |
| ... | @@ -8944,7 +9765,7 @@ pub fn deinit(self: *Builder) void { | ... | @@ -8944,7 +9765,7 @@ pub fn deinit(self: *Builder) void { |
| 8944 | 9765 | ||
| 8945 | pub fn finishModuleAsm(self: *Builder, aw: *Writer.Allocating) Allocator.Error!void { | 9766 | pub fn finishModuleAsm(self: *Builder, aw: *Writer.Allocating) Allocator.Error!void { |
| 8946 | self.module_asm = aw.toArrayList(); | 9767 | self.module_asm = aw.toArrayList(); |
| 8947 | if (self.module_asm.getLast()) |last| if (last != '\n') | 9768 | if (self.module_asm.last()) |last| if (last != '\n') |
| 8948 | try self.module_asm.append(self.gpa, '\n'); | 9769 | try self.module_asm.append(self.gpa, '\n'); |
| 8949 | } | 9770 | } |
| 8950 | 9771 | ||
| ... | @@ -8990,7 +9811,7 @@ pub fn trailingString(self: *Builder) Allocator.Error!String { | ... | @@ -8990,7 +9811,7 @@ pub fn trailingString(self: *Builder) Allocator.Error!String { |
| 8990 | } | 9811 | } |
| 8991 | 9812 | ||
| 8992 | pub fn trailingStringAssumeCapacity(self: *Builder) String { | 9813 | pub fn trailingStringAssumeCapacity(self: *Builder) String { |
| 8993 | const start = self.string_indices.getLast().?; | 9814 | const start = self.string_indices.last().?; |
| 8994 | const bytes: []const u8 = self.string_bytes.items[start..]; | 9815 | const bytes: []const u8 = self.string_bytes.items[start..]; |
| 8995 | const gop = self.string_map.getOrPutAssumeCapacityAdapted(bytes, String.Adapter{ .builder = self }); | 9816 | const gop = self.string_map.getOrPutAssumeCapacityAdapted(bytes, String.Adapter{ .builder = self }); |
| 8996 | if (gop.found_existing) { | 9817 | if (gop.found_existing) { |
| ... | @@ -9092,17 +9913,17 @@ pub fn attrs(self: *Builder, attributes: []Attribute.Index) Allocator.Error!Attr | ... | @@ -9092,17 +9913,17 @@ pub fn attrs(self: *Builder, attributes: []Attribute.Index) Allocator.Error!Attr |
| 9092 | return @backingInt(lhs_kind) < @backingInt(rhs_kind); | 9913 | return @backingInt(lhs_kind) < @backingInt(rhs_kind); |
| 9093 | } | 9914 | } |
| 9094 | }.lessThan); | 9915 | }.lessThan); |
| 9095 | return @fromBackingInt(@intCast(try self.attrGeneric(@ptrCast(attributes)))); | 9916 | return @fromBackingInt(try self.attrGeneric(@ptrCast(attributes))); |
| 9096 | } | 9917 | } |
| 9097 | 9918 | ||
| 9098 | pub fn fnAttrs(self: *Builder, fn_attributes: []const Attributes) Allocator.Error!FunctionAttributes { | 9919 | pub fn fnAttrs(self: *Builder, fn_attributes: []const Attributes) Allocator.Error!FunctionAttributes { |
| 9099 | try self.function_attributes_set.ensureUnusedCapacity(self.gpa, 1); | 9920 | try self.function_attributes_set.ensureUnusedCapacity(self.gpa, 1); |
| 9100 | const function_attributes: FunctionAttributes = @fromBackingInt(@intCast(try self.attrGeneric(@ptrCast( | 9921 | const function_attributes: FunctionAttributes = @fromBackingInt(try self.attrGeneric(@ptrCast( |
| 9101 | fn_attributes[0..if (std.mem.lastIndexOfNone(Attributes, fn_attributes, &.{.none})) |last| | 9922 | fn_attributes[0..if (std.mem.findLastNone(Attributes, fn_attributes, &.{.none})) |last| |
| 9102 | last + 1 | 9923 | last + 1 |
| 9103 | else | 9924 | else |
| 9104 | 0], | 9925 | 0], |
| 9105 | )))); | 9926 | ))); |
| 9106 | 9927 | ||
| 9107 | _ = self.function_attributes_set.getOrPutAssumeCapacity(function_attributes); | 9928 | _ = self.function_attributes_set.getOrPutAssumeCapacity(function_attributes); |
| 9108 | return function_attributes; | 9929 | return function_attributes; |
| ... | @@ -9121,7 +9942,7 @@ pub fn addGlobalAssumeCapacity(self: *Builder, name: StrtabString, global: Globa | ... | @@ -9121,7 +9942,7 @@ pub fn addGlobalAssumeCapacity(self: *Builder, name: StrtabString, global: Globa |
| 9121 | if (name == .empty) { | 9942 | if (name == .empty) { |
| 9122 | id = self.next_unnamed_global; | 9943 | id = self.next_unnamed_global; |
| 9123 | assert(id != self.next_replaced_global); | 9944 | assert(id != self.next_replaced_global); |
| 9124 | self.next_unnamed_global = @fromBackingInt(@intCast(@backingInt(id) + 1)); | 9945 | self.next_unnamed_global = @fromBackingInt(@backingInt(id) + 1); |
| 9125 | } | 9946 | } |
| 9126 | while (true) { | 9947 | while (true) { |
| 9127 | const global_gop = self.globals.getOrPutAssumeCapacity(id); | 9948 | const global_gop = self.globals.getOrPutAssumeCapacity(id); |
| ... | @@ -9710,17 +10531,17 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void | ... | @@ -9710,17 +10531,17 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void |
| 9710 | var metadata_formatter: Metadata.Formatter = .{ .builder = self, .need_comma = undefined }; | 10531 | var metadata_formatter: Metadata.Formatter = .{ .builder = self, .need_comma = undefined }; |
| 9711 | defer metadata_formatter.map.deinit(self.gpa); | 10532 | defer metadata_formatter.map.deinit(self.gpa); |
| 9712 | 10533 | ||
| 9713 | if (self.source_filename != .none or self.data_layout != .none or self.target_triple != .none) { | 10534 | if (self.source_filename != .none or self.data_layout.string_repr != .none or self.target_triple != .none) { |
| 9714 | if (need_newline) try w.writeByte('\n') else need_newline = true; | 10535 | if (need_newline) try w.writeByte('\n') else need_newline = true; |
| 9715 | if (self.source_filename != .none) try w.print( | 10536 | if (self.source_filename != .none) try w.print( |
| 9716 | \\; ModuleID = '{s}' | 10537 | \\; ModuleID = '{s}' |
| 9717 | \\source_filename = {f} | 10538 | \\source_filename = {f} |
| 9718 | \\ | 10539 | \\ |
| 9719 | , .{ self.source_filename.slice(self).?, self.source_filename.fmtQ(self) }); | 10540 | , .{ self.source_filename.slice(self).?, self.source_filename.fmtQ(self) }); |
| 9720 | if (self.data_layout != .none) try w.print( | 10541 | if (self.data_layout.string_repr != .none) try w.print( |
| 9721 | \\target datalayout = {f} | 10542 | \\target datalayout = {f} |
| 9722 | \\ | 10543 | \\ |
| 9723 | , .{self.data_layout.fmtQ(self)}); | 10544 | , .{self.data_layout.string_repr.fmtQ(self)}); |
| 9724 | if (self.target_triple != .none) try w.print( | 10545 | if (self.target_triple != .none) try w.print( |
| 9725 | \\target triple = {f} | 10546 | \\target triple = {f} |
| 9726 | \\ | 10547 | \\ |
| ... | @@ -10058,7 +10879,7 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void | ... | @@ -10058,7 +10879,7 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void |
| 10058 | continue; | 10879 | continue; |
| 10059 | }, | 10880 | }, |
| 10060 | .br => |tag| { | 10881 | .br => |tag| { |
| 10061 | const target: Function.Block.Index = @fromBackingInt(@intCast(instruction.data)); | 10882 | const target: Function.Block.Index = @fromBackingInt(instruction.data); |
| 10062 | try w.print(" {s} {f}", .{ | 10883 | try w.print(" {s} {f}", .{ |
| 10063 | @tagName(tag), target.toInst(&function).fmt(function_index, self, .{ .percent = true }), | 10884 | @tagName(tag), target.toInst(&function).fmt(function_index, self, .{ .percent = true }), |
| 10064 | }); | 10885 | }); |
| ... | @@ -10187,7 +11008,7 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void | ... | @@ -10187,7 +11008,7 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void |
| 10187 | .fneg, | 11008 | .fneg, |
| 10188 | .@"fneg fast", | 11009 | .@"fneg fast", |
| 10189 | => |tag| { | 11010 | => |tag| { |
| 10190 | const val: Value = @fromBackingInt(@intCast(instruction.data)); | 11011 | const val: Value = @fromBackingInt(instruction.data); |
| 10191 | try w.print(" %{f} = {s} {f}", .{ | 11012 | try w.print(" %{f} = {s} {f}", .{ |
| 10192 | instruction_index.name(&function).fmt(self), | 11013 | instruction_index.name(&function).fmt(self), |
| 10193 | @tagName(tag), | 11014 | @tagName(tag), |
| ... | @@ -10288,7 +11109,7 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void | ... | @@ -10288,7 +11109,7 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void |
| 10288 | } | 11109 | } |
| 10289 | }, | 11110 | }, |
| 10290 | .ret => |tag| { | 11111 | .ret => |tag| { |
| 10291 | const val: Value = @fromBackingInt(@intCast(instruction.data)); | 11112 | const val: Value = @fromBackingInt(instruction.data); |
| 10292 | try w.print(" {s} {f}", .{ | 11113 | try w.print(" {s} {f}", .{ |
| 10293 | @tagName(tag), | 11114 | @tagName(tag), |
| 10294 | val.fmt(function_index, self, .{ .percent = true }), | 11115 | val.fmt(function_index, self, .{ .percent = true }), |
| ... | @@ -11020,7 +11841,7 @@ fn opaqueTypeAssumeCapacity(self: *Builder, name: String) Type { | ... | @@ -11020,7 +11841,7 @@ fn opaqueTypeAssumeCapacity(self: *Builder, name: String) Type { |
| 11020 | if (name == .empty) { | 11841 | if (name == .empty) { |
| 11021 | id = self.next_unnamed_type; | 11842 | id = self.next_unnamed_type; |
| 11022 | assert(id != .none); | 11843 | assert(id != .none); |
| 11023 | self.next_unnamed_type = @fromBackingInt(@intCast(@backingInt(id) + 1)); | 11844 | self.next_unnamed_type = @fromBackingInt(@backingInt(id) + 1); |
| 11024 | } else assert(!name.isAnon()); | 11845 | } else assert(!name.isAnon()); |
| 11025 | while (true) { | 11846 | while (true) { |
| 11026 | const type_gop = self.types.getOrPutAssumeCapacity(id); | 11847 | const type_gop = self.types.getOrPutAssumeCapacity(id); |
| ... | @@ -11135,7 +11956,7 @@ fn typeExtraDataTrail( | ... | @@ -11135,7 +11956,7 @@ fn typeExtraDataTrail( |
| 11135 | ) |field_name, field_type, value| | 11956 | ) |field_name, field_type, value| |
| 11136 | @field(result, field_name) = switch (field_type) { | 11957 | @field(result, field_name) = switch (field_type) { |
| 11137 | u32 => value, | 11958 | u32 => value, |
| 11138 | String, Type => @fromBackingInt(@intCast(value)), | 11959 | String, Type => @fromBackingInt(value), |
| 11139 | else => @compileError("bad field type: " ++ @typeName(field_type)), | 11960 | else => @compileError("bad field type: " ++ @typeName(field_type)), |
| 11140 | }; | 11961 | }; |
| 11141 | return .{ | 11962 | return .{ |
| ... | @@ -11746,7 +12567,7 @@ fn castConstAssumeCapacity(self: *Builder, tag: Constant.Tag, val: Constant, ty: | ... | @@ -11746,7 +12567,7 @@ fn castConstAssumeCapacity(self: *Builder, tag: Constant.Tag, val: Constant, ty: |
| 11746 | return std.meta.eql(lhs_key.cast, rhs_extra); | 12567 | return std.meta.eql(lhs_key.cast, rhs_extra); |
| 11747 | } | 12568 | } |
| 11748 | }; | 12569 | }; |
| 11749 | const data = Key{ .tag = tag, .cast = .{ .val = val, .type = ty } }; | 12570 | const data: Key = .{ .tag = tag, .cast = .{ .val = val, .type = ty } }; |
| 11750 | const gop = self.constant_map.getOrPutAssumeCapacityAdapted(data, Adapter{ .builder = self }); | 12571 | const gop = self.constant_map.getOrPutAssumeCapacityAdapted(data, Adapter{ .builder = self }); |
| 11751 | if (!gop.found_existing) { | 12572 | if (!gop.found_existing) { |
| 11752 | gop.key_ptr.* = {}; | 12573 | gop.key_ptr.* = {}; |
| ... | @@ -11828,10 +12649,10 @@ fn gepConstAssumeCapacity( | ... | @@ -11828,10 +12649,10 @@ fn gepConstAssumeCapacity( |
| 11828 | std.mem.eql(Constant, lhs_key.indices, rhs_indices); | 12649 | std.mem.eql(Constant, lhs_key.indices, rhs_indices); |
| 11829 | } | 12650 | } |
| 11830 | }; | 12651 | }; |
| 11831 | const data = Key{ | 12652 | const data: Key = .{ |
| 11832 | .type = ty, | 12653 | .type = ty, |
| 11833 | .base = base, | 12654 | .base = base, |
| 11834 | .inrange = if (inrange) |index| @fromBackingInt(@intCast(index)) else .none, | 12655 | .inrange = if (inrange) |index| @fromBackingInt(index) else .none, |
| 11835 | .indices = indices, | 12656 | .indices = indices, |
| 11836 | }; | 12657 | }; |
| 11837 | const gop = self.constant_map.getOrPutAssumeCapacityAdapted(data, Adapter{ .builder = self }); | 12658 | const gop = self.constant_map.getOrPutAssumeCapacityAdapted(data, Adapter{ .builder = self }); |
| ... | @@ -11885,7 +12706,7 @@ fn binConstAssumeCapacity( | ... | @@ -11885,7 +12706,7 @@ fn binConstAssumeCapacity( |
| 11885 | return std.meta.eql(lhs_key.extra, rhs_extra); | 12706 | return std.meta.eql(lhs_key.extra, rhs_extra); |
| 11886 | } | 12707 | } |
| 11887 | }; | 12708 | }; |
| 11888 | const data = Key{ .tag = tag, .extra = .{ .lhs = lhs, .rhs = rhs } }; | 12709 | const data: Key = .{ .tag = tag, .extra = .{ .lhs = lhs, .rhs = rhs } }; |
| 11889 | const gop = self.constant_map.getOrPutAssumeCapacityAdapted(data, Adapter{ .builder = self }); | 12710 | const gop = self.constant_map.getOrPutAssumeCapacityAdapted(data, Adapter{ .builder = self }); |
| 11890 | if (!gop.found_existing) { | 12711 | if (!gop.found_existing) { |
| 11891 | gop.key_ptr.* = {}; | 12712 | gop.key_ptr.* = {}; |
| ... | @@ -11924,8 +12745,8 @@ fn asmConstAssumeCapacity( | ... | @@ -11924,8 +12745,8 @@ fn asmConstAssumeCapacity( |
| 11924 | } | 12745 | } |
| 11925 | }; | 12746 | }; |
| 11926 | 12747 | ||
| 11927 | const data = Key{ | 12748 | const data: Key = .{ |
| 11928 | .tag = @fromBackingInt(@intCast(@backingInt(Constant.Tag.@"asm") + @as(u4, @bitCast(info)))), | 12749 | .tag = @fromBackingInt(@backingInt(Constant.Tag.@"asm") + @as(u4, @bitCast(info))), |
| 11929 | .extra = .{ .type = ty, .assembly = assembly, .constraints = constraints }, | 12750 | .extra = .{ .type = ty, .assembly = assembly, .constraints = constraints }, |
| 11930 | }; | 12751 | }; |
| 11931 | const gop = self.constant_map.getOrPutAssumeCapacityAdapted(data, Adapter{ .builder = self }); | 12752 | const gop = self.constant_map.getOrPutAssumeCapacityAdapted(data, Adapter{ .builder = self }); |
| ... | @@ -12073,7 +12894,7 @@ fn constantExtraDataTrail( | ... | @@ -12073,7 +12894,7 @@ fn constantExtraDataTrail( |
| 12073 | ) |field_name, field_type, value| | 12894 | ) |field_name, field_type, value| |
| 12074 | @field(result, field_name) = switch (field_type) { | 12895 | @field(result, field_name) = switch (field_type) { |
| 12075 | u32 => value, | 12896 | u32 => value, |
| 12076 | String, Type, Constant, Function.Index, Function.Block.Index => @fromBackingInt(@intCast(value)), | 12897 | String, Type, Constant, Function.Index, Function.Block.Index => @fromBackingInt(value), |
| 12077 | Constant.GetElementPtr.Info => @bitCast(value), | 12898 | Constant.GetElementPtr.Info => @bitCast(value), |
| 12078 | else => @compileError("bad field type: " ++ @typeName(field_type)), | 12899 | else => @compileError("bad field type: " ++ @typeName(field_type)), |
| 12079 | }; | 12900 | }; |
| ... | @@ -12151,7 +12972,7 @@ fn metadataExtraDataTrail( | ... | @@ -12151,7 +12972,7 @@ fn metadataExtraDataTrail( |
| 12151 | ) |field_name, field_type, value| | 12972 | ) |field_name, field_type, value| |
| 12152 | @field(result, field_name) = switch (field_type) { | 12973 | @field(result, field_name) = switch (field_type) { |
| 12153 | u32 => value, | 12974 | u32 => value, |
| 12154 | Metadata.String, Metadata.String.Optional, Variable.Index, Value => @fromBackingInt(@intCast(value)), | 12975 | Metadata.String, Metadata.String.Optional, Variable.Index, Value => @fromBackingInt(value), |
| 12155 | Metadata, Metadata.Optional, Metadata.DIFlags => @bitCast(value), | 12976 | Metadata, Metadata.Optional, Metadata.DIFlags => @bitCast(value), |
| 12156 | else => @compileError("bad field type: " ++ @typeName(field_type)), | 12977 | else => @compileError("bad field type: " ++ @typeName(field_type)), |
| 12157 | }; | 12978 | }; |
| ... | @@ -12221,7 +13042,7 @@ pub fn trailingMetadataString(self: *Builder) Allocator.Error!Metadata.String { | ... | @@ -12221,7 +13042,7 @@ pub fn trailingMetadataString(self: *Builder) Allocator.Error!Metadata.String { |
| 12221 | } | 13042 | } |
| 12222 | 13043 | ||
| 12223 | pub fn trailingMetadataStringAssumeCapacity(self: *Builder) Metadata.String { | 13044 | pub fn trailingMetadataStringAssumeCapacity(self: *Builder) Metadata.String { |
| 12224 | const start = self.metadata_string_indices.getLast().?; | 13045 | const start = self.metadata_string_indices.last().?; |
| 12225 | const bytes: []const u8 = self.metadata_string_bytes.items[start..]; | 13046 | const bytes: []const u8 = self.metadata_string_bytes.items[start..]; |
| 12226 | assert(bytes.len > 0); | 13047 | assert(bytes.len > 0); |
| 12227 | const gop = self.metadata_string_map.getOrPutAssumeCapacityAdapted(bytes, Metadata.String.Adapter{ .builder = self }); | 13048 | const gop = self.metadata_string_map.getOrPutAssumeCapacityAdapted(bytes, Metadata.String.Adapter{ .builder = self }); |
| ... | @@ -12663,7 +13484,7 @@ fn metadataSimpleAssumeCapacity(self: *Builder, tag: Metadata.Tag, value: anytyp | ... | @@ -12663,7 +13484,7 @@ fn metadataSimpleAssumeCapacity(self: *Builder, tag: Metadata.Tag, value: anytyp |
| 12663 | builder: *const Builder, | 13484 | builder: *const Builder, |
| 12664 | pub fn hash(_: @This(), key: Key) u32 { | 13485 | pub fn hash(_: @This(), key: Key) u32 { |
| 12665 | var hasher = std.hash.Wyhash.init(std.hash.int(@backingInt(key.tag))); | 13486 | var hasher = std.hash.Wyhash.init(std.hash.int(@backingInt(key.tag))); |
| 12666 | inline for (comptime std.meta.fieldNames(@TypeOf(value))) |field_name| { | 13487 | inline for (@typeInfo(@TypeOf(value)).@"struct".field_names) |field_name| { |
| 12667 | hasher.update(std.mem.asBytes(&@field(key.value, field_name))); | 13488 | hasher.update(std.mem.asBytes(&@field(key.value, field_name))); |
| 12668 | } | 13489 | } |
| 12669 | return @truncate(hasher.final()); | 13490 | return @truncate(hasher.final()); |
| ... | @@ -12759,8 +13580,8 @@ fn debugSubprogramAssumeCapacity( | ... | @@ -12759,8 +13580,8 @@ fn debugSubprogramAssumeCapacity( |
| 12759 | compile_unit: ?Metadata, | 13580 | compile_unit: ?Metadata, |
| 12760 | ) Metadata { | 13581 | ) Metadata { |
| 12761 | assert(!self.strip); | 13582 | assert(!self.strip); |
| 12762 | const tag: Metadata.Tag = @fromBackingInt(@intCast(@backingInt(Metadata.Tag.subprogram) + | 13583 | const tag: Metadata.Tag = @fromBackingInt(@backingInt(Metadata.Tag.subprogram) + |
| 12763 | @as(u3, @truncate(@as(u32, @bitCast(options.sp_flags)) >> 2)))); | 13584 | @as(u3, @truncate(@as(u32, @bitCast(options.sp_flags)) >> 2))); |
| 12764 | return self.metadataDistinctAssumeCapacity(tag, Metadata.Subprogram{ | 13585 | return self.metadataDistinctAssumeCapacity(tag, Metadata.Subprogram{ |
| 12765 | .file = .wrap(file), | 13586 | .file = .wrap(file), |
| 12766 | .name = .wrap(name), | 13587 | .name = .wrap(name), |
| ... | @@ -13345,7 +14166,7 @@ fn metadataConstantAssumeCapacity(self: *Builder, constant: Constant) Metadata { | ... | @@ -13345,7 +14166,7 @@ fn metadataConstantAssumeCapacity(self: *Builder, constant: Constant) Metadata { |
| 13345 | 14166 | ||
| 13346 | pub fn eql(ctx: @This(), lhs_key: Constant, _: void, rhs_index: usize) bool { | 14167 | pub fn eql(ctx: @This(), lhs_key: Constant, _: void, rhs_index: usize) bool { |
| 13347 | if (Metadata.Tag.constant != ctx.builder.metadata_items.items(.tag)[rhs_index]) return false; | 14168 | if (Metadata.Tag.constant != ctx.builder.metadata_items.items(.tag)[rhs_index]) return false; |
| 13348 | const rhs_data: Constant = @fromBackingInt(@intCast(ctx.builder.metadata_items.items(.data)[rhs_index])); | 14169 | const rhs_data: Constant = @fromBackingInt(ctx.builder.metadata_items.items(.data)[rhs_index]); |
| 13349 | return rhs_data == lhs_key; | 14170 | return rhs_data == lhs_key; |
| 13350 | } | 14171 | } |
| 13351 | }; | 14172 | }; |
| ... | @@ -13418,7 +14239,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco | ... | @@ -13418,7 +14239,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco |
| 13418 | }); | 14239 | }); |
| 13419 | } | 14240 | } |
| 13420 | 14241 | ||
| 13421 | if (self.data_layout.slice(self)) |data_layout| { | 14242 | if (self.data_layout.string_repr.slice(self)) |data_layout| { |
| 13422 | try module_block.writeAbbrev(ModuleBlock.String{ | 14243 | try module_block.writeAbbrev(ModuleBlock.String{ |
| 13423 | .code = 3, | 14244 | .code = 3, |
| 13424 | .string = data_layout, | 14245 | .string = data_layout, |
| ... | @@ -13577,6 +14398,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco | ... | @@ -13577,6 +14398,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco |
| 13577 | switch (attr_index.toAttribute(self)) { | 14398 | switch (attr_index.toAttribute(self)) { |
| 13578 | .zeroext, | 14399 | .zeroext, |
| 13579 | .signext, | 14400 | .signext, |
| 14401 | .noext, | ||
| 13580 | .inreg, | 14402 | .inreg, |
| 13581 | .@"noalias", | 14403 | .@"noalias", |
| 13582 | .nocapture, | 14404 | .nocapture, |
| ... | @@ -13594,11 +14416,13 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco | ... | @@ -13594,11 +14416,13 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco |
| 13594 | .readnone, | 14416 | .readnone, |
| 13595 | .readonly, | 14417 | .readonly, |
| 13596 | .writeonly, | 14418 | .writeonly, |
| 14419 | .writable, | ||
| 14420 | .dead_on_unwind, | ||
| 13597 | .alwaysinline, | 14421 | .alwaysinline, |
| 13598 | .builtin, | 14422 | .builtin, |
| 13599 | .cold, | 14423 | .cold, |
| 13600 | .convergent, | 14424 | .convergent, |
| 13601 | .disable_sanitizer_information, | 14425 | .disable_sanitizer_instrumentation, |
| 13602 | .fn_ret_thunk_extern, | 14426 | .fn_ret_thunk_extern, |
| 13603 | .hot, | 14427 | .hot, |
| 13604 | .inlinehint, | 14428 | .inlinehint, |
| ... | @@ -13607,6 +14431,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco | ... | @@ -13607,6 +14431,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco |
| 13607 | .naked, | 14431 | .naked, |
| 13608 | .nobuiltin, | 14432 | .nobuiltin, |
| 13609 | .nocallback, | 14433 | .nocallback, |
| 14434 | .nodivergencesource, | ||
| 13610 | .noduplicate, | 14435 | .noduplicate, |
| 13611 | .noimplicitfloat, | 14436 | .noimplicitfloat, |
| 13612 | .@"noinline", | 14437 | .@"noinline", |
| ... | @@ -13623,6 +14448,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco | ... | @@ -13623,6 +14448,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco |
| 13623 | .nosanitize_bounds, | 14448 | .nosanitize_bounds, |
| 13624 | .nosanitize_coverage, | 14449 | .nosanitize_coverage, |
| 13625 | .null_pointer_is_valid, | 14450 | .null_pointer_is_valid, |
| 14451 | .optdebug, | ||
| 13626 | .optforfuzzing, | 14452 | .optforfuzzing, |
| 13627 | .optnone, | 14453 | .optnone, |
| 13628 | .optsize, | 14454 | .optsize, |
| ... | @@ -13633,18 +14459,21 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco | ... | @@ -13633,18 +14459,21 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco |
| 13633 | .sanitize_thread, | 14459 | .sanitize_thread, |
| 13634 | .sanitize_hwaddress, | 14460 | .sanitize_hwaddress, |
| 13635 | .sanitize_memtag, | 14461 | .sanitize_memtag, |
| 14462 | .sanitize_realtime, | ||
| 14463 | .sanitize_realtime_blocking, | ||
| 14464 | .sanitize_alloc_token, | ||
| 13636 | .speculative_load_hardening, | 14465 | .speculative_load_hardening, |
| 13637 | .speculatable, | 14466 | .speculatable, |
| 13638 | .ssp, | 14467 | .ssp, |
| 13639 | .sspstrong, | 14468 | .sspstrong, |
| 13640 | .sspreq, | 14469 | .sspreq, |
| 13641 | .strictfp, | 14470 | .strictfp, |
| 14471 | .denormal_fpenv, | ||
| 13642 | .nocf_check, | 14472 | .nocf_check, |
| 13643 | .shadowcallstack, | 14473 | .shadowcallstack, |
| 13644 | .mustprogress, | 14474 | .mustprogress, |
| 13645 | .no_sanitize_address, | 14475 | .nooutline, |
| 13646 | .no_sanitize_hwaddress, | 14476 | .nocreateundeforpoison, |
| 13647 | .sanitize_address_dyninit, | ||
| 13648 | => { | 14477 | => { |
| 13649 | try record.ensureUnusedCapacity(self.gpa, 2); | 14478 | try record.ensureUnusedCapacity(self.gpa, 2); |
| 13650 | record.appendAssumeCapacity(0); | 14479 | record.appendAssumeCapacity(0); |
| ... | @@ -13670,6 +14499,12 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco | ... | @@ -13670,6 +14499,12 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco |
| 13670 | record.appendAssumeCapacity(@backingInt(kind)); | 14499 | record.appendAssumeCapacity(@backingInt(kind)); |
| 13671 | record.appendAssumeCapacity(alignment.resolve(self).toByteUnits() orelse 0); | 14500 | record.appendAssumeCapacity(alignment.resolve(self).toByteUnits() orelse 0); |
| 13672 | }, | 14501 | }, |
| 14502 | .captures => |captures| { | ||
| 14503 | try record.ensureUnusedCapacity(self.gpa, 3); | ||
| 14504 | record.appendAssumeCapacity(1); | ||
| 14505 | record.appendAssumeCapacity(@backingInt(kind)); | ||
| 14506 | record.appendAssumeCapacity(@as(u32, @bitCast(captures))); | ||
| 14507 | }, | ||
| 13673 | .dereferenceable, | 14508 | .dereferenceable, |
| 13674 | .dereferenceable_or_null, | 14509 | .dereferenceable_or_null, |
| 13675 | => |size| { | 14510 | => |size| { |
| ... | @@ -13684,6 +14519,9 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco | ... | @@ -13684,6 +14519,9 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco |
| 13684 | record.appendAssumeCapacity(@backingInt(kind)); | 14519 | record.appendAssumeCapacity(@backingInt(kind)); |
| 13685 | record.appendAssumeCapacity(@as(u32, @bitCast(fpclass))); | 14520 | record.appendAssumeCapacity(@as(u32, @bitCast(fpclass))); |
| 13686 | }, | 14521 | }, |
| 14522 | .initializes => @panic("TODO"), | ||
| 14523 | .dead_on_return => @panic("TODO"), | ||
| 14524 | .range => @panic("TODO"), | ||
| 13687 | .allockind => |allockind| { | 14525 | .allockind => |allockind| { |
| 13688 | try record.ensureUnusedCapacity(self.gpa, 3); | 14526 | try record.ensureUnusedCapacity(self.gpa, 3); |
| 13689 | record.appendAssumeCapacity(1); | 14527 | record.appendAssumeCapacity(1); |
| ... | @@ -13955,8 +14793,11 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco | ... | @@ -13955,8 +14793,11 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco |
| 13955 | } | 14793 | } |
| 13956 | 14794 | ||
| 13957 | const strtab = alias.global.strtab(self); | 14795 | const strtab = alias.global.strtab(self); |
| 13958 | |||
| 13959 | const global = alias.global.ptrConst(self); | 14796 | const global = alias.global.ptrConst(self); |
| 14797 | |||
| 14798 | // LLVM requires the types to match | ||
| 14799 | assert(global.addr_space == alias.aliasee.typeOf(self).pointerAddrSpace(self)); | ||
| 14800 | |||
| 13960 | try module_block.writeAbbrev(ModuleBlock.Alias{ | 14801 | try module_block.writeAbbrev(ModuleBlock.Alias{ |
| 13961 | .strtab_offset = strtab.offset, | 14802 | .strtab_offset = strtab.offset, |
| 13962 | .strtab_size = strtab.size, | 14803 | .strtab_size = strtab.size, |
| ... | @@ -14096,7 +14937,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco | ... | @@ -14096,7 +14937,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco |
| 14096 | } | 14937 | } |
| 14097 | }, | 14938 | }, |
| 14098 | .string => { | 14939 | .string => { |
| 14099 | const str: String = @fromBackingInt(@intCast(data)); | 14940 | const str: String = @fromBackingInt(data); |
| 14100 | if (str == .none) { | 14941 | if (str == .none) { |
| 14101 | try constants_block.writeAbbrev(ConstantsBlock.Null{}); | 14942 | try constants_block.writeAbbrev(ConstantsBlock.Null{}); |
| 14102 | } else { | 14943 | } else { |
| ... | @@ -14223,7 +15064,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco | ... | @@ -14223,7 +15064,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco |
| 14223 | .dso_local_equivalent, | 15064 | .dso_local_equivalent, |
| 14224 | .no_cfi, | 15065 | .no_cfi, |
| 14225 | => |tag| { | 15066 | => |tag| { |
| 14226 | const function: Function.Index = @fromBackingInt(@intCast(data)); | 15067 | const function: Function.Index = @fromBackingInt(data); |
| 14227 | try constants_block.writeAbbrev(ConstantsBlock.DsoLocalEquivalentOrNoCfi{ | 15068 | try constants_block.writeAbbrev(ConstantsBlock.DsoLocalEquivalentOrNoCfi{ |
| 14228 | .code = switch (tag) { | 15069 | .code = switch (tag) { |
| 14229 | .dso_local_equivalent => .DSO_LOCAL_EQUIVALENT, | 15070 | .dso_local_equivalent => .DSO_LOCAL_EQUIVALENT, |
| ... | @@ -14606,7 +15447,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco | ... | @@ -14606,7 +15447,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco |
| 14606 | }, metadata_adapter); | 15447 | }, metadata_adapter); |
| 14607 | }, | 15448 | }, |
| 14608 | .constant => { | 15449 | .constant => { |
| 14609 | const constant: Constant = @fromBackingInt(@intCast(data)); | 15450 | const constant: Constant = @fromBackingInt(data); |
| 14610 | try metadata_block.writeAbbrevAdapted(MetadataBlock.Constant{ | 15451 | try metadata_block.writeAbbrevAdapted(MetadataBlock.Constant{ |
| 14611 | .ty = constant.typeOf(self), | 15452 | .ty = constant.typeOf(self), |
| 14612 | .constant = constant, | 15453 | .constant = constant, |
| ... | @@ -14775,7 +15616,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco | ... | @@ -14775,7 +15616,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco |
| 14775 | var adapter: FunctionAdapter = .{ | 15616 | var adapter: FunctionAdapter = .{ |
| 14776 | .metadata_adapter = metadata_adapter, | 15617 | .metadata_adapter = metadata_adapter, |
| 14777 | .func = &func, | 15618 | .func = &func, |
| 14778 | .instruction_index = @fromBackingInt(@intCast(0)), | 15619 | .instruction_index = @fromBackingInt(0), |
| 14779 | }; | 15620 | }; |
| 14780 | 15621 | ||
| 14781 | // Emit function level metadata block | 15622 | // Emit function level metadata block |
| ... | @@ -14786,7 +15627,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco | ... | @@ -14786,7 +15627,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco |
| 14786 | for (func.debug_values) |value| { | 15627 | for (func.debug_values) |value| { |
| 14787 | try metadata_block.writeAbbrev(MetadataBlock.Value{ | 15628 | try metadata_block.writeAbbrev(MetadataBlock.Value{ |
| 14788 | .ty = value.typeOf(@fromBackingInt(@intCast(func_index)), self), | 15629 | .ty = value.typeOf(@fromBackingInt(@intCast(func_index)), self), |
| 14789 | .value = @fromBackingInt(@intCast(adapter.getValueIndex(value.toValue()))), | 15630 | .value = @fromBackingInt(adapter.getValueIndex(value.toValue())), |
| 14790 | }); | 15631 | }); |
| 14791 | } | 15632 | } |
| 14792 | 15633 | ||
| ... | @@ -15068,10 +15909,10 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco | ... | @@ -15068,10 +15909,10 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco |
| 15068 | }); | 15909 | }); |
| 15069 | }, | 15910 | }, |
| 15070 | .fneg => try function_block.writeAbbrev(FunctionBlock.FNeg{ | 15911 | .fneg => try function_block.writeAbbrev(FunctionBlock.FNeg{ |
| 15071 | .val = adapter.getOffsetValueIndex(@fromBackingInt(@intCast(data))), | 15912 | .val = adapter.getOffsetValueIndex(@fromBackingInt(data)), |
| 15072 | }), | 15913 | }), |
| 15073 | .@"fneg fast" => try function_block.writeAbbrev(FunctionBlock.FNegFast{ | 15914 | .@"fneg fast" => try function_block.writeAbbrev(FunctionBlock.FNegFast{ |
| 15074 | .val = adapter.getOffsetValueIndex(@fromBackingInt(@intCast(data))), | 15915 | .val = adapter.getOffsetValueIndex(@fromBackingInt(data)), |
| 15075 | .fast_math = FastMath.fast, | 15916 | .fast_math = FastMath.fast, |
| 15076 | }), | 15917 | }), |
| 15077 | .extractvalue => { | 15918 | .extractvalue => { |
| ... | @@ -15271,7 +16112,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco | ... | @@ -15271,7 +16112,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco |
| 15271 | try function_block.writeUnabbrev(16, record.items); | 16112 | try function_block.writeUnabbrev(16, record.items); |
| 15272 | }, | 16113 | }, |
| 15273 | .ret => try function_block.writeAbbrev(FunctionBlock.Ret{ | 16114 | .ret => try function_block.writeAbbrev(FunctionBlock.Ret{ |
| 15274 | .val = adapter.getOffsetValueIndex(@fromBackingInt(@intCast(data))), | 16115 | .val = adapter.getOffsetValueIndex(@fromBackingInt(data)), |
| 15275 | }), | 16116 | }), |
| 15276 | .@"ret void" => try function_block.writeAbbrev(FunctionBlock.RetVoid{}), | 16117 | .@"ret void" => try function_block.writeAbbrev(FunctionBlock.RetVoid{}), |
| 15277 | .atomicrmw => { | 16118 | .atomicrmw => { |
lib/std/zig/llvm/bitcode_writer.zig+1-1| ... | @@ -246,7 +246,7 @@ pub fn BitcodeWriter(comptime types: []const type) type { | ... | @@ -246,7 +246,7 @@ pub fn BitcodeWriter(comptime types: []const type) type { |
| 246 | 246 | ||
| 247 | try self.bitcode.writeBits(comptime abbrevId(Abbrev), abbrev_len); | 247 | try self.bitcode.writeBits(comptime abbrevId(Abbrev), abbrev_len); |
| 248 | 248 | ||
| 249 | const field_names = comptime std.meta.fieldNames(Abbrev); | 249 | const field_names = @typeInfo(Abbrev).@"struct".field_names; |
| 250 | 250 | ||
| 251 | // This abbreviation might only contain literals | 251 | // This abbreviation might only contain literals |
| 252 | if (field_names.len == 0) return; | 252 | if (field_names.len == 0) return; |
lib/std/zig/system.zig+9-9| ... | @@ -597,23 +597,23 @@ fn abiAndDynamicLinkerFromFile( | ... | @@ -597,23 +597,23 @@ fn abiAndDynamicLinkerFromFile( |
| 597 | .ofmt = query.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch), | 597 | .ofmt = query.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch), |
| 598 | .dynamic_linker = query.dynamic_linker orelse .none, | 598 | .dynamic_linker = query.dynamic_linker orelse .none, |
| 599 | }; | 599 | }; |
| 600 | var rpath_offset: ?u64 = null; // Found inside PT_DYNAMIC | 600 | var rpath_offset: ?u64 = null; // Found inside PT.DYNAMIC |
| 601 | const look_for_ld = query.dynamic_linker == null; | 601 | const look_for_ld = query.dynamic_linker == null; |
| 602 | 602 | ||
| 603 | var got_dyn_section: bool = false; | 603 | var got_dyn_section: bool = false; |
| 604 | { | 604 | { |
| 605 | var it = header.iterateProgramHeaders(file_reader); | 605 | var it = header.iterateProgramHeaders(file_reader); |
| 606 | while (try it.next()) |phdr| switch (phdr.p_type) { | 606 | while (try it.next()) |phdr| switch (phdr.type) { |
| 607 | elf.PT_INTERP => { | 607 | .INTERP => { |
| 608 | got_dyn_section = true; | 608 | got_dyn_section = true; |
| 609 | 609 | ||
| 610 | if (look_for_ld) { | 610 | if (look_for_ld) { |
| 611 | const p_filesz = phdr.p_filesz; | 611 | const p_filesz = phdr.filesz; |
| 612 | if (p_filesz > result.dynamic_linker.buffer.len) return error.NameTooLong; | 612 | if (p_filesz > result.dynamic_linker.buffer.len) return error.NameTooLong; |
| 613 | const filesz: usize = @intCast(p_filesz); | 613 | const filesz: usize = @intCast(p_filesz); |
| 614 | try file_reader.seekTo(phdr.p_offset); | 614 | try file_reader.seekTo(phdr.offset); |
| 615 | try file_reader.interface.readSliceAll(result.dynamic_linker.buffer[0..filesz]); | 615 | try file_reader.interface.readSliceAll(result.dynamic_linker.buffer[0..filesz]); |
| 616 | // PT_INTERP includes a null byte in filesz. | 616 | // PT.INTERP includes a null byte in filesz. |
| 617 | const len = filesz - 1; | 617 | const len = filesz - 1; |
| 618 | // dynamic_linker.max_byte is "max", not "len". | 618 | // dynamic_linker.max_byte is "max", not "len". |
| 619 | // We know it will fit in u8 because we check against dynamic_linker.buffer.len above. | 619 | // We know it will fit in u8 because we check against dynamic_linker.buffer.len above. |
| ... | @@ -631,11 +631,11 @@ fn abiAndDynamicLinkerFromFile( | ... | @@ -631,11 +631,11 @@ fn abiAndDynamicLinkerFromFile( |
| 631 | } | 631 | } |
| 632 | }, | 632 | }, |
| 633 | // We only need this for detecting glibc version. | 633 | // We only need this for detecting glibc version. |
| 634 | elf.PT_DYNAMIC => { | 634 | .DYNAMIC => { |
| 635 | got_dyn_section = true; | 635 | got_dyn_section = true; |
| 636 | 636 | ||
| 637 | if (builtin.target.os.tag == .linux and result.isGnuLibC() and query.glibc_version == null) { | 637 | if (builtin.target.os.tag == .linux and result.isGnuLibC() and query.glibc_version == null) { |
| 638 | var dyn_it = header.iterateDynamicSection(file_reader, phdr.p_offset, phdr.p_filesz); | 638 | var dyn_it = header.iterateDynamicSection(file_reader, phdr.offset, phdr.filesz); |
| 639 | while (try dyn_it.next()) |dyn| { | 639 | while (try dyn_it.next()) |dyn| { |
| 640 | if (dyn.d_tag == elf.DT_RUNPATH) { | 640 | if (dyn.d_tag == elf.DT_RUNPATH) { |
| 641 | rpath_offset = dyn.d_val; | 641 | rpath_offset = dyn.d_val; |
| ... | @@ -973,7 +973,7 @@ fn detectAbiAndDynamicLinker(io: Io, cpu: Target.Cpu, os: Target.Os, query: Targ | ... | @@ -973,7 +973,7 @@ fn detectAbiAndDynamicLinker(io: Io, cpu: Target.Cpu, os: Target.Os, query: Targ |
| 973 | // relying on `builtin.target`. | 973 | // relying on `builtin.target`. |
| 974 | const all_abis = comptime blk: { | 974 | const all_abis = comptime blk: { |
| 975 | assert(@backingInt(Target.Abi.none) == 0); | 975 | assert(@backingInt(Target.Abi.none) == 0); |
| 976 | const field_names = std.meta.fieldNames(Target.Abi)[1..]; | 976 | const field_names = @typeInfo(Target.Abi).@"enum".field_names[1..]; |
| 977 | var array: [field_names.len]Target.Abi = undefined; | 977 | var array: [field_names.len]Target.Abi = undefined; |
| 978 | for (field_names, 0..) |field_name, i| { | 978 | for (field_names, 0..) |field_name, i| { |
| 979 | array[i] = @field(Target.Abi, field_name); | 979 | array[i] = @field(Target.Abi, field_name); |
lib/std/zig/target.zig+25-25| ... | @@ -46,6 +46,8 @@ pub const available_libcs = [_]ArchOsAbi{ | ... | @@ -46,6 +46,8 @@ pub const available_libcs = [_]ArchOsAbi{ |
| 46 | .{ .arch = .csky, .os = .linux, .abi = .gnueabi, .os_ver = .{ .major = 4, .minor = 20, .patch = 0 }, .glibc_min = .{ .major = 2, .minor = 29, .patch = 0 }, .glibc_triple = "csky-linux-gnuabiv2-soft" }, | 46 | .{ .arch = .csky, .os = .linux, .abi = .gnueabi, .os_ver = .{ .major = 4, .minor = 20, .patch = 0 }, .glibc_min = .{ .major = 2, .minor = 29, .patch = 0 }, .glibc_triple = "csky-linux-gnuabiv2-soft" }, |
| 47 | .{ .arch = .csky, .os = .linux, .abi = .gnueabihf, .os_ver = .{ .major = 4, .minor = 20, .patch = 0 }, .glibc_min = .{ .major = 2, .minor = 29, .patch = 0 }, .glibc_triple = "csky-linux-gnuabiv2" }, | 47 | .{ .arch = .csky, .os = .linux, .abi = .gnueabihf, .os_ver = .{ .major = 4, .minor = 20, .patch = 0 }, .glibc_min = .{ .major = 2, .minor = 29, .patch = 0 }, .glibc_triple = "csky-linux-gnuabiv2" }, |
| 48 | .{ .arch = .hexagon, .os = .linux, .abi = .musl, .os_ver = .{ .major = 3, .minor = 2, .patch = 102 } }, | 48 | .{ .arch = .hexagon, .os = .linux, .abi = .musl, .os_ver = .{ .major = 3, .minor = 2, .patch = 102 } }, |
| 49 | .{ .arch = .loongarch32, .os = .linux, .abi = .gnu, .os_ver = .{ .major = 6, .minor = 19, .patch = 0 }, .glibc_min = .{ .major = 2, .minor = 44, .patch = 0 }, .glibc_triple = "loongarch32-linux-gnuf64" }, | ||
| 50 | .{ .arch = .loongarch32, .os = .linux, .abi = .gnusf, .os_ver = .{ .major = 6, .minor = 19, .patch = 0 }, .glibc_min = .{ .major = 2, .minor = 44, .patch = 0 }, .glibc_triple = "loongarch32-linux-gnusf" }, | ||
| 49 | .{ .arch = .loongarch64, .os = .linux, .abi = .gnu, .os_ver = .{ .major = 5, .minor = 19, .patch = 0 }, .glibc_min = .{ .major = 2, .minor = 36, .patch = 0 }, .glibc_triple = "loongarch64-linux-gnuf64" }, | 51 | .{ .arch = .loongarch64, .os = .linux, .abi = .gnu, .os_ver = .{ .major = 5, .minor = 19, .patch = 0 }, .glibc_min = .{ .major = 2, .minor = 36, .patch = 0 }, .glibc_triple = "loongarch64-linux-gnuf64" }, |
| 50 | .{ .arch = .loongarch64, .os = .linux, .abi = .gnusf, .os_ver = .{ .major = 5, .minor = 19, .patch = 0 }, .glibc_min = .{ .major = 2, .minor = 36, .patch = 0 }, .glibc_triple = "loongarch64-linux-gnusf" }, | 52 | .{ .arch = .loongarch64, .os = .linux, .abi = .gnusf, .os_ver = .{ .major = 5, .minor = 19, .patch = 0 }, .glibc_min = .{ .major = 2, .minor = 36, .patch = 0 }, .glibc_triple = "loongarch64-linux-gnusf" }, |
| 51 | .{ .arch = .loongarch64, .os = .linux, .abi = .musl, .os_ver = .{ .major = 5, .minor = 19, .patch = 0 } }, | 53 | .{ .arch = .loongarch64, .os = .linux, .abi = .musl, .os_ver = .{ .major = 5, .minor = 19, .patch = 0 } }, |
| ... | @@ -499,34 +501,32 @@ pub fn intByteSize(target: *const std.Target, bits: u16) u16 { | ... | @@ -499,34 +501,32 @@ pub fn intByteSize(target: *const std.Target, bits: u16) u16 { |
| 499 | } | 501 | } |
| 500 | 502 | ||
| 501 | pub fn intAlignment(target: *const std.Target, bits: u16) u16 { | 503 | pub fn intAlignment(target: *const std.Target, bits: u16) u16 { |
| 502 | return switch (target.cpu.arch) { | 504 | return switch (bits) { |
| 503 | .x86 => switch (bits) { | 505 | 0 => 1, |
| 504 | 0...8 => 1, | 506 | else => @min( |
| 505 | 9...16 => 2, | 507 | std.math.ceilPowerOfTwoPromote(u16, @intCast((@as(u17, bits) + 7) / 8)), |
| 506 | 17...32 => 4, | 508 | target.cMaxIntAlignment(), |
| 507 | 33...64 => switch (target.os.tag) { | 509 | ), |
| 508 | .uefi, .windows => 8, | ||
| 509 | else => 4, | ||
| 510 | }, | ||
| 511 | else => 16, | ||
| 512 | }, | ||
| 513 | .x86_64 => switch (bits) { | ||
| 514 | 0...8 => 1, | ||
| 515 | 9...16 => 2, | ||
| 516 | 17...32 => 4, | ||
| 517 | 33...64 => 8, | ||
| 518 | else => 16, | ||
| 519 | }, | ||
| 520 | else => switch (bits) { | ||
| 521 | 0 => 1, | ||
| 522 | else => @min( | ||
| 523 | std.math.ceilPowerOfTwoPromote(u16, @intCast((@as(u17, bits) + 7) / 8)), | ||
| 524 | target.cMaxIntAlignment(), | ||
| 525 | ), | ||
| 526 | }, | ||
| 527 | }; | 510 | }; |
| 528 | } | 511 | } |
| 529 | 512 | ||
| 513 | pub fn compilerRtFloatAbi(target: *const std.Target, bits: u16) std.Target.Abi.Float { | ||
| 514 | if (target.cpu.has(.x86, .soft_float)) return .soft; | ||
| 515 | // Marks targets where clang does not even provide a usable C type. | ||
| 516 | const no_c_type_available = .soft; | ||
| 517 | switch (bits) { | ||
| 518 | else => unreachable, | ||
| 519 | 16 => if (target.cpu.arch.isMIPS() or target.cpu.arch.isPowerPC()) return no_c_type_available, | ||
| 520 | 32, 64 => {}, | ||
| 521 | 80 => if (target.cTypeBitSize(.longdouble) != 80) return no_c_type_available, | ||
| 522 | 128 => { | ||
| 523 | if (target.cpu.arch.isX86()) return .hard; // if (target.abi == .msvc) __m128i else __float128 | ||
| 524 | if (target.cTypeBitSize(.longdouble) != 128) return no_c_type_available; | ||
| 525 | }, | ||
| 526 | } | ||
| 527 | return .hard; | ||
| 528 | } | ||
| 529 | |||
| 530 | const std = @import("std"); | 530 | const std = @import("std"); |
| 531 | const assert = std.debug.assert; | 531 | const assert = std.debug.assert; |
| 532 | const Allocator = std.mem.Allocator; | 532 | const Allocator = std.mem.Allocator; |
lib/std/zip.zig+1-1| ... | @@ -109,7 +109,7 @@ pub const EndRecord = extern struct { | ... | @@ -109,7 +109,7 @@ pub const EndRecord = extern struct { |
| 109 | 109 | ||
| 110 | /// TODO audit this logic | 110 | /// TODO audit this logic |
| 111 | pub fn findBuffer(buffer: []const u8) FindBufferError!EndRecord { | 111 | pub fn findBuffer(buffer: []const u8) FindBufferError!EndRecord { |
| 112 | const pos = std.mem.lastIndexOf(u8, buffer, &end_record_sig) orelse return error.ZipNoEndRecord; | 112 | const pos = std.mem.findLast(u8, buffer, &end_record_sig) orelse return error.ZipNoEndRecord; |
| 113 | if (pos + @sizeOf(EndRecord) > buffer.len) return error.EndOfStream; | 113 | if (pos + @sizeOf(EndRecord) > buffer.len) return error.EndOfStream; |
| 114 | const record_ptr: *EndRecord = @ptrCast(buffer[pos..][0..@sizeOf(EndRecord)]); | 114 | const record_ptr: *EndRecord = @ptrCast(buffer[pos..][0..@sizeOf(EndRecord)]); |
| 115 | var record = record_ptr.*; | 115 | var record = record_ptr.*; |
lib/std/zon.zig+41| ... | @@ -37,10 +37,51 @@ | ... | @@ -37,10 +37,51 @@ |
| 37 | //! ZON does not have syntax for pointers, but the parsers will allocate as needed to match the | 37 | //! ZON does not have syntax for pointers, but the parsers will allocate as needed to match the |
| 38 | //! given Zig types. Similarly, the serializer will traverse pointers. | 38 | //! given Zig types. Similarly, the serializer will traverse pointers. |
| 39 | 39 | ||
| 40 | const std = @import("std"); | ||
| 41 | |||
| 40 | pub const parse = @import("zon/parse.zig"); | 42 | pub const parse = @import("zon/parse.zig"); |
| 41 | pub const stringify = @import("zon/stringify.zig"); | 43 | pub const stringify = @import("zon/stringify.zig"); |
| 42 | pub const Serializer = @import("zon/Serializer.zig"); | 44 | pub const Serializer = @import("zon/Serializer.zig"); |
| 43 | 45 | ||
| 46 | /// Returns a formatter that formats the given value using stringify. | ||
| 47 | pub fn fmt(value: anytype, options: stringify.SerializeOptions) Formatter(@TypeOf(value)) { | ||
| 48 | return Formatter(@TypeOf(value)){ .value = value, .options = options }; | ||
| 49 | } | ||
| 50 | |||
| 51 | test fmt { | ||
| 52 | const expectFmt = std.testing.expectFmt; | ||
| 53 | try expectFmt("123", "{f}", .{fmt(@as(u32, 123), .{})}); | ||
| 54 | try expectFmt( | ||
| 55 | \\.{ | ||
| 56 | \\ .num = 927, | ||
| 57 | \\ .msg = "hello", | ||
| 58 | \\ .sub = .{ .mybool = true }, | ||
| 59 | \\} | ||
| 60 | , "{f}", .{fmt(struct { | ||
| 61 | num: u32, | ||
| 62 | msg: []const u8, | ||
| 63 | sub: struct { | ||
| 64 | mybool: bool, | ||
| 65 | }, | ||
| 66 | }{ | ||
| 67 | .num = 927, | ||
| 68 | .msg = "hello", | ||
| 69 | .sub = .{ .mybool = true }, | ||
| 70 | }, .{})}); | ||
| 71 | } | ||
| 72 | |||
| 73 | /// Formats the given value using stringify. | ||
| 74 | pub fn Formatter(comptime T: type) type { | ||
| 75 | return struct { | ||
| 76 | value: T, | ||
| 77 | options: stringify.SerializeOptions, | ||
| 78 | |||
| 79 | pub fn format(self: @This(), writer: *std.Io.Writer) std.Io.Writer.Error!void { | ||
| 80 | try stringify.serialize(self.value, self.options, writer); | ||
| 81 | } | ||
| 82 | }; | ||
| 83 | } | ||
| 84 | |||
| 44 | test { | 85 | test { |
| 45 | _ = parse; | 86 | _ = parse; |
| 46 | _ = stringify; | 87 | _ = stringify; |
lib/std/zon/parse.zig+1-6| ... | @@ -9,7 +9,6 @@ | ... | @@ -9,7 +9,6 @@ |
| 9 | //! For lower level control over parsing, see `std.zig.Zoir`. | 9 | //! For lower level control over parsing, see `std.zig.Zoir`. |
| 10 | 10 | ||
| 11 | const std = @import("std"); | 11 | const std = @import("std"); |
| 12 | const builtin = @import("builtin"); | ||
| 13 | const Allocator = std.mem.Allocator; | 12 | const Allocator = std.mem.Allocator; |
| 14 | const Ast = std.zig.Ast; | 13 | const Ast = std.zig.Ast; |
| 15 | const Zoir = std.zig.Zoir; | 14 | const Zoir = std.zig.Zoir; |
| ... | @@ -1868,8 +1867,6 @@ test "std.zon tuples" { | ... | @@ -1868,8 +1867,6 @@ test "std.zon tuples" { |
| 1868 | 1867 | ||
| 1869 | // Test sizes 0 to 3 since small sizes get parsed differently | 1868 | // Test sizes 0 to 3 since small sizes get parsed differently |
| 1870 | test "std.zon arrays and slices" { | 1869 | test "std.zon arrays and slices" { |
| 1871 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/20881 | ||
| 1872 | |||
| 1873 | const gpa = std.testing.allocator; | 1870 | const gpa = std.testing.allocator; |
| 1874 | 1871 | ||
| 1875 | // Literals | 1872 | // Literals |
| ... | @@ -2802,8 +2799,6 @@ test "std.zon negative char" { | ... | @@ -2802,8 +2799,6 @@ test "std.zon negative char" { |
| 2802 | } | 2799 | } |
| 2803 | 2800 | ||
| 2804 | test "std.zon parse float" { | 2801 | test "std.zon parse float" { |
| 2805 | if (builtin.cpu.arch == .x86) return error.SkipZigTest; | ||
| 2806 | |||
| 2807 | const gpa = std.testing.allocator; | 2802 | const gpa = std.testing.allocator; |
| 2808 | 2803 | ||
| 2809 | // Test decimals | 2804 | // Test decimals |
| ... | @@ -3135,7 +3130,7 @@ test "std.zon free on error" { | ... | @@ -3135,7 +3130,7 @@ test "std.zon free on error" { |
| 3135 | } | 3130 | } |
| 3136 | 3131 | ||
| 3137 | test "std.zon vector" { | 3132 | test "std.zon vector" { |
| 3138 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/15330 | 3133 | const builtin = @import("builtin"); |
| 3139 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .s390x) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/25957 | 3134 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .s390x) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/25957 |
| 3140 | 3135 | ||
| 3141 | const gpa = std.testing.allocator; | 3136 | const gpa = std.testing.allocator; |
lib/std/zon/stringify.zig-3| ... | @@ -1151,9 +1151,6 @@ test "std.zon depth limits" { | ... | @@ -1151,9 +1151,6 @@ test "std.zon depth limits" { |
| 1151 | } | 1151 | } |
| 1152 | 1152 | ||
| 1153 | test "std.zon stringify primitives" { | 1153 | test "std.zon stringify primitives" { |
| 1154 | // Issue: https://github.com/ziglang/zig/issues/20880 | ||
| 1155 | if (@import("builtin").zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 1156 | |||
| 1157 | try expectSerializeEqual( | 1154 | try expectSerializeEqual( |
| 1158 | \\.{ | 1155 | \\.{ |
| 1159 | \\ .a = 1.5, | 1156 | \\ .a = 1.5, |
lib/zig.h+3079-991| ... | @@ -166,6 +166,12 @@ | ... | @@ -166,6 +166,12 @@ |
| 166 | #endif | 166 | #endif |
| 167 | #define zig_expand_has_builtin(b) zig_has_builtin(b) | 167 | #define zig_expand_has_builtin(b) zig_has_builtin(b) |
| 168 | 168 | ||
| 169 | #if defined(__has_feature) | ||
| 170 | #define zig_has_feature(feature) __has_feature(feature) | ||
| 171 | #else | ||
| 172 | #define zig_has_feature(feature) 0 | ||
| 173 | #endif | ||
| 174 | |||
| 169 | #if defined(__has_attribute) | 175 | #if defined(__has_attribute) |
| 170 | #define zig_has_attribute(attribute) __has_attribute(attribute) | 176 | #define zig_has_attribute(attribute) __has_attribute(attribute) |
| 171 | #else | 177 | #else |
| ... | @@ -175,9 +181,9 @@ | ... | @@ -175,9 +181,9 @@ |
| 175 | #if __STDC_VERSION__ >= 201112L | 181 | #if __STDC_VERSION__ >= 201112L |
| 176 | #define zig_static_assert(cond, msg) _Static_assert(cond, msg) | 182 | #define zig_static_assert(cond, msg) _Static_assert(cond, msg) |
| 177 | #elif zig_has_attribute(unused) | 183 | #elif zig_has_attribute(unused) |
| 178 | #define zig_static_assert(cond, _) typedef char zig_expand_concat(zig_static_assert_fail_, __LINE__)[!!(cond)] __attribute__((unused)) | 184 | #define zig_static_assert(cond, msg) typedef char zig_expand_concat(zig_static_assert_fail_, __LINE__)[(cond) ? 1 : -1] __attribute__((unused)) |
| 179 | #else | 185 | #else |
| 180 | #define zig_static_assert(cond, _) typedef char zig_expand_concat(zig_static_assert_fail_, __LINE__)[!!(cond)] | 186 | #define zig_static_assert(cond, msg) typedef char zig_expand_concat(zig_static_assert_fail_, __LINE__)[(cond) ? 1 : -1] |
| 181 | #endif | 187 | #endif |
| 182 | 188 | ||
| 183 | #if __STDC_VERSION__ >= 202311L | 189 | #if __STDC_VERSION__ >= 202311L |
| ... | @@ -193,10 +199,8 @@ | ... | @@ -193,10 +199,8 @@ |
| 193 | #endif | 199 | #endif |
| 194 | 200 | ||
| 195 | #if defined(zig_msvc) | 201 | #if defined(zig_msvc) |
| 196 | #define zig_const_arr | ||
| 197 | #define zig_callconv(c) __##c | 202 | #define zig_callconv(c) __##c |
| 198 | #else | 203 | #else |
| 199 | #define zig_const_arr static const | ||
| 200 | #define zig_callconv(c) __attribute__((c)) | 204 | #define zig_callconv(c) __attribute__((c)) |
| 201 | #endif | 205 | #endif |
| 202 | 206 | ||
| ... | @@ -267,12 +271,20 @@ | ... | @@ -267,12 +271,20 @@ |
| 267 | 271 | ||
| 268 | #if __STDC_VERSION__ >= 202311L | 272 | #if __STDC_VERSION__ >= 202311L |
| 269 | #define zig_align(alignment) alignas(alignment) | 273 | #define zig_align(alignment) alignas(alignment) |
| 270 | #elif __STDC_VERSION__ >= 201112L | 274 | #elif __STDC_VERSION__ >= 201112L || zig_has_feature(c_alignas) |
| 271 | #define zig_align(alignment) _Alignas(alignment) | 275 | #define zig_align(alignment) _Alignas(alignment) |
| 272 | #else | 276 | #else |
| 273 | #define zig_align(alignment) zig_under_align(alignment) | 277 | #define zig_align(alignment) zig_under_align(alignment) |
| 274 | #endif | 278 | #endif |
| 275 | 279 | ||
| 280 | #if __STDC_VERSION__ >= 202311L | ||
| 281 | #define zig_alignOf(Type) alignof(Type) | ||
| 282 | #elif __STDC_VERSION__ >= 201112L || zig_has_feature(c_alignof) | ||
| 283 | #define zig_alignOf(Type) _Alignof(Type) | ||
| 284 | #else | ||
| 285 | #define zig_alignOf(Type) (sizeof(struct { char c; Type t; }) - sizeof(Type)) | ||
| 286 | #endif | ||
| 287 | |||
| 276 | #if zig_has_attribute(aligned) || defined(zig_tinyc) | 288 | #if zig_has_attribute(aligned) || defined(zig_tinyc) |
| 277 | #define zig_align_fn(alignment) __attribute__((aligned(alignment))) | 289 | #define zig_align_fn(alignment) __attribute__((aligned(alignment))) |
| 278 | #elif defined(zig_msvc) | 290 | #elif defined(zig_msvc) |
| ... | @@ -350,11 +362,9 @@ | ... | @@ -350,11 +362,9 @@ |
| 350 | #define zig_export(symbol, name) __attribute__((alias(symbol))) | 362 | #define zig_export(symbol, name) __attribute__((alias(symbol))) |
| 351 | #else | 363 | #else |
| 352 | #define zig_export(symbol, name) ; \ | 364 | #define zig_export(symbol, name) ; \ |
| 353 | __asm(zig_mangle_c(name) " = " zig_mangle_c(symbol)) | 365 | __asm("\t.globl\t" zig_mangle_c(name) "\n" zig_mangle_c(name) " = " zig_mangle_c(symbol)) |
| 354 | #endif | 366 | #endif |
| 355 | 367 | ||
| 356 | #define zig_mangled_tentative zig_mangled | ||
| 357 | #define zig_mangled_final zig_mangled | ||
| 358 | #if defined(zig_msvc) | 368 | #if defined(zig_msvc) |
| 359 | #define zig_mangled(mangled, unmangled) ; \ | 369 | #define zig_mangled(mangled, unmangled) ; \ |
| 360 | zig_export(#mangled, unmangled) | 370 | zig_export(#mangled, unmangled) |
| ... | @@ -364,7 +374,7 @@ | ... | @@ -364,7 +374,7 @@ |
| 364 | #else /* zig_msvc */ | 374 | #else /* zig_msvc */ |
| 365 | #define zig_mangled(mangled, unmangled) __asm(zig_mangle_c(unmangled)) | 375 | #define zig_mangled(mangled, unmangled) __asm(zig_mangle_c(unmangled)) |
| 366 | #define zig_mangled_export(mangled, unmangled, symbol) \ | 376 | #define zig_mangled_export(mangled, unmangled, symbol) \ |
| 367 | zig_mangled_final(mangled, unmangled) \ | 377 | zig_mangled(mangled, unmangled) \ |
| 368 | zig_export(symbol, unmangled) | 378 | zig_export(symbol, unmangled) |
| 369 | #endif /* zig_msvc */ | 379 | #endif /* zig_msvc */ |
| 370 | 380 | ||
| ... | @@ -550,6 +560,9 @@ | ... | @@ -550,6 +560,9 @@ |
| 550 | #define zig_noreturn | 560 | #define zig_noreturn |
| 551 | #endif | 561 | #endif |
| 552 | 562 | ||
| 563 | #define zig_has_always 1 | ||
| 564 | #define zig_has_never 0 | ||
| 565 | |||
| 553 | #define zig_compiler_rt_abbrev_uint32_t si | 566 | #define zig_compiler_rt_abbrev_uint32_t si |
| 554 | #define zig_compiler_rt_abbrev_int32_t si | 567 | #define zig_compiler_rt_abbrev_int32_t si |
| 555 | #define zig_compiler_rt_abbrev_uint64_t di | 568 | #define zig_compiler_rt_abbrev_uint64_t di |
| ... | @@ -560,7 +573,11 @@ | ... | @@ -560,7 +573,11 @@ |
| 560 | #define zig_compiler_rt_abbrev_zig_f32 sf | 573 | #define zig_compiler_rt_abbrev_zig_f32 sf |
| 561 | #define zig_compiler_rt_abbrev_zig_f64 df | 574 | #define zig_compiler_rt_abbrev_zig_f64 df |
| 562 | #define zig_compiler_rt_abbrev_zig_f80 xf | 575 | #define zig_compiler_rt_abbrev_zig_f80 xf |
| 576 | #ifdef zig_powerpc | ||
| 577 | #define zig_compiler_rt_abbrev_zig_f128 kf | ||
| 578 | #else | ||
| 563 | #define zig_compiler_rt_abbrev_zig_f128 tf | 579 | #define zig_compiler_rt_abbrev_zig_f128 tf |
| 580 | #endif | ||
| 564 | 581 | ||
| 565 | zig_extern void *memcpy (void *zig_restrict, void const *zig_restrict, size_t); | 582 | zig_extern void *memcpy (void *zig_restrict, void const *zig_restrict, size_t); |
| 566 | zig_extern void *memset (void *, int, size_t); | 583 | zig_extern void *memset (void *, int, size_t); |
| ... | @@ -645,16 +662,6 @@ typedef signed long long int16_t; | ... | @@ -645,16 +662,6 @@ typedef signed long long int16_t; |
| 645 | #define INT16_MAX ( INT16_C(0x7FFF)) | 662 | #define INT16_MAX ( INT16_C(0x7FFF)) |
| 646 | #define UINT16_MAX ( INT16_C(0xFFFF)) | 663 | #define UINT16_MAX ( INT16_C(0xFFFF)) |
| 647 | 664 | ||
| 648 | #if defined(zig_ez80) | ||
| 649 | typedef unsigned int uint24_t; | ||
| 650 | typedef signed int int24_t; | ||
| 651 | #define INT24_C(c) c | ||
| 652 | #define UINT24_C(c) c##U | ||
| 653 | #endif | ||
| 654 | #define INT24_MIN (~INT24_C(0x7FFF)) | ||
| 655 | #define INT24_MAX ( INT24_C(0x7FFF)) | ||
| 656 | #define UINT24_MAX ( INT24_C(0xFFFF)) | ||
| 657 | |||
| 658 | #if SCHAR_MIN == ~0x7FFFFFFF && SCHAR_MAX == 0x7FFFFFFF && UCHAR_MAX == 0xFFFFFFFF | 665 | #if SCHAR_MIN == ~0x7FFFFFFF && SCHAR_MAX == 0x7FFFFFFF && UCHAR_MAX == 0xFFFFFFFF |
| 659 | typedef unsigned char uint32_t; | 666 | typedef unsigned char uint32_t; |
| 660 | typedef signed char int32_t; | 667 | typedef signed char int32_t; |
| ... | @@ -685,17 +692,6 @@ typedef signed long long int32_t; | ... | @@ -685,17 +692,6 @@ typedef signed long long int32_t; |
| 685 | #define INT32_MAX ( INT32_C(0x7FFFFFFF)) | 692 | #define INT32_MAX ( INT32_C(0x7FFFFFFF)) |
| 686 | #define UINT32_MAX ( INT32_C(0xFFFFFFFF)) | 693 | #define UINT32_MAX ( INT32_C(0xFFFFFFFF)) |
| 687 | 694 | ||
| 688 | #if defined(zig_ez80) | ||
| 689 | typedef unsigned __int48 uint48_t; | ||
| 690 | typedef signed __int48 int48_t; | ||
| 691 | #define INT48_C(c) c | ||
| 692 | /* no suffix */ | ||
| 693 | #define UINT48_C(c) ((uint48_t)(c)) | ||
| 694 | #endif | ||
| 695 | #define INT48_MIN (~INT48_C(0x7FFFFFFFFFFF)) | ||
| 696 | #define INT48_MAX ( INT48_C(0x7FFFFFFFFFFF)) | ||
| 697 | #define UINT48_MAX ( INT48_C(0xFFFFFFFFFFFF)) | ||
| 698 | |||
| 699 | #if SCHAR_MIN == ~0x7FFFFFFFFFFFFFFF && SCHAR_MAX == 0x7FFFFFFFFFFFFFFF && UCHAR_MAX == 0xFFFFFFFFFFFFFFFF | 695 | #if SCHAR_MIN == ~0x7FFFFFFFFFFFFFFF && SCHAR_MAX == 0x7FFFFFFFFFFFFFFF && UCHAR_MAX == 0xFFFFFFFFFFFFFFFF |
| 700 | typedef unsigned char uint64_t; | 696 | typedef unsigned char uint64_t; |
| 701 | typedef signed char int64_t; | 697 | typedef signed char int64_t; |
| ... | @@ -726,6 +722,27 @@ typedef signed long long int64_t; | ... | @@ -726,6 +722,27 @@ typedef signed long long int64_t; |
| 726 | #define INT64_MAX ( INT64_C(0x7FFFFFFFFFFFFFFF)) | 722 | #define INT64_MAX ( INT64_C(0x7FFFFFFFFFFFFFFF)) |
| 727 | #define UINT64_MAX ( INT64_C(0xFFFFFFFFFFFFFFFF)) | 723 | #define UINT64_MAX ( INT64_C(0xFFFFFFFFFFFFFFFF)) |
| 728 | 724 | ||
| 725 | #if defined(zig_ez80) | ||
| 726 | |||
| 727 | typedef unsigned int uint24_t; | ||
| 728 | typedef signed int int24_t; | ||
| 729 | #define INT24_C(c) c | ||
| 730 | #define UINT24_C(c) c##U | ||
| 731 | #define INT24_MIN (~INT24_C(0x7FFF)) | ||
| 732 | #define INT24_MAX ( INT24_C(0x7FFF)) | ||
| 733 | #define UINT24_MAX ( INT24_C(0xFFFF)) | ||
| 734 | |||
| 735 | typedef unsigned __int48 uint48_t; | ||
| 736 | typedef signed __int48 int48_t; | ||
| 737 | #define INT48_C(c) c | ||
| 738 | /* no suffix */ | ||
| 739 | #define UINT48_C(c) ((uint48_t)(c)) | ||
| 740 | #define INT48_MIN (~INT48_C(0x7FFFFFFFFFFF)) | ||
| 741 | #define INT48_MAX ( INT48_C(0x7FFFFFFFFFFF)) | ||
| 742 | #define UINT48_MAX ( INT48_C(0xFFFFFFFFFFFF)) | ||
| 743 | |||
| 744 | #endif | ||
| 745 | |||
| 729 | typedef size_t uintptr_t; | 746 | typedef size_t uintptr_t; |
| 730 | typedef ptrdiff_t intptr_t; | 747 | typedef ptrdiff_t intptr_t; |
| 731 | 748 | ||
| ... | @@ -739,23 +756,145 @@ typedef ptrdiff_t intptr_t; | ... | @@ -739,23 +756,145 @@ typedef ptrdiff_t intptr_t; |
| 739 | #define zig_maxInt_i16 INT16_MAX | 756 | #define zig_maxInt_i16 INT16_MAX |
| 740 | #define zig_minInt_u16 UINT16_C(0) | 757 | #define zig_minInt_u16 UINT16_C(0) |
| 741 | #define zig_maxInt_u16 UINT16_MAX | 758 | #define zig_maxInt_u16 UINT16_MAX |
| 742 | #define zig_minInt_i24 INT24_MIN | ||
| 743 | #define zig_maxInt_i24 INT24_MAX | ||
| 744 | #define zig_minInt_u24 UINT24_C(0) | ||
| 745 | #define zig_maxInt_u24 UINT24_MAX | ||
| 746 | #define zig_minInt_i32 INT32_MIN | 759 | #define zig_minInt_i32 INT32_MIN |
| 747 | #define zig_maxInt_i32 INT32_MAX | 760 | #define zig_maxInt_i32 INT32_MAX |
| 748 | #define zig_minInt_u32 UINT32_C(0) | 761 | #define zig_minInt_u32 UINT32_C(0) |
| 749 | #define zig_maxInt_u32 UINT32_MAX | 762 | #define zig_maxInt_u32 UINT32_MAX |
| 750 | #define zig_minInt_i48 INT48_MIN | ||
| 751 | #define zig_maxInt_i48 INT48_MAX | ||
| 752 | #define zig_minInt_u48 UINT48_C(0) | ||
| 753 | #define zig_maxInt_u48 UINT48_MAX | ||
| 754 | #define zig_minInt_i64 INT64_MIN | 763 | #define zig_minInt_i64 INT64_MIN |
| 755 | #define zig_maxInt_i64 INT64_MAX | 764 | #define zig_maxInt_i64 INT64_MAX |
| 756 | #define zig_minInt_u64 UINT64_C(0) | 765 | #define zig_minInt_u64 UINT64_C(0) |
| 757 | #define zig_maxInt_u64 UINT64_MAX | 766 | #define zig_maxInt_u64 UINT64_MAX |
| 758 | 767 | ||
| 768 | // zig_promoted_T implements C integral promotions except with signedness preserved, which | ||
| 769 | // allows wrapping operations to avoid the ub that would be caused by the normal promotion. | ||
| 770 | |||
| 771 | #if INT8_MAX <= INT_MAX | ||
| 772 | typedef unsigned int zig_promoted_i8; | ||
| 773 | #elif INT8_MAX <= LONG_MAX | ||
| 774 | typedef unsigned long zig_promoted_i8; | ||
| 775 | #elif INT8_MAX <= LLONG_MAX | ||
| 776 | typedef unsigned long long zig_promoted_i8; | ||
| 777 | #else | ||
| 778 | typedef int8_t zig_promoted_i8; | ||
| 779 | #endif | ||
| 780 | #if UINT8_MAX <= UINT_MAX | ||
| 781 | typedef unsigned int zig_promoted_u8; | ||
| 782 | #elif UINT8_MAX <= ULONG_MAX | ||
| 783 | typedef unsigned long zig_promoted_u8; | ||
| 784 | #elif UINT8_MAX <= ULLONG_MAX | ||
| 785 | typedef unsigned long long zig_promoted_u8; | ||
| 786 | #else | ||
| 787 | typedef uint8_t zig_promoted_u8; | ||
| 788 | #endif | ||
| 789 | |||
| 790 | #if INT16_MAX <= INT_MAX | ||
| 791 | typedef unsigned int zig_promoted_i16; | ||
| 792 | #elif INT16_MAX <= LONG_MAX | ||
| 793 | typedef unsigned long zig_promoted_i16; | ||
| 794 | #elif INT16_MAX <= LLONG_MAX | ||
| 795 | typedef unsigned long long zig_promoted_i16; | ||
| 796 | #else | ||
| 797 | typedef int16_t zig_promoted_i16; | ||
| 798 | #endif | ||
| 799 | #if UINT16_MAX <= UINT_MAX | ||
| 800 | typedef unsigned int zig_promoted_u16; | ||
| 801 | #elif UINT16_MAX <= ULONG_MAX | ||
| 802 | typedef unsigned long zig_promoted_u16; | ||
| 803 | #elif UINT16_MAX <= ULLONG_MAX | ||
| 804 | typedef unsigned long long zig_promoted_u16; | ||
| 805 | #else | ||
| 806 | typedef uint16_t zig_promoted_u16; | ||
| 807 | #endif | ||
| 808 | |||
| 809 | #if INT32_MAX <= INT_MAX | ||
| 810 | typedef unsigned int zig_promoted_i32; | ||
| 811 | #elif INT32_MAX <= LONG_MAX | ||
| 812 | typedef unsigned long zig_promoted_i32; | ||
| 813 | #elif INT32_MAX <= LLONG_MAX | ||
| 814 | typedef unsigned long long zig_promoted_i32; | ||
| 815 | #else | ||
| 816 | typedef int32_t zig_promoted_i32; | ||
| 817 | #endif | ||
| 818 | #if UINT32_MAX <= UINT_MAX | ||
| 819 | typedef unsigned int zig_promoted_u32; | ||
| 820 | #elif UINT32_MAX <= ULONG_MAX | ||
| 821 | typedef unsigned long zig_promoted_u32; | ||
| 822 | #elif UINT32_MAX <= ULLONG_MAX | ||
| 823 | typedef unsigned long long zig_promoted_u32; | ||
| 824 | #else | ||
| 825 | typedef uint32_t zig_promoted_u32; | ||
| 826 | #endif | ||
| 827 | |||
| 828 | #if INT64_MAX <= INT_MAX | ||
| 829 | typedef unsigned int zig_promoted_i64; | ||
| 830 | #elif INT64_MAX <= LONG_MAX | ||
| 831 | typedef unsigned long zig_promoted_i64; | ||
| 832 | #elif INT64_MAX <= LLONG_MAX | ||
| 833 | typedef unsigned long long zig_promoted_i64; | ||
| 834 | #else | ||
| 835 | typedef int64_t zig_promoted_i64; | ||
| 836 | #endif | ||
| 837 | #if UINT64_MAX <= UINT_MAX | ||
| 838 | typedef unsigned int zig_promoted_u64; | ||
| 839 | #elif UINT64_MAX <= ULONG_MAX | ||
| 840 | typedef unsigned long zig_promoted_u64; | ||
| 841 | #elif UINT64_MAX <= ULLONG_MAX | ||
| 842 | typedef unsigned long long zig_promoted_u64; | ||
| 843 | #else | ||
| 844 | typedef uint64_t zig_promoted_u64; | ||
| 845 | #endif | ||
| 846 | |||
| 847 | #ifdef zig_ez80 | ||
| 848 | |||
| 849 | #define zig_minInt_i24 INT24_MIN | ||
| 850 | #define zig_maxInt_i24 INT24_MAX | ||
| 851 | #define zig_minInt_u24 UINT24_C(0) | ||
| 852 | #define zig_maxInt_u24 UINT24_MAX | ||
| 853 | #define zig_minInt_i48 INT48_MIN | ||
| 854 | #define zig_maxInt_i48 INT48_MAX | ||
| 855 | #define zig_minInt_u48 UINT48_C(0) | ||
| 856 | #define zig_maxInt_u48 UINT48_MAX | ||
| 857 | |||
| 858 | #if INT24_MAX <= INT_MAX | ||
| 859 | typedef unsigned int zig_promoted_i24; | ||
| 860 | #elif INT24_MAX <= LONG_MAX | ||
| 861 | typedef unsigned long zig_promoted_i24; | ||
| 862 | #elif INT24_MAX <= LLONG_MAX | ||
| 863 | typedef unsigned long long zig_promoted_i24; | ||
| 864 | #else | ||
| 865 | typedef int24_t zig_promoted_i24; | ||
| 866 | #endif | ||
| 867 | #if UINT24_MAX <= UINT_MAX | ||
| 868 | typedef unsigned int zig_promoted_u24; | ||
| 869 | #elif UINT24_MAX <= ULONG_MAX | ||
| 870 | typedef unsigned long zig_promoted_u24; | ||
| 871 | #elif UINT24_MAX <= ULLONG_MAX | ||
| 872 | typedef unsigned long long zig_promoted_u24; | ||
| 873 | #else | ||
| 874 | typedef uint24_t zig_promoted_u24; | ||
| 875 | #endif | ||
| 876 | |||
| 877 | #if INT48_MAX <= INT_MAX | ||
| 878 | typedef unsigned int zig_promoted_i48; | ||
| 879 | #elif INT48_MAX <= LONG_MAX | ||
| 880 | typedef unsigned long zig_promoted_i48; | ||
| 881 | #elif INT48_MAX <= LLONG_MAX | ||
| 882 | typedef unsigned long long zig_promoted_i48; | ||
| 883 | #else | ||
| 884 | typedef int48_t zig_promoted_i48; | ||
| 885 | #endif | ||
| 886 | #if UINT48_MAX <= UINT_MAX | ||
| 887 | typedef unsigned int zig_promoted_u48; | ||
| 888 | #elif UINT48_MAX <= ULONG_MAX | ||
| 889 | typedef unsigned long zig_promoted_u48; | ||
| 890 | #elif UINT48_MAX <= ULLONG_MAX | ||
| 891 | typedef unsigned long long zig_promoted_u48; | ||
| 892 | #else | ||
| 893 | typedef uint48_t zig_promoted_u48; | ||
| 894 | #endif | ||
| 895 | |||
| 896 | #endif | ||
| 897 | |||
| 759 | #define zig_intLimit(s, w, limit, bits) zig_shr_##s##w(zig_##limit##Int_##s##w, w - (bits)) | 898 | #define zig_intLimit(s, w, limit, bits) zig_shr_##s##w(zig_##limit##Int_##s##w, w - (bits)) |
| 760 | #define zig_minInt_i(w, bits) zig_intLimit(i, w, min, bits) | 899 | #define zig_minInt_i(w, bits) zig_intLimit(i, w, min, bits) |
| 761 | #define zig_maxInt_i(w, bits) zig_intLimit(i, w, max, bits) | 900 | #define zig_maxInt_i(w, bits) zig_intLimit(i, w, max, bits) |
| ... | @@ -770,7 +909,33 @@ typedef ptrdiff_t intptr_t; | ... | @@ -770,7 +909,33 @@ typedef ptrdiff_t intptr_t; |
| 770 | zig_operator(Type, Type, operation, operator) | 909 | zig_operator(Type, Type, operation, operator) |
| 771 | #define zig_shift_operator(Type, operation, operator) \ | 910 | #define zig_shift_operator(Type, operation, operator) \ |
| 772 | zig_operator(Type, uint8_t, operation, operator) | 911 | zig_operator(Type, uint8_t, operation, operator) |
| 773 | #define zig_int_helpers(w, PromotedUnsigned) \ | 912 | |
| 913 | #define zig_int_casts_common(bw, sw) \ | ||
| 914 | static inline uint##bw##_t zig_u##bw##_intCast_u##sw(uint##sw##_t arg) { \ | ||
| 915 | return arg; \ | ||
| 916 | } \ | ||
| 917 | \ | ||
| 918 | static inline uint##bw##_t zig_u##bw##_intCast_i##sw(int##sw##_t arg) { \ | ||
| 919 | return (uint##bw##_t)arg; \ | ||
| 920 | } \ | ||
| 921 | \ | ||
| 922 | static inline int##bw##_t zig_i##bw##_intCast_u##sw(uint##sw##_t arg) { \ | ||
| 923 | return arg; \ | ||
| 924 | } \ | ||
| 925 | \ | ||
| 926 | static inline int##bw##_t zig_i##bw##_intCast_i##sw(int##sw##_t arg) { \ | ||
| 927 | return arg; \ | ||
| 928 | } \ | ||
| 929 | \ | ||
| 930 | static inline uint##sw##_t zig_u##sw##_truncate_u##bw(uint##bw##_t arg, uint8_t bits) { \ | ||
| 931 | return (uint##sw##_t)arg & zig_maxInt_u(sw, bits); \ | ||
| 932 | } \ | ||
| 933 | \ | ||
| 934 | static inline int##sw##_t zig_i##sw##_truncate_i##bw(int##bw##_t arg, uint8_t bits) { \ | ||
| 935 | return ((uint##sw##_t)arg & UINT##sw##_C(1) << (bits - UINT8_C(1))) != UINT##sw##_C(0) \ | ||
| 936 | ? (int##sw##_t)arg | zig_minInt_i(sw, bits) : (int##sw##_t)arg & zig_maxInt_i(sw, bits); \ | ||
| 937 | } | ||
| 938 | #define zig_int_operators(w) \ | ||
| 774 | zig_basic_operator(uint##w##_t, and_u##w, &) \ | 939 | zig_basic_operator(uint##w##_t, and_u##w, &) \ |
| 775 | zig_basic_operator( int##w##_t, and_i##w, &) \ | 940 | zig_basic_operator( int##w##_t, and_i##w, &) \ |
| 776 | zig_basic_operator(uint##w##_t, or_u##w, |) \ | 941 | zig_basic_operator(uint##w##_t, or_u##w, |) \ |
| ... | @@ -786,44 +951,48 @@ typedef ptrdiff_t intptr_t; | ... | @@ -786,44 +951,48 @@ typedef ptrdiff_t intptr_t; |
| 786 | return ((lhs ^ sign_mask) >> rhs) ^ sign_mask; \ | 951 | return ((lhs ^ sign_mask) >> rhs) ^ sign_mask; \ |
| 787 | } \ | 952 | } \ |
| 788 | \ | 953 | \ |
| 789 | static inline uint##w##_t zig_not_u##w(uint##w##_t val, uint8_t bits) { \ | 954 | static inline uint##w##_t zig_not_u##w(uint##w##_t arg, uint8_t bits) { \ |
| 790 | return val ^ zig_maxInt_u(w, bits); \ | 955 | return arg ^ zig_maxInt_u(w, bits); \ |
| 791 | } \ | 956 | } \ |
| 792 | \ | 957 | \ |
| 793 | static inline int##w##_t zig_not_i##w(int##w##_t val, uint8_t bits) { \ | 958 | static inline int##w##_t zig_not_i##w(int##w##_t arg, uint8_t bits) { \ |
| 794 | (void)bits; \ | 959 | (void)bits; \ |
| 795 | return ~val; \ | 960 | return ~arg; \ |
| 796 | } \ | 961 | } \ |
| 797 | \ | 962 | \ |
| 798 | static inline uint##w##_t zig_wrap_u##w(uint##w##_t val, uint8_t bits) { \ | 963 | zig_basic_operator(uint##w##_t, divFloor_u##w, /) \ |
| 799 | return val & zig_maxInt_u(w, bits); \ | 964 | \ |
| 965 | static inline int##w##_t zig_divFloor_i##w(int##w##_t lhs, int##w##_t rhs) { \ | ||
| 966 | return lhs / rhs + (lhs % rhs != INT##w##_C(0) ? zig_shr_i##w(lhs ^ rhs, UINT8_C(w) - UINT8_C(1)) : INT##w##_C(0)); \ | ||
| 800 | } \ | 967 | } \ |
| 801 | \ | 968 | \ |
| 802 | static inline int##w##_t zig_wrap_i##w(int##w##_t val, uint8_t bits) { \ | 969 | static inline uint##w##_t zig_divCeil_u##w(uint##w##_t lhs, uint##w##_t rhs) { \ |
| 803 | return (val & UINT##w##_C(1) << (bits - UINT8_C(1))) != 0 \ | 970 | return lhs / rhs + (lhs % rhs != UINT##w##_C(0) ? UINT##w##_C(1) : UINT##w##_C(0)); \ |
| 804 | ? val | zig_minInt_i(w, bits) : val & zig_maxInt_i(w, bits); \ | ||
| 805 | } \ | 971 | } \ |
| 806 | \ | 972 | \ |
| 807 | static inline uint##w##_t zig_abs_i##w(int##w##_t val) { \ | 973 | static inline int##w##_t zig_divCeil_i##w(int##w##_t lhs, int##w##_t rhs) { \ |
| 808 | return (val < 0) ? -(uint##w##_t)val : (uint##w##_t)val; \ | 974 | return lhs / rhs + (lhs % rhs != INT##w##_C(0) \ |
| 975 | ? zig_shr_i##w(lhs ^ rhs, UINT8_C(w) - UINT8_C(1)) + INT##w##_C(1) : INT##w##_C(0)); \ | ||
| 809 | } \ | 976 | } \ |
| 810 | \ | 977 | \ |
| 811 | zig_basic_operator(uint##w##_t, div_floor_u##w, /) \ | 978 | zig_basic_operator(uint##w##_t, mod_u##w, %) \ |
| 979 | zig_int_casts_common(w, w) \ | ||
| 812 | \ | 980 | \ |
| 813 | static inline int##w##_t zig_div_floor_i##w(int##w##_t lhs, int##w##_t rhs) { \ | 981 | static inline uint##w##_t zig_u##w##_bitCast_u##w(uint##w##_t arg, uint8_t bits) { \ |
| 814 | return lhs / rhs + (lhs % rhs != INT##w##_C(0) ? zig_shr_i##w(lhs ^ rhs, UINT8_C(w) - UINT8_C(1)) : INT##w##_C(0)); \ | 982 | return zig_u##w##_truncate_u##w(arg, bits); \ |
| 815 | } \ | 983 | } \ |
| 816 | \ | 984 | \ |
| 817 | static inline uint##w##_t zig_div_ceil_u##w(uint##w##_t lhs, uint##w##_t rhs) { \ | 985 | static inline uint##w##_t zig_u##w##_bitCast_i##w(int##w##_t arg, uint8_t bits) { \ |
| 818 | return lhs / rhs + (lhs % rhs != UINT##w##_C(0) ? UINT##w##_C(1) : UINT##w##_C(0)); \ | 986 | return zig_u##w##_bitCast_u##w((uint##w##_t)arg, bits); \ |
| 819 | } \ | 987 | } \ |
| 820 | \ | 988 | \ |
| 821 | static inline int##w##_t zig_div_ceil_i##w(int##w##_t lhs, int##w##_t rhs) { \ | 989 | static inline int##w##_t zig_i##w##_bitCast_i##w(int##w##_t arg, uint8_t bits) { \ |
| 822 | return lhs / rhs + (lhs % rhs != INT##w##_C(0) \ | 990 | return zig_i##w##_truncate_i##w(arg, bits); \ |
| 823 | ? zig_shr_i##w(lhs ^ rhs, UINT8_C(w) - UINT8_C(1)) + INT##w##_C(1) : INT##w##_C(0)); \ | ||
| 824 | } \ | 991 | } \ |
| 825 | \ | 992 | \ |
| 826 | zig_basic_operator(uint##w##_t, mod_u##w, %) \ | 993 | static inline int##w##_t zig_i##w##_bitCast_u##w(uint##w##_t arg, uint8_t bits) { \ |
| 994 | return zig_i##w##_bitCast_i##w((int##w##_t)arg, bits); \ | ||
| 995 | } \ | ||
| 827 | \ | 996 | \ |
| 828 | static inline int##w##_t zig_mod_i##w(int##w##_t lhs, int##w##_t rhs) { \ | 997 | static inline int##w##_t zig_mod_i##w(int##w##_t lhs, int##w##_t rhs) { \ |
| 829 | int##w##_t rem = lhs % rhs; \ | 998 | int##w##_t rem = lhs % rhs; \ |
| ... | @@ -831,100 +1000,102 @@ typedef ptrdiff_t intptr_t; | ... | @@ -831,100 +1000,102 @@ typedef ptrdiff_t intptr_t; |
| 831 | } \ | 1000 | } \ |
| 832 | \ | 1001 | \ |
| 833 | static inline uint##w##_t zig_shlw_u##w(uint##w##_t lhs, uint8_t rhs, uint8_t bits) { \ | 1002 | static inline uint##w##_t zig_shlw_u##w(uint##w##_t lhs, uint8_t rhs, uint8_t bits) { \ |
| 834 | return zig_wrap_u##w(zig_shl_u##w(lhs, rhs), bits); \ | 1003 | return zig_u##w##_truncate_u##w(zig_shl_u##w(lhs, rhs), bits); \ |
| 835 | } \ | 1004 | } \ |
| 836 | \ | 1005 | \ |
| 837 | static inline int##w##_t zig_shlw_i##w(int##w##_t lhs, uint8_t rhs, uint8_t bits) { \ | 1006 | static inline int##w##_t zig_shlw_i##w(int##w##_t lhs, uint8_t rhs, uint8_t bits) { \ |
| 838 | return zig_wrap_i##w((int##w##_t)zig_shl_u##w((uint##w##_t)lhs, rhs), bits); \ | 1007 | return zig_i##w##_bitCast_u##w(zig_shl_u##w(zig_u##w##_bitCast_i##w(lhs, bits), rhs), bits); \ |
| 839 | } \ | 1008 | } \ |
| 840 | \ | 1009 | \ |
| 841 | static inline uint##w##_t zig_addw_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \ | 1010 | static inline uint##w##_t zig_addw_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \ |
| 842 | return zig_wrap_u##w(lhs + rhs, bits); \ | 1011 | return zig_u##w##_truncate_u##w((zig_promoted_u##w)lhs + rhs, bits); \ |
| 843 | } \ | 1012 | } \ |
| 844 | \ | 1013 | \ |
| 845 | static inline int##w##_t zig_addw_i##w(int##w##_t lhs, int##w##_t rhs, uint8_t bits) { \ | 1014 | static inline int##w##_t zig_addw_i##w(int##w##_t lhs, int##w##_t rhs, uint8_t bits) { \ |
| 846 | return zig_wrap_i##w((int##w##_t)((uint##w##_t)lhs + (uint##w##_t)rhs), bits); \ | 1015 | return zig_i##w##_bitCast_u##w(zig_addw_u##w(zig_u##w##_bitCast_i##w(lhs, bits), zig_u##w##_bitCast_i##w(rhs, bits), bits), bits); \ |
| 847 | } \ | 1016 | } \ |
| 848 | \ | 1017 | \ |
| 849 | static inline uint##w##_t zig_subw_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \ | 1018 | static inline uint##w##_t zig_subw_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \ |
| 850 | return zig_wrap_u##w(lhs - rhs, bits); \ | 1019 | return zig_u##w##_truncate_u##w((zig_promoted_u##w)lhs - rhs, bits); \ |
| 851 | } \ | 1020 | } \ |
| 852 | \ | 1021 | \ |
| 853 | static inline int##w##_t zig_subw_i##w(int##w##_t lhs, int##w##_t rhs, uint8_t bits) { \ | 1022 | static inline int##w##_t zig_subw_i##w(int##w##_t lhs, int##w##_t rhs, uint8_t bits) { \ |
| 854 | return zig_wrap_i##w((int##w##_t)((uint##w##_t)lhs - (uint##w##_t)rhs), bits); \ | 1023 | return zig_i##w##_bitCast_u##w(zig_subw_u##w(zig_u##w##_bitCast_i##w(lhs, bits), zig_u##w##_bitCast_i##w(rhs, bits), bits), bits); \ |
| 855 | } \ | 1024 | } \ |
| 856 | \ | 1025 | \ |
| 857 | static inline uint##w##_t zig_mulw_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \ | 1026 | static inline uint##w##_t zig_mulw_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \ |
| 858 | return zig_wrap_u##w((PromotedUnsigned)lhs * rhs, bits); \ | 1027 | return zig_u##w##_truncate_u##w((zig_promoted_u##w)lhs * rhs, bits); \ |
| 859 | } \ | 1028 | } \ |
| 860 | \ | 1029 | \ |
| 861 | static inline int##w##_t zig_mulw_i##w(int##w##_t lhs, int##w##_t rhs, uint8_t bits) { \ | 1030 | static inline int##w##_t zig_mulw_i##w(int##w##_t lhs, int##w##_t rhs, uint8_t bits) { \ |
| 862 | return zig_wrap_i##w((int##w##_t)((uint##w##_t)lhs * (uint##w##_t)rhs), bits); \ | 1031 | return zig_i##w##_bitCast_u##w(zig_mulw_u##w(zig_u##w##_bitCast_i##w(lhs, bits), zig_u##w##_bitCast_i##w(rhs, bits), bits), bits); \ |
| 1032 | } \ | ||
| 1033 | \ | ||
| 1034 | static inline uint##w##_t zig_abs_i##w(int##w##_t arg) { \ | ||
| 1035 | int##w##_t tmp = zig_shr_i##w(arg, UINT8_C(w) - UINT8_C(1)); \ | ||
| 1036 | return zig_u##w##_bitCast_i##w(zig_subw_i##w(zig_xor_i##w(arg, tmp), tmp, UINT8_C(w)), UINT8_C(w)); \ | ||
| 1037 | } \ | ||
| 1038 | \ | ||
| 1039 | static inline uint##w##_t zig_min_u##w(uint##w##_t lhs, uint##w##_t rhs) { \ | ||
| 1040 | return lhs < rhs ? lhs : rhs; \ | ||
| 1041 | } \ | ||
| 1042 | \ | ||
| 1043 | static inline int##w##_t zig_min_i##w(int##w##_t lhs, int##w##_t rhs) { \ | ||
| 1044 | return lhs < rhs ? lhs : rhs; \ | ||
| 1045 | } \ | ||
| 1046 | \ | ||
| 1047 | static inline uint##w##_t zig_max_u##w(uint##w##_t lhs, uint##w##_t rhs) { \ | ||
| 1048 | return lhs >= rhs ? lhs : rhs; \ | ||
| 1049 | } \ | ||
| 1050 | \ | ||
| 1051 | static inline int##w##_t zig_max_i##w(int##w##_t lhs, int##w##_t rhs) { \ | ||
| 1052 | return lhs >= rhs ? lhs : rhs; \ | ||
| 863 | } | 1053 | } |
| 864 | #if UINT8_MAX <= UINT_MAX | 1054 | zig_int_operators(8) |
| 865 | zig_int_helpers(8, unsigned int) | 1055 | zig_int_operators(16) |
| 866 | #elif UINT8_MAX <= ULONG_MAX | 1056 | zig_int_operators(32) |
| 867 | zig_int_helpers(8, unsigned long) | 1057 | zig_int_operators(64) |
| 868 | #elif UINT8_MAX <= ULLONG_MAX | 1058 | #ifdef zig_ez80 |
| 869 | zig_int_helpers(8, unsigned long long) | 1059 | zig_int_operators(24) |
| 870 | #else | 1060 | zig_int_operators(48) |
| 871 | zig_int_helpers(8, uint8_t) | 1061 | #endif |
| 872 | #endif | 1062 | |
| 873 | #if UINT16_MAX <= UINT_MAX | 1063 | #define zig_int_casts(bw, sw) \ |
| 874 | zig_int_helpers(16, unsigned int) | 1064 | static inline uint##sw##_t zig_u##sw##_intCast_u##bw(uint##bw##_t arg) { \ |
| 875 | #elif UINT16_MAX <= ULONG_MAX | 1065 | return (uint##sw##_t)arg; \ |
| 876 | zig_int_helpers(16, unsigned long) | 1066 | } \ |
| 877 | #elif UINT16_MAX <= ULLONG_MAX | 1067 | \ |
| 878 | zig_int_helpers(16, unsigned long long) | 1068 | static inline uint##sw##_t zig_u##sw##_intCast_i##bw(int##bw##_t arg) { \ |
| 879 | #else | 1069 | return (uint##sw##_t)arg; \ |
| 880 | zig_int_helpers(16, uint16_t) | 1070 | } \ |
| 881 | #endif | 1071 | \ |
| 882 | #if defined(zig_ez80) | 1072 | static inline int##sw##_t zig_i##sw##_intCast_u##bw(uint##bw##_t arg) { \ |
| 883 | #if UINT24_MAX <= UINT_MAX | 1073 | return (int##sw##_t)arg; \ |
| 884 | zig_int_helpers(24, unsigned int) | 1074 | } \ |
| 885 | #elif UINT24_MAX <= ULONG_MAX | 1075 | \ |
| 886 | zig_int_helpers(24, unsigned long) | 1076 | static inline int##sw##_t zig_i##sw##_intCast_i##bw(int##bw##_t arg) { \ |
| 887 | #elif UINT24_MAX <= ULLONG_MAX | 1077 | return (int##sw##_t)arg; \ |
| 888 | zig_int_helpers(24, unsigned long long) | 1078 | } \ |
| 889 | #else | 1079 | \ |
| 890 | zig_int_helpers(24, uint24_t) | 1080 | zig_int_casts_common(bw, sw) |
| 891 | #endif | 1081 | zig_int_casts(16, 8) |
| 892 | #endif | 1082 | zig_int_casts(32, 8) |
| 893 | #if UINT32_MAX <= UINT_MAX | 1083 | zig_int_casts(64, 8) |
| 894 | zig_int_helpers(32, unsigned int) | 1084 | zig_int_casts(32, 16) |
| 895 | #elif UINT32_MAX <= ULONG_MAX | 1085 | zig_int_casts(64, 16) |
| 896 | zig_int_helpers(32, unsigned long) | 1086 | zig_int_casts(64, 32) |
| 897 | #elif UINT32_MAX <= ULLONG_MAX | 1087 | #ifdef zig_ez80 |
| 898 | zig_int_helpers(32, unsigned long long) | 1088 | zig_int_casts(32, 24) |
| 899 | #else | 1089 | zig_int_casts(48, 24) |
| 900 | zig_int_helpers(32, uint32_t) | 1090 | zig_int_casts(64, 24) |
| 901 | #endif | 1091 | zig_int_casts(64, 48) |
| 902 | #if defined(zig_ez80) | ||
| 903 | #if UINT24_MAX <= UINT_MAX | ||
| 904 | zig_int_helpers(48, unsigned int) | ||
| 905 | #elif UINT24_MAX <= ULONG_MAX | ||
| 906 | zig_int_helpers(48, unsigned long) | ||
| 907 | #elif UINT24_MAX <= ULLONG_MAX | ||
| 908 | zig_int_helpers(48, unsigned long long) | ||
| 909 | #else | ||
| 910 | zig_int_helpers(48, uint48_t) | ||
| 911 | #endif | ||
| 912 | #endif | ||
| 913 | #if UINT64_MAX <= UINT_MAX | ||
| 914 | zig_int_helpers(64, unsigned int) | ||
| 915 | #elif UINT64_MAX <= ULONG_MAX | ||
| 916 | zig_int_helpers(64, unsigned long) | ||
| 917 | #elif UINT64_MAX <= ULLONG_MAX | ||
| 918 | zig_int_helpers(64, unsigned long long) | ||
| 919 | #else | ||
| 920 | zig_int_helpers(64, uint64_t) | ||
| 921 | #endif | 1092 | #endif |
| 922 | 1093 | ||
| 923 | static inline bool zig_addo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) { | 1094 | static inline bool zig_addo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) { |
| 924 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) | 1095 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) |
| 925 | uint32_t full_res; | 1096 | uint32_t full_res; |
| 926 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); | 1097 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); |
| 927 | *res = zig_wrap_u32(full_res, bits); | 1098 | *res = zig_u32_truncate_u32(full_res, bits); |
| 928 | return overflow || full_res < zig_minInt_u(32, bits) || full_res > zig_maxInt_u(32, bits); | 1099 | return overflow || full_res < zig_minInt_u(32, bits) || full_res > zig_maxInt_u(32, bits); |
| 929 | #else | 1100 | #else |
| 930 | *res = zig_addw_u32(lhs, rhs, bits); | 1101 | *res = zig_addw_u32(lhs, rhs, bits); |
| ... | @@ -936,19 +1107,19 @@ static inline bool zig_addo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t | ... | @@ -936,19 +1107,19 @@ static inline bool zig_addo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t |
| 936 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) | 1107 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) |
| 937 | int32_t full_res; | 1108 | int32_t full_res; |
| 938 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); | 1109 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); |
| 1110 | *res = zig_i32_truncate_i32(full_res, bits); | ||
| 1111 | return overflow || full_res < zig_minInt_i(32, bits) || full_res > zig_maxInt_i(32, bits); | ||
| 939 | #else | 1112 | #else |
| 940 | int32_t full_res = (int32_t)((uint32_t)lhs + (uint32_t)rhs); | 1113 | *res = zig_addw_i32(lhs, rhs, bits); |
| 941 | bool overflow = ((full_res ^ lhs) & (full_res ^ rhs)) < 0; | 1114 | return ((*res ^ lhs) & (*res ^ rhs)) < INT32_C(0); |
| 942 | #endif | 1115 | #endif |
| 943 | *res = zig_wrap_i32(full_res, bits); | ||
| 944 | return overflow || full_res < zig_minInt_i(32, bits) || full_res > zig_maxInt_i(32, bits); | ||
| 945 | } | 1116 | } |
| 946 | 1117 | ||
| 947 | static inline bool zig_addo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8_t bits) { | 1118 | static inline bool zig_addo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8_t bits) { |
| 948 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) | 1119 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) |
| 949 | uint64_t full_res; | 1120 | uint64_t full_res; |
| 950 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); | 1121 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); |
| 951 | *res = zig_wrap_u64(full_res, bits); | 1122 | *res = zig_u64_truncate_u64(full_res, bits); |
| 952 | return overflow || full_res < zig_minInt_u(64, bits) || full_res > zig_maxInt_u(64, bits); | 1123 | return overflow || full_res < zig_minInt_u(64, bits) || full_res > zig_maxInt_u(64, bits); |
| 953 | #else | 1124 | #else |
| 954 | *res = zig_addw_u64(lhs, rhs, bits); | 1125 | *res = zig_addw_u64(lhs, rhs, bits); |
| ... | @@ -960,24 +1131,24 @@ static inline bool zig_addo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t | ... | @@ -960,24 +1131,24 @@ static inline bool zig_addo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t |
| 960 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) | 1131 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) |
| 961 | int64_t full_res; | 1132 | int64_t full_res; |
| 962 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); | 1133 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); |
| 1134 | *res = zig_i64_truncate_i64(full_res, bits); | ||
| 1135 | return overflow || full_res < zig_minInt_i(64, bits) || full_res > zig_maxInt_i(64, bits); | ||
| 963 | #else | 1136 | #else |
| 964 | int64_t full_res = (int64_t)((uint64_t)lhs + (uint64_t)rhs); | 1137 | *res = zig_addw_i64(lhs, rhs, bits); |
| 965 | bool overflow = ((full_res ^ lhs) & (full_res ^ rhs)) < 0; | 1138 | return ((*res ^ lhs) & (*res ^ rhs)) < INT64_C(0); |
| 966 | #endif | 1139 | #endif |
| 967 | *res = zig_wrap_i64(full_res, bits); | ||
| 968 | return overflow || full_res < zig_minInt_i(64, bits) || full_res > zig_maxInt_i(64, bits); | ||
| 969 | } | 1140 | } |
| 970 | 1141 | ||
| 971 | static inline bool zig_addo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t bits) { | 1142 | static inline bool zig_addo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t bits) { |
| 972 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) | 1143 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) |
| 973 | uint8_t full_res; | 1144 | uint8_t full_res; |
| 974 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); | 1145 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); |
| 975 | *res = zig_wrap_u8(full_res, bits); | 1146 | *res = zig_u8_truncate_u8(full_res, bits); |
| 976 | return overflow || full_res < zig_minInt_u(8, bits) || full_res > zig_maxInt_u(8, bits); | 1147 | return overflow || full_res < zig_minInt_u(8, bits) || full_res > zig_maxInt_u(8, bits); |
| 977 | #else | 1148 | #else |
| 978 | uint32_t full_res; | 1149 | uint32_t full_res; |
| 979 | bool overflow = zig_addo_u32(&full_res, lhs, rhs, bits); | 1150 | bool overflow = zig_addo_u32(&full_res, lhs, rhs, bits); |
| 980 | *res = (uint8_t)full_res; | 1151 | *res = zig_u8_intCast_u32(full_res); |
| 981 | return overflow; | 1152 | return overflow; |
| 982 | #endif | 1153 | #endif |
| 983 | } | 1154 | } |
| ... | @@ -986,12 +1157,12 @@ static inline bool zig_addo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits | ... | @@ -986,12 +1157,12 @@ static inline bool zig_addo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits |
| 986 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) | 1157 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) |
| 987 | int8_t full_res; | 1158 | int8_t full_res; |
| 988 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); | 1159 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); |
| 989 | *res = zig_wrap_i8(full_res, bits); | 1160 | *res = zig_i8_truncate_i8(full_res, bits); |
| 990 | return overflow || full_res < zig_minInt_i(8, bits) || full_res > zig_maxInt_i(8, bits); | 1161 | return overflow || full_res < zig_minInt_i(8, bits) || full_res > zig_maxInt_i(8, bits); |
| 991 | #else | 1162 | #else |
| 992 | int32_t full_res; | 1163 | int32_t full_res; |
| 993 | bool overflow = zig_addo_i32(&full_res, lhs, rhs, bits); | 1164 | bool overflow = zig_addo_i32(&full_res, lhs, rhs, bits); |
| 994 | *res = (int8_t)full_res; | 1165 | *res = zig_i8_intCast_i32(full_res); |
| 995 | return overflow; | 1166 | return overflow; |
| 996 | #endif | 1167 | #endif |
| 997 | } | 1168 | } |
| ... | @@ -1000,12 +1171,12 @@ static inline bool zig_addo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8 | ... | @@ -1000,12 +1171,12 @@ static inline bool zig_addo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8 |
| 1000 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) | 1171 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) |
| 1001 | uint16_t full_res; | 1172 | uint16_t full_res; |
| 1002 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); | 1173 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); |
| 1003 | *res = zig_wrap_u16(full_res, bits); | 1174 | *res = zig_u16_truncate_u16(full_res, bits); |
| 1004 | return overflow || full_res < zig_minInt_u(16, bits) || full_res > zig_maxInt_u(16, bits); | 1175 | return overflow || full_res < zig_minInt_u(16, bits) || full_res > zig_maxInt_u(16, bits); |
| 1005 | #else | 1176 | #else |
| 1006 | uint32_t full_res; | 1177 | uint32_t full_res; |
| 1007 | bool overflow = zig_addo_u32(&full_res, lhs, rhs, bits); | 1178 | bool overflow = zig_addo_u32(&full_res, lhs, rhs, bits); |
| 1008 | *res = (uint16_t)full_res; | 1179 | *res = zig_u16_intCast_u32(full_res); |
| 1009 | return overflow; | 1180 | return overflow; |
| 1010 | #endif | 1181 | #endif |
| 1011 | } | 1182 | } |
| ... | @@ -1014,27 +1185,28 @@ static inline bool zig_addo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t | ... | @@ -1014,27 +1185,28 @@ static inline bool zig_addo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t |
| 1014 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) | 1185 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) |
| 1015 | int16_t full_res; | 1186 | int16_t full_res; |
| 1016 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); | 1187 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); |
| 1017 | *res = zig_wrap_i16(full_res, bits); | 1188 | *res = zig_i16_truncate_i16(full_res, bits); |
| 1018 | return overflow || full_res < zig_minInt_i(16, bits) || full_res > zig_maxInt_i(16, bits); | 1189 | return overflow || full_res < zig_minInt_i(16, bits) || full_res > zig_maxInt_i(16, bits); |
| 1019 | #else | 1190 | #else |
| 1020 | int32_t full_res; | 1191 | int32_t full_res; |
| 1021 | bool overflow = zig_addo_i32(&full_res, lhs, rhs, bits); | 1192 | bool overflow = zig_addo_i32(&full_res, lhs, rhs, bits); |
| 1022 | *res = (int16_t)full_res; | 1193 | *res = zig_i16_intCast_i32(full_res); |
| 1023 | return overflow; | 1194 | return overflow; |
| 1024 | #endif | 1195 | #endif |
| 1025 | } | 1196 | } |
| 1026 | 1197 | ||
| 1027 | #if defined(zig_ez80) | 1198 | #if defined(zig_ez80) |
| 1199 | |||
| 1028 | static inline bool zig_addo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) { | 1200 | static inline bool zig_addo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) { |
| 1029 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) | 1201 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) |
| 1030 | uint24_t full_res; | 1202 | uint24_t full_res; |
| 1031 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); | 1203 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); |
| 1032 | *res = zig_wrap_u24(full_res, bits); | 1204 | *res = zig_u24_truncate_u24(full_res, bits); |
| 1033 | return overflow || full_res < zig_minInt_u(24, bits) || full_res > zig_maxInt_u(24, bits); | 1205 | return overflow || full_res < zig_minInt_u(24, bits) || full_res > zig_maxInt_u(24, bits); |
| 1034 | #else | 1206 | #else |
| 1035 | uint32_t full_res; | 1207 | uint32_t full_res; |
| 1036 | bool overflow = zig_addo_u32(&full_res, lhs, rhs, bits); | 1208 | bool overflow = zig_addo_u32(&full_res, lhs, rhs, bits); |
| 1037 | *res = (uint24_t)full_res; | 1209 | *res = zig_u24_intCast_u32(full_res); |
| 1038 | return overflow; | 1210 | return overflow; |
| 1039 | #endif | 1211 | #endif |
| 1040 | } | 1212 | } |
| ... | @@ -1043,28 +1215,26 @@ static inline bool zig_addo_i24(int24_t *res, int24_t lhs, int24_t rhs, uint8_t | ... | @@ -1043,28 +1215,26 @@ static inline bool zig_addo_i24(int24_t *res, int24_t lhs, int24_t rhs, uint8_t |
| 1043 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) | 1215 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) |
| 1044 | int24_t full_res; | 1216 | int24_t full_res; |
| 1045 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); | 1217 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); |
| 1046 | *res = zig_wrap_i24(full_res, bits); | 1218 | *res = zig_i24_truncate_i24(full_res, bits); |
| 1047 | return overflow || full_res < zig_minInt_i(24, bits) || full_res > zig_maxInt_i(24, bits); | 1219 | return overflow || full_res < zig_minInt_i(24, bits) || full_res > zig_maxInt_i(24, bits); |
| 1048 | #else | 1220 | #else |
| 1049 | int32_t full_res; | 1221 | int32_t full_res; |
| 1050 | bool overflow = zig_addo_i32(&full_res, lhs, rhs, bits); | 1222 | bool overflow = zig_addo_i32(&full_res, lhs, rhs, bits); |
| 1051 | *res = (int24_t)full_res; | 1223 | *res = zig_i24_intCast_i32(full_res); |
| 1052 | return overflow; | 1224 | return overflow; |
| 1053 | #endif | 1225 | #endif |
| 1054 | } | 1226 | } |
| 1055 | #endif | ||
| 1056 | 1227 | ||
| 1057 | #if defined(zig_ez80) | ||
| 1058 | static inline bool zig_addo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) { | 1228 | static inline bool zig_addo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) { |
| 1059 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) | 1229 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) |
| 1060 | uint48_t full_res; | 1230 | uint48_t full_res; |
| 1061 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); | 1231 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); |
| 1062 | *res = zig_wrap_u48(full_res, bits); | 1232 | *res = zig_u48_truncate_u48(full_res, bits); |
| 1063 | return overflow || full_res < zig_minInt_u(48, bits) || full_res > zig_maxInt_u(48, bits); | 1233 | return overflow || full_res < zig_minInt_u(48, bits) || full_res > zig_maxInt_u(48, bits); |
| 1064 | #else | 1234 | #else |
| 1065 | uint64_t full_res; | 1235 | uint64_t full_res; |
| 1066 | bool overflow = zig_addo_u64(&full_res, lhs, rhs, bits); | 1236 | bool overflow = zig_addo_u64(&full_res, lhs, rhs, bits); |
| 1067 | *res = (uint48_t)full_res; | 1237 | *res = zig_u48_intCast_u64(full_res); |
| 1068 | return overflow; | 1238 | return overflow; |
| 1069 | #endif | 1239 | #endif |
| 1070 | } | 1240 | } |
| ... | @@ -1073,22 +1243,23 @@ static inline bool zig_addo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t | ... | @@ -1073,22 +1243,23 @@ static inline bool zig_addo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t |
| 1073 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) | 1243 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) |
| 1074 | int48_t full_res; | 1244 | int48_t full_res; |
| 1075 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); | 1245 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); |
| 1076 | *res = zig_wrap_i48(full_res, bits); | 1246 | *res = zig_i48_truncate_i48(full_res, bits); |
| 1077 | return overflow || full_res < zig_minInt_i(48, bits) || full_res > zig_maxInt_i(48, bits); | 1247 | return overflow || full_res < zig_minInt_i(48, bits) || full_res > zig_maxInt_i(48, bits); |
| 1078 | #else | 1248 | #else |
| 1079 | int64_t full_res; | 1249 | int64_t full_res; |
| 1080 | bool overflow = zig_addo_i64(&full_res, lhs, rhs, bits); | 1250 | bool overflow = zig_addo_i64(&full_res, lhs, rhs, bits); |
| 1081 | *res = (int48_t)full_res; | 1251 | *res = zig_i48_intCast_i64(full_res); |
| 1082 | return overflow; | 1252 | return overflow; |
| 1083 | #endif | 1253 | #endif |
| 1084 | } | 1254 | } |
| 1255 | |||
| 1085 | #endif | 1256 | #endif |
| 1086 | 1257 | ||
| 1087 | static inline bool zig_subo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) { | 1258 | static inline bool zig_subo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) { |
| 1088 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) | 1259 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) |
| 1089 | uint32_t full_res; | 1260 | uint32_t full_res; |
| 1090 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); | 1261 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); |
| 1091 | *res = zig_wrap_u32(full_res, bits); | 1262 | *res = zig_u32_truncate_u32(full_res, bits); |
| 1092 | return overflow || full_res < zig_minInt_u(32, bits) || full_res > zig_maxInt_u(32, bits); | 1263 | return overflow || full_res < zig_minInt_u(32, bits) || full_res > zig_maxInt_u(32, bits); |
| 1093 | #else | 1264 | #else |
| 1094 | *res = zig_subw_u32(lhs, rhs, bits); | 1265 | *res = zig_subw_u32(lhs, rhs, bits); |
| ... | @@ -1100,20 +1271,19 @@ static inline bool zig_subo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t | ... | @@ -1100,20 +1271,19 @@ static inline bool zig_subo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t |
| 1100 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) | 1271 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) |
| 1101 | int32_t full_res; | 1272 | int32_t full_res; |
| 1102 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); | 1273 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); |
| 1274 | *res = zig_i32_truncate_i32(full_res, bits); | ||
| 1275 | return overflow || full_res < zig_minInt_i(32, bits) || full_res > zig_maxInt_i(32, bits); | ||
| 1103 | #else | 1276 | #else |
| 1104 | int32_t full_res = (int32_t)((uint32_t)lhs - (uint32_t)rhs); | 1277 | *res = zig_subw_i32(lhs, rhs, bits); |
| 1105 | bool overflow = ((lhs ^ rhs) & (full_res ^ lhs)) < 0; | 1278 | return ((lhs ^ rhs) & (*res ^ lhs)) < INT32_C(0); |
| 1106 | #endif | 1279 | #endif |
| 1107 | *res = zig_wrap_i32(full_res, bits); | ||
| 1108 | return overflow || full_res < zig_minInt_i(32, bits) || full_res > zig_maxInt_i(32, bits); | ||
| 1109 | } | 1280 | } |
| 1110 | 1281 | ||
| 1111 | |||
| 1112 | static inline bool zig_subo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8_t bits) { | 1282 | static inline bool zig_subo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8_t bits) { |
| 1113 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) | 1283 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) |
| 1114 | uint64_t full_res; | 1284 | uint64_t full_res; |
| 1115 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); | 1285 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); |
| 1116 | *res = zig_wrap_u64(full_res, bits); | 1286 | *res = zig_u64_truncate_u64(full_res, bits); |
| 1117 | return overflow || full_res < zig_minInt_u(64, bits) || full_res > zig_maxInt_u(64, bits); | 1287 | return overflow || full_res < zig_minInt_u(64, bits) || full_res > zig_maxInt_u(64, bits); |
| 1118 | #else | 1288 | #else |
| 1119 | *res = zig_subw_u64(lhs, rhs, bits); | 1289 | *res = zig_subw_u64(lhs, rhs, bits); |
| ... | @@ -1125,24 +1295,24 @@ static inline bool zig_subo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t | ... | @@ -1125,24 +1295,24 @@ static inline bool zig_subo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t |
| 1125 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) | 1295 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) |
| 1126 | int64_t full_res; | 1296 | int64_t full_res; |
| 1127 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); | 1297 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); |
| 1298 | *res = zig_i64_truncate_i64(full_res, bits); | ||
| 1299 | return overflow || full_res < zig_minInt_i(64, bits) || full_res > zig_maxInt_i(64, bits); | ||
| 1128 | #else | 1300 | #else |
| 1129 | int64_t full_res = (int64_t)((uint64_t)lhs - (uint64_t)rhs); | 1301 | *res = zig_subw_i64(lhs, rhs, bits); |
| 1130 | bool overflow = ((lhs ^ rhs) & (full_res ^ lhs)) < 0; | 1302 | return ((lhs ^ rhs) & (*res ^ lhs)) < INT64_C(0); |
| 1131 | #endif | 1303 | #endif |
| 1132 | *res = zig_wrap_i64(full_res, bits); | ||
| 1133 | return overflow || full_res < zig_minInt_i(64, bits) || full_res > zig_maxInt_i(64, bits); | ||
| 1134 | } | 1304 | } |
| 1135 | 1305 | ||
| 1136 | static inline bool zig_subo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t bits) { | 1306 | static inline bool zig_subo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t bits) { |
| 1137 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) | 1307 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) |
| 1138 | uint8_t full_res; | 1308 | uint8_t full_res; |
| 1139 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); | 1309 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); |
| 1140 | *res = zig_wrap_u8(full_res, bits); | 1310 | *res = zig_u8_truncate_u8(full_res, bits); |
| 1141 | return overflow || full_res < zig_minInt_u(8, bits) || full_res > zig_maxInt_u(8, bits); | 1311 | return overflow || full_res < zig_minInt_u(8, bits) || full_res > zig_maxInt_u(8, bits); |
| 1142 | #else | 1312 | #else |
| 1143 | uint32_t full_res; | 1313 | uint32_t full_res; |
| 1144 | bool overflow = zig_subo_u32(&full_res, lhs, rhs, bits); | 1314 | bool overflow = zig_subo_u32(&full_res, lhs, rhs, bits); |
| 1145 | *res = (uint8_t)full_res; | 1315 | *res = zig_u8_intCast_u32(full_res); |
| 1146 | return overflow; | 1316 | return overflow; |
| 1147 | #endif | 1317 | #endif |
| 1148 | } | 1318 | } |
| ... | @@ -1151,12 +1321,12 @@ static inline bool zig_subo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits | ... | @@ -1151,12 +1321,12 @@ static inline bool zig_subo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits |
| 1151 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) | 1321 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) |
| 1152 | int8_t full_res; | 1322 | int8_t full_res; |
| 1153 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); | 1323 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); |
| 1154 | *res = zig_wrap_i8(full_res, bits); | 1324 | *res = zig_i8_truncate_i8(full_res, bits); |
| 1155 | return overflow || full_res < zig_minInt_i(8, bits) || full_res > zig_maxInt_i(8, bits); | 1325 | return overflow || full_res < zig_minInt_i(8, bits) || full_res > zig_maxInt_i(8, bits); |
| 1156 | #else | 1326 | #else |
| 1157 | int32_t full_res; | 1327 | int32_t full_res; |
| 1158 | bool overflow = zig_subo_i32(&full_res, lhs, rhs, bits); | 1328 | bool overflow = zig_subo_i32(&full_res, lhs, rhs, bits); |
| 1159 | *res = (int8_t)full_res; | 1329 | *res = zig_i8_intCast_i32(full_res); |
| 1160 | return overflow; | 1330 | return overflow; |
| 1161 | #endif | 1331 | #endif |
| 1162 | } | 1332 | } |
| ... | @@ -1165,12 +1335,12 @@ static inline bool zig_subo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8 | ... | @@ -1165,12 +1335,12 @@ static inline bool zig_subo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8 |
| 1165 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) | 1335 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) |
| 1166 | uint16_t full_res; | 1336 | uint16_t full_res; |
| 1167 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); | 1337 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); |
| 1168 | *res = zig_wrap_u16(full_res, bits); | 1338 | *res = zig_u16_truncate_u16(full_res, bits); |
| 1169 | return overflow || full_res < zig_minInt_u(16, bits) || full_res > zig_maxInt_u(16, bits); | 1339 | return overflow || full_res < zig_minInt_u(16, bits) || full_res > zig_maxInt_u(16, bits); |
| 1170 | #else | 1340 | #else |
| 1171 | uint32_t full_res; | 1341 | uint32_t full_res; |
| 1172 | bool overflow = zig_subo_u32(&full_res, lhs, rhs, bits); | 1342 | bool overflow = zig_subo_u32(&full_res, lhs, rhs, bits); |
| 1173 | *res = (uint16_t)full_res; | 1343 | *res = zig_u16_intCast_u32(full_res); |
| 1174 | return overflow; | 1344 | return overflow; |
| 1175 | #endif | 1345 | #endif |
| 1176 | } | 1346 | } |
| ... | @@ -1179,27 +1349,28 @@ static inline bool zig_subo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t | ... | @@ -1179,27 +1349,28 @@ static inline bool zig_subo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t |
| 1179 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) | 1349 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) |
| 1180 | int16_t full_res; | 1350 | int16_t full_res; |
| 1181 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); | 1351 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); |
| 1182 | *res = zig_wrap_i16(full_res, bits); | 1352 | *res = zig_i16_truncate_i16(full_res, bits); |
| 1183 | return overflow || full_res < zig_minInt_i(16, bits) || full_res > zig_maxInt_i(16, bits); | 1353 | return overflow || full_res < zig_minInt_i(16, bits) || full_res > zig_maxInt_i(16, bits); |
| 1184 | #else | 1354 | #else |
| 1185 | int32_t full_res; | 1355 | int32_t full_res; |
| 1186 | bool overflow = zig_subo_i32(&full_res, lhs, rhs, bits); | 1356 | bool overflow = zig_subo_i32(&full_res, lhs, rhs, bits); |
| 1187 | *res = (int16_t)full_res; | 1357 | *res = zig_i16_intCast_i32(full_res); |
| 1188 | return overflow; | 1358 | return overflow; |
| 1189 | #endif | 1359 | #endif |
| 1190 | } | 1360 | } |
| 1191 | 1361 | ||
| 1192 | #if defined(zig_ez80) | 1362 | #if defined(zig_ez80) |
| 1363 | |||
| 1193 | static inline bool zig_subo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) { | 1364 | static inline bool zig_subo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) { |
| 1194 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) | 1365 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) |
| 1195 | uint24_t full_res; | 1366 | uint24_t full_res; |
| 1196 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); | 1367 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); |
| 1197 | *res = zig_wrap_u24(full_res, bits); | 1368 | *res = zig_u24_truncate_u24(full_res, bits); |
| 1198 | return overflow || full_res < zig_minInt_u(24, bits) || full_res > zig_maxInt_u(24, bits); | 1369 | return overflow || full_res < zig_minInt_u(24, bits) || full_res > zig_maxInt_u(24, bits); |
| 1199 | #else | 1370 | #else |
| 1200 | uint32_t full_res; | 1371 | uint32_t full_res; |
| 1201 | bool overflow = zig_subo_u32(&full_res, lhs, rhs, bits); | 1372 | bool overflow = zig_subo_u32(&full_res, lhs, rhs, bits); |
| 1202 | *res = (uint24_t)full_res; | 1373 | *res = zig_u24_intCast_u32(full_res); |
| 1203 | return overflow; | 1374 | return overflow; |
| 1204 | #endif | 1375 | #endif |
| 1205 | } | 1376 | } |
| ... | @@ -1208,28 +1379,26 @@ static inline bool zig_subo_i24(int24_t *res, int24_t lhs, int24_t rhs, uint8_t | ... | @@ -1208,28 +1379,26 @@ static inline bool zig_subo_i24(int24_t *res, int24_t lhs, int24_t rhs, uint8_t |
| 1208 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) | 1379 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) |
| 1209 | int24_t full_res; | 1380 | int24_t full_res; |
| 1210 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); | 1381 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); |
| 1211 | *res = zig_wrap_i24(full_res, bits); | 1382 | *res = zig_i24_truncate_i24(full_res, bits); |
| 1212 | return overflow || full_res < zig_minInt_i(24, bits) || full_res > zig_maxInt_i(24, bits); | 1383 | return overflow || full_res < zig_minInt_i(24, bits) || full_res > zig_maxInt_i(24, bits); |
| 1213 | #else | 1384 | #else |
| 1214 | int32_t full_res; | 1385 | int32_t full_res; |
| 1215 | bool overflow = zig_subo_i32(&full_res, lhs, rhs, bits); | 1386 | bool overflow = zig_subo_i32(&full_res, lhs, rhs, bits); |
| 1216 | *res = (int24_t)full_res; | 1387 | *res = zig_i24_intCast_i32(full_res); |
| 1217 | return overflow; | 1388 | return overflow; |
| 1218 | #endif | 1389 | #endif |
| 1219 | } | 1390 | } |
| 1220 | #endif | ||
| 1221 | 1391 | ||
| 1222 | #if defined(zig_ez80) | ||
| 1223 | static inline bool zig_subo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) { | 1392 | static inline bool zig_subo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) { |
| 1224 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) | 1393 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) |
| 1225 | uint48_t full_res; | 1394 | uint48_t full_res; |
| 1226 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); | 1395 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); |
| 1227 | *res = zig_wrap_u48(full_res, bits); | 1396 | *res = zig_u48_truncate_u48(full_res, bits); |
| 1228 | return overflow || full_res < zig_minInt_u(48, bits) || full_res > zig_maxInt_u(48, bits); | 1397 | return overflow || full_res < zig_minInt_u(48, bits) || full_res > zig_maxInt_u(48, bits); |
| 1229 | #else | 1398 | #else |
| 1230 | uint64_t full_res; | 1399 | uint64_t full_res; |
| 1231 | bool overflow = zig_subo_u64(&full_res, lhs, rhs, bits); | 1400 | bool overflow = zig_subo_u64(&full_res, lhs, rhs, bits); |
| 1232 | *res = (uint48_t)full_res; | 1401 | *res = zig_u48_intCast_u64(full_res); |
| 1233 | return overflow; | 1402 | return overflow; |
| 1234 | #endif | 1403 | #endif |
| 1235 | } | 1404 | } |
| ... | @@ -1238,22 +1407,23 @@ static inline bool zig_subo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t | ... | @@ -1238,22 +1407,23 @@ static inline bool zig_subo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t |
| 1238 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) | 1407 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) |
| 1239 | int48_t full_res; | 1408 | int48_t full_res; |
| 1240 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); | 1409 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); |
| 1241 | *res = zig_wrap_i48(full_res, bits); | 1410 | *res = zig_i48_truncate_i48(full_res, bits); |
| 1242 | return overflow || full_res < zig_minInt_i(48, bits) || full_res > zig_maxInt_i(48, bits); | 1411 | return overflow || full_res < zig_minInt_i(48, bits) || full_res > zig_maxInt_i(48, bits); |
| 1243 | #else | 1412 | #else |
| 1244 | int64_t full_res; | 1413 | int64_t full_res; |
| 1245 | bool overflow = zig_subo_i64(&full_res, lhs, rhs, bits); | 1414 | bool overflow = zig_subo_i64(&full_res, lhs, rhs, bits); |
| 1246 | *res = (int48_t)full_res; | 1415 | *res = zig_i48_intCast_i64(full_res); |
| 1247 | return overflow; | 1416 | return overflow; |
| 1248 | #endif | 1417 | #endif |
| 1249 | } | 1418 | } |
| 1419 | |||
| 1250 | #endif | 1420 | #endif |
| 1251 | 1421 | ||
| 1252 | static inline bool zig_mulo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) { | 1422 | static inline bool zig_mulo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) { |
| 1253 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) | 1423 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) |
| 1254 | uint32_t full_res; | 1424 | uint32_t full_res; |
| 1255 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); | 1425 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); |
| 1256 | *res = zig_wrap_u32(full_res, bits); | 1426 | *res = zig_u32_truncate_u32(full_res, bits); |
| 1257 | return overflow || full_res < zig_minInt_u(32, bits) || full_res > zig_maxInt_u(32, bits); | 1427 | return overflow || full_res < zig_minInt_u(32, bits) || full_res > zig_maxInt_u(32, bits); |
| 1258 | #else | 1428 | #else |
| 1259 | *res = zig_mulw_u32(lhs, rhs, bits); | 1429 | *res = zig_mulw_u32(lhs, rhs, bits); |
| ... | @@ -1261,8 +1431,8 @@ static inline bool zig_mulo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8 | ... | @@ -1261,8 +1431,8 @@ static inline bool zig_mulo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8 |
| 1261 | #endif | 1431 | #endif |
| 1262 | } | 1432 | } |
| 1263 | 1433 | ||
| 1264 | zig_extern int32_t __mulosi4(int32_t lhs, int32_t rhs, int *overflow); | ||
| 1265 | static inline bool zig_mulo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t bits) { | 1434 | static inline bool zig_mulo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t bits) { |
| 1435 | zig_extern int32_t __mulosi4(int32_t lhs, int32_t rhs, int *overflow); | ||
| 1266 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) | 1436 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) |
| 1267 | int32_t full_res; | 1437 | int32_t full_res; |
| 1268 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); | 1438 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); |
| ... | @@ -1271,7 +1441,7 @@ static inline bool zig_mulo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t | ... | @@ -1271,7 +1441,7 @@ static inline bool zig_mulo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t |
| 1271 | int32_t full_res = __mulosi4(lhs, rhs, &overflow_int); | 1441 | int32_t full_res = __mulosi4(lhs, rhs, &overflow_int); |
| 1272 | bool overflow = overflow_int != 0; | 1442 | bool overflow = overflow_int != 0; |
| 1273 | #endif | 1443 | #endif |
| 1274 | *res = zig_wrap_i32(full_res, bits); | 1444 | *res = zig_i32_truncate_i32(full_res, bits); |
| 1275 | return overflow || full_res < zig_minInt_i(32, bits) || full_res > zig_maxInt_i(32, bits); | 1445 | return overflow || full_res < zig_minInt_i(32, bits) || full_res > zig_maxInt_i(32, bits); |
| 1276 | } | 1446 | } |
| 1277 | 1447 | ||
| ... | @@ -1279,7 +1449,7 @@ static inline bool zig_mulo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8 | ... | @@ -1279,7 +1449,7 @@ static inline bool zig_mulo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8 |
| 1279 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) | 1449 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) |
| 1280 | uint64_t full_res; | 1450 | uint64_t full_res; |
| 1281 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); | 1451 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); |
| 1282 | *res = zig_wrap_u64(full_res, bits); | 1452 | *res = zig_u64_truncate_u64(full_res, bits); |
| 1283 | return overflow || full_res < zig_minInt_u(64, bits) || full_res > zig_maxInt_u(64, bits); | 1453 | return overflow || full_res < zig_minInt_u(64, bits) || full_res > zig_maxInt_u(64, bits); |
| 1284 | #else | 1454 | #else |
| 1285 | *res = zig_mulw_u64(lhs, rhs, bits); | 1455 | *res = zig_mulw_u64(lhs, rhs, bits); |
| ... | @@ -1287,8 +1457,8 @@ static inline bool zig_mulo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8 | ... | @@ -1287,8 +1457,8 @@ static inline bool zig_mulo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8 |
| 1287 | #endif | 1457 | #endif |
| 1288 | } | 1458 | } |
| 1289 | 1459 | ||
| 1290 | zig_extern int64_t __mulodi4(int64_t lhs, int64_t rhs, int *overflow); | ||
| 1291 | static inline bool zig_mulo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t bits) { | 1460 | static inline bool zig_mulo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t bits) { |
| 1461 | zig_extern int64_t __mulodi4(int64_t lhs, int64_t rhs, int *overflow); | ||
| 1292 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) | 1462 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) |
| 1293 | int64_t full_res; | 1463 | int64_t full_res; |
| 1294 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); | 1464 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); |
| ... | @@ -1297,7 +1467,7 @@ static inline bool zig_mulo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t | ... | @@ -1297,7 +1467,7 @@ static inline bool zig_mulo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t |
| 1297 | int64_t full_res = __mulodi4(lhs, rhs, &overflow_int); | 1467 | int64_t full_res = __mulodi4(lhs, rhs, &overflow_int); |
| 1298 | bool overflow = overflow_int != 0; | 1468 | bool overflow = overflow_int != 0; |
| 1299 | #endif | 1469 | #endif |
| 1300 | *res = zig_wrap_i64(full_res, bits); | 1470 | *res = zig_i64_truncate_i64(full_res, bits); |
| 1301 | return overflow || full_res < zig_minInt_i(64, bits) || full_res > zig_maxInt_i(64, bits); | 1471 | return overflow || full_res < zig_minInt_i(64, bits) || full_res > zig_maxInt_i(64, bits); |
| 1302 | } | 1472 | } |
| 1303 | 1473 | ||
| ... | @@ -1305,12 +1475,12 @@ static inline bool zig_mulo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t b | ... | @@ -1305,12 +1475,12 @@ static inline bool zig_mulo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t b |
| 1305 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) | 1475 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) |
| 1306 | uint8_t full_res; | 1476 | uint8_t full_res; |
| 1307 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); | 1477 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); |
| 1308 | *res = zig_wrap_u8(full_res, bits); | 1478 | *res = zig_u8_truncate_u8(full_res, bits); |
| 1309 | return overflow || full_res < zig_minInt_u(8, bits) || full_res > zig_maxInt_u(8, bits); | 1479 | return overflow || full_res < zig_minInt_u(8, bits) || full_res > zig_maxInt_u(8, bits); |
| 1310 | #else | 1480 | #else |
| 1311 | uint32_t full_res; | 1481 | uint32_t full_res; |
| 1312 | bool overflow = zig_mulo_u32(&full_res, lhs, rhs, bits); | 1482 | bool overflow = zig_mulo_u32(&full_res, lhs, rhs, bits); |
| 1313 | *res = (uint8_t)full_res; | 1483 | *res = zig_u8_intCast_u32(full_res); |
| 1314 | return overflow; | 1484 | return overflow; |
| 1315 | #endif | 1485 | #endif |
| 1316 | } | 1486 | } |
| ... | @@ -1319,12 +1489,12 @@ static inline bool zig_mulo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits | ... | @@ -1319,12 +1489,12 @@ static inline bool zig_mulo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits |
| 1319 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) | 1489 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) |
| 1320 | int8_t full_res; | 1490 | int8_t full_res; |
| 1321 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); | 1491 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); |
| 1322 | *res = zig_wrap_i8(full_res, bits); | 1492 | *res = zig_i8_truncate_i8(full_res, bits); |
| 1323 | return overflow || full_res < zig_minInt_i(8, bits) || full_res > zig_maxInt_i(8, bits); | 1493 | return overflow || full_res < zig_minInt_i(8, bits) || full_res > zig_maxInt_i(8, bits); |
| 1324 | #else | 1494 | #else |
| 1325 | int32_t full_res; | 1495 | int32_t full_res; |
| 1326 | bool overflow = zig_mulo_i32(&full_res, lhs, rhs, bits); | 1496 | bool overflow = zig_mulo_i32(&full_res, lhs, rhs, bits); |
| 1327 | *res = (int8_t)full_res; | 1497 | *res = zig_i8_intCast_i32(full_res); |
| 1328 | return overflow; | 1498 | return overflow; |
| 1329 | #endif | 1499 | #endif |
| 1330 | } | 1500 | } |
| ... | @@ -1333,12 +1503,12 @@ static inline bool zig_mulo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8 | ... | @@ -1333,12 +1503,12 @@ static inline bool zig_mulo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8 |
| 1333 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) | 1503 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) |
| 1334 | uint16_t full_res; | 1504 | uint16_t full_res; |
| 1335 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); | 1505 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); |
| 1336 | *res = zig_wrap_u16(full_res, bits); | 1506 | *res = zig_u16_truncate_u16(full_res, bits); |
| 1337 | return overflow || full_res < zig_minInt_u(16, bits) || full_res > zig_maxInt_u(16, bits); | 1507 | return overflow || full_res < zig_minInt_u(16, bits) || full_res > zig_maxInt_u(16, bits); |
| 1338 | #else | 1508 | #else |
| 1339 | uint32_t full_res; | 1509 | uint32_t full_res; |
| 1340 | bool overflow = zig_mulo_u32(&full_res, lhs, rhs, bits); | 1510 | bool overflow = zig_mulo_u32(&full_res, lhs, rhs, bits); |
| 1341 | *res = (uint16_t)full_res; | 1511 | *res = zig_u16_intCast_u32(full_res); |
| 1342 | return overflow; | 1512 | return overflow; |
| 1343 | #endif | 1513 | #endif |
| 1344 | } | 1514 | } |
| ... | @@ -1347,27 +1517,28 @@ static inline bool zig_mulo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t | ... | @@ -1347,27 +1517,28 @@ static inline bool zig_mulo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t |
| 1347 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) | 1517 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) |
| 1348 | int16_t full_res; | 1518 | int16_t full_res; |
| 1349 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); | 1519 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); |
| 1350 | *res = zig_wrap_i16(full_res, bits); | 1520 | *res = zig_i16_truncate_i16(full_res, bits); |
| 1351 | return overflow || full_res < zig_minInt_i(16, bits) || full_res > zig_maxInt_i(16, bits); | 1521 | return overflow || full_res < zig_minInt_i(16, bits) || full_res > zig_maxInt_i(16, bits); |
| 1352 | #else | 1522 | #else |
| 1353 | int32_t full_res; | 1523 | int32_t full_res; |
| 1354 | bool overflow = zig_mulo_i32(&full_res, lhs, rhs, bits); | 1524 | bool overflow = zig_mulo_i32(&full_res, lhs, rhs, bits); |
| 1355 | *res = (int16_t)full_res; | 1525 | *res = zig_i16_intCast_i32(full_res); |
| 1356 | return overflow; | 1526 | return overflow; |
| 1357 | #endif | 1527 | #endif |
| 1358 | } | 1528 | } |
| 1359 | 1529 | ||
| 1360 | #if defined(zig_ez80) | 1530 | #if defined(zig_ez80) |
| 1531 | |||
| 1361 | static inline bool zig_mulo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) { | 1532 | static inline bool zig_mulo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) { |
| 1362 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) | 1533 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) |
| 1363 | uint24_t full_res; | 1534 | uint24_t full_res; |
| 1364 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); | 1535 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); |
| 1365 | *res = zig_wrap_u24(full_res, bits); | 1536 | *res = zig_u24_truncate_u24(full_res, bits); |
| 1366 | return overflow || full_res < zig_minInt_u(24, bits) || full_res > zig_maxInt_u(24, bits); | 1537 | return overflow || full_res < zig_minInt_u(24, bits) || full_res > zig_maxInt_u(24, bits); |
| 1367 | #else | 1538 | #else |
| 1368 | uint32_t full_res; | 1539 | uint32_t full_res; |
| 1369 | bool overflow = zig_mulo_u32(&full_res, lhs, rhs, bits); | 1540 | bool overflow = zig_mulo_u32(&full_res, lhs, rhs, bits); |
| 1370 | *res = (uint24_t)full_res; | 1541 | *res = zig_u24_intCast_u32(full_res); |
| 1371 | return overflow; | 1542 | return overflow; |
| 1372 | #endif | 1543 | #endif |
| 1373 | } | 1544 | } |
| ... | @@ -1376,28 +1547,26 @@ static inline bool zig_mulo_i24(int24_t *res, int24_t lhs, int24_t rhs, uint8_t | ... | @@ -1376,28 +1547,26 @@ static inline bool zig_mulo_i24(int24_t *res, int24_t lhs, int24_t rhs, uint8_t |
| 1376 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) | 1547 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) |
| 1377 | int24_t full_res; | 1548 | int24_t full_res; |
| 1378 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); | 1549 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); |
| 1379 | *res = zig_wrap_i24(full_res, bits); | 1550 | *res = zig_i24_truncate_i24(full_res, bits); |
| 1380 | return overflow || full_res < zig_minInt_i(24, bits) || full_res > zig_maxInt_i(24, bits); | 1551 | return overflow || full_res < zig_minInt_i(24, bits) || full_res > zig_maxInt_i(24, bits); |
| 1381 | #else | 1552 | #else |
| 1382 | int32_t full_res; | 1553 | int32_t full_res; |
| 1383 | bool overflow = zig_mulo_i32(&full_res, lhs, rhs, bits); | 1554 | bool overflow = zig_mulo_i32(&full_res, lhs, rhs, bits); |
| 1384 | *res = (int24_t)full_res; | 1555 | *res = zig_i24_intCast_i32(full_res); |
| 1385 | return overflow; | 1556 | return overflow; |
| 1386 | #endif | 1557 | #endif |
| 1387 | } | 1558 | } |
| 1388 | #endif | ||
| 1389 | 1559 | ||
| 1390 | #if defined(zig_ez80) | ||
| 1391 | static inline bool zig_mulo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) { | 1560 | static inline bool zig_mulo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) { |
| 1392 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) | 1561 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) |
| 1393 | uint48_t full_res; | 1562 | uint48_t full_res; |
| 1394 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); | 1563 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); |
| 1395 | *res = zig_wrap_u48(full_res, bits); | 1564 | *res = zig_u48_truncate_u48(full_res, bits); |
| 1396 | return overflow || full_res < zig_minInt_u(48, bits) || full_res > zig_maxInt_u(48, bits); | 1565 | return overflow || full_res < zig_minInt_u(48, bits) || full_res > zig_maxInt_u(48, bits); |
| 1397 | #else | 1566 | #else |
| 1398 | uint64_t full_res; | 1567 | uint64_t full_res; |
| 1399 | bool overflow = zig_mulo_u64(&full_res, lhs, rhs, bits); | 1568 | bool overflow = zig_mulo_u64(&full_res, lhs, rhs, bits); |
| 1400 | *res = (uint48_t)full_res; | 1569 | *res = zig_u48_intCast_u64(full_res); |
| 1401 | return overflow; | 1570 | return overflow; |
| 1402 | #endif | 1571 | #endif |
| 1403 | } | 1572 | } |
| ... | @@ -1406,18 +1575,32 @@ static inline bool zig_mulo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t | ... | @@ -1406,18 +1575,32 @@ static inline bool zig_mulo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t |
| 1406 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) | 1575 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) |
| 1407 | int48_t full_res; | 1576 | int48_t full_res; |
| 1408 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); | 1577 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); |
| 1409 | *res = zig_wrap_i48(full_res, bits); | 1578 | *res = zig_i48_truncate_i48(full_res, bits); |
| 1410 | return overflow || full_res < zig_minInt_i(48, bits) || full_res > zig_maxInt_i(48, bits); | 1579 | return overflow || full_res < zig_minInt_i(48, bits) || full_res > zig_maxInt_i(48, bits); |
| 1411 | #else | 1580 | #else |
| 1412 | int64_t full_res; | 1581 | int64_t full_res; |
| 1413 | bool overflow = zig_mulo_i64(&full_res, lhs, rhs, bits); | 1582 | bool overflow = zig_mulo_i64(&full_res, lhs, rhs, bits); |
| 1414 | *res = (int48_t)full_res; | 1583 | *res = zig_i48_intCast_i64(full_res); |
| 1415 | return overflow; | 1584 | return overflow; |
| 1416 | #endif | 1585 | #endif |
| 1417 | } | 1586 | } |
| 1587 | |||
| 1418 | #endif | 1588 | #endif |
| 1419 | 1589 | ||
| 1420 | #define zig_int_builtins(w) \ | 1590 | #define zig_shls_builtins(lw, rw) \ |
| 1591 | static inline uint##lw##_t zig_shls_u##lw##_u##rw(uint##lw##_t lhs, uint##rw##_t rhs, uint8_t bits) { \ | ||
| 1592 | uint##lw##_t res; \ | ||
| 1593 | if (rhs < bits && !zig_shlo_u##lw(&res, lhs, zig_u8_intCast_u##rw(rhs), bits)) return res; \ | ||
| 1594 | return lhs == INT##lw##_C(0) ? zig_minInt_u(lw, bits) : zig_maxInt_u(lw, bits); \ | ||
| 1595 | } \ | ||
| 1596 | \ | ||
| 1597 | static inline int##lw##_t zig_shls_i##lw##_u##rw(int##lw##_t lhs, uint##rw##_t rhs, uint8_t bits) { \ | ||
| 1598 | int##lw##_t res; \ | ||
| 1599 | if (rhs < bits && !zig_shlo_i##lw(&res, lhs, zig_u8_intCast_u##rw(rhs), bits)) return res; \ | ||
| 1600 | return lhs == INT##lw##_C(0) ? INT##lw##_C(0) : \ | ||
| 1601 | lhs < INT##lw##_C(0) ? zig_minInt_i(lw, bits) : zig_maxInt_i(lw, bits); \ | ||
| 1602 | } | ||
| 1603 | #define zig_int_sat_builtins(w) \ | ||
| 1421 | static inline bool zig_shlo_u##w(uint##w##_t *res, uint##w##_t lhs, uint8_t rhs, uint8_t bits) { \ | 1604 | static inline bool zig_shlo_u##w(uint##w##_t *res, uint##w##_t lhs, uint8_t rhs, uint8_t bits) { \ |
| 1422 | *res = zig_shlw_u##w(lhs, rhs, bits); \ | 1605 | *res = zig_shlw_u##w(lhs, rhs, bits); \ |
| 1423 | return lhs > zig_maxInt_u(w, bits) >> rhs; \ | 1606 | return lhs > zig_maxInt_u(w, bits) >> rhs; \ |
| ... | @@ -1429,18 +1612,10 @@ static inline bool zig_mulo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t | ... | @@ -1429,18 +1612,10 @@ static inline bool zig_mulo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t |
| 1429 | return (lhs & mask) != INT##w##_C(0) && (lhs & mask) != mask; \ | 1612 | return (lhs & mask) != INT##w##_C(0) && (lhs & mask) != mask; \ |
| 1430 | } \ | 1613 | } \ |
| 1431 | \ | 1614 | \ |
| 1432 | static inline uint##w##_t zig_shls_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \ | 1615 | zig_shls_builtins(w, 8) \ |
| 1433 | uint##w##_t res; \ | 1616 | zig_shls_builtins(w, 16) \ |
| 1434 | if (rhs < bits && !zig_shlo_u##w(&res, lhs, rhs, bits)) return res; \ | 1617 | zig_shls_builtins(w, 32) \ |
| 1435 | return lhs == INT##w##_C(0) ? INT##w##_C(0) : zig_maxInt_u(w, bits); \ | 1618 | zig_shls_builtins(w, 64) \ |
| 1436 | } \ | ||
| 1437 | \ | ||
| 1438 | static inline int##w##_t zig_shls_i##w(int##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \ | ||
| 1439 | int##w##_t res; \ | ||
| 1440 | if (rhs < bits && !zig_shlo_i##w(&res, lhs, rhs, bits)) return res; \ | ||
| 1441 | return lhs == INT##w##_C(0) ? INT##w##_C(0) : \ | ||
| 1442 | lhs < INT##w##_C(0) ? zig_minInt_i(w, bits) : zig_maxInt_i(w, bits); \ | ||
| 1443 | } \ | ||
| 1444 | \ | 1619 | \ |
| 1445 | static inline uint##w##_t zig_adds_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \ | 1620 | static inline uint##w##_t zig_adds_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \ |
| 1446 | uint##w##_t res; \ | 1621 | uint##w##_t res; \ |
| ... | @@ -1474,332 +1649,321 @@ static inline bool zig_mulo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t | ... | @@ -1474,332 +1649,321 @@ static inline bool zig_mulo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t |
| 1474 | if (!zig_mulo_i##w(&res, lhs, rhs, bits)) return res; \ | 1649 | if (!zig_mulo_i##w(&res, lhs, rhs, bits)) return res; \ |
| 1475 | return (lhs ^ rhs) < INT##w##_C(0) ? zig_minInt_i(w, bits) : zig_maxInt_i(w, bits); \ | 1650 | return (lhs ^ rhs) < INT##w##_C(0) ? zig_minInt_i(w, bits) : zig_maxInt_i(w, bits); \ |
| 1476 | } | 1651 | } |
| 1477 | zig_int_builtins(8) | 1652 | zig_int_sat_builtins(8) |
| 1478 | zig_int_builtins(16) | 1653 | zig_int_sat_builtins(16) |
| 1479 | #if defined(zig_ez80) | 1654 | zig_int_sat_builtins(32) |
| 1480 | zig_int_builtins(24) | 1655 | zig_int_sat_builtins(64) |
| 1481 | #endif | ||
| 1482 | zig_int_builtins(32) | ||
| 1483 | #if defined(zig_ez80) | 1656 | #if defined(zig_ez80) |
| 1484 | zig_int_builtins(48) | 1657 | zig_int_sat_builtins(24) |
| 1658 | zig_int_sat_builtins(48) | ||
| 1485 | #endif | 1659 | #endif |
| 1486 | zig_int_builtins(64) | ||
| 1487 | 1660 | ||
| 1488 | #define zig_builtin8(name, val) __builtin_##name(val) | 1661 | #define zig_builtin8(name, arg) __builtin_##name(arg) |
| 1489 | typedef unsigned int zig_Builtin8; | 1662 | typedef unsigned int zig_Builtin8; |
| 1490 | 1663 | ||
| 1491 | #define zig_builtin16(name, val) __builtin_##name(val) | 1664 | #define zig_builtin16(name, arg) __builtin_##name(arg) |
| 1492 | typedef unsigned int zig_Builtin16; | 1665 | typedef unsigned int zig_Builtin16; |
| 1493 | 1666 | ||
| 1494 | #if defined(zig_ez80) | ||
| 1495 | #define zig_builtin24(name, val) __builtin_##name(val) | ||
| 1496 | typedef unsigned int zig_Builtin24; | ||
| 1497 | #endif | ||
| 1498 | |||
| 1499 | #if INT_MIN <= INT32_MIN | 1667 | #if INT_MIN <= INT32_MIN |
| 1500 | #define zig_builtin32(name, val) __builtin_##name(val) | 1668 | #define zig_builtin32(name, arg) __builtin_##name(arg) |
| 1501 | typedef unsigned int zig_Builtin32; | 1669 | typedef unsigned int zig_Builtin32; |
| 1502 | #elif LONG_MIN <= INT32_MIN | 1670 | #elif LONG_MIN <= INT32_MIN |
| 1503 | #define zig_builtin32(name, val) __builtin_##name##l(val) | 1671 | #define zig_builtin32(name, arg) __builtin_##name##l(arg) |
| 1504 | typedef unsigned long zig_Builtin32; | 1672 | typedef unsigned long zig_Builtin32; |
| 1505 | #endif | 1673 | #endif |
| 1506 | 1674 | ||
| 1507 | #if defined(zig_ez80) | ||
| 1508 | #define zig_builtin48(name, val) __builtin_##name(val) | ||
| 1509 | typedef unsigned long long zig_Builtin48; | ||
| 1510 | #endif | ||
| 1511 | |||
| 1512 | #if INT_MIN <= INT64_MIN | 1675 | #if INT_MIN <= INT64_MIN |
| 1513 | #define zig_builtin64(name, val) __builtin_##name(val) | 1676 | #define zig_builtin64(name, arg) __builtin_##name(arg) |
| 1514 | typedef unsigned int zig_Builtin64; | 1677 | typedef unsigned int zig_Builtin64; |
| 1515 | #elif LONG_MIN <= INT64_MIN | 1678 | #elif LONG_MIN <= INT64_MIN |
| 1516 | #define zig_builtin64(name, val) __builtin_##name##l(val) | 1679 | #define zig_builtin64(name, arg) __builtin_##name##l(arg) |
| 1517 | typedef unsigned long zig_Builtin64; | 1680 | typedef unsigned long zig_Builtin64; |
| 1518 | #elif LLONG_MIN <= INT64_MIN | 1681 | #elif LLONG_MIN <= INT64_MIN |
| 1519 | #define zig_builtin64(name, val) __builtin_##name##ll(val) | 1682 | #define zig_builtin64(name, arg) __builtin_##name##ll(arg) |
| 1520 | typedef unsigned long long zig_Builtin64; | 1683 | typedef unsigned long long zig_Builtin64; |
| 1521 | #endif | 1684 | #endif |
| 1522 | 1685 | ||
| 1523 | static inline uint8_t zig_byte_swap_u8(uint8_t val, uint8_t bits) { | 1686 | #if defined(zig_ez80) |
| 1524 | return zig_wrap_u8(val >> (8 - bits), bits); | 1687 | #define zig_builtin24(name, arg) __builtin_##name(arg) |
| 1688 | typedef unsigned int zig_Builtin24; | ||
| 1689 | #define zig_builtin48(name, arg) __builtin_##name(arg) | ||
| 1690 | typedef unsigned long long zig_Builtin48; | ||
| 1691 | #endif | ||
| 1692 | |||
| 1693 | static inline uint8_t zig_byteSwap_u8(uint8_t arg, uint8_t bits) { | ||
| 1694 | return zig_u8_truncate_u8(arg >> (8 - bits), bits); | ||
| 1525 | } | 1695 | } |
| 1526 | 1696 | ||
| 1527 | static inline int8_t zig_byte_swap_i8(int8_t val, uint8_t bits) { | 1697 | static inline int8_t zig_byteSwap_i8(int8_t arg, uint8_t bits) { |
| 1528 | return zig_wrap_i8((int8_t)zig_byte_swap_u8((uint8_t)val, bits), bits); | 1698 | return zig_i8_truncate_i8((int8_t)zig_byteSwap_u8((uint8_t)arg, bits), bits); |
| 1529 | } | 1699 | } |
| 1530 | 1700 | ||
| 1531 | static inline uint16_t zig_byte_swap_u16(uint16_t val, uint8_t bits) { | 1701 | static inline uint16_t zig_byteSwap_u16(uint16_t arg, uint8_t bits) { |
| 1532 | uint16_t full_res; | 1702 | uint16_t full_res; |
| 1533 | #if zig_has_builtin(bswap16) || defined(zig_gcc) | 1703 | #if zig_has_builtin(bswap16) || defined(zig_gcc) |
| 1534 | full_res = __builtin_bswap16(val); | 1704 | full_res = __builtin_bswap16(arg); |
| 1535 | #else | 1705 | #else |
| 1536 | full_res = (uint16_t)zig_byte_swap_u8((uint8_t)(val >> 0), 8) << 8 | | 1706 | full_res = (uint16_t)zig_byteSwap_u8((uint8_t)(arg >> 0), 8) << 8 | |
| 1537 | (uint16_t)zig_byte_swap_u8((uint8_t)(val >> 8), 8) >> 0; | 1707 | (uint16_t)zig_byteSwap_u8((uint8_t)(arg >> 8), 8) >> 0; |
| 1538 | #endif | 1708 | #endif |
| 1539 | return zig_wrap_u16(full_res >> (16 - bits), bits); | 1709 | return zig_u16_truncate_u16(full_res >> (16 - bits), bits); |
| 1540 | } | 1710 | } |
| 1541 | 1711 | ||
| 1542 | static inline int16_t zig_byte_swap_i16(int16_t val, uint8_t bits) { | 1712 | static inline int16_t zig_byteSwap_i16(int16_t arg, uint8_t bits) { |
| 1543 | return zig_wrap_i16((int16_t)zig_byte_swap_u16((uint16_t)val, bits), bits); | 1713 | return zig_i16_truncate_i16((int16_t)zig_byteSwap_u16((uint16_t)arg, bits), bits); |
| 1544 | } | 1714 | } |
| 1545 | 1715 | ||
| 1546 | #if defined(zig_ez80) | 1716 | #if defined(zig_ez80) |
| 1547 | static inline uint16_t zig_byte_swap_u24(uint24_t val, uint8_t bits) { | 1717 | static inline uint16_t zig_byteSwap_u24(uint24_t arg, uint8_t bits) { |
| 1548 | uint24_t full_res; | 1718 | uint24_t full_res; |
| 1549 | #if zig_has_builtin(bswap24) || defined(zig_gcc) | 1719 | #if zig_has_builtin(bswap24) || defined(zig_gcc) |
| 1550 | full_res = __builtin_bswap24(val); | 1720 | full_res = __builtin_bswap24(arg); |
| 1551 | #else | 1721 | #else |
| 1552 | full_res = (uint24_t)zig_byte_swap_u8((uint8_t)(val >> 0), 8) << 16 | | 1722 | full_res = (uint24_t)zig_byteSwap_u8((uint8_t)(arg >> 0), 8) << 16 | |
| 1553 | (uint24_t)zig_byte_swap_u16((uint16_t)(val >> 8), 16) >> 0; | 1723 | (uint24_t)zig_byteSwap_u16((uint16_t)(arg >> 8), 16) >> 0; |
| 1554 | #endif | 1724 | #endif |
| 1555 | return zig_wrap_u24(full_res >> (24 - bits), bits); | 1725 | return zig_u24_truncate_u24(full_res >> (24 - bits), bits); |
| 1556 | } | 1726 | } |
| 1557 | 1727 | ||
| 1558 | static inline int16_t zig_byte_swap_i24(int24_t val, uint8_t bits) { | 1728 | static inline int16_t zig_byteSwap_i24(int24_t arg, uint8_t bits) { |
| 1559 | return zig_wrap_i24((int24_t)zig_byte_swap_u24((uint24_t)val, bits), bits); | 1729 | return zig_i24_truncate_i24((int24_t)zig_byteSwap_u24((uint24_t)arg, bits), bits); |
| 1560 | } | 1730 | } |
| 1561 | #endif | 1731 | #endif |
| 1562 | 1732 | ||
| 1563 | static inline uint32_t zig_byte_swap_u32(uint32_t val, uint8_t bits) { | 1733 | static inline uint32_t zig_byteSwap_u32(uint32_t arg, uint8_t bits) { |
| 1564 | uint32_t full_res; | 1734 | uint32_t full_res; |
| 1565 | #if zig_has_builtin(bswap32) || defined(zig_gcc) | 1735 | #if zig_has_builtin(bswap32) || defined(zig_gcc) |
| 1566 | full_res = __builtin_bswap32(val); | 1736 | full_res = __builtin_bswap32(arg); |
| 1567 | #else | 1737 | #else |
| 1568 | full_res = (uint32_t)zig_byte_swap_u16((uint16_t)(val >> 0), 16) << 16 | | 1738 | full_res = (uint32_t)zig_byteSwap_u16((uint16_t)(arg >> 0), 16) << 16 | |
| 1569 | (uint32_t)zig_byte_swap_u16((uint16_t)(val >> 16), 16) >> 0; | 1739 | (uint32_t)zig_byteSwap_u16((uint16_t)(arg >> 16), 16) >> 0; |
| 1570 | #endif | 1740 | #endif |
| 1571 | return zig_wrap_u32(full_res >> (32 - bits), bits); | 1741 | return zig_u32_truncate_u32(full_res >> (32 - bits), bits); |
| 1572 | } | 1742 | } |
| 1573 | 1743 | ||
| 1574 | static inline int32_t zig_byte_swap_i32(int32_t val, uint8_t bits) { | 1744 | static inline int32_t zig_byteSwap_i32(int32_t arg, uint8_t bits) { |
| 1575 | return zig_wrap_i32((int32_t)zig_byte_swap_u32((uint32_t)val, bits), bits); | 1745 | return zig_i32_truncate_i32((int32_t)zig_byteSwap_u32((uint32_t)arg, bits), bits); |
| 1576 | } | 1746 | } |
| 1577 | 1747 | ||
| 1578 | #if defined(zig_ez80) | 1748 | #if defined(zig_ez80) |
| 1579 | static inline uint32_t zig_byte_swap_u48(uint48_t val, uint8_t bits) { | 1749 | static inline uint32_t zig_byteSwap_u48(uint48_t arg, uint8_t bits) { |
| 1580 | uint48_t full_res; | 1750 | uint48_t full_res; |
| 1581 | #if zig_has_builtin(bswap48) || defined(zig_gcc) | 1751 | #if zig_has_builtin(bswap48) || defined(zig_gcc) |
| 1582 | full_res = __builtin_bswap48(val); | 1752 | full_res = __builtin_bswap48(arg); |
| 1583 | #else | 1753 | #else |
| 1584 | full_res = (uint48_t)zig_byte_swap_u24((uint24_t)(val >> 0), 24) << 24 | | 1754 | full_res = (uint48_t)zig_byteSwap_u24((uint24_t)(arg >> 0), 24) << 24 | |
| 1585 | (uint48_t)zig_byte_swap_u24((uint24_t)(val >> 24), 24) >> 0; | 1755 | (uint48_t)zig_byteSwap_u24((uint24_t)(arg >> 24), 24) >> 0; |
| 1586 | #endif | 1756 | #endif |
| 1587 | return zig_wrap_u48(full_res >> (48 - bits), bits); | 1757 | return zig_u48_truncate_u48(full_res >> (48 - bits), bits); |
| 1588 | } | 1758 | } |
| 1589 | 1759 | ||
| 1590 | static inline int32_t zig_byte_swap_i48(int48_t val, uint8_t bits) { | 1760 | static inline int32_t zig_byteSwap_i48(int48_t arg, uint8_t bits) { |
| 1591 | return zig_wrap_i48((int48_t)zig_byte_swap_u48((uint48_t)val, bits), bits); | 1761 | return zig_i48_truncate_i48((int48_t)zig_byteSwap_u48((uint48_t)arg, bits), bits); |
| 1592 | } | 1762 | } |
| 1593 | #endif | 1763 | #endif |
| 1594 | 1764 | ||
| 1595 | static inline uint64_t zig_byte_swap_u64(uint64_t val, uint8_t bits) { | 1765 | static inline uint64_t zig_byteSwap_u64(uint64_t arg, uint8_t bits) { |
| 1596 | uint64_t full_res; | 1766 | uint64_t full_res; |
| 1597 | #if zig_has_builtin(bswap64) || defined(zig_gcc) | 1767 | #if zig_has_builtin(bswap64) || defined(zig_gcc) |
| 1598 | full_res = __builtin_bswap64(val); | 1768 | full_res = __builtin_bswap64(arg); |
| 1599 | #else | 1769 | #else |
| 1600 | full_res = (uint64_t)zig_byte_swap_u32((uint32_t)(val >> 0), 32) << 32 | | 1770 | full_res = (uint64_t)zig_byteSwap_u32((uint32_t)(arg >> 0), 32) << 32 | |
| 1601 | (uint64_t)zig_byte_swap_u32((uint32_t)(val >> 32), 32) >> 0; | 1771 | (uint64_t)zig_byteSwap_u32((uint32_t)(arg >> 32), 32) >> 0; |
| 1602 | #endif | 1772 | #endif |
| 1603 | return zig_wrap_u64(full_res >> (64 - bits), bits); | 1773 | return zig_u64_truncate_u64(full_res >> (64 - bits), bits); |
| 1604 | } | 1774 | } |
| 1605 | 1775 | ||
| 1606 | static inline int64_t zig_byte_swap_i64(int64_t val, uint8_t bits) { | 1776 | static inline int64_t zig_byteSwap_i64(int64_t arg, uint8_t bits) { |
| 1607 | return zig_wrap_i64((int64_t)zig_byte_swap_u64((uint64_t)val, bits), bits); | 1777 | return zig_i64_truncate_i64((int64_t)zig_byteSwap_u64((uint64_t)arg, bits), bits); |
| 1608 | } | 1778 | } |
| 1609 | 1779 | ||
| 1610 | static inline uint8_t zig_bit_reverse_u8(uint8_t val, uint8_t bits) { | 1780 | static inline uint8_t zig_bitReverse_u8(uint8_t arg, uint8_t bits) { |
| 1611 | uint8_t full_res; | 1781 | uint8_t full_res; |
| 1612 | #if zig_has_builtin(bitreverse8) | 1782 | #if zig_has_builtin(bitreverse8) |
| 1613 | full_res = __builtin_bitreverse8(val); | 1783 | full_res = __builtin_bitreverse8(arg); |
| 1614 | #else | 1784 | #else |
| 1615 | static uint8_t const lut[0x10] = { | 1785 | static uint8_t const lut[0x10] = { |
| 1616 | 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe, | 1786 | 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe, |
| 1617 | 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf | 1787 | 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf |
| 1618 | }; | 1788 | }; |
| 1619 | full_res = lut[val >> 0 & 0xF] << 4 | lut[val >> 4 & 0xF] << 0; | 1789 | full_res = lut[arg >> 0 & 0xF] << 4 | lut[arg >> 4 & 0xF] << 0; |
| 1620 | #endif | 1790 | #endif |
| 1621 | return zig_wrap_u8(full_res >> (8 - bits), bits); | 1791 | return zig_u8_truncate_u8(full_res >> (8 - bits), bits); |
| 1622 | } | 1792 | } |
| 1623 | 1793 | ||
| 1624 | static inline int8_t zig_bit_reverse_i8(int8_t val, uint8_t bits) { | 1794 | static inline int8_t zig_bitReverse_i8(int8_t arg, uint8_t bits) { |
| 1625 | return zig_wrap_i8((int8_t)zig_bit_reverse_u8((uint8_t)val, bits), bits); | 1795 | return zig_i8_truncate_i8((int8_t)zig_bitReverse_u8((uint8_t)arg, bits), bits); |
| 1626 | } | 1796 | } |
| 1627 | 1797 | ||
| 1628 | static inline uint16_t zig_bit_reverse_u16(uint16_t val, uint8_t bits) { | 1798 | static inline uint16_t zig_bitReverse_u16(uint16_t arg, uint8_t bits) { |
| 1629 | uint16_t full_res; | 1799 | uint16_t full_res; |
| 1630 | #if zig_has_builtin(bitreverse16) | 1800 | #if zig_has_builtin(bitreverse16) |
| 1631 | full_res = __builtin_bitreverse16(val); | 1801 | full_res = __builtin_bitreverse16(arg); |
| 1632 | #else | 1802 | #else |
| 1633 | full_res = (uint16_t)zig_bit_reverse_u8((uint8_t)(val >> 0), 8) << 8 | | 1803 | full_res = (uint16_t)zig_bitReverse_u8((uint8_t)(arg >> 0), 8) << 8 | |
| 1634 | (uint16_t)zig_bit_reverse_u8((uint8_t)(val >> 8), 8) >> 0; | 1804 | (uint16_t)zig_bitReverse_u8((uint8_t)(arg >> 8), 8) >> 0; |
| 1635 | #endif | 1805 | #endif |
| 1636 | return zig_wrap_u16(full_res >> (16 - bits), bits); | 1806 | return zig_u16_truncate_u16(full_res >> (16 - bits), bits); |
| 1637 | } | 1807 | } |
| 1638 | 1808 | ||
| 1639 | static inline int16_t zig_bit_reverse_i16(int16_t val, uint8_t bits) { | 1809 | static inline int16_t zig_bitReverse_i16(int16_t arg, uint8_t bits) { |
| 1640 | return zig_wrap_i16((int16_t)zig_bit_reverse_u16((uint16_t)val, bits), bits); | 1810 | return zig_i16_truncate_i16((int16_t)zig_bitReverse_u16((uint16_t)arg, bits), bits); |
| 1641 | } | 1811 | } |
| 1642 | 1812 | ||
| 1643 | #if defined(zig_ez80) | 1813 | #if defined(zig_ez80) |
| 1644 | static inline uint24_t zig_bit_reverse_u24(uint24_t val, uint8_t bits) { | 1814 | static inline uint24_t zig_bitReverse_u24(uint24_t arg, uint8_t bits) { |
| 1645 | uint24_t full_res; | 1815 | uint24_t full_res; |
| 1646 | #if zig_has_builtin(bitreverse24) | 1816 | #if zig_has_builtin(bitreverse24) |
| 1647 | full_res = __builtin_bitreverse24(val); | 1817 | full_res = __builtin_bitreverse24(arg); |
| 1648 | #else | 1818 | #else |
| 1649 | full_res = (uint24_t)zig_bit_reverse_u8((uint8_t)(val >> 0), 8) << 16 | | 1819 | full_res = (uint24_t)zig_bitReverse_u8((uint8_t)(arg >> 0), 8) << 16 | |
| 1650 | (uint24_t)zig_bit_reverse_u16((uint16_t)(val >> 8), 16) >> 0; | 1820 | (uint24_t)zig_bitReverse_u16((uint16_t)(arg >> 8), 16) >> 0; |
| 1651 | #endif | 1821 | #endif |
| 1652 | return zig_wrap_u24(full_res >> (24 - bits), bits); | 1822 | return zig_u24_truncate_u24(full_res >> (24 - bits), bits); |
| 1653 | } | 1823 | } |
| 1654 | 1824 | ||
| 1655 | static inline int24_t zig_bit_reverse_i24(int24_t val, uint8_t bits) { | 1825 | static inline int24_t zig_bitReverse_i24(int24_t arg, uint8_t bits) { |
| 1656 | return zig_wrap_i24((int24_t)zig_bit_reverse_u24((uint24_t)val, bits), bits); | 1826 | return zig_i24_truncate_i24((int24_t)zig_bitReverse_u24((uint24_t)arg, bits), bits); |
| 1657 | } | 1827 | } |
| 1658 | #endif | 1828 | #endif |
| 1659 | 1829 | ||
| 1660 | static inline uint32_t zig_bit_reverse_u32(uint32_t val, uint8_t bits) { | 1830 | static inline uint32_t zig_bitReverse_u32(uint32_t arg, uint8_t bits) { |
| 1661 | uint32_t full_res; | 1831 | uint32_t full_res; |
| 1662 | #if zig_has_builtin(bitreverse32) | 1832 | #if zig_has_builtin(bitreverse32) |
| 1663 | full_res = __builtin_bitreverse32(val); | 1833 | full_res = __builtin_bitreverse32(arg); |
| 1664 | #else | 1834 | #else |
| 1665 | full_res = (uint32_t)zig_bit_reverse_u16((uint16_t)(val >> 0), 16) << 16 | | 1835 | full_res = (uint32_t)zig_bitReverse_u16((uint16_t)(arg >> 0), 16) << 16 | |
| 1666 | (uint32_t)zig_bit_reverse_u16((uint16_t)(val >> 16), 16) >> 0; | 1836 | (uint32_t)zig_bitReverse_u16((uint16_t)(arg >> 16), 16) >> 0; |
| 1667 | #endif | 1837 | #endif |
| 1668 | return zig_wrap_u32(full_res >> (32 - bits), bits); | 1838 | return zig_u32_truncate_u32(full_res >> (32 - bits), bits); |
| 1669 | } | 1839 | } |
| 1670 | 1840 | ||
| 1671 | static inline int32_t zig_bit_reverse_i32(int32_t val, uint8_t bits) { | 1841 | static inline int32_t zig_bitReverse_i32(int32_t arg, uint8_t bits) { |
| 1672 | return zig_wrap_i32((int32_t)zig_bit_reverse_u32((uint32_t)val, bits), bits); | 1842 | return zig_i32_truncate_i32((int32_t)zig_bitReverse_u32((uint32_t)arg, bits), bits); |
| 1673 | } | 1843 | } |
| 1674 | 1844 | ||
| 1675 | #if defined(zig_ez80) | 1845 | #if defined(zig_ez80) |
| 1676 | static inline uint32_t zig_bit_reverse_u48(uint48_t val, uint8_t bits) { | 1846 | static inline uint32_t zig_bitReverse_u48(uint48_t arg, uint8_t bits) { |
| 1677 | uint48_t full_res; | 1847 | uint48_t full_res; |
| 1678 | #if zig_has_builtin(bitreverse48) | 1848 | #if zig_has_builtin(bitreverse48) |
| 1679 | full_res = __builtin_bitreverse48(val); | 1849 | full_res = __builtin_bitreverse48(arg); |
| 1680 | #else | 1850 | #else |
| 1681 | full_res = (uint48_t)zig_bit_reverse_u24((uint24_t)(val >> 0), 24) << 24 | | 1851 | full_res = (uint48_t)zig_bitReverse_u24((uint24_t)(arg >> 0), 24) << 24 | |
| 1682 | (uint48_t)zig_bit_reverse_u24((uint24_t)(val >> 24), 24) >> 0; | 1852 | (uint48_t)zig_bitReverse_u24((uint24_t)(arg >> 24), 24) >> 0; |
| 1683 | #endif | 1853 | #endif |
| 1684 | return zig_wrap_u32(full_res >> (48 - bits), bits); | 1854 | return zig_u48_truncate_u48(full_res >> (48 - bits), bits); |
| 1685 | } | 1855 | } |
| 1686 | 1856 | ||
| 1687 | static inline int32_t zig_bit_reverse_i48(int48_t val, uint8_t bits) { | 1857 | static inline int32_t zig_bitReverse_i48(int48_t arg, uint8_t bits) { |
| 1688 | return zig_wrap_i48((int48_t)zig_bit_reverse_u48((uint48_t)val, bits), bits); | 1858 | return zig_i48_truncate_i48((int48_t)zig_bitReverse_u48((uint48_t)arg, bits), bits); |
| 1689 | } | 1859 | } |
| 1690 | #endif | 1860 | #endif |
| 1691 | 1861 | ||
| 1692 | static inline uint64_t zig_bit_reverse_u64(uint64_t val, uint8_t bits) { | 1862 | static inline uint64_t zig_bitReverse_u64(uint64_t arg, uint8_t bits) { |
| 1693 | uint64_t full_res; | 1863 | uint64_t full_res; |
| 1694 | #if zig_has_builtin(bitreverse64) | 1864 | #if zig_has_builtin(bitreverse64) |
| 1695 | full_res = __builtin_bitreverse64(val); | 1865 | full_res = __builtin_bitreverse64(arg); |
| 1696 | #else | 1866 | #else |
| 1697 | full_res = (uint64_t)zig_bit_reverse_u32((uint32_t)(val >> 0), 32) << 32 | | 1867 | full_res = (uint64_t)zig_bitReverse_u32((uint32_t)(arg >> 0), 32) << 32 | |
| 1698 | (uint64_t)zig_bit_reverse_u32((uint32_t)(val >> 32), 32) >> 0; | 1868 | (uint64_t)zig_bitReverse_u32((uint32_t)(arg >> 32), 32) >> 0; |
| 1699 | #endif | 1869 | #endif |
| 1700 | return zig_wrap_u64(full_res >> (64 - bits), bits); | 1870 | return zig_u64_truncate_u64(full_res >> (64 - bits), bits); |
| 1701 | } | 1871 | } |
| 1702 | 1872 | ||
| 1703 | static inline int64_t zig_bit_reverse_i64(int64_t val, uint8_t bits) { | 1873 | static inline int64_t zig_bitReverse_i64(int64_t arg, uint8_t bits) { |
| 1704 | return zig_wrap_i64((int64_t)zig_bit_reverse_u64((uint64_t)val, bits), bits); | 1874 | return zig_i64_truncate_i64((int64_t)zig_bitReverse_u64((uint64_t)arg, bits), bits); |
| 1705 | } | 1875 | } |
| 1706 | 1876 | ||
| 1707 | #define zig_builtin_popcount_common(w) \ | 1877 | #define zig_builtin_popCount_common(w) \ |
| 1708 | static inline uint8_t zig_popcount_i##w(int##w##_t val, uint8_t bits) { \ | 1878 | static inline uint8_t zig_popCount_i##w(int##w##_t arg, uint8_t bits) { \ |
| 1709 | return zig_popcount_u##w((uint##w##_t)val, bits); \ | 1879 | return zig_popCount_u##w((uint##w##_t)arg, bits); \ |
| 1710 | } | 1880 | } |
| 1711 | #if zig_has_builtin(popcount) || defined(zig_gcc) || defined(zig_tinyc) | 1881 | #if zig_has_builtin(popCount) || defined(zig_gcc) || defined(zig_tinyc) |
| 1712 | #define zig_builtin_popcount(w) \ | 1882 | #define zig_builtin_popCount(w) \ |
| 1713 | static inline uint8_t zig_popcount_u##w(uint##w##_t val, uint8_t bits) { \ | 1883 | static inline uint8_t zig_popCount_u##w(uint##w##_t arg, uint8_t bits) { \ |
| 1714 | (void)bits; \ | 1884 | (void)bits; \ |
| 1715 | return zig_builtin##w(popcount, val); \ | 1885 | return zig_builtin##w(popcount, arg); \ |
| 1716 | } \ | 1886 | } \ |
| 1717 | \ | 1887 | \ |
| 1718 | zig_builtin_popcount_common(w) | 1888 | zig_builtin_popCount_common(w) |
| 1719 | #else | 1889 | #else |
| 1720 | #define zig_builtin_popcount(w) \ | 1890 | #define zig_builtin_popCount(w) \ |
| 1721 | static inline uint8_t zig_popcount_u##w(uint##w##_t val, uint8_t bits) { \ | 1891 | static inline uint8_t zig_popCount_u##w(uint##w##_t arg, uint8_t bits) { \ |
| 1722 | (void)bits; \ | 1892 | (void)bits; \ |
| 1723 | uint##w##_t temp = val - ((val >> 1) & (UINT##w##_MAX / 3)); \ | 1893 | uint##w##_t temp = arg - ((arg >> 1) & (UINT##w##_MAX / 3)); \ |
| 1724 | temp = (temp & (UINT##w##_MAX / 5)) + ((temp >> 2) & (UINT##w##_MAX / 5)); \ | 1894 | temp = (temp & (UINT##w##_MAX / 5)) + ((temp >> 2) & (UINT##w##_MAX / 5)); \ |
| 1725 | temp = (temp + (temp >> 4)) & (UINT##w##_MAX / 17); \ | 1895 | temp = (temp + (temp >> 4)) & (UINT##w##_MAX / 17); \ |
| 1726 | return temp * (UINT##w##_MAX / 255) >> (UINT8_C(w) - UINT8_C(8)); \ | 1896 | return temp * (UINT##w##_MAX / 255) >> (UINT8_C(w) - UINT8_C(8)); \ |
| 1727 | } \ | 1897 | } \ |
| 1728 | \ | 1898 | \ |
| 1729 | zig_builtin_popcount_common(w) | 1899 | zig_builtin_popCount_common(w) |
| 1730 | #endif | ||
| 1731 | zig_builtin_popcount(8) | ||
| 1732 | zig_builtin_popcount(16) | ||
| 1733 | #if defined(zig_ez80) | ||
| 1734 | zig_builtin_popcount(24) | ||
| 1735 | #endif | 1900 | #endif |
| 1736 | zig_builtin_popcount(32) | 1901 | zig_builtin_popCount(8) |
| 1902 | zig_builtin_popCount(16) | ||
| 1903 | zig_builtin_popCount(32) | ||
| 1904 | zig_builtin_popCount(64) | ||
| 1737 | #if defined(zig_ez80) | 1905 | #if defined(zig_ez80) |
| 1738 | zig_builtin_popcount(48) | 1906 | zig_builtin_popCount(24) |
| 1907 | zig_builtin_popCount(48) | ||
| 1739 | #endif | 1908 | #endif |
| 1740 | zig_builtin_popcount(64) | ||
| 1741 | 1909 | ||
| 1742 | #define zig_builtin_ctz_common(w) \ | 1910 | #define zig_builtin_ctz_common(w) \ |
| 1743 | static inline uint8_t zig_ctz_i##w(int##w##_t val, uint8_t bits) { \ | 1911 | static inline uint8_t zig_ctz_i##w(int##w##_t arg, uint8_t bits) { \ |
| 1744 | return zig_ctz_u##w((uint##w##_t)val, bits); \ | 1912 | return zig_ctz_u##w((uint##w##_t)arg, bits); \ |
| 1745 | } | 1913 | } |
| 1746 | #if zig_has_builtin(ctz) || defined(zig_gcc) || defined(zig_tinyc) | 1914 | #if zig_has_builtin(ctz) || defined(zig_gcc) || defined(zig_tinyc) |
| 1747 | #define zig_builtin_ctz(w) \ | 1915 | #define zig_builtin_ctz(w) \ |
| 1748 | static inline uint8_t zig_ctz_u##w(uint##w##_t val, uint8_t bits) { \ | 1916 | static inline uint8_t zig_ctz_u##w(uint##w##_t arg, uint8_t bits) { \ |
| 1749 | if (val == 0) return bits; \ | 1917 | if (arg == 0) return bits; \ |
| 1750 | return zig_builtin##w(ctz, val); \ | 1918 | return zig_builtin##w(ctz, arg); \ |
| 1751 | } \ | 1919 | } \ |
| 1752 | \ | 1920 | \ |
| 1753 | zig_builtin_ctz_common(w) | 1921 | zig_builtin_ctz_common(w) |
| 1754 | #else | 1922 | #else |
| 1755 | #define zig_builtin_ctz(w) \ | 1923 | #define zig_builtin_ctz(w) \ |
| 1756 | static inline uint8_t zig_ctz_u##w(uint##w##_t val, uint8_t bits) { \ | 1924 | static inline uint8_t zig_ctz_u##w(uint##w##_t arg, uint8_t bits) { \ |
| 1757 | return zig_popcount_u##w(zig_not_u##w(val, bits) & zig_subw_u##w(val, 1, bits), bits); \ | 1925 | return zig_popCount_u##w(zig_not_u##w(arg, bits) & zig_subw_u##w(arg, 1, bits), bits); \ |
| 1758 | } \ | 1926 | } \ |
| 1759 | \ | 1927 | \ |
| 1760 | zig_builtin_ctz_common(w) | 1928 | zig_builtin_ctz_common(w) |
| 1761 | #endif | 1929 | #endif |
| 1762 | zig_builtin_ctz(8) | 1930 | zig_builtin_ctz(8) |
| 1763 | zig_builtin_ctz(16) | 1931 | zig_builtin_ctz(16) |
| 1764 | #if defined(zig_ez80) | ||
| 1765 | zig_builtin_ctz(24) | ||
| 1766 | #endif | ||
| 1767 | zig_builtin_ctz(32) | 1932 | zig_builtin_ctz(32) |
| 1933 | zig_builtin_ctz(64) | ||
| 1768 | #if defined(zig_ez80) | 1934 | #if defined(zig_ez80) |
| 1935 | zig_builtin_ctz(24) | ||
| 1769 | zig_builtin_ctz(48) | 1936 | zig_builtin_ctz(48) |
| 1770 | #endif | 1937 | #endif |
| 1771 | zig_builtin_ctz(64) | ||
| 1772 | 1938 | ||
| 1773 | #define zig_builtin_clz_common(w) \ | 1939 | #define zig_builtin_clz_common(w) \ |
| 1774 | static inline uint8_t zig_clz_i##w(int##w##_t val, uint8_t bits) { \ | 1940 | static inline uint8_t zig_clz_i##w(int##w##_t arg, uint8_t bits) { \ |
| 1775 | return zig_clz_u##w((uint##w##_t)val, bits); \ | 1941 | return zig_clz_u##w((uint##w##_t)arg, bits); \ |
| 1776 | } | 1942 | } |
| 1777 | #if zig_has_builtin(clz) || defined(zig_gcc) || defined(zig_tinyc) | 1943 | #if zig_has_builtin(clz) || defined(zig_gcc) || defined(zig_tinyc) |
| 1778 | #define zig_builtin_clz(w) \ | 1944 | #define zig_builtin_clz(w) \ |
| 1779 | static inline uint8_t zig_clz_u##w(uint##w##_t val, uint8_t bits) { \ | 1945 | static inline uint8_t zig_clz_u##w(uint##w##_t arg, uint8_t bits) { \ |
| 1780 | if (val == 0) return bits; \ | 1946 | if (arg == 0) return bits; \ |
| 1781 | return zig_builtin##w(clz, val) - (zig_bitSizeOf(zig_Builtin##w) - bits); \ | 1947 | return zig_builtin##w(clz, arg) - (zig_bitSizeOf(zig_Builtin##w) - bits); \ |
| 1782 | } \ | 1948 | } \ |
| 1783 | \ | 1949 | \ |
| 1784 | zig_builtin_clz_common(w) | 1950 | zig_builtin_clz_common(w) |
| 1785 | #else | 1951 | #else |
| 1786 | #define zig_builtin_clz(w) \ | 1952 | #define zig_builtin_clz(w) \ |
| 1787 | static inline uint8_t zig_clz_u##w(uint##w##_t val, uint8_t bits) { \ | 1953 | static inline uint8_t zig_clz_u##w(uint##w##_t arg, uint8_t bits) { \ |
| 1788 | return zig_ctz_u##w(zig_bit_reverse_u##w(val, bits), bits); \ | 1954 | return zig_ctz_u##w(zig_bitReverse_u##w(arg, bits), bits); \ |
| 1789 | } \ | 1955 | } \ |
| 1790 | \ | 1956 | \ |
| 1791 | zig_builtin_clz_common(w) | 1957 | zig_builtin_clz_common(w) |
| 1792 | #endif | 1958 | #endif |
| 1793 | zig_builtin_clz(8) | 1959 | zig_builtin_clz(8) |
| 1794 | zig_builtin_clz(16) | 1960 | zig_builtin_clz(16) |
| 1795 | #if defined(zig_ez80) | ||
| 1796 | zig_builtin_clz(24) | ||
| 1797 | #endif | ||
| 1798 | zig_builtin_clz(32) | 1961 | zig_builtin_clz(32) |
| 1962 | zig_builtin_clz(64) | ||
| 1799 | #if defined(zig_ez80) | 1963 | #if defined(zig_ez80) |
| 1964 | zig_builtin_clz(24) | ||
| 1800 | zig_builtin_clz(48) | 1965 | zig_builtin_clz(48) |
| 1801 | #endif | 1966 | #endif |
| 1802 | zig_builtin_clz(64) | ||
| 1803 | 1967 | ||
| 1804 | /* ======================== 128-bit Integer Support ========================= */ | 1968 | /* ======================== 128-bit Integer Support ========================= */ |
| 1805 | 1969 | ||
| ... | @@ -1816,16 +1980,14 @@ zig_builtin_clz(64) | ... | @@ -1816,16 +1980,14 @@ zig_builtin_clz(64) |
| 1816 | typedef unsigned __int128 zig_u128; | 1980 | typedef unsigned __int128 zig_u128; |
| 1817 | typedef signed __int128 zig_i128; | 1981 | typedef signed __int128 zig_i128; |
| 1818 | 1982 | ||
| 1819 | #define zig_make_u128(hi, lo) ((zig_u128)(hi)<<64|(lo)) | 1983 | #define zig_init_u128(hi, lo) ((zig_u128)(hi)<<64|(lo)) |
| 1820 | #define zig_make_i128(hi, lo) ((zig_i128)zig_make_u128(hi, lo)) | 1984 | #define zig_init_i128(hi, lo) ((zig_i128)zig_make_u128(hi, lo)) |
| 1821 | #define zig_init_u128(hi, lo) zig_make_u128(hi, lo) | 1985 | #define zig_make_u128(hi, lo) zig_init_u128(hi, lo) |
| 1822 | #define zig_init_i128(hi, lo) zig_make_i128(hi, lo) | 1986 | #define zig_make_i128(hi, lo) zig_init_i128(hi, lo) |
| 1823 | #define zig_hi_u128(val) ((uint64_t)((val) >> 64)) | 1987 | #define zig_hi_u128(arg) ((uint64_t)((arg) >> 64)) |
| 1824 | #define zig_lo_u128(val) ((uint64_t)((val) >> 0)) | 1988 | #define zig_lo_u128(arg) ((uint64_t)((arg) >> 0)) |
| 1825 | #define zig_hi_i128(val) (( int64_t)((val) >> 64)) | 1989 | #define zig_hi_i128(arg) (( int64_t)((arg) >> 64)) |
| 1826 | #define zig_lo_i128(val) ((uint64_t)((val) >> 0)) | 1990 | #define zig_lo_i128(arg) ((uint64_t)((arg) >> 0)) |
| 1827 | #define zig_bitCast_u128(val) ((zig_u128)(val)) | ||
| 1828 | #define zig_bitCast_i128(val) ((zig_i128)(val)) | ||
| 1829 | #define zig_cmp_int128(Type) \ | 1991 | #define zig_cmp_int128(Type) \ |
| 1830 | static inline int32_t zig_cmp_##Type(zig_##Type lhs, zig_##Type rhs) { \ | 1992 | static inline int32_t zig_cmp_##Type(zig_##Type lhs, zig_##Type rhs) { \ |
| 1831 | return (lhs > rhs) - (lhs < rhs); \ | 1993 | return (lhs > rhs) - (lhs < rhs); \ |
| ... | @@ -1835,32 +1997,49 @@ typedef signed __int128 zig_i128; | ... | @@ -1835,32 +1997,49 @@ typedef signed __int128 zig_i128; |
| 1835 | return lhs operator rhs; \ | 1997 | return lhs operator rhs; \ |
| 1836 | } | 1998 | } |
| 1837 | 1999 | ||
| 1838 | #else /* zig_has_int128 */ | 2000 | static inline zig_u128 zig_shl_u128(zig_u128 lhs, uint8_t rhs) { |
| 2001 | return lhs << rhs; | ||
| 2002 | } | ||
| 1839 | 2003 | ||
| 1840 | #if zig_little_endian | 2004 | static inline zig_u128 zig_shr_u128(zig_u128 lhs, uint8_t rhs) { |
| 1841 | typedef struct { zig_align(16) uint64_t lo; uint64_t hi; } zig_u128; | 2005 | return lhs >> rhs; |
| 1842 | typedef struct { zig_align(16) uint64_t lo; int64_t hi; } zig_i128; | 2006 | } |
| 2007 | |||
| 2008 | static inline zig_i128 zig_shl_i128(zig_i128 lhs, uint8_t rhs) { | ||
| 2009 | return lhs << rhs; | ||
| 2010 | } | ||
| 2011 | |||
| 2012 | static inline zig_i128 zig_shr_i128(zig_i128 lhs, uint8_t rhs) { | ||
| 2013 | // This works around a GCC miscompilation, but it has the side benefit of | ||
| 2014 | // emitting better code. It is behind the `#if` because it depends on | ||
| 2015 | // arithmetic right shift, which is implementation-defined in C, but should | ||
| 2016 | // be guaranteed on any GCC-compatible compiler. | ||
| 2017 | #if defined(zig_gnuc) | ||
| 2018 | return lhs >> rhs; | ||
| 1843 | #else | 2019 | #else |
| 1844 | typedef struct { zig_align(16) uint64_t hi; uint64_t lo; } zig_u128; | 2020 | zig_i128 sign_mask = lhs < zig_make_i128(0, 0) ? -zig_make_i128(0, 1) : zig_make_i128(0, 0); |
| 1845 | typedef struct { zig_align(16) int64_t hi; uint64_t lo; } zig_i128; | 2021 | return ((lhs ^ sign_mask) >> rhs) ^ sign_mask; |
| 1846 | #endif | 2022 | #endif |
| 2023 | } | ||
| 1847 | 2024 | ||
| 1848 | #define zig_make_u128(hi, lo) ((zig_u128){ .h##i = (hi), .l##o = (lo) }) | 2025 | #else /* zig_has_int128 */ |
| 1849 | #define zig_make_i128(hi, lo) ((zig_i128){ .h##i = (hi), .l##o = (lo) }) | ||
| 1850 | 2026 | ||
| 1851 | #if defined(zig_msvc) /* MSVC doesn't allow struct literals in constant expressions */ | 2027 | #if zig_little_endian |
| 1852 | #define zig_init_u128(hi, lo) { .h##i = (hi), .l##o = (lo) } | 2028 | typedef struct { zig_align(ZIG_TARGET_MAX_INT_ALIGNMENT) uint64_t lo; uint64_t hi; } zig_u128; |
| 1853 | #define zig_init_i128(hi, lo) { .h##i = (hi), .l##o = (lo) } | 2029 | typedef struct { zig_align(ZIG_TARGET_MAX_INT_ALIGNMENT) uint64_t lo; int64_t hi; } zig_i128; |
| 1854 | #else /* But non-MSVC doesn't like the unprotected commas */ | 2030 | #else |
| 1855 | #define zig_init_u128(hi, lo) zig_make_u128(hi, lo) | 2031 | typedef struct { zig_align(ZIG_TARGET_MAX_INT_ALIGNMENT) uint64_t hi; uint64_t lo; } zig_u128; |
| 1856 | #define zig_init_i128(hi, lo) zig_make_i128(hi, lo) | 2032 | typedef struct { zig_align(ZIG_TARGET_MAX_INT_ALIGNMENT) int64_t hi; uint64_t lo; } zig_i128; |
| 1857 | #endif | 2033 | #endif |
| 1858 | #define zig_hi_u128(val) ((val).hi) | 2034 | |
| 1859 | #define zig_lo_u128(val) ((val).lo) | 2035 | #define zig_init_u128(hi, lo) { .h##i = hi, .l##o = lo } |
| 1860 | #define zig_hi_i128(val) ((val).hi) | 2036 | #define zig_init_i128(hi, lo) { .h##i = hi, .l##o = lo } |
| 1861 | #define zig_lo_i128(val) ((val).lo) | 2037 | #define zig_make_u128(hi, lo) (zig_u128)zig_init_u128(hi, lo) |
| 1862 | #define zig_bitCast_u128(val) zig_make_u128((uint64_t)(val).hi, (val).lo) | 2038 | #define zig_make_i128(hi, lo) (zig_i128)zig_init_i128(hi, lo) |
| 1863 | #define zig_bitCast_i128(val) zig_make_i128(( int64_t)(val).hi, (val).lo) | 2039 | #define zig_hi_u128(arg) (arg).hi |
| 2040 | #define zig_lo_u128(arg) (arg).lo | ||
| 2041 | #define zig_hi_i128(arg) (arg).hi | ||
| 2042 | #define zig_lo_i128(arg) (arg).lo | ||
| 1864 | #define zig_cmp_int128(Type) \ | 2043 | #define zig_cmp_int128(Type) \ |
| 1865 | static inline int32_t zig_cmp_##Type(zig_##Type lhs, zig_##Type rhs) { \ | 2044 | static inline int32_t zig_cmp_##Type(zig_##Type lhs, zig_##Type rhs) { \ |
| 1866 | return (lhs.hi == rhs.hi) \ | 2045 | return (lhs.hi == rhs.hi) \ |
| ... | @@ -1872,6 +2051,30 @@ typedef struct { zig_align(16) int64_t hi; uint64_t lo; } zig_i128; | ... | @@ -1872,6 +2051,30 @@ typedef struct { zig_align(16) int64_t hi; uint64_t lo; } zig_i128; |
| 1872 | return (zig_##Type){ .hi = lhs.hi operator rhs.hi, .lo = lhs.lo operator rhs.lo }; \ | 2051 | return (zig_##Type){ .hi = lhs.hi operator rhs.hi, .lo = lhs.lo operator rhs.lo }; \ |
| 1873 | } | 2052 | } |
| 1874 | 2053 | ||
| 2054 | static inline zig_u128 zig_shl_u128(zig_u128 lhs, uint8_t rhs) { | ||
| 2055 | if (rhs == UINT8_C(0)) return lhs; | ||
| 2056 | if (rhs >= UINT8_C(64)) return (zig_u128){ .hi = lhs.lo << (rhs - UINT8_C(64)), .lo = zig_minInt_u64 }; | ||
| 2057 | return (zig_u128){ .hi = lhs.hi << rhs | lhs.lo >> (UINT8_C(64) - rhs), .lo = lhs.lo << rhs }; | ||
| 2058 | } | ||
| 2059 | |||
| 2060 | static inline zig_u128 zig_shr_u128(zig_u128 lhs, uint8_t rhs) { | ||
| 2061 | if (rhs == UINT8_C(0)) return lhs; | ||
| 2062 | if (rhs >= UINT8_C(64)) return (zig_u128){ .hi = zig_minInt_u64, .lo = lhs.hi >> (rhs - UINT8_C(64)) }; | ||
| 2063 | return (zig_u128){ .hi = lhs.hi >> rhs, .lo = lhs.hi << (UINT8_C(64) - rhs) | lhs.lo >> rhs }; | ||
| 2064 | } | ||
| 2065 | |||
| 2066 | static inline zig_i128 zig_shl_i128(zig_i128 lhs, uint8_t rhs) { | ||
| 2067 | if (rhs == UINT8_C(0)) return lhs; | ||
| 2068 | if (rhs >= UINT8_C(64)) return (zig_i128){ .hi = lhs.lo << (rhs - UINT8_C(64)), .lo = zig_minInt_u64 }; | ||
| 2069 | return (zig_i128){ .hi = lhs.hi << rhs | lhs.lo >> (UINT8_C(64) - rhs), .lo = lhs.lo << rhs }; | ||
| 2070 | } | ||
| 2071 | |||
| 2072 | static inline zig_i128 zig_shr_i128(zig_i128 lhs, uint8_t rhs) { | ||
| 2073 | if (rhs == UINT8_C(0)) return lhs; | ||
| 2074 | if (rhs >= UINT8_C(64)) return (zig_i128){ .hi = zig_shr_i64(lhs.hi, 63), .lo = zig_shr_i64(lhs.hi, (rhs - UINT8_C(64))) }; | ||
| 2075 | return (zig_i128){ .hi = zig_shr_i64(lhs.hi, rhs), .lo = lhs.lo >> rhs | (uint64_t)lhs.hi << (UINT8_C(64) - rhs) }; | ||
| 2076 | } | ||
| 2077 | |||
| 1875 | #endif /* zig_has_int128 */ | 2078 | #endif /* zig_has_int128 */ |
| 1876 | 2079 | ||
| 1877 | #define zig_minInt_u128 zig_make_u128(zig_minInt_u64, zig_minInt_u64) | 2080 | #define zig_minInt_u128 zig_make_u128(zig_minInt_u64, zig_minInt_u64) |
| ... | @@ -1891,42 +2094,177 @@ zig_bit_int128(i128, or, |) | ... | @@ -1891,42 +2094,177 @@ zig_bit_int128(i128, or, |) |
| 1891 | zig_bit_int128(u128, xor, ^) | 2094 | zig_bit_int128(u128, xor, ^) |
| 1892 | zig_bit_int128(i128, xor, ^) | 2095 | zig_bit_int128(i128, xor, ^) |
| 1893 | 2096 | ||
| 1894 | static inline zig_u128 zig_shr_u128(zig_u128 lhs, uint8_t rhs); | 2097 | static inline uint8_t zig_u8_intCast_u128(zig_u128 arg) { |
| 2098 | return (uint8_t)zig_lo_u128(arg); | ||
| 2099 | } | ||
| 2100 | static inline uint8_t zig_u8_intCast_i128(zig_i128 arg) { | ||
| 2101 | return (uint8_t)zig_lo_i128(arg); | ||
| 2102 | } | ||
| 2103 | static inline int8_t zig_i8_intCast_i128(zig_i128 arg) { | ||
| 2104 | return (int8_t)zig_lo_i128(arg); | ||
| 2105 | } | ||
| 2106 | static inline int8_t zig_i8_intCast_u128(zig_u128 arg) { | ||
| 2107 | return (int8_t)zig_lo_u128(arg); | ||
| 2108 | } | ||
| 1895 | 2109 | ||
| 1896 | #if zig_has_int128 | 2110 | static inline uint16_t zig_u16_intCast_u128(zig_u128 arg) { |
| 2111 | return (uint16_t)zig_lo_u128(arg); | ||
| 2112 | } | ||
| 2113 | static inline uint16_t zig_u16_intCast_i128(zig_i128 arg) { | ||
| 2114 | return (uint16_t)zig_lo_i128(arg); | ||
| 2115 | } | ||
| 2116 | static inline int16_t zig_i16_intCast_i128(zig_i128 arg) { | ||
| 2117 | return (int16_t)zig_lo_i128(arg); | ||
| 2118 | } | ||
| 2119 | static inline int16_t zig_i16_intCast_u128(zig_u128 arg) { | ||
| 2120 | return (int16_t)zig_lo_u128(arg); | ||
| 2121 | } | ||
| 1897 | 2122 | ||
| 1898 | static inline zig_u128 zig_not_u128(zig_u128 val, uint8_t bits) { | 2123 | static inline uint32_t zig_u32_intCast_u128(zig_u128 arg) { |
| 1899 | return val ^ zig_maxInt_u(128, bits); | 2124 | return (uint32_t)zig_lo_u128(arg); |
| 2125 | } | ||
| 2126 | static inline uint32_t zig_u32_intCast_i128(zig_i128 arg) { | ||
| 2127 | return (uint32_t)zig_lo_i128(arg); | ||
| 2128 | } | ||
| 2129 | static inline int32_t zig_i32_intCast_i128(zig_i128 arg) { | ||
| 2130 | return (int32_t)zig_lo_i128(arg); | ||
| 2131 | } | ||
| 2132 | static inline int32_t zig_i32_intCast_u128(zig_u128 arg) { | ||
| 2133 | return (int32_t)zig_lo_u128(arg); | ||
| 1900 | } | 2134 | } |
| 1901 | 2135 | ||
| 1902 | static inline zig_i128 zig_not_i128(zig_i128 val, uint8_t bits) { | 2136 | static inline uint64_t zig_u64_intCast_u128(zig_u128 arg) { |
| 1903 | (void)bits; | 2137 | return zig_lo_u128(arg); |
| 1904 | return ~val; | 2138 | } |
| 2139 | static inline uint64_t zig_u64_intCast_i128(zig_i128 arg) { | ||
| 2140 | return zig_lo_i128(arg); | ||
| 2141 | } | ||
| 2142 | static inline int64_t zig_i64_intCast_i128(zig_i128 arg) { | ||
| 2143 | return (int64_t)zig_lo_i128(arg); | ||
| 2144 | } | ||
| 2145 | static inline int64_t zig_i64_intCast_u128(zig_u128 arg) { | ||
| 2146 | return (int64_t)zig_lo_u128(arg); | ||
| 1905 | } | 2147 | } |
| 1906 | 2148 | ||
| 1907 | static inline zig_u128 zig_shr_u128(zig_u128 lhs, uint8_t rhs) { | 2149 | static inline zig_u128 zig_u128_intCast_u8(uint8_t arg) { |
| 1908 | return lhs >> rhs; | 2150 | return zig_make_u128(UINT8_C(0), arg); |
| 2151 | } | ||
| 2152 | static inline zig_u128 zig_u128_intCast_i8(int8_t arg) { | ||
| 2153 | return zig_make_u128(UINT8_C(0), (uint8_t)arg); | ||
| 2154 | } | ||
| 2155 | static inline zig_i128 zig_i128_intCast_i8(int8_t arg) { | ||
| 2156 | return zig_make_i128(zig_shr_i64(arg, 63), (uint8_t)arg); | ||
| 2157 | } | ||
| 2158 | static inline zig_i128 zig_i128_intCast_u8(uint8_t arg) { | ||
| 2159 | return zig_make_i128(INT8_C(0), arg); | ||
| 1909 | } | 2160 | } |
| 1910 | 2161 | ||
| 1911 | static inline zig_u128 zig_shl_u128(zig_u128 lhs, uint8_t rhs) { | 2162 | static inline zig_u128 zig_u128_intCast_u16(uint16_t arg) { |
| 1912 | return lhs << rhs; | 2163 | return zig_make_u128(UINT16_C(0), arg); |
| 2164 | } | ||
| 2165 | static inline zig_u128 zig_u128_intCast_i16(int16_t arg) { | ||
| 2166 | return zig_make_u128(UINT16_C(0), (uint16_t)arg); | ||
| 2167 | } | ||
| 2168 | static inline zig_i128 zig_i128_intCast_i16(int16_t arg) { | ||
| 2169 | return zig_make_i128(zig_shr_i64(arg, 63), (uint16_t)arg); | ||
| 2170 | } | ||
| 2171 | static inline zig_i128 zig_i128_intCast_u16(uint16_t arg) { | ||
| 2172 | return zig_make_i128(INT16_C(0), arg); | ||
| 1913 | } | 2173 | } |
| 1914 | 2174 | ||
| 1915 | static inline zig_i128 zig_shr_i128(zig_i128 lhs, uint8_t rhs) { | 2175 | static inline zig_u128 zig_u128_intCast_u32(uint32_t arg) { |
| 1916 | // This works around a GCC miscompilation, but it has the side benefit of | 2176 | return zig_make_u128(UINT32_C(0), arg); |
| 1917 | // emitting better code. It is behind the `#if` because it depends on | 2177 | } |
| 1918 | // arithmetic right shift, which is implementation-defined in C, but should | 2178 | static inline zig_u128 zig_u128_intCast_i32(int32_t arg) { |
| 1919 | // be guaranteed on any GCC-compatible compiler. | 2179 | return zig_make_u128(UINT32_C(0), (uint32_t)arg); |
| 1920 | #if defined(zig_gnuc) | 2180 | } |
| 1921 | return lhs >> rhs; | 2181 | static inline zig_i128 zig_i128_intCast_i32(int32_t arg) { |
| 2182 | return zig_make_i128(zig_shr_i64(arg, 63), (uint32_t)arg); | ||
| 2183 | } | ||
| 2184 | static inline zig_i128 zig_i128_intCast_u32(uint32_t arg) { | ||
| 2185 | return zig_make_i128(INT32_C(0), arg); | ||
| 2186 | } | ||
| 2187 | |||
| 2188 | static inline zig_u128 zig_u128_intCast_u64(uint64_t arg) { | ||
| 2189 | return zig_make_u128(UINT64_C(0), arg); | ||
| 2190 | } | ||
| 2191 | static inline zig_u128 zig_u128_intCast_i64(int64_t arg) { | ||
| 2192 | return zig_make_u128(UINT64_C(0), (uint64_t)arg); | ||
| 2193 | } | ||
| 2194 | static inline zig_i128 zig_i128_intCast_i64(int64_t arg) { | ||
| 2195 | return zig_make_i128(zig_shr_i64(arg, 63), (uint64_t)arg); | ||
| 2196 | } | ||
| 2197 | static inline zig_i128 zig_i128_intCast_u64(uint64_t arg) { | ||
| 2198 | return zig_make_i128(INT64_C(0), arg); | ||
| 2199 | } | ||
| 2200 | |||
| 2201 | static inline zig_u128 zig_u128_intCast_u128(zig_u128 arg) { | ||
| 2202 | return arg; | ||
| 2203 | } | ||
| 2204 | static inline zig_u128 zig_u128_intCast_i128(zig_i128 arg) { | ||
| 2205 | #if zig_has_int128 | ||
| 2206 | return (zig_u128)arg; | ||
| 1922 | #else | 2207 | #else |
| 1923 | zig_i128 sign_mask = lhs < zig_make_i128(0, 0) ? -zig_make_i128(0, 1) : zig_make_i128(0, 0); | 2208 | return zig_make_u128(zig_u64_bitCast_i64(zig_hi_i128(arg), UINT8_C(64)), zig_lo_u128(arg)); |
| 1924 | return ((lhs ^ sign_mask) >> rhs) ^ sign_mask; | 2209 | #endif |
| 2210 | } | ||
| 2211 | static inline zig_i128 zig_i128_intCast_i128(zig_i128 arg) { | ||
| 2212 | return arg; | ||
| 2213 | } | ||
| 2214 | static inline zig_i128 zig_i128_intCast_u128(zig_u128 arg) { | ||
| 2215 | #if zig_has_int128 | ||
| 2216 | return (zig_i128)arg; | ||
| 2217 | #else | ||
| 2218 | return zig_make_i128(zig_i64_bitCast_u64(zig_hi_i128(arg), UINT8_C(64)), zig_lo_u128(arg)); | ||
| 1925 | #endif | 2219 | #endif |
| 1926 | } | 2220 | } |
| 1927 | 2221 | ||
| 1928 | static inline zig_i128 zig_shl_i128(zig_i128 lhs, uint8_t rhs) { | 2222 | #define zig_int128_cast_builtins(w) \ |
| 1929 | return lhs << rhs; | 2223 | static inline uint##w##_t zig_u##w##_truncate_u128(zig_u128 arg, uint8_t bits) { \ |
| 2224 | return zig_u##w##_truncate_u##w((uint##w##_t)zig_lo_u128(arg), bits); \ | ||
| 2225 | } \ | ||
| 2226 | \ | ||
| 2227 | static inline int##w##_t zig_i##w##_truncate_i128(zig_i128 arg, uint8_t bits) { \ | ||
| 2228 | return zig_i##w##_truncate_i##w((int##w##_t)zig_lo_i128(arg), bits); \ | ||
| 2229 | } | ||
| 2230 | zig_int128_cast_builtins(8) | ||
| 2231 | zig_int128_cast_builtins(16) | ||
| 2232 | zig_int128_cast_builtins(32) | ||
| 2233 | zig_int128_cast_builtins(64) | ||
| 2234 | |||
| 2235 | static inline zig_u128 zig_u128_truncate_u128(zig_u128 arg, uint8_t bits) { | ||
| 2236 | return zig_and_u128(arg, zig_maxInt_u(128, bits)); | ||
| 2237 | } | ||
| 2238 | static inline zig_i128 zig_i128_truncate_i128(zig_i128 arg, uint8_t bits) { | ||
| 2239 | if (bits > UINT8_C(64)) return zig_make_i128(zig_i64_truncate_i64(zig_hi_i128(arg), bits - UINT8_C(64)), zig_lo_i128(arg)); | ||
| 2240 | int64_t lo = zig_i64_truncate_i128(arg, bits); | ||
| 2241 | return zig_make_i128(zig_shr_i64(lo, 63), (uint64_t)lo); | ||
| 2242 | } | ||
| 2243 | |||
| 2244 | static inline zig_u128 zig_u128_bitCast_u128(zig_u128 arg, uint8_t bits) { | ||
| 2245 | (void)bits; | ||
| 2246 | return arg; | ||
| 2247 | } | ||
| 2248 | static inline zig_u128 zig_u128_bitCast_i128(zig_i128 arg, uint8_t bits) { | ||
| 2249 | return zig_u128_truncate_u128(zig_u128_intCast_i128(arg), bits); | ||
| 2250 | } | ||
| 2251 | static inline zig_i128 zig_i128_bitCast_i128(zig_i128 arg, uint8_t bits) { | ||
| 2252 | (void)bits; | ||
| 2253 | return arg; | ||
| 2254 | } | ||
| 2255 | static inline zig_i128 zig_i128_bitCast_u128(zig_u128 arg, uint8_t bits) { | ||
| 2256 | return zig_i128_truncate_i128(zig_i128_intCast_u128(arg), bits); | ||
| 2257 | } | ||
| 2258 | |||
| 2259 | #if zig_has_int128 | ||
| 2260 | |||
| 2261 | static inline zig_u128 zig_not_u128(zig_u128 arg, uint8_t bits) { | ||
| 2262 | return arg ^ zig_maxInt_u(128, bits); | ||
| 2263 | } | ||
| 2264 | |||
| 2265 | static inline zig_i128 zig_not_i128(zig_i128 arg, uint8_t bits) { | ||
| 2266 | (void)bits; | ||
| 2267 | return ~arg; | ||
| 1930 | } | 2268 | } |
| 1931 | 2269 | ||
| 1932 | static inline zig_u128 zig_add_u128(zig_u128 lhs, zig_u128 rhs) { | 2270 | static inline zig_u128 zig_add_u128(zig_u128 lhs, zig_u128 rhs) { |
| ... | @@ -1953,11 +2291,11 @@ static inline zig_i128 zig_mul_i128(zig_i128 lhs, zig_i128 rhs) { | ... | @@ -1953,11 +2291,11 @@ static inline zig_i128 zig_mul_i128(zig_i128 lhs, zig_i128 rhs) { |
| 1953 | return lhs * rhs; | 2291 | return lhs * rhs; |
| 1954 | } | 2292 | } |
| 1955 | 2293 | ||
| 1956 | static inline zig_u128 zig_div_trunc_u128(zig_u128 lhs, zig_u128 rhs) { | 2294 | static inline zig_u128 zig_divTrunc_u128(zig_u128 lhs, zig_u128 rhs) { |
| 1957 | return lhs / rhs; | 2295 | return lhs / rhs; |
| 1958 | } | 2296 | } |
| 1959 | 2297 | ||
| 1960 | static inline zig_i128 zig_div_trunc_i128(zig_i128 lhs, zig_i128 rhs) { | 2298 | static inline zig_i128 zig_divTrunc_i128(zig_i128 lhs, zig_i128 rhs) { |
| 1961 | return lhs / rhs; | 2299 | return lhs / rhs; |
| 1962 | } | 2300 | } |
| 1963 | 2301 | ||
| ... | @@ -1971,36 +2309,14 @@ static inline zig_i128 zig_rem_i128(zig_i128 lhs, zig_i128 rhs) { | ... | @@ -1971,36 +2309,14 @@ static inline zig_i128 zig_rem_i128(zig_i128 lhs, zig_i128 rhs) { |
| 1971 | 2309 | ||
| 1972 | #else /* zig_has_int128 */ | 2310 | #else /* zig_has_int128 */ |
| 1973 | 2311 | ||
| 1974 | static inline zig_u128 zig_not_u128(zig_u128 val, uint8_t bits) { | 2312 | static inline zig_u128 zig_not_u128(zig_u128 arg, uint8_t bits) { |
| 1975 | return (zig_u128){ .hi = zig_not_u64(val.hi, bits - UINT8_C(64)), .lo = zig_not_u64(val.lo, UINT8_C(64)) }; | 2313 | if (bits <= UINT8_C(64)) return (zig_u128){ .hi = UINT64_C(0), .lo = zig_not_u64(arg.lo, bits) }; |
| 1976 | } | 2314 | return (zig_u128){ .hi = zig_not_u64(arg.hi, bits - UINT8_C(64)), .lo = zig_not_u64(arg.lo, UINT8_C(64)) }; |
| 1977 | |||
| 1978 | static inline zig_i128 zig_not_i128(zig_i128 val, uint8_t bits) { | ||
| 1979 | return (zig_i128){ .hi = zig_not_i64(val.hi, bits - UINT8_C(64)), .lo = zig_not_u64(val.lo, UINT8_C(64)) }; | ||
| 1980 | } | ||
| 1981 | |||
| 1982 | static inline zig_u128 zig_shr_u128(zig_u128 lhs, uint8_t rhs) { | ||
| 1983 | if (rhs == UINT8_C(0)) return lhs; | ||
| 1984 | if (rhs >= UINT8_C(64)) return (zig_u128){ .hi = zig_minInt_u64, .lo = lhs.hi >> (rhs - UINT8_C(64)) }; | ||
| 1985 | return (zig_u128){ .hi = lhs.hi >> rhs, .lo = lhs.hi << (UINT8_C(64) - rhs) | lhs.lo >> rhs }; | ||
| 1986 | } | ||
| 1987 | |||
| 1988 | static inline zig_u128 zig_shl_u128(zig_u128 lhs, uint8_t rhs) { | ||
| 1989 | if (rhs == UINT8_C(0)) return lhs; | ||
| 1990 | if (rhs >= UINT8_C(64)) return (zig_u128){ .hi = lhs.lo << (rhs - UINT8_C(64)), .lo = zig_minInt_u64 }; | ||
| 1991 | return (zig_u128){ .hi = lhs.hi << rhs | lhs.lo >> (UINT8_C(64) - rhs), .lo = lhs.lo << rhs }; | ||
| 1992 | } | ||
| 1993 | |||
| 1994 | static inline zig_i128 zig_shr_i128(zig_i128 lhs, uint8_t rhs) { | ||
| 1995 | if (rhs == UINT8_C(0)) return lhs; | ||
| 1996 | if (rhs >= UINT8_C(64)) return (zig_i128){ .hi = zig_shr_i64(lhs.hi, 63), .lo = zig_shr_i64(lhs.hi, (rhs - UINT8_C(64))) }; | ||
| 1997 | return (zig_i128){ .hi = zig_shr_i64(lhs.hi, rhs), .lo = lhs.lo >> rhs | (uint64_t)lhs.hi << (UINT8_C(64) - rhs) }; | ||
| 1998 | } | 2315 | } |
| 1999 | 2316 | ||
| 2000 | static inline zig_i128 zig_shl_i128(zig_i128 lhs, uint8_t rhs) { | 2317 | static inline zig_i128 zig_not_i128(zig_i128 arg, uint8_t bits) { |
| 2001 | if (rhs == UINT8_C(0)) return lhs; | 2318 | (void)bits; |
| 2002 | if (rhs >= UINT8_C(64)) return (zig_i128){ .hi = lhs.lo << (rhs - UINT8_C(64)), .lo = zig_minInt_u64 }; | 2319 | return (zig_i128){ .hi = ~arg.hi, .lo = ~arg.lo }; |
| 2003 | return (zig_i128){ .hi = lhs.hi << rhs | lhs.lo >> (UINT8_C(64) - rhs), .lo = lhs.lo << rhs }; | ||
| 2004 | } | 2320 | } |
| 2005 | 2321 | ||
| 2006 | static inline zig_u128 zig_add_u128(zig_u128 lhs, zig_u128 rhs) { | 2322 | static inline zig_u128 zig_add_u128(zig_u128 lhs, zig_u128 rhs) { |
| ... | @@ -2027,59 +2343,59 @@ static inline zig_i128 zig_sub_i128(zig_i128 lhs, zig_i128 rhs) { | ... | @@ -2027,59 +2343,59 @@ static inline zig_i128 zig_sub_i128(zig_i128 lhs, zig_i128 rhs) { |
| 2027 | return res; | 2343 | return res; |
| 2028 | } | 2344 | } |
| 2029 | 2345 | ||
| 2030 | zig_extern zig_i128 __multi3(zig_i128 lhs, zig_i128 rhs); | ||
| 2031 | static zig_i128 zig_mul_i128(zig_i128 lhs, zig_i128 rhs) { | 2346 | static zig_i128 zig_mul_i128(zig_i128 lhs, zig_i128 rhs) { |
| 2347 | zig_extern zig_i128 __multi3(zig_i128 lhs, zig_i128 rhs); | ||
| 2032 | return __multi3(lhs, rhs); | 2348 | return __multi3(lhs, rhs); |
| 2033 | } | 2349 | } |
| 2034 | 2350 | ||
| 2035 | static zig_u128 zig_mul_u128(zig_u128 lhs, zig_u128 rhs) { | 2351 | static zig_u128 zig_mul_u128(zig_u128 lhs, zig_u128 rhs) { |
| 2036 | return zig_bitCast_u128(zig_mul_i128(zig_bitCast_i128(lhs), zig_bitCast_i128(rhs))); | 2352 | return zig_u128_bitCast_i128(zig_mul_i128(zig_i128_bitCast_u128(lhs, UINT8_C(128)), zig_i128_bitCast_u128(rhs, UINT8_C(128))), UINT8_C(128)); |
| 2037 | } | 2353 | } |
| 2038 | 2354 | ||
| 2039 | zig_extern zig_u128 __udivti3(zig_u128 lhs, zig_u128 rhs); | 2355 | static zig_u128 zig_divTrunc_u128(zig_u128 lhs, zig_u128 rhs) { |
| 2040 | static zig_u128 zig_div_trunc_u128(zig_u128 lhs, zig_u128 rhs) { | 2356 | zig_extern zig_u128 __udivti3(zig_u128 lhs, zig_u128 rhs); |
| 2041 | return __udivti3(lhs, rhs); | 2357 | return __udivti3(lhs, rhs); |
| 2042 | } | 2358 | } |
| 2043 | 2359 | ||
| 2044 | zig_extern zig_i128 __divti3(zig_i128 lhs, zig_i128 rhs); | 2360 | static zig_i128 zig_divTrunc_i128(zig_i128 lhs, zig_i128 rhs) { |
| 2045 | static zig_i128 zig_div_trunc_i128(zig_i128 lhs, zig_i128 rhs) { | 2361 | zig_extern zig_i128 __divti3(zig_i128 lhs, zig_i128 rhs); |
| 2046 | return __divti3(lhs, rhs); | 2362 | return __divti3(lhs, rhs); |
| 2047 | } | 2363 | } |
| 2048 | 2364 | ||
| 2049 | zig_extern zig_u128 __umodti3(zig_u128 lhs, zig_u128 rhs); | ||
| 2050 | static zig_u128 zig_rem_u128(zig_u128 lhs, zig_u128 rhs) { | 2365 | static zig_u128 zig_rem_u128(zig_u128 lhs, zig_u128 rhs) { |
| 2366 | zig_extern zig_u128 __umodti3(zig_u128 lhs, zig_u128 rhs); | ||
| 2051 | return __umodti3(lhs, rhs); | 2367 | return __umodti3(lhs, rhs); |
| 2052 | } | 2368 | } |
| 2053 | 2369 | ||
| 2054 | zig_extern zig_i128 __modti3(zig_i128 lhs, zig_i128 rhs); | ||
| 2055 | static zig_i128 zig_rem_i128(zig_i128 lhs, zig_i128 rhs) { | 2370 | static zig_i128 zig_rem_i128(zig_i128 lhs, zig_i128 rhs) { |
| 2371 | zig_extern zig_i128 __modti3(zig_i128 lhs, zig_i128 rhs); | ||
| 2056 | return __modti3(lhs, rhs); | 2372 | return __modti3(lhs, rhs); |
| 2057 | } | 2373 | } |
| 2058 | 2374 | ||
| 2059 | #endif /* zig_has_int128 */ | 2375 | #endif /* zig_has_int128 */ |
| 2060 | 2376 | ||
| 2061 | #define zig_div_floor_u128 zig_div_trunc_u128 | 2377 | #define zig_divFloor_u128 zig_divTrunc_u128 |
| 2062 | 2378 | ||
| 2063 | static inline zig_i128 zig_div_floor_i128(zig_i128 lhs, zig_i128 rhs) { | 2379 | static inline zig_i128 zig_divFloor_i128(zig_i128 lhs, zig_i128 rhs) { |
| 2064 | zig_i128 rem = zig_rem_i128(lhs, rhs); | 2380 | zig_i128 rem = zig_rem_i128(lhs, rhs); |
| 2065 | int64_t mask = zig_or_u64((uint64_t)zig_hi_i128(rem), zig_lo_i128(rem)) != UINT64_C(0) | 2381 | int64_t mask = zig_or_u64((uint64_t)zig_hi_i128(rem), zig_lo_i128(rem)) != UINT64_C(0) |
| 2066 | ? zig_shr_i64(zig_xor_i64(zig_hi_i128(lhs), zig_hi_i128(rhs)), UINT8_C(63)) : INT64_C(0); | 2382 | ? zig_shr_i64(zig_xor_i64(zig_hi_i128(lhs), zig_hi_i128(rhs)), UINT8_C(63)) : INT64_C(0); |
| 2067 | return zig_add_i128(zig_div_trunc_i128(lhs, rhs), zig_make_i128(mask, (uint64_t)mask)); | 2383 | return zig_add_i128(zig_divTrunc_i128(lhs, rhs), zig_make_i128(mask, (uint64_t)mask)); |
| 2068 | } | 2384 | } |
| 2069 | 2385 | ||
| 2070 | static inline zig_u128 zig_div_ceil_u128(zig_u128 lhs, zig_u128 rhs) { | 2386 | static inline zig_u128 zig_divCeil_u128(zig_u128 lhs, zig_u128 rhs) { |
| 2071 | zig_u128 rem = zig_rem_u128(lhs, rhs); | 2387 | zig_u128 rem = zig_rem_u128(lhs, rhs); |
| 2072 | uint64_t mask = zig_or_u64(zig_hi_u128(rem), zig_lo_u128(rem)) != UINT64_C(0) | 2388 | uint64_t mask = zig_or_u64(zig_hi_u128(rem), zig_lo_u128(rem)) != UINT64_C(0) |
| 2073 | ? UINT64_C(1) : UINT64_C(0); | 2389 | ? UINT64_C(1) : UINT64_C(0); |
| 2074 | return zig_add_u128(zig_div_trunc_u128(lhs, rhs), zig_make_u128(UINT64_C(0), mask)); | 2390 | return zig_add_u128(zig_divTrunc_u128(lhs, rhs), zig_make_u128(UINT64_C(0), mask)); |
| 2075 | } | 2391 | } |
| 2076 | 2392 | ||
| 2077 | static inline zig_i128 zig_div_ceil_i128(zig_i128 lhs, zig_i128 rhs) { | 2393 | static inline zig_i128 zig_divCeil_i128(zig_i128 lhs, zig_i128 rhs) { |
| 2078 | zig_i128 rem = zig_rem_i128(lhs, rhs); | 2394 | zig_i128 rem = zig_rem_i128(lhs, rhs); |
| 2079 | int64_t mask = zig_or_u64((uint64_t)zig_hi_i128(rem), zig_lo_i128(rem)) != UINT64_C(0) | 2395 | int64_t mask = zig_or_u64((uint64_t)zig_hi_i128(rem), zig_lo_i128(rem)) != UINT64_C(0) |
| 2080 | ? zig_shr_i64(zig_xor_i64(zig_hi_i128(lhs), zig_hi_i128(rhs)), UINT8_C(63)) + INT64_C(1) | 2396 | ? zig_shr_i64(zig_xor_i64(zig_hi_i128(lhs), zig_hi_i128(rhs)), UINT8_C(63)) + INT64_C(1) |
| 2081 | : INT64_C(0); | 2397 | : INT64_C(0); |
| 2082 | return zig_add_i128(zig_div_trunc_i128(lhs, rhs), zig_make_i128(INT64_C(0), (uint64_t)mask)); | 2398 | return zig_add_i128(zig_divTrunc_i128(lhs, rhs), zig_make_i128(INT64_C(0), (uint64_t)mask)); |
| 2083 | } | 2399 | } |
| 2084 | 2400 | ||
| 2085 | #define zig_mod_u128 zig_rem_u128 | 2401 | #define zig_mod_u128 zig_rem_u128 |
| ... | @@ -2107,51 +2423,41 @@ static inline zig_i128 zig_max_i128(zig_i128 lhs, zig_i128 rhs) { | ... | @@ -2107,51 +2423,41 @@ static inline zig_i128 zig_max_i128(zig_i128 lhs, zig_i128 rhs) { |
| 2107 | return zig_cmp_i128(lhs, rhs) > INT32_C(0) ? lhs : rhs; | 2423 | return zig_cmp_i128(lhs, rhs) > INT32_C(0) ? lhs : rhs; |
| 2108 | } | 2424 | } |
| 2109 | 2425 | ||
| 2110 | static inline zig_u128 zig_wrap_u128(zig_u128 val, uint8_t bits) { | ||
| 2111 | return zig_and_u128(val, zig_maxInt_u(128, bits)); | ||
| 2112 | } | ||
| 2113 | |||
| 2114 | static inline zig_i128 zig_wrap_i128(zig_i128 val, uint8_t bits) { | ||
| 2115 | if (bits > UINT8_C(64)) return zig_make_i128(zig_wrap_i64(zig_hi_i128(val), bits - UINT8_C(64)), zig_lo_i128(val)); | ||
| 2116 | int64_t lo = zig_wrap_i64((int64_t)zig_lo_i128(val), bits); | ||
| 2117 | return zig_make_i128(zig_shr_i64(lo, 63), (uint64_t)lo); | ||
| 2118 | } | ||
| 2119 | |||
| 2120 | static inline zig_u128 zig_shlw_u128(zig_u128 lhs, uint8_t rhs, uint8_t bits) { | 2426 | static inline zig_u128 zig_shlw_u128(zig_u128 lhs, uint8_t rhs, uint8_t bits) { |
| 2121 | return zig_wrap_u128(zig_shl_u128(lhs, rhs), bits); | 2427 | return zig_u128_truncate_u128(zig_shl_u128(lhs, rhs), bits); |
| 2122 | } | 2428 | } |
| 2123 | 2429 | ||
| 2124 | static inline zig_i128 zig_shlw_i128(zig_i128 lhs, uint8_t rhs, uint8_t bits) { | 2430 | static inline zig_i128 zig_shlw_i128(zig_i128 lhs, uint8_t rhs, uint8_t bits) { |
| 2125 | return zig_wrap_i128(zig_bitCast_i128(zig_shl_u128(zig_bitCast_u128(lhs), rhs)), bits); | 2431 | return zig_i128_truncate_i128(zig_i128_bitCast_u128(zig_shl_u128(zig_u128_bitCast_i128(lhs, bits), rhs), bits), bits); |
| 2126 | } | 2432 | } |
| 2127 | 2433 | ||
| 2128 | static inline zig_u128 zig_addw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) { | 2434 | static inline zig_u128 zig_addw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) { |
| 2129 | return zig_wrap_u128(zig_add_u128(lhs, rhs), bits); | 2435 | return zig_u128_truncate_u128(zig_add_u128(lhs, rhs), bits); |
| 2130 | } | 2436 | } |
| 2131 | 2437 | ||
| 2132 | static inline zig_i128 zig_addw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) { | 2438 | static inline zig_i128 zig_addw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) { |
| 2133 | return zig_wrap_i128(zig_bitCast_i128(zig_add_u128(zig_bitCast_u128(lhs), zig_bitCast_u128(rhs))), bits); | 2439 | return zig_i128_truncate_i128(zig_i128_bitCast_u128(zig_add_u128(zig_u128_bitCast_i128(lhs, bits), zig_u128_bitCast_i128(rhs, bits)), bits), bits); |
| 2134 | } | 2440 | } |
| 2135 | 2441 | ||
| 2136 | static inline zig_u128 zig_subw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) { | 2442 | static inline zig_u128 zig_subw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) { |
| 2137 | return zig_wrap_u128(zig_sub_u128(lhs, rhs), bits); | 2443 | return zig_u128_truncate_u128(zig_sub_u128(lhs, rhs), bits); |
| 2138 | } | 2444 | } |
| 2139 | 2445 | ||
| 2140 | static inline zig_i128 zig_subw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) { | 2446 | static inline zig_i128 zig_subw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) { |
| 2141 | return zig_wrap_i128(zig_bitCast_i128(zig_sub_u128(zig_bitCast_u128(lhs), zig_bitCast_u128(rhs))), bits); | 2447 | return zig_i128_truncate_i128(zig_i128_bitCast_u128(zig_sub_u128(zig_u128_bitCast_i128(lhs, bits), zig_u128_bitCast_i128(rhs, bits)), bits), bits); |
| 2142 | } | 2448 | } |
| 2143 | 2449 | ||
| 2144 | static inline zig_u128 zig_mulw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) { | 2450 | static inline zig_u128 zig_mulw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) { |
| 2145 | return zig_wrap_u128(zig_mul_u128(lhs, rhs), bits); | 2451 | return zig_u128_truncate_u128(zig_mul_u128(lhs, rhs), bits); |
| 2146 | } | 2452 | } |
| 2147 | 2453 | ||
| 2148 | static inline zig_i128 zig_mulw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) { | 2454 | static inline zig_i128 zig_mulw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) { |
| 2149 | return zig_wrap_i128(zig_bitCast_i128(zig_mul_u128(zig_bitCast_u128(lhs), zig_bitCast_u128(rhs))), bits); | 2455 | return zig_i128_truncate_i128(zig_i128_bitCast_u128(zig_mul_u128(zig_u128_bitCast_i128(lhs, bits), zig_u128_bitCast_i128(rhs, bits)), bits), bits); |
| 2150 | } | 2456 | } |
| 2151 | 2457 | ||
| 2152 | static inline zig_u128 zig_abs_i128(zig_i128 val) { | 2458 | static inline zig_u128 zig_abs_i128(zig_i128 arg) { |
| 2153 | zig_i128 tmp = zig_shr_i128(val, 127); | 2459 | zig_u128 tmp = zig_u128_bitCast_i128(zig_shr_i128(arg, 127), UINT8_C(128)); |
| 2154 | return zig_bitCast_u128(zig_sub_i128(zig_xor_i128(val, tmp), tmp)); | 2460 | return zig_sub_u128(zig_xor_u128(zig_u128_bitCast_i128(arg, UINT8_C(128)), tmp), tmp); |
| 2155 | } | 2461 | } |
| 2156 | 2462 | ||
| 2157 | #if zig_has_int128 | 2463 | #if zig_has_int128 |
| ... | @@ -2160,7 +2466,7 @@ static inline bool zig_addo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint | ... | @@ -2160,7 +2466,7 @@ static inline bool zig_addo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint |
| 2160 | #if zig_has_builtin(add_overflow) | 2466 | #if zig_has_builtin(add_overflow) |
| 2161 | zig_u128 full_res; | 2467 | zig_u128 full_res; |
| 2162 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); | 2468 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); |
| 2163 | *res = zig_wrap_u128(full_res, bits); | 2469 | *res = zig_u128_truncate_u128(full_res, bits); |
| 2164 | return overflow || full_res < zig_minInt_u(128, bits) || full_res > zig_maxInt_u(128, bits); | 2470 | return overflow || full_res < zig_minInt_u(128, bits) || full_res > zig_maxInt_u(128, bits); |
| 2165 | #else | 2471 | #else |
| 2166 | *res = zig_addw_u128(lhs, rhs, bits); | 2472 | *res = zig_addw_u128(lhs, rhs, bits); |
| ... | @@ -2176,7 +2482,7 @@ static inline bool zig_addo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint | ... | @@ -2176,7 +2482,7 @@ static inline bool zig_addo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint |
| 2176 | zig_i128 full_res = (zig_i128)((zig_u128)lhs + (zig_u128)rhs); | 2482 | zig_i128 full_res = (zig_i128)((zig_u128)lhs + (zig_u128)rhs); |
| 2177 | bool overflow = ((full_res ^ lhs) & (full_res ^ rhs)) < 0; | 2483 | bool overflow = ((full_res ^ lhs) & (full_res ^ rhs)) < 0; |
| 2178 | #endif | 2484 | #endif |
| 2179 | *res = zig_wrap_i128(full_res, bits); | 2485 | *res = zig_i128_truncate_i128(full_res, bits); |
| 2180 | return overflow || full_res < zig_minInt_i(128, bits) || full_res > zig_maxInt_i(128, bits); | 2486 | return overflow || full_res < zig_minInt_i(128, bits) || full_res > zig_maxInt_i(128, bits); |
| 2181 | } | 2487 | } |
| 2182 | 2488 | ||
| ... | @@ -2184,7 +2490,7 @@ static inline bool zig_subo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint | ... | @@ -2184,7 +2490,7 @@ static inline bool zig_subo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint |
| 2184 | #if zig_has_builtin(sub_overflow) | 2490 | #if zig_has_builtin(sub_overflow) |
| 2185 | zig_u128 full_res; | 2491 | zig_u128 full_res; |
| 2186 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); | 2492 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); |
| 2187 | *res = zig_wrap_u128(full_res, bits); | 2493 | *res = zig_u128_truncate_u128(full_res, bits); |
| 2188 | return overflow || full_res < zig_minInt_u(128, bits) || full_res > zig_maxInt_u(128, bits); | 2494 | return overflow || full_res < zig_minInt_u(128, bits) || full_res > zig_maxInt_u(128, bits); |
| 2189 | #else | 2495 | #else |
| 2190 | *res = zig_subw_u128(lhs, rhs, bits); | 2496 | *res = zig_subw_u128(lhs, rhs, bits); |
| ... | @@ -2200,7 +2506,7 @@ static inline bool zig_subo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint | ... | @@ -2200,7 +2506,7 @@ static inline bool zig_subo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint |
| 2200 | zig_i128 full_res = (zig_i128)((zig_u128)lhs - (zig_u128)rhs); | 2506 | zig_i128 full_res = (zig_i128)((zig_u128)lhs - (zig_u128)rhs); |
| 2201 | bool overflow = ((lhs ^ rhs) & (full_res ^ lhs)) < 0; | 2507 | bool overflow = ((lhs ^ rhs) & (full_res ^ lhs)) < 0; |
| 2202 | #endif | 2508 | #endif |
| 2203 | *res = zig_wrap_i128(full_res, bits); | 2509 | *res = zig_i128_truncate_i128(full_res, bits); |
| 2204 | return overflow || full_res < zig_minInt_i(128, bits) || full_res > zig_maxInt_i(128, bits); | 2510 | return overflow || full_res < zig_minInt_i(128, bits) || full_res > zig_maxInt_i(128, bits); |
| 2205 | } | 2511 | } |
| 2206 | 2512 | ||
| ... | @@ -2208,7 +2514,7 @@ static inline bool zig_mulo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint | ... | @@ -2208,7 +2514,7 @@ static inline bool zig_mulo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint |
| 2208 | #if zig_has_builtin(mul_overflow) | 2514 | #if zig_has_builtin(mul_overflow) |
| 2209 | zig_u128 full_res; | 2515 | zig_u128 full_res; |
| 2210 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); | 2516 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); |
| 2211 | *res = zig_wrap_u128(full_res, bits); | 2517 | *res = zig_u128_truncate_u128(full_res, bits); |
| 2212 | return overflow || full_res < zig_minInt_u(128, bits) || full_res > zig_maxInt_u(128, bits); | 2518 | return overflow || full_res < zig_minInt_u(128, bits) || full_res > zig_maxInt_u(128, bits); |
| 2213 | #else | 2519 | #else |
| 2214 | *res = zig_mulw_u128(lhs, rhs, bits); | 2520 | *res = zig_mulw_u128(lhs, rhs, bits); |
| ... | @@ -2216,8 +2522,8 @@ static inline bool zig_mulo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint | ... | @@ -2216,8 +2522,8 @@ static inline bool zig_mulo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint |
| 2216 | #endif | 2522 | #endif |
| 2217 | } | 2523 | } |
| 2218 | 2524 | ||
| 2219 | zig_extern zig_i128 __muloti4(zig_i128 lhs, zig_i128 rhs, int *overflow); | ||
| 2220 | static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) { | 2525 | static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) { |
| 2526 | zig_extern zig_i128 __muloti4(zig_i128 lhs, zig_i128 rhs, int *overflow); | ||
| 2221 | #if zig_has_builtin(mul_overflow) | 2527 | #if zig_has_builtin(mul_overflow) |
| 2222 | zig_i128 full_res; | 2528 | zig_i128 full_res; |
| 2223 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); | 2529 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); |
| ... | @@ -2226,50 +2532,78 @@ static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint | ... | @@ -2226,50 +2532,78 @@ static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint |
| 2226 | zig_i128 full_res = __muloti4(lhs, rhs, &overflow_int); | 2532 | zig_i128 full_res = __muloti4(lhs, rhs, &overflow_int); |
| 2227 | bool overflow = overflow_int != 0; | 2533 | bool overflow = overflow_int != 0; |
| 2228 | #endif | 2534 | #endif |
| 2229 | *res = zig_wrap_i128(full_res, bits); | 2535 | *res = zig_i128_truncate_i128(full_res, bits); |
| 2230 | return overflow || full_res < zig_minInt_i(128, bits) || full_res > zig_maxInt_i(128, bits); | 2536 | return overflow || full_res < zig_minInt_i(128, bits) || full_res > zig_maxInt_i(128, bits); |
| 2231 | } | 2537 | } |
| 2232 | 2538 | ||
| 2233 | #else /* zig_has_int128 */ | 2539 | #else /* zig_has_int128 */ |
| 2234 | 2540 | ||
| 2235 | static inline bool zig_addo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) { | 2541 | static inline bool zig_addo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) { |
| 2236 | uint64_t hi; | 2542 | if (bits <= UINT8_C(64)) { |
| 2237 | bool overflow = zig_addo_u64(&hi, lhs.hi, rhs.hi, bits - 64); | 2543 | uint64_t lo; |
| 2238 | return overflow ^ zig_addo_u64(&res->hi, hi, zig_addo_u64(&res->lo, lhs.lo, rhs.lo, 64), bits - 64); | 2544 | bool overflow = zig_addo_u64(&lo, zig_u64_intCast_u128(lhs), zig_u64_intCast_u128(rhs), bits); |
| 2545 | *res = zig_u128_intCast_u64(lo); | ||
| 2546 | return overflow; | ||
| 2547 | } else { | ||
| 2548 | uint64_t hi; | ||
| 2549 | bool overflow = zig_addo_u64(&hi, lhs.hi, rhs.hi, bits - UINT8_C(64)); | ||
| 2550 | return overflow ^ zig_addo_u64(&res->hi, hi, zig_addo_u64(&res->lo, lhs.lo, rhs.lo, UINT8_C(64)), bits - UINT8_C(64)); | ||
| 2551 | } | ||
| 2239 | } | 2552 | } |
| 2240 | 2553 | ||
| 2241 | static inline bool zig_addo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) { | 2554 | static inline bool zig_addo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) { |
| 2242 | int64_t hi; | 2555 | if (bits <= UINT8_C(64)) { |
| 2243 | bool overflow = zig_addo_i64(&hi, lhs.hi, rhs.hi, bits - 64); | 2556 | int64_t lo; |
| 2244 | return overflow ^ zig_addo_i64(&res->hi, hi, zig_addo_u64(&res->lo, lhs.lo, rhs.lo, 64), bits - 64); | 2557 | bool overflow = zig_addo_i64(&lo, zig_i64_intCast_i128(lhs), zig_i64_intCast_i128(rhs), bits); |
| 2558 | *res = zig_i128_intCast_i64(lo); | ||
| 2559 | return overflow; | ||
| 2560 | } else { | ||
| 2561 | int64_t hi; | ||
| 2562 | bool overflow = zig_addo_i64(&hi, lhs.hi, rhs.hi, bits - UINT8_C(64)); | ||
| 2563 | return overflow ^ zig_addo_i64(&res->hi, hi, zig_addo_u64(&res->lo, lhs.lo, rhs.lo, UINT8_C(64)), bits - UINT8_C(64)); | ||
| 2564 | } | ||
| 2245 | } | 2565 | } |
| 2246 | 2566 | ||
| 2247 | static inline bool zig_subo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) { | 2567 | static inline bool zig_subo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) { |
| 2248 | uint64_t hi; | 2568 | if (bits <= UINT8_C(64)) { |
| 2249 | bool overflow = zig_subo_u64(&hi, lhs.hi, rhs.hi, bits - 64); | 2569 | uint64_t lo; |
| 2250 | return overflow ^ zig_subo_u64(&res->hi, hi, zig_subo_u64(&res->lo, lhs.lo, rhs.lo, 64), bits - 64); | 2570 | bool overflow = zig_subo_u64(&lo, zig_u64_intCast_u128(lhs), zig_u64_intCast_u128(rhs), bits); |
| 2571 | *res = zig_u128_intCast_u64(lo); | ||
| 2572 | return overflow; | ||
| 2573 | } else { | ||
| 2574 | uint64_t hi; | ||
| 2575 | bool overflow = zig_subo_u64(&hi, lhs.hi, rhs.hi, bits - UINT8_C(64)); | ||
| 2576 | return overflow ^ zig_subo_u64(&res->hi, hi, zig_subo_u64(&res->lo, lhs.lo, rhs.lo, UINT8_C(64)), bits - UINT8_C(64)); | ||
| 2577 | } | ||
| 2251 | } | 2578 | } |
| 2252 | 2579 | ||
| 2253 | static inline bool zig_subo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) { | 2580 | static inline bool zig_subo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) { |
| 2254 | int64_t hi; | 2581 | if (bits <= UINT8_C(64)) { |
| 2255 | bool overflow = zig_subo_i64(&hi, lhs.hi, rhs.hi, bits - 64); | 2582 | int64_t lo; |
| 2256 | return overflow ^ zig_subo_i64(&res->hi, hi, zig_subo_u64(&res->lo, lhs.lo, rhs.lo, 64), bits - 64); | 2583 | bool overflow = zig_subo_i64(&lo, zig_i64_intCast_i128(lhs), zig_i64_intCast_i128(rhs), bits); |
| 2584 | *res = zig_i128_intCast_i64(lo); | ||
| 2585 | return overflow; | ||
| 2586 | } else { | ||
| 2587 | int64_t hi; | ||
| 2588 | bool overflow = zig_subo_i64(&hi, lhs.hi, rhs.hi, bits - UINT8_C(64)); | ||
| 2589 | return overflow ^ zig_subo_i64(&res->hi, hi, zig_subo_u64(&res->lo, lhs.lo, rhs.lo, UINT8_C(64)), bits - UINT8_C(64)); | ||
| 2590 | } | ||
| 2257 | } | 2591 | } |
| 2258 | 2592 | ||
| 2259 | static inline bool zig_mulo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) { | 2593 | static inline bool zig_mulo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) { |
| 2260 | *res = zig_mulw_u128(lhs, rhs, bits); | 2594 | *res = zig_mulw_u128(lhs, rhs, bits); |
| 2261 | return zig_cmp_u128(*res, zig_make_u128(0, 0)) != INT32_C(0) && | 2595 | return zig_cmp_u128(rhs, zig_make_u128(0, 0)) != INT32_C(0) && |
| 2262 | zig_cmp_u128(lhs, zig_div_trunc_u128(zig_maxInt_u(128, bits), rhs)) > INT32_C(0); | 2596 | zig_cmp_u128(lhs, zig_divTrunc_u128(zig_maxInt_u(128, bits), rhs)) > INT32_C(0); |
| 2263 | } | 2597 | } |
| 2264 | 2598 | ||
| 2265 | zig_extern zig_i128 __muloti4(zig_i128 lhs, zig_i128 rhs, int *overflow); | ||
| 2266 | static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) { | 2599 | static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) { |
| 2600 | zig_extern zig_i128 __muloti4(zig_i128 lhs, zig_i128 rhs, int *overflow); | ||
| 2267 | int overflow_int; | 2601 | int overflow_int; |
| 2268 | zig_i128 full_res = __muloti4(lhs, rhs, &overflow_int); | 2602 | zig_i128 full_res = __muloti4(lhs, rhs, &overflow_int); |
| 2269 | bool overflow = overflow_int != 0 || | 2603 | bool overflow = overflow_int != 0 || |
| 2270 | zig_cmp_i128(full_res, zig_minInt_i(128, bits)) < INT32_C(0) || | 2604 | zig_cmp_i128(full_res, zig_minInt_i(128, bits)) < INT32_C(0) || |
| 2271 | zig_cmp_i128(full_res, zig_maxInt_i(128, bits)) > INT32_C(0); | 2605 | zig_cmp_i128(full_res, zig_maxInt_i(128, bits)) > INT32_C(0); |
| 2272 | *res = zig_wrap_i128(full_res, bits); | 2606 | *res = zig_i128_truncate_i128(full_res, bits); |
| 2273 | return overflow; | 2607 | return overflow; |
| 2274 | } | 2608 | } |
| 2275 | 2609 | ||
| ... | @@ -2282,28 +2616,54 @@ static inline bool zig_shlo_u128(zig_u128 *res, zig_u128 lhs, uint8_t rhs, uint8 | ... | @@ -2282,28 +2616,54 @@ static inline bool zig_shlo_u128(zig_u128 *res, zig_u128 lhs, uint8_t rhs, uint8 |
| 2282 | 2616 | ||
| 2283 | static inline bool zig_shlo_i128(zig_i128 *res, zig_i128 lhs, uint8_t rhs, uint8_t bits) { | 2617 | static inline bool zig_shlo_i128(zig_i128 *res, zig_i128 lhs, uint8_t rhs, uint8_t bits) { |
| 2284 | *res = zig_shlw_i128(lhs, rhs, bits); | 2618 | *res = zig_shlw_i128(lhs, rhs, bits); |
| 2285 | zig_i128 mask = zig_bitCast_i128(zig_shl_u128(zig_maxInt_u128, bits - rhs - UINT8_C(1))); | 2619 | zig_i128 mask = zig_i128_bitCast_u128(zig_shl_u128(zig_maxInt_u128, bits - rhs - UINT8_C(1)), bits); |
| 2286 | return zig_cmp_i128(zig_and_i128(lhs, mask), zig_make_i128(0, 0)) != INT32_C(0) && | 2620 | return zig_cmp_i128(zig_and_i128(lhs, mask), zig_make_i128(0, 0)) != INT32_C(0) && |
| 2287 | zig_cmp_i128(zig_and_i128(lhs, mask), mask) != INT32_C(0); | 2621 | zig_cmp_i128(zig_and_i128(lhs, mask), mask) != INT32_C(0); |
| 2288 | } | 2622 | } |
| 2289 | 2623 | ||
| 2290 | static inline zig_u128 zig_shls_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) { | 2624 | #define zig_int128_shls_builtins(rw) \ |
| 2625 | static inline zig_u128 zig_shls_u128_u##rw(zig_u128 lhs, uint##rw##_t rhs, uint8_t bits) { \ | ||
| 2626 | zig_u128 res; \ | ||
| 2627 | if (rhs < bits && !zig_shlo_u128(&res, lhs, zig_u8_intCast_u##rw(rhs), bits)) return res; \ | ||
| 2628 | switch (zig_cmp_u128(lhs, zig_make_u128(UINT64_C(0), UINT64_C(0)))) { \ | ||
| 2629 | case 0: return zig_minInt_u(128, bits); \ | ||
| 2630 | case 1: return zig_maxInt_u(128, bits); \ | ||
| 2631 | default: zig_unreachable(); \ | ||
| 2632 | } \ | ||
| 2633 | } \ | ||
| 2634 | \ | ||
| 2635 | static inline zig_i128 zig_shls_i128_u##rw(zig_i128 lhs, uint##rw##_t rhs, uint8_t bits) { \ | ||
| 2636 | zig_i128 res; \ | ||
| 2637 | if (rhs < bits && !zig_shlo_i128(&res, lhs, zig_u8_intCast_u##rw(rhs), bits)) return res; \ | ||
| 2638 | switch (zig_cmp_i128(lhs, zig_make_i128(INT64_C(0), UINT64_C(0)))) { \ | ||
| 2639 | case -1: return zig_minInt_i(128, bits); \ | ||
| 2640 | case 0: return zig_make_i128(INT64_C(0), UINT64_C(0)); \ | ||
| 2641 | case 1: return zig_maxInt_i(128, bits); \ | ||
| 2642 | default: zig_unreachable(); \ | ||
| 2643 | } \ | ||
| 2644 | } | ||
| 2645 | zig_int128_shls_builtins(8) | ||
| 2646 | zig_int128_shls_builtins(16) | ||
| 2647 | zig_int128_shls_builtins(32) | ||
| 2648 | zig_int128_shls_builtins(64) | ||
| 2649 | |||
| 2650 | static inline zig_u128 zig_shls_u128_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) { | ||
| 2291 | zig_u128 res; | 2651 | zig_u128 res; |
| 2292 | if (zig_cmp_u128(rhs, zig_make_u128(0, bits)) < INT32_C(0) && !zig_shlo_u128(&res, lhs, (uint8_t)zig_lo_u128(rhs), bits)) return res; | 2652 | if (zig_cmp_u128(rhs, zig_make_u128(0, bits)) < INT32_C(0) && !zig_shlo_u128(&res, lhs, (uint8_t)zig_lo_u128(rhs), bits)) return res; |
| 2293 | switch (zig_cmp_u128(lhs, zig_make_u128(0, 0))) { | 2653 | switch (zig_cmp_u128(lhs, zig_make_u128(0, 0))) { |
| 2294 | case 0: return zig_make_u128(0, 0); | 2654 | case INT32_C(0): return zig_make_u128(0, 0); |
| 2295 | case 1: return zig_maxInt_u(128, bits); | 2655 | case INT32_C(1): return zig_maxInt_u(128, bits); |
| 2296 | default: zig_unreachable(); | 2656 | default: zig_unreachable(); |
| 2297 | } | 2657 | } |
| 2298 | } | 2658 | } |
| 2299 | 2659 | ||
| 2300 | static inline zig_i128 zig_shls_i128(zig_i128 lhs, zig_u128 rhs, uint8_t bits) { | 2660 | static inline zig_i128 zig_shls_i128_u128(zig_i128 lhs, zig_u128 rhs, uint8_t bits) { |
| 2301 | zig_i128 res; | 2661 | zig_i128 res; |
| 2302 | if (zig_cmp_u128(rhs, zig_make_u128(0, bits)) < INT32_C(0) && !zig_shlo_i128(&res, lhs, (uint8_t)zig_lo_u128(rhs), bits)) return res; | 2662 | if (zig_cmp_u128(rhs, zig_make_u128(0, bits)) < INT32_C(0) && !zig_shlo_i128(&res, lhs, (uint8_t)zig_lo_u128(rhs), bits)) return res; |
| 2303 | switch (zig_cmp_i128(lhs, zig_make_i128(0, 0))) { | 2663 | switch (zig_cmp_i128(lhs, zig_make_i128(0, 0))) { |
| 2304 | case -1: return zig_minInt_i(128, bits); | 2664 | case -INT32_C(1): return zig_minInt_i(128, bits); |
| 2305 | case 0: return zig_make_i128(0, 0); | 2665 | case INT32_C(0): return zig_make_i128(0, 0); |
| 2306 | case 1: return zig_maxInt_i(128, bits); | 2666 | case INT32_C(1): return zig_maxInt_i(128, bits); |
| 2307 | default: zig_unreachable(); | 2667 | default: zig_unreachable(); |
| 2308 | } | 2668 | } |
| 2309 | } | 2669 | } |
| ... | @@ -2341,57 +2701,60 @@ static inline zig_i128 zig_muls_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) { | ... | @@ -2341,57 +2701,60 @@ static inline zig_i128 zig_muls_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) { |
| 2341 | return zig_cmp_i128(zig_xor_i128(lhs, rhs), zig_make_i128(0, 0)) < INT32_C(0) ? zig_minInt_i(128, bits) : zig_maxInt_i(128, bits); | 2701 | return zig_cmp_i128(zig_xor_i128(lhs, rhs), zig_make_i128(0, 0)) < INT32_C(0) ? zig_minInt_i(128, bits) : zig_maxInt_i(128, bits); |
| 2342 | } | 2702 | } |
| 2343 | 2703 | ||
| 2344 | static inline uint8_t zig_clz_u128(zig_u128 val, uint8_t bits) { | 2704 | static inline uint8_t zig_clz_u128(zig_u128 arg, uint8_t bits) { |
| 2345 | if (bits <= UINT8_C(64)) return zig_clz_u64(zig_lo_u128(val), bits); | 2705 | if (bits <= UINT8_C(64)) return zig_clz_u64(zig_lo_u128(arg), bits); |
| 2346 | if (zig_hi_u128(val) != 0) return zig_clz_u64(zig_hi_u128(val), bits - UINT8_C(64)); | 2706 | if (zig_hi_u128(arg) != 0) return zig_clz_u64(zig_hi_u128(arg), bits - UINT8_C(64)); |
| 2347 | return zig_clz_u64(zig_lo_u128(val), UINT8_C(64)) + (bits - UINT8_C(64)); | 2707 | return zig_clz_u64(zig_lo_u128(arg), UINT8_C(64)) + (bits - UINT8_C(64)); |
| 2348 | } | 2708 | } |
| 2349 | 2709 | ||
| 2350 | static inline uint8_t zig_clz_i128(zig_i128 val, uint8_t bits) { | 2710 | static inline uint8_t zig_clz_i128(zig_i128 arg, uint8_t bits) { |
| 2351 | return zig_clz_u128(zig_bitCast_u128(val), bits); | 2711 | return zig_clz_u128(zig_u128_bitCast_i128(arg, bits), bits); |
| 2352 | } | 2712 | } |
| 2353 | 2713 | ||
| 2354 | static inline uint8_t zig_ctz_u128(zig_u128 val, uint8_t bits) { | 2714 | static inline uint8_t zig_ctz_u128(zig_u128 arg, uint8_t bits) { |
| 2355 | if (zig_lo_u128(val) != 0) return zig_ctz_u64(zig_lo_u128(val), UINT8_C(64)); | 2715 | if (zig_lo_u128(arg) != 0) return zig_ctz_u64(zig_lo_u128(arg), UINT8_C(64)); |
| 2356 | return zig_ctz_u64(zig_hi_u128(val), bits - UINT8_C(64)) + UINT8_C(64); | 2716 | return zig_ctz_u64(zig_hi_u128(arg), bits - UINT8_C(64)) + UINT8_C(64); |
| 2357 | } | 2717 | } |
| 2358 | 2718 | ||
| 2359 | static inline uint8_t zig_ctz_i128(zig_i128 val, uint8_t bits) { | 2719 | static inline uint8_t zig_ctz_i128(zig_i128 arg, uint8_t bits) { |
| 2360 | return zig_ctz_u128(zig_bitCast_u128(val), bits); | 2720 | return zig_ctz_u128(zig_u128_bitCast_i128(arg, bits), bits); |
| 2361 | } | 2721 | } |
| 2362 | 2722 | ||
| 2363 | static inline uint8_t zig_popcount_u128(zig_u128 val, uint8_t bits) { | 2723 | static inline uint8_t zig_popCount_u128(zig_u128 arg, uint8_t bits) { |
| 2364 | return zig_popcount_u64(zig_hi_u128(val), bits - UINT8_C(64)) + | 2724 | return (bits > UINT8_C(64) ? zig_popCount_u64(zig_hi_u128(arg), bits - UINT8_C(64)) : UINT8_C(0)) + |
| 2365 | zig_popcount_u64(zig_lo_u128(val), UINT8_C(64)); | 2725 | zig_popCount_u64(zig_lo_u128(arg), UINT8_C(64)); |
| 2366 | } | 2726 | } |
| 2367 | 2727 | ||
| 2368 | static inline uint8_t zig_popcount_i128(zig_i128 val, uint8_t bits) { | 2728 | static inline uint8_t zig_popCount_i128(zig_i128 arg, uint8_t bits) { |
| 2369 | return zig_popcount_u128(zig_bitCast_u128(val), bits); | 2729 | return zig_popCount_u128(zig_u128_bitCast_i128(arg, bits), bits); |
| 2370 | } | 2730 | } |
| 2371 | 2731 | ||
| 2372 | static inline zig_u128 zig_byte_swap_u128(zig_u128 val, uint8_t bits) { | 2732 | static inline zig_u128 zig_byteSwap_u128(zig_u128 arg, uint8_t bits) { |
| 2373 | zig_u128 full_res; | 2733 | zig_u128 full_res; |
| 2374 | #if zig_has_builtin(bswap128) | 2734 | #if zig_has_builtin(bswap128) |
| 2375 | full_res = __builtin_bswap128(val); | 2735 | full_res = __builtin_bswap128(arg); |
| 2376 | #else | 2736 | #else |
| 2377 | full_res = zig_make_u128(zig_byte_swap_u64(zig_lo_u128(val), UINT8_C(64)), | 2737 | full_res = zig_make_u128( |
| 2378 | zig_byte_swap_u64(zig_hi_u128(val), UINT8_C(64))); | 2738 | zig_byteSwap_u64(zig_lo_u128(arg), UINT8_C(64)), |
| 2739 | zig_byteSwap_u64(zig_hi_u128(arg), UINT8_C(64)) | ||
| 2740 | ); | ||
| 2379 | #endif | 2741 | #endif |
| 2380 | return zig_shr_u128(full_res, UINT8_C(128) - bits); | 2742 | return zig_shr_u128(full_res, UINT8_C(128) - bits); |
| 2381 | } | 2743 | } |
| 2382 | 2744 | ||
| 2383 | static inline zig_i128 zig_byte_swap_i128(zig_i128 val, uint8_t bits) { | 2745 | static inline zig_i128 zig_byteSwap_i128(zig_i128 arg, uint8_t bits) { |
| 2384 | return zig_bitCast_i128(zig_byte_swap_u128(zig_bitCast_u128(val), bits)); | 2746 | return zig_i128_bitCast_u128(zig_byteSwap_u128(zig_u128_bitCast_i128(arg, bits), bits), bits); |
| 2385 | } | 2747 | } |
| 2386 | 2748 | ||
| 2387 | static inline zig_u128 zig_bit_reverse_u128(zig_u128 val, uint8_t bits) { | 2749 | static inline zig_u128 zig_bitReverse_u128(zig_u128 arg, uint8_t bits) { |
| 2388 | return zig_shr_u128(zig_make_u128(zig_bit_reverse_u64(zig_lo_u128(val), UINT8_C(64)), | 2750 | return zig_shr_u128(zig_make_u128( |
| 2389 | zig_bit_reverse_u64(zig_hi_u128(val), UINT8_C(64))), | 2751 | zig_bitReverse_u64(zig_lo_u128(arg), UINT8_C(64)), |
| 2390 | UINT8_C(128) - bits); | 2752 | zig_bitReverse_u64(zig_hi_u128(arg), UINT8_C(64)) |
| 2753 | ), UINT8_C(128) - bits); | ||
| 2391 | } | 2754 | } |
| 2392 | 2755 | ||
| 2393 | static inline zig_i128 zig_bit_reverse_i128(zig_i128 val, uint8_t bits) { | 2756 | static inline zig_i128 zig_bitReverse_i128(zig_i128 arg, uint8_t bits) { |
| 2394 | return zig_bitCast_i128(zig_bit_reverse_u128(zig_bitCast_u128(val), bits)); | 2757 | return zig_i128_bitCast_u128(zig_bitReverse_u128(zig_u128_bitCast_i128(arg, bits), bits), bits); |
| 2395 | } | 2758 | } |
| 2396 | 2759 | ||
| 2397 | #if zig_has_int128 | 2760 | #if zig_has_int128 |
| ... | @@ -2411,15 +2774,218 @@ static inline zig_i128 zig_bit_reverse_i128(zig_i128 val, uint8_t bits) { | ... | @@ -2411,15 +2774,218 @@ static inline zig_i128 zig_bit_reverse_i128(zig_i128 val, uint8_t bits) { |
| 2411 | /* ========================== Big Integer Support =========================== */ | 2774 | /* ========================== Big Integer Support =========================== */ |
| 2412 | 2775 | ||
| 2413 | static inline uint16_t zig_int_bytes(uint16_t bits) { | 2776 | static inline uint16_t zig_int_bytes(uint16_t bits) { |
| 2414 | uint16_t bytes = (bits + CHAR_BIT - 1) / CHAR_BIT; | 2777 | uint16_t bytes = (bits - UINT16_C(1)) / CHAR_BIT + UINT16_C(1); |
| 2415 | uint16_t alignment = ZIG_TARGET_MAX_INT_ALIGNMENT; | 2778 | uint16_t alignment = ZIG_TARGET_MAX_INT_ALIGNMENT; |
| 2779 | |||
| 2416 | while (alignment / 2 >= bytes) alignment /= 2; | 2780 | while (alignment / 2 >= bytes) alignment /= 2; |
| 2417 | return (bytes + alignment - 1) / alignment * alignment; | 2781 | return (bytes + alignment - 1) / alignment * alignment; |
| 2418 | } | 2782 | } |
| 2419 | 2783 | ||
| 2420 | static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | 2784 | static inline void zig_minInt_big(void *res, bool is_signed, uint16_t bits) { |
| 2785 | uint8_t *res_bytes = res; | ||
| 2786 | uint16_t size = zig_int_bytes(bits); | ||
| 2787 | uint16_t byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)); | ||
| 2788 | uint16_t remainder_bits = zig_u8_truncate_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT8_C(1); | ||
| 2789 | uint8_t sign_byte; | ||
| 2790 | uint8_t fill_byte; | ||
| 2791 | |||
| 2792 | if (is_signed) { | ||
| 2793 | int8_t signed_sign_byte = zig_minInt_i(8, remainder_bits); | ||
| 2794 | |||
| 2795 | sign_byte = zig_u8_bitCast_i8(signed_sign_byte, UINT8_C(8)); | ||
| 2796 | fill_byte = zig_u8_bitCast_i8(zig_shr_i8(signed_sign_byte, UINT8_C(7)), UINT8_C(8)); | ||
| 2797 | } else { | ||
| 2798 | sign_byte = zig_minInt_u(8, remainder_bits); | ||
| 2799 | fill_byte = UINT8_C(0); | ||
| 2800 | } | ||
| 2801 | |||
| 2802 | #if zig_little_endian | ||
| 2803 | memset(&res_bytes[0], zig_minInt_u8, byte_offset); | ||
| 2804 | res_bytes[byte_offset] = sign_byte; | ||
| 2805 | byte_offset += UINT16_C(1); | ||
| 2806 | memset(&res_bytes[byte_offset], fill_byte, size - byte_offset); | ||
| 2807 | #else | ||
| 2808 | byte_offset = size - UINT16_C(1) - byte_offset; | ||
| 2809 | memset(&res_bytes[0], fill_byte, byte_offset); | ||
| 2810 | res_bytes[byte_offset] = sign_byte; | ||
| 2811 | byte_offset += UINT16_C(1); | ||
| 2812 | memset(&res_bytes[byte_offset], zig_minInt_u8, size - byte_offset); | ||
| 2813 | #endif | ||
| 2814 | } | ||
| 2815 | |||
| 2816 | static inline void zig_maxInt_big(void *res, bool is_signed, uint16_t bits) { | ||
| 2817 | uint8_t *res_bytes = res; | ||
| 2818 | uint16_t size = zig_int_bytes(bits); | ||
| 2819 | uint16_t byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)); | ||
| 2820 | uint16_t remainder_bits = zig_u8_truncate_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT8_C(1); | ||
| 2821 | uint8_t sign_byte; | ||
| 2822 | uint8_t fill_byte; | ||
| 2823 | |||
| 2824 | if (is_signed) { | ||
| 2825 | int8_t signed_sign_byte = zig_maxInt_i(8, remainder_bits); | ||
| 2826 | |||
| 2827 | sign_byte = zig_u8_bitCast_i8(signed_sign_byte, UINT8_C(8)); | ||
| 2828 | fill_byte = zig_u8_bitCast_i8(zig_shr_i8(signed_sign_byte, UINT8_C(7)), UINT8_C(8)); | ||
| 2829 | } else { | ||
| 2830 | sign_byte = zig_maxInt_u(8, remainder_bits); | ||
| 2831 | fill_byte = UINT8_C(0); | ||
| 2832 | } | ||
| 2833 | |||
| 2834 | #if zig_little_endian | ||
| 2835 | memset(&res_bytes[0], zig_maxInt_u8, byte_offset); | ||
| 2836 | res_bytes[byte_offset] = sign_byte; | ||
| 2837 | byte_offset += UINT16_C(1); | ||
| 2838 | memset(&res_bytes[byte_offset], fill_byte, size - byte_offset); | ||
| 2839 | #else | ||
| 2840 | byte_offset = size - UINT16_C(1) - byte_offset; | ||
| 2841 | memset(&res_bytes[0], fill_byte, byte_offset); | ||
| 2842 | res_bytes[byte_offset] = sign_byte; | ||
| 2843 | byte_offset += UINT16_C(1); | ||
| 2844 | memset(&res_bytes[byte_offset], zig_maxInt_u8, size - byte_offset); | ||
| 2845 | #endif | ||
| 2846 | } | ||
| 2847 | |||
| 2848 | static inline int8_t zig_signFill_big(const void *arg, bool is_signed, uint16_t bits) { | ||
| 2849 | const uint8_t *arg_bytes = arg; | ||
| 2850 | uint16_t byte_offset = 0; | ||
| 2851 | |||
| 2852 | if (!is_signed) return INT8_C(0); | ||
| 2853 | #if zig_little_endian | ||
| 2854 | byte_offset = zig_int_bytes(bits) - 1; | ||
| 2855 | #endif | ||
| 2856 | return zig_shr_i8(zig_i8_bitCast_u8(arg_bytes[byte_offset], UINT8_C(8)), UINT8_C(7)); | ||
| 2857 | } | ||
| 2858 | |||
| 2859 | static inline void zig_big_intCast_big(void *res, const void *arg, bool res_is_signed, uint16_t res_bits, bool arg_is_signed, uint16_t arg_bits) { | ||
| 2860 | uint8_t *res_bytes = res; | ||
| 2861 | const uint8_t *arg_bytes = arg; | ||
| 2862 | uint16_t res_size = zig_int_bytes(res_bits); | ||
| 2863 | uint16_t arg_size = zig_int_bytes(arg_bits); | ||
| 2864 | uint16_t copy_size = zig_min_u16(res_size, arg_size); | ||
| 2865 | uint8_t sign_fill = zig_u8_bitCast_i8(zig_signFill_big(arg, arg_is_signed, arg_bits), UINT8_C(8)); | ||
| 2866 | |||
| 2867 | #if zig_little_endian | ||
| 2868 | memcpy(&res_bytes[0], &arg_bytes[0], copy_size); | ||
| 2869 | memset(&res_bytes[copy_size], sign_fill, res_size - copy_size); | ||
| 2870 | #else | ||
| 2871 | memset(&res_bytes[0], sign_fill, res_size - copy_size); | ||
| 2872 | memcpy(&res_bytes[res_size - copy_size], &arg_bytes[arg_size - copy_size], copy_size); | ||
| 2873 | #endif | ||
| 2874 | } | ||
| 2875 | |||
| 2876 | static inline void zig_big_truncate_big(void *res, const void *arg, bool res_is_signed, uint16_t res_bits, bool arg_is_signed, uint16_t arg_bits) { | ||
| 2877 | uint8_t *res_bytes = res; | ||
| 2878 | const uint8_t *arg_bytes = arg; | ||
| 2879 | uint16_t res_size = zig_int_bytes(res_bits); | ||
| 2880 | |||
| 2881 | if (res_is_signed != arg_is_signed) zig_unreachable(); | ||
| 2882 | if (res_bits > arg_bits) zig_unreachable(); | ||
| 2883 | |||
| 2884 | if (res_is_signed) { | ||
| 2885 | uint16_t arg_byte_offset = UINT16_C(0); | ||
| 2886 | |||
| 2887 | #if zig_big_endian | ||
| 2888 | arg_byte_offset = zig_int_bytes(arg_bits) - res_size; | ||
| 2889 | #endif | ||
| 2890 | |||
| 2891 | memcpy(&res_bytes[0], &arg_bytes[arg_byte_offset], res_size); | ||
| 2892 | } else { | ||
| 2893 | uint16_t res_byte_offset = zig_shr_u16(res_bits - UINT16_C(1), UINT8_C(3)); | ||
| 2894 | uint16_t arg_byte_offset = res_byte_offset; | ||
| 2895 | |||
| 2896 | #if zig_little_endian | ||
| 2897 | memcpy(&res_bytes[0], &arg_bytes[0], res_byte_offset); | ||
| 2898 | #else | ||
| 2899 | res_byte_offset = res_size - UINT16_C(1) - res_byte_offset; | ||
| 2900 | arg_byte_offset = zig_int_bytes(arg_bits) - UINT16_C(1) - arg_byte_offset; | ||
| 2901 | |||
| 2902 | memset(&res_bytes[0], zig_minInt_u8, res_byte_offset); | ||
| 2903 | #endif | ||
| 2904 | |||
| 2905 | res_bytes[res_byte_offset] = zig_u8_truncate_u8( | ||
| 2906 | arg_bytes[arg_byte_offset], | ||
| 2907 | zig_u8_truncate_u8(res_bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1) | ||
| 2908 | ); | ||
| 2909 | res_byte_offset += UINT16_C(1); | ||
| 2910 | arg_byte_offset += UINT16_C(1); | ||
| 2911 | |||
| 2912 | #if zig_little_endian | ||
| 2913 | memset(&res_bytes[res_byte_offset], zig_minInt_u8, res_size - res_byte_offset); | ||
| 2914 | #else | ||
| 2915 | memcpy(&res_bytes[res_byte_offset], &arg_bytes[arg_byte_offset], res_size - res_byte_offset); | ||
| 2916 | #endif | ||
| 2917 | } | ||
| 2918 | } | ||
| 2919 | |||
| 2920 | #define zig_big_casts(is, s, w, IntType) \ | ||
| 2921 | static inline IntType zig_##s##w##_intCast_big(const void *arg, bool arg_is_signed, uint16_t arg_bits) { \ | ||
| 2922 | IntType res; \ | ||
| 2923 | zig_big_intCast_big(&res, arg, is, w, arg_is_signed, arg_bits); \ | ||
| 2924 | return res; \ | ||
| 2925 | } \ | ||
| 2926 | \ | ||
| 2927 | static inline void zig_big_intCast_##s##w(void *res, IntType arg, bool res_is_signed, uint16_t res_bits) { \ | ||
| 2928 | zig_big_intCast_big(res, &arg, res_is_signed, res_bits, is, w); \ | ||
| 2929 | } \ | ||
| 2930 | \ | ||
| 2931 | static inline IntType zig_##s##w##_truncate_big(const void *arg, uint8_t res_bits, bool arg_is_signed, uint16_t arg_bits) { \ | ||
| 2932 | IntType res; \ | ||
| 2933 | zig_big_truncate_big(&res, arg, is, res_bits, arg_is_signed, arg_bits); \ | ||
| 2934 | return res; \ | ||
| 2935 | } \ | ||
| 2936 | \ | ||
| 2937 | static inline void zig_big_truncate_##s##w(void *res, IntType arg, bool res_is_signed, uint16_t res_bits) { \ | ||
| 2938 | zig_big_truncate_big(res, &arg, res_is_signed, res_bits, is, w); \ | ||
| 2939 | } | ||
| 2940 | zig_big_casts(false, u, 8, uint8_t) | ||
| 2941 | zig_big_casts(true , i, 8, int8_t) | ||
| 2942 | zig_big_casts(false, u, 16, uint16_t) | ||
| 2943 | zig_big_casts(true , i, 16, int16_t) | ||
| 2944 | zig_big_casts(false, u, 32, uint32_t) | ||
| 2945 | zig_big_casts(true , i, 32, int32_t) | ||
| 2946 | zig_big_casts(false, u, 64, uint64_t) | ||
| 2947 | zig_big_casts(true , i, 64, int64_t) | ||
| 2948 | zig_big_casts(false, u, 128, zig_u128) | ||
| 2949 | zig_big_casts(true , i, 128, zig_i128) | ||
| 2950 | |||
| 2951 | static inline void zig_big_bitCast_big(void *res, const void *arg, bool res_is_signed, uint16_t bits) { | ||
| 2952 | uint8_t *res_bytes = res; | ||
| 2953 | const uint8_t *arg_bytes = arg; | ||
| 2954 | uint16_t size = zig_int_bytes(bits); | ||
| 2955 | uint16_t byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)); | ||
| 2956 | uint16_t remainder_bits = zig_u8_truncate_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT8_C(1); | ||
| 2957 | uint8_t sign_byte; | ||
| 2958 | uint8_t fill_byte; | ||
| 2959 | |||
| 2960 | #if zig_big_endian | ||
| 2961 | byte_offset = size - UINT16_C(1) - byte_offset; | ||
| 2962 | #endif | ||
| 2963 | |||
| 2964 | if (res_is_signed) { | ||
| 2965 | int8_t signed_sign_byte = zig_i8_bitCast_u8(arg_bytes[byte_offset], remainder_bits); | ||
| 2966 | |||
| 2967 | sign_byte = zig_u8_bitCast_i8(signed_sign_byte, UINT8_C(8)); | ||
| 2968 | fill_byte = zig_u8_bitCast_i8(zig_shr_i8(signed_sign_byte, UINT8_C(7)), UINT8_C(8)); | ||
| 2969 | } else { | ||
| 2970 | sign_byte = zig_u8_bitCast_u8(arg_bytes[byte_offset], remainder_bits); | ||
| 2971 | fill_byte = UINT8_C(0); | ||
| 2972 | } | ||
| 2973 | |||
| 2974 | #if zig_little_endian | ||
| 2975 | memcpy(&res_bytes[0], &arg_bytes[0], byte_offset); | ||
| 2976 | res_bytes[byte_offset] = sign_byte; | ||
| 2977 | byte_offset += UINT16_C(1); | ||
| 2978 | memset(&res_bytes[byte_offset], fill_byte, size - byte_offset); | ||
| 2979 | #else | ||
| 2980 | memset(&res_bytes[0], fill_byte, byte_offset); | ||
| 2981 | res_bytes[byte_offset] = sign_byte; | ||
| 2982 | byte_offset += UINT16_C(1); | ||
| 2983 | memcpy(&res_bytes[byte_offset], &arg_bytes[byte_offset], size - byte_offset); | ||
| 2984 | #endif | ||
| 2985 | } | ||
| 2986 | |||
| 2987 | static inline int32_t zig_cmp_big_u8(const void *lhs, uint8_t rhs, bool is_signed, uint16_t bits) { | ||
| 2421 | const uint8_t *lhs_bytes = lhs; | 2988 | const uint8_t *lhs_bytes = lhs; |
| 2422 | const uint8_t *rhs_bytes = rhs; | ||
| 2423 | uint16_t byte_offset = 0; | 2989 | uint16_t byte_offset = 0; |
| 2424 | bool do_signed = is_signed; | 2990 | bool do_signed = is_signed; |
| 2425 | uint16_t remaining_bytes = zig_int_bytes(bits); | 2991 | uint16_t remaining_bytes = zig_int_bytes(bits); |
| ... | @@ -2429,6 +2995,7 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign | ... | @@ -2429,6 +2995,7 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign |
| 2429 | #endif | 2995 | #endif |
| 2430 | 2996 | ||
| 2431 | while (remaining_bytes >= 128 / CHAR_BIT) { | 2997 | while (remaining_bytes >= 128 / CHAR_BIT) { |
| 2998 | uint8_t rhs_byte = remaining_bytes == 128 / CHAR_BIT ? rhs : UINT8_C(0); | ||
| 2432 | int32_t limb_cmp; | 2999 | int32_t limb_cmp; |
| 2433 | 3000 | ||
| 2434 | #if zig_little_endian | 3001 | #if zig_little_endian |
| ... | @@ -2437,18 +3004,16 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign | ... | @@ -2437,18 +3004,16 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign |
| 2437 | 3004 | ||
| 2438 | if (do_signed) { | 3005 | if (do_signed) { |
| 2439 | zig_i128 lhs_limb; | 3006 | zig_i128 lhs_limb; |
| 2440 | zig_i128 rhs_limb; | 3007 | zig_i128 rhs_limb = zig_i128_intCast_u8(rhs_byte); |
| 2441 | 3008 | ||
| 2442 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | 3009 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); |
| 2443 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 2444 | limb_cmp = zig_cmp_i128(lhs_limb, rhs_limb); | 3010 | limb_cmp = zig_cmp_i128(lhs_limb, rhs_limb); |
| 2445 | do_signed = false; | 3011 | do_signed = false; |
| 2446 | } else { | 3012 | } else { |
| 2447 | zig_u128 lhs_limb; | 3013 | zig_u128 lhs_limb; |
| 2448 | zig_u128 rhs_limb; | 3014 | zig_u128 rhs_limb = zig_u128_intCast_u8(rhs_byte); |
| 2449 | 3015 | ||
| 2450 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | 3016 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); |
| 2451 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 2452 | limb_cmp = zig_cmp_u128(lhs_limb, rhs_limb); | 3017 | limb_cmp = zig_cmp_u128(lhs_limb, rhs_limb); |
| 2453 | } | 3018 | } |
| 2454 | 3019 | ||
| ... | @@ -2461,24 +3026,24 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign | ... | @@ -2461,24 +3026,24 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign |
| 2461 | } | 3026 | } |
| 2462 | 3027 | ||
| 2463 | while (remaining_bytes >= 64 / CHAR_BIT) { | 3028 | while (remaining_bytes >= 64 / CHAR_BIT) { |
| 3029 | uint8_t rhs_byte = remaining_bytes == 64 / CHAR_BIT ? rhs : UINT8_C(0); | ||
| 3030 | |||
| 2464 | #if zig_little_endian | 3031 | #if zig_little_endian |
| 2465 | byte_offset -= 64 / CHAR_BIT; | 3032 | byte_offset -= 64 / CHAR_BIT; |
| 2466 | #endif | 3033 | #endif |
| 2467 | 3034 | ||
| 2468 | if (do_signed) { | 3035 | if (do_signed) { |
| 2469 | int64_t lhs_limb; | 3036 | int64_t lhs_limb; |
| 2470 | int64_t rhs_limb; | 3037 | int64_t rhs_limb = zig_i64_intCast_u8(rhs_byte); |
| 2471 | 3038 | ||
| 2472 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | 3039 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); |
| 2473 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 2474 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); | 3040 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); |
| 2475 | do_signed = false; | 3041 | do_signed = false; |
| 2476 | } else { | 3042 | } else { |
| 2477 | uint64_t lhs_limb; | 3043 | uint64_t lhs_limb; |
| 2478 | uint64_t rhs_limb; | 3044 | uint64_t rhs_limb = zig_u64_intCast_u8(rhs_byte); |
| 2479 | 3045 | ||
| 2480 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | 3046 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); |
| 2481 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 2482 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); | 3047 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); |
| 2483 | } | 3048 | } |
| 2484 | 3049 | ||
| ... | @@ -2490,24 +3055,24 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign | ... | @@ -2490,24 +3055,24 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign |
| 2490 | } | 3055 | } |
| 2491 | 3056 | ||
| 2492 | while (remaining_bytes >= 32 / CHAR_BIT) { | 3057 | while (remaining_bytes >= 32 / CHAR_BIT) { |
| 3058 | uint8_t rhs_byte = remaining_bytes == 32 / CHAR_BIT ? rhs : UINT8_C(0); | ||
| 3059 | |||
| 2493 | #if zig_little_endian | 3060 | #if zig_little_endian |
| 2494 | byte_offset -= 32 / CHAR_BIT; | 3061 | byte_offset -= 32 / CHAR_BIT; |
| 2495 | #endif | 3062 | #endif |
| 2496 | 3063 | ||
| 2497 | if (do_signed) { | 3064 | if (do_signed) { |
| 2498 | int32_t lhs_limb; | 3065 | int32_t lhs_limb; |
| 2499 | int32_t rhs_limb; | 3066 | int32_t rhs_limb = zig_i32_intCast_u8(rhs_byte); |
| 2500 | 3067 | ||
| 2501 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | 3068 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); |
| 2502 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 2503 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); | 3069 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); |
| 2504 | do_signed = false; | 3070 | do_signed = false; |
| 2505 | } else { | 3071 | } else { |
| 2506 | uint32_t lhs_limb; | 3072 | uint32_t lhs_limb; |
| 2507 | uint32_t rhs_limb; | 3073 | uint32_t rhs_limb = zig_u32_intCast_u8(rhs_byte); |
| 2508 | 3074 | ||
| 2509 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | 3075 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); |
| 2510 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 2511 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); | 3076 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); |
| 2512 | } | 3077 | } |
| 2513 | 3078 | ||
| ... | @@ -2519,24 +3084,24 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign | ... | @@ -2519,24 +3084,24 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign |
| 2519 | } | 3084 | } |
| 2520 | 3085 | ||
| 2521 | while (remaining_bytes >= 16 / CHAR_BIT) { | 3086 | while (remaining_bytes >= 16 / CHAR_BIT) { |
| 3087 | uint8_t rhs_byte = remaining_bytes == 16 / CHAR_BIT ? rhs : UINT8_C(0); | ||
| 3088 | |||
| 2522 | #if zig_little_endian | 3089 | #if zig_little_endian |
| 2523 | byte_offset -= 16 / CHAR_BIT; | 3090 | byte_offset -= 16 / CHAR_BIT; |
| 2524 | #endif | 3091 | #endif |
| 2525 | 3092 | ||
| 2526 | if (do_signed) { | 3093 | if (do_signed) { |
| 2527 | int16_t lhs_limb; | 3094 | int16_t lhs_limb; |
| 2528 | int16_t rhs_limb; | 3095 | int16_t rhs_limb = zig_i16_intCast_u8(rhs_byte); |
| 2529 | 3096 | ||
| 2530 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | 3097 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); |
| 2531 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 2532 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); | 3098 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); |
| 2533 | do_signed = false; | 3099 | do_signed = false; |
| 2534 | } else { | 3100 | } else { |
| 2535 | uint16_t lhs_limb; | 3101 | uint16_t lhs_limb; |
| 2536 | uint16_t rhs_limb; | 3102 | uint16_t rhs_limb = zig_u16_intCast_u8(rhs_byte); |
| 2537 | 3103 | ||
| 2538 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | 3104 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); |
| 2539 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 2540 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); | 3105 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); |
| 2541 | } | 3106 | } |
| 2542 | 3107 | ||
| ... | @@ -2548,24 +3113,26 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign | ... | @@ -2548,24 +3113,26 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign |
| 2548 | } | 3113 | } |
| 2549 | 3114 | ||
| 2550 | while (remaining_bytes >= 8 / CHAR_BIT) { | 3115 | while (remaining_bytes >= 8 / CHAR_BIT) { |
| 3116 | uint8_t rhs_byte = remaining_bytes == 16 / CHAR_BIT ? rhs : UINT8_C(0); | ||
| 3117 | |||
| 2551 | #if zig_little_endian | 3118 | #if zig_little_endian |
| 2552 | byte_offset -= 8 / CHAR_BIT; | 3119 | byte_offset -= 8 / CHAR_BIT; |
| 2553 | #endif | 3120 | #endif |
| 2554 | 3121 | ||
| 2555 | if (do_signed) { | 3122 | if (do_signed) { |
| 2556 | int8_t lhs_limb; | 3123 | int8_t lhs_limb; |
| 2557 | int8_t rhs_limb; | 3124 | int16_t lhs_cmp_limb; |
| 3125 | int16_t rhs_cmp_limb = zig_i16_intCast_u8(rhs_byte); | ||
| 2558 | 3126 | ||
| 2559 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | 3127 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); |
| 2560 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | 3128 | lhs_cmp_limb = zig_i16_intCast_i8(lhs_limb); |
| 2561 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); | 3129 | if (lhs_cmp_limb != rhs_cmp_limb) return (lhs_cmp_limb > rhs_cmp_limb) - (lhs_cmp_limb < rhs_cmp_limb); |
| 2562 | do_signed = false; | 3130 | do_signed = false; |
| 2563 | } else { | 3131 | } else { |
| 2564 | uint8_t lhs_limb; | 3132 | uint8_t lhs_limb; |
| 2565 | uint8_t rhs_limb; | 3133 | uint8_t rhs_limb = rhs_byte; |
| 2566 | 3134 | ||
| 2567 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | 3135 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); |
| 2568 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 2569 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); | 3136 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); |
| 2570 | } | 3137 | } |
| 2571 | 3138 | ||
| ... | @@ -2579,148 +3146,472 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign | ... | @@ -2579,148 +3146,472 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign |
| 2579 | return 0; | 3146 | return 0; |
| 2580 | } | 3147 | } |
| 2581 | 3148 | ||
| 2582 | static inline void zig_and_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | 3149 | static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { |
| 2583 | uint8_t *res_bytes = res; | ||
| 2584 | const uint8_t *lhs_bytes = lhs; | 3150 | const uint8_t *lhs_bytes = lhs; |
| 2585 | const uint8_t *rhs_bytes = rhs; | 3151 | const uint8_t *rhs_bytes = rhs; |
| 2586 | uint16_t byte_offset = 0; | 3152 | uint16_t byte_offset = 0; |
| 3153 | bool do_signed = is_signed; | ||
| 2587 | uint16_t remaining_bytes = zig_int_bytes(bits); | 3154 | uint16_t remaining_bytes = zig_int_bytes(bits); |
| 2588 | (void)is_signed; | 3155 | |
| 3156 | #if zig_little_endian | ||
| 3157 | byte_offset = remaining_bytes; | ||
| 3158 | #endif | ||
| 2589 | 3159 | ||
| 2590 | while (remaining_bytes >= 128 / CHAR_BIT) { | 3160 | while (remaining_bytes >= 128 / CHAR_BIT) { |
| 2591 | zig_u128 res_limb; | 3161 | int32_t limb_cmp; |
| 2592 | zig_u128 lhs_limb; | ||
| 2593 | zig_u128 rhs_limb; | ||
| 2594 | 3162 | ||
| 2595 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | 3163 | #if zig_little_endian |
| 2596 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | 3164 | byte_offset -= 128 / CHAR_BIT; |
| 2597 | res_limb = zig_and_u128(lhs_limb, rhs_limb); | 3165 | #endif |
| 2598 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | 3166 | |
| 3167 | if (do_signed) { | ||
| 3168 | zig_i128 lhs_limb; | ||
| 3169 | zig_i128 rhs_limb; | ||
| 3170 | |||
| 3171 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | ||
| 3172 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 3173 | limb_cmp = zig_cmp_i128(lhs_limb, rhs_limb); | ||
| 3174 | do_signed = false; | ||
| 3175 | } else { | ||
| 3176 | zig_u128 lhs_limb; | ||
| 3177 | zig_u128 rhs_limb; | ||
| 3178 | |||
| 3179 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | ||
| 3180 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 3181 | limb_cmp = zig_cmp_u128(lhs_limb, rhs_limb); | ||
| 3182 | } | ||
| 2599 | 3183 | ||
| 3184 | if (limb_cmp != 0) return limb_cmp; | ||
| 2600 | remaining_bytes -= 128 / CHAR_BIT; | 3185 | remaining_bytes -= 128 / CHAR_BIT; |
| 3186 | |||
| 3187 | #if zig_big_endian | ||
| 2601 | byte_offset += 128 / CHAR_BIT; | 3188 | byte_offset += 128 / CHAR_BIT; |
| 3189 | #endif | ||
| 2602 | } | 3190 | } |
| 2603 | 3191 | ||
| 2604 | while (remaining_bytes >= 64 / CHAR_BIT) { | 3192 | while (remaining_bytes >= 64 / CHAR_BIT) { |
| 2605 | uint64_t res_limb; | 3193 | #if zig_little_endian |
| 2606 | uint64_t lhs_limb; | 3194 | byte_offset -= 64 / CHAR_BIT; |
| 2607 | uint64_t rhs_limb; | 3195 | #endif |
| 2608 | 3196 | ||
| 2609 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | 3197 | if (do_signed) { |
| 2610 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | 3198 | int64_t lhs_limb; |
| 2611 | res_limb = zig_and_u64(lhs_limb, rhs_limb); | 3199 | int64_t rhs_limb; |
| 2612 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | 3200 | |
| 3201 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | ||
| 3202 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 3203 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); | ||
| 3204 | do_signed = false; | ||
| 3205 | } else { | ||
| 3206 | uint64_t lhs_limb; | ||
| 3207 | uint64_t rhs_limb; | ||
| 3208 | |||
| 3209 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | ||
| 3210 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 3211 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); | ||
| 3212 | } | ||
| 2613 | 3213 | ||
| 2614 | remaining_bytes -= 64 / CHAR_BIT; | 3214 | remaining_bytes -= 64 / CHAR_BIT; |
| 3215 | |||
| 3216 | #if zig_big_endian | ||
| 2615 | byte_offset += 64 / CHAR_BIT; | 3217 | byte_offset += 64 / CHAR_BIT; |
| 3218 | #endif | ||
| 2616 | } | 3219 | } |
| 2617 | 3220 | ||
| 2618 | while (remaining_bytes >= 32 / CHAR_BIT) { | 3221 | while (remaining_bytes >= 32 / CHAR_BIT) { |
| 2619 | uint32_t res_limb; | 3222 | #if zig_little_endian |
| 2620 | uint32_t lhs_limb; | 3223 | byte_offset -= 32 / CHAR_BIT; |
| 2621 | uint32_t rhs_limb; | 3224 | #endif |
| 2622 | 3225 | ||
| 2623 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | 3226 | if (do_signed) { |
| 2624 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | 3227 | int32_t lhs_limb; |
| 2625 | res_limb = zig_and_u32(lhs_limb, rhs_limb); | 3228 | int32_t rhs_limb; |
| 2626 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | 3229 | |
| 3230 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | ||
| 3231 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 3232 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); | ||
| 3233 | do_signed = false; | ||
| 3234 | } else { | ||
| 3235 | uint32_t lhs_limb; | ||
| 3236 | uint32_t rhs_limb; | ||
| 3237 | |||
| 3238 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | ||
| 3239 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 3240 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); | ||
| 3241 | } | ||
| 2627 | 3242 | ||
| 2628 | remaining_bytes -= 32 / CHAR_BIT; | 3243 | remaining_bytes -= 32 / CHAR_BIT; |
| 3244 | |||
| 3245 | #if zig_big_endian | ||
| 2629 | byte_offset += 32 / CHAR_BIT; | 3246 | byte_offset += 32 / CHAR_BIT; |
| 3247 | #endif | ||
| 2630 | } | 3248 | } |
| 2631 | 3249 | ||
| 2632 | while (remaining_bytes >= 16 / CHAR_BIT) { | 3250 | while (remaining_bytes >= 16 / CHAR_BIT) { |
| 2633 | uint16_t res_limb; | 3251 | #if zig_little_endian |
| 2634 | uint16_t lhs_limb; | 3252 | byte_offset -= 16 / CHAR_BIT; |
| 2635 | uint16_t rhs_limb; | 3253 | #endif |
| 2636 | 3254 | ||
| 2637 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | 3255 | if (do_signed) { |
| 2638 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | 3256 | int16_t lhs_limb; |
| 2639 | res_limb = zig_and_u16(lhs_limb, rhs_limb); | 3257 | int16_t rhs_limb; |
| 2640 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | 3258 | |
| 3259 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | ||
| 3260 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 3261 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); | ||
| 3262 | do_signed = false; | ||
| 3263 | } else { | ||
| 3264 | uint16_t lhs_limb; | ||
| 3265 | uint16_t rhs_limb; | ||
| 3266 | |||
| 3267 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | ||
| 3268 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 3269 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); | ||
| 3270 | } | ||
| 2641 | 3271 | ||
| 2642 | remaining_bytes -= 16 / CHAR_BIT; | 3272 | remaining_bytes -= 16 / CHAR_BIT; |
| 3273 | |||
| 3274 | #if zig_big_endian | ||
| 2643 | byte_offset += 16 / CHAR_BIT; | 3275 | byte_offset += 16 / CHAR_BIT; |
| 3276 | #endif | ||
| 2644 | } | 3277 | } |
| 2645 | 3278 | ||
| 2646 | while (remaining_bytes >= 8 / CHAR_BIT) { | 3279 | while (remaining_bytes >= 8 / CHAR_BIT) { |
| 2647 | uint8_t res_limb; | 3280 | #if zig_little_endian |
| 2648 | uint8_t lhs_limb; | 3281 | byte_offset -= 8 / CHAR_BIT; |
| 2649 | uint8_t rhs_limb; | 3282 | #endif |
| 2650 | 3283 | ||
| 2651 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | 3284 | if (do_signed) { |
| 2652 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | 3285 | int8_t lhs_limb; |
| 2653 | res_limb = zig_and_u8(lhs_limb, rhs_limb); | 3286 | int8_t rhs_limb; |
| 2654 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | 3287 | |
| 3288 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | ||
| 3289 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 3290 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); | ||
| 3291 | do_signed = false; | ||
| 3292 | } else { | ||
| 3293 | uint8_t lhs_limb; | ||
| 3294 | uint8_t rhs_limb; | ||
| 3295 | |||
| 3296 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | ||
| 3297 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 3298 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); | ||
| 3299 | } | ||
| 2655 | 3300 | ||
| 2656 | remaining_bytes -= 8 / CHAR_BIT; | 3301 | remaining_bytes -= 8 / CHAR_BIT; |
| 3302 | |||
| 3303 | #if zig_big_endian | ||
| 2657 | byte_offset += 8 / CHAR_BIT; | 3304 | byte_offset += 8 / CHAR_BIT; |
| 3305 | #endif | ||
| 2658 | } | 3306 | } |
| 3307 | |||
| 3308 | return 0; | ||
| 2659 | } | 3309 | } |
| 2660 | 3310 | ||
| 2661 | static inline void zig_or_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | 3311 | static inline void zig_not_big(void *res, const void *arg, bool is_signed, uint16_t bits) { |
| 2662 | uint8_t *res_bytes = res; | 3312 | uint8_t *res_bytes = res; |
| 2663 | const uint8_t *lhs_bytes = lhs; | 3313 | const uint8_t *arg_bytes = arg; |
| 2664 | const uint8_t *rhs_bytes = rhs; | ||
| 2665 | uint16_t byte_offset = 0; | 3314 | uint16_t byte_offset = 0; |
| 2666 | uint16_t remaining_bytes = zig_int_bytes(bits); | 3315 | uint16_t remaining_bytes = zig_int_bytes(bits); |
| 2667 | (void)is_signed; | 3316 | uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits); |
| 3317 | |||
| 3318 | #if zig_big_endian | ||
| 3319 | byte_offset = remaining_bytes; | ||
| 3320 | #endif | ||
| 2668 | 3321 | ||
| 2669 | while (remaining_bytes >= 128 / CHAR_BIT) { | 3322 | while (remaining_bytes >= 128 / CHAR_BIT) { |
| 2670 | zig_u128 res_limb; | 3323 | uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0); |
| 2671 | zig_u128 lhs_limb; | ||
| 2672 | zig_u128 rhs_limb; | ||
| 2673 | 3324 | ||
| 2674 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | 3325 | #if zig_big_endian |
| 2675 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | 3326 | byte_offset -= 128 / CHAR_BIT; |
| 2676 | res_limb = zig_or_u128(lhs_limb, rhs_limb); | 3327 | #endif |
| 2677 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | 3328 | |
| 3329 | if (remaining_bytes != 128 / CHAR_BIT || is_signed) { | ||
| 3330 | zig_i128 res_limb; | ||
| 3331 | zig_i128 arg_limb; | ||
| 3332 | |||
| 3333 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); | ||
| 3334 | res_limb = zig_not_i128(arg_limb, limb_bits); | ||
| 3335 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3336 | } else { | ||
| 3337 | zig_u128 res_limb; | ||
| 3338 | zig_u128 arg_limb; | ||
| 3339 | |||
| 3340 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); | ||
| 3341 | res_limb = zig_not_u128(arg_limb, limb_bits); | ||
| 3342 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3343 | } | ||
| 2678 | 3344 | ||
| 2679 | remaining_bytes -= 128 / CHAR_BIT; | 3345 | remaining_bytes -= 128 / CHAR_BIT; |
| 3346 | |||
| 3347 | #if zig_little_endian | ||
| 2680 | byte_offset += 128 / CHAR_BIT; | 3348 | byte_offset += 128 / CHAR_BIT; |
| 3349 | #endif | ||
| 2681 | } | 3350 | } |
| 2682 | 3351 | ||
| 2683 | while (remaining_bytes >= 64 / CHAR_BIT) { | 3352 | while (remaining_bytes >= 64 / CHAR_BIT) { |
| 2684 | uint64_t res_limb; | 3353 | uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0); |
| 2685 | uint64_t lhs_limb; | ||
| 2686 | uint64_t rhs_limb; | ||
| 2687 | 3354 | ||
| 2688 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | 3355 | #if zig_big_endian |
| 2689 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | 3356 | byte_offset -= 64 / CHAR_BIT; |
| 2690 | res_limb = zig_or_u64(lhs_limb, rhs_limb); | 3357 | #endif |
| 2691 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | 3358 | |
| 3359 | if (remaining_bytes != 64 / CHAR_BIT || is_signed) { | ||
| 3360 | int64_t res_limb; | ||
| 3361 | int64_t arg_limb; | ||
| 3362 | |||
| 3363 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); | ||
| 3364 | res_limb = zig_not_i64(arg_limb, limb_bits); | ||
| 3365 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3366 | } else { | ||
| 3367 | uint64_t res_limb; | ||
| 3368 | uint64_t arg_limb; | ||
| 3369 | |||
| 3370 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); | ||
| 3371 | res_limb = zig_not_u64(arg_limb, limb_bits); | ||
| 3372 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3373 | } | ||
| 2692 | 3374 | ||
| 2693 | remaining_bytes -= 64 / CHAR_BIT; | 3375 | remaining_bytes -= 64 / CHAR_BIT; |
| 3376 | |||
| 3377 | #if zig_little_endian | ||
| 2694 | byte_offset += 64 / CHAR_BIT; | 3378 | byte_offset += 64 / CHAR_BIT; |
| 3379 | #endif | ||
| 2695 | } | 3380 | } |
| 2696 | 3381 | ||
| 2697 | while (remaining_bytes >= 32 / CHAR_BIT) { | 3382 | while (remaining_bytes >= 32 / CHAR_BIT) { |
| 2698 | uint32_t res_limb; | 3383 | uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0); |
| 2699 | uint32_t lhs_limb; | ||
| 2700 | uint32_t rhs_limb; | ||
| 2701 | 3384 | ||
| 2702 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | 3385 | #if zig_big_endian |
| 2703 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | 3386 | byte_offset -= 32 / CHAR_BIT; |
| 2704 | res_limb = zig_or_u32(lhs_limb, rhs_limb); | 3387 | #endif |
| 2705 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | 3388 | |
| 3389 | if (remaining_bytes != 32 / CHAR_BIT || is_signed) { | ||
| 3390 | int32_t res_limb; | ||
| 3391 | int32_t arg_limb; | ||
| 3392 | |||
| 3393 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); | ||
| 3394 | res_limb = zig_not_i32(arg_limb, limb_bits); | ||
| 3395 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3396 | } else { | ||
| 3397 | uint32_t res_limb; | ||
| 3398 | uint32_t arg_limb; | ||
| 3399 | |||
| 3400 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); | ||
| 3401 | res_limb = zig_not_u32(arg_limb, limb_bits); | ||
| 3402 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3403 | } | ||
| 2706 | 3404 | ||
| 2707 | remaining_bytes -= 32 / CHAR_BIT; | 3405 | remaining_bytes -= 32 / CHAR_BIT; |
| 3406 | |||
| 3407 | #if zig_little_endian | ||
| 2708 | byte_offset += 32 / CHAR_BIT; | 3408 | byte_offset += 32 / CHAR_BIT; |
| 3409 | #endif | ||
| 2709 | } | 3410 | } |
| 2710 | 3411 | ||
| 2711 | while (remaining_bytes >= 16 / CHAR_BIT) { | 3412 | while (remaining_bytes >= 16 / CHAR_BIT) { |
| 2712 | uint16_t res_limb; | 3413 | uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0); |
| 2713 | uint16_t lhs_limb; | ||
| 2714 | uint16_t rhs_limb; | ||
| 2715 | 3414 | ||
| 2716 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | 3415 | #if zig_big_endian |
| 2717 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | 3416 | byte_offset -= 16 / CHAR_BIT; |
| 2718 | res_limb = zig_or_u16(lhs_limb, rhs_limb); | 3417 | #endif |
| 2719 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 2720 | 3418 | ||
| 2721 | remaining_bytes -= 16 / CHAR_BIT; | 3419 | if (remaining_bytes != 16 / CHAR_BIT || is_signed) { |
| 2722 | byte_offset += 16 / CHAR_BIT; | 3420 | int16_t res_limb; |
| 2723 | } | 3421 | int16_t arg_limb; |
| 3422 | |||
| 3423 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); | ||
| 3424 | res_limb = zig_not_i16(arg_limb, limb_bits); | ||
| 3425 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3426 | } else { | ||
| 3427 | uint16_t res_limb; | ||
| 3428 | uint16_t arg_limb; | ||
| 3429 | |||
| 3430 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); | ||
| 3431 | res_limb = zig_not_u16(arg_limb, limb_bits); | ||
| 3432 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3433 | } | ||
| 3434 | |||
| 3435 | remaining_bytes -= 16 / CHAR_BIT; | ||
| 3436 | |||
| 3437 | #if zig_little_endian | ||
| 3438 | byte_offset += 16 / CHAR_BIT; | ||
| 3439 | #endif | ||
| 3440 | } | ||
| 3441 | |||
| 3442 | while (remaining_bytes >= 8 / CHAR_BIT) { | ||
| 3443 | uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0); | ||
| 3444 | |||
| 3445 | #if zig_big_endian | ||
| 3446 | byte_offset -= 8 / CHAR_BIT; | ||
| 3447 | #endif | ||
| 3448 | |||
| 3449 | if (remaining_bytes != 8 / CHAR_BIT || is_signed) { | ||
| 3450 | int8_t res_limb; | ||
| 3451 | int8_t arg_limb; | ||
| 3452 | |||
| 3453 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); | ||
| 3454 | res_limb = zig_not_i8(arg_limb, limb_bits); | ||
| 3455 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3456 | } else { | ||
| 3457 | uint8_t res_limb; | ||
| 3458 | uint8_t arg_limb; | ||
| 3459 | |||
| 3460 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); | ||
| 3461 | res_limb = zig_not_u8(arg_limb, limb_bits); | ||
| 3462 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3463 | } | ||
| 3464 | |||
| 3465 | remaining_bytes -= 8 / CHAR_BIT; | ||
| 3466 | |||
| 3467 | #if zig_little_endian | ||
| 3468 | byte_offset += 8 / CHAR_BIT; | ||
| 3469 | #endif | ||
| 3470 | } | ||
| 3471 | } | ||
| 3472 | |||
| 3473 | static inline void zig_and_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | ||
| 3474 | uint8_t *res_bytes = res; | ||
| 3475 | const uint8_t *lhs_bytes = lhs; | ||
| 3476 | const uint8_t *rhs_bytes = rhs; | ||
| 3477 | uint16_t byte_offset = 0; | ||
| 3478 | uint16_t remaining_bytes = zig_int_bytes(bits); | ||
| 3479 | (void)is_signed; | ||
| 3480 | |||
| 3481 | while (remaining_bytes >= 128 / CHAR_BIT) { | ||
| 3482 | zig_u128 res_limb; | ||
| 3483 | zig_u128 lhs_limb; | ||
| 3484 | zig_u128 rhs_limb; | ||
| 3485 | |||
| 3486 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | ||
| 3487 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 3488 | res_limb = zig_and_u128(lhs_limb, rhs_limb); | ||
| 3489 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3490 | |||
| 3491 | remaining_bytes -= 128 / CHAR_BIT; | ||
| 3492 | byte_offset += 128 / CHAR_BIT; | ||
| 3493 | } | ||
| 3494 | |||
| 3495 | while (remaining_bytes >= 64 / CHAR_BIT) { | ||
| 3496 | uint64_t res_limb; | ||
| 3497 | uint64_t lhs_limb; | ||
| 3498 | uint64_t rhs_limb; | ||
| 3499 | |||
| 3500 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | ||
| 3501 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 3502 | res_limb = zig_and_u64(lhs_limb, rhs_limb); | ||
| 3503 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3504 | |||
| 3505 | remaining_bytes -= 64 / CHAR_BIT; | ||
| 3506 | byte_offset += 64 / CHAR_BIT; | ||
| 3507 | } | ||
| 3508 | |||
| 3509 | while (remaining_bytes >= 32 / CHAR_BIT) { | ||
| 3510 | uint32_t res_limb; | ||
| 3511 | uint32_t lhs_limb; | ||
| 3512 | uint32_t rhs_limb; | ||
| 3513 | |||
| 3514 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | ||
| 3515 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 3516 | res_limb = zig_and_u32(lhs_limb, rhs_limb); | ||
| 3517 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3518 | |||
| 3519 | remaining_bytes -= 32 / CHAR_BIT; | ||
| 3520 | byte_offset += 32 / CHAR_BIT; | ||
| 3521 | } | ||
| 3522 | |||
| 3523 | while (remaining_bytes >= 16 / CHAR_BIT) { | ||
| 3524 | uint16_t res_limb; | ||
| 3525 | uint16_t lhs_limb; | ||
| 3526 | uint16_t rhs_limb; | ||
| 3527 | |||
| 3528 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | ||
| 3529 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 3530 | res_limb = zig_and_u16(lhs_limb, rhs_limb); | ||
| 3531 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3532 | |||
| 3533 | remaining_bytes -= 16 / CHAR_BIT; | ||
| 3534 | byte_offset += 16 / CHAR_BIT; | ||
| 3535 | } | ||
| 3536 | |||
| 3537 | while (remaining_bytes >= 8 / CHAR_BIT) { | ||
| 3538 | uint8_t res_limb; | ||
| 3539 | uint8_t lhs_limb; | ||
| 3540 | uint8_t rhs_limb; | ||
| 3541 | |||
| 3542 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | ||
| 3543 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 3544 | res_limb = zig_and_u8(lhs_limb, rhs_limb); | ||
| 3545 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3546 | |||
| 3547 | remaining_bytes -= 8 / CHAR_BIT; | ||
| 3548 | byte_offset += 8 / CHAR_BIT; | ||
| 3549 | } | ||
| 3550 | } | ||
| 3551 | |||
| 3552 | static inline void zig_or_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | ||
| 3553 | uint8_t *res_bytes = res; | ||
| 3554 | const uint8_t *lhs_bytes = lhs; | ||
| 3555 | const uint8_t *rhs_bytes = rhs; | ||
| 3556 | uint16_t byte_offset = 0; | ||
| 3557 | uint16_t remaining_bytes = zig_int_bytes(bits); | ||
| 3558 | (void)is_signed; | ||
| 3559 | |||
| 3560 | while (remaining_bytes >= 128 / CHAR_BIT) { | ||
| 3561 | zig_u128 res_limb; | ||
| 3562 | zig_u128 lhs_limb; | ||
| 3563 | zig_u128 rhs_limb; | ||
| 3564 | |||
| 3565 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | ||
| 3566 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 3567 | res_limb = zig_or_u128(lhs_limb, rhs_limb); | ||
| 3568 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3569 | |||
| 3570 | remaining_bytes -= 128 / CHAR_BIT; | ||
| 3571 | byte_offset += 128 / CHAR_BIT; | ||
| 3572 | } | ||
| 3573 | |||
| 3574 | while (remaining_bytes >= 64 / CHAR_BIT) { | ||
| 3575 | uint64_t res_limb; | ||
| 3576 | uint64_t lhs_limb; | ||
| 3577 | uint64_t rhs_limb; | ||
| 3578 | |||
| 3579 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | ||
| 3580 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 3581 | res_limb = zig_or_u64(lhs_limb, rhs_limb); | ||
| 3582 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3583 | |||
| 3584 | remaining_bytes -= 64 / CHAR_BIT; | ||
| 3585 | byte_offset += 64 / CHAR_BIT; | ||
| 3586 | } | ||
| 3587 | |||
| 3588 | while (remaining_bytes >= 32 / CHAR_BIT) { | ||
| 3589 | uint32_t res_limb; | ||
| 3590 | uint32_t lhs_limb; | ||
| 3591 | uint32_t rhs_limb; | ||
| 3592 | |||
| 3593 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | ||
| 3594 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 3595 | res_limb = zig_or_u32(lhs_limb, rhs_limb); | ||
| 3596 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3597 | |||
| 3598 | remaining_bytes -= 32 / CHAR_BIT; | ||
| 3599 | byte_offset += 32 / CHAR_BIT; | ||
| 3600 | } | ||
| 3601 | |||
| 3602 | while (remaining_bytes >= 16 / CHAR_BIT) { | ||
| 3603 | uint16_t res_limb; | ||
| 3604 | uint16_t lhs_limb; | ||
| 3605 | uint16_t rhs_limb; | ||
| 3606 | |||
| 3607 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | ||
| 3608 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 3609 | res_limb = zig_or_u16(lhs_limb, rhs_limb); | ||
| 3610 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3611 | |||
| 3612 | remaining_bytes -= 16 / CHAR_BIT; | ||
| 3613 | byte_offset += 16 / CHAR_BIT; | ||
| 3614 | } | ||
| 2724 | 3615 | ||
| 2725 | while (remaining_bytes >= 8 / CHAR_BIT) { | 3616 | while (remaining_bytes >= 8 / CHAR_BIT) { |
| 2726 | uint8_t res_limb; | 3617 | uint8_t res_limb; |
| ... | @@ -2816,13 +3707,415 @@ static inline void zig_xor_big(void *res, const void *lhs, const void *rhs, bool | ... | @@ -2816,13 +3707,415 @@ static inline void zig_xor_big(void *res, const void *lhs, const void *rhs, bool |
| 2816 | } | 3707 | } |
| 2817 | } | 3708 | } |
| 2818 | 3709 | ||
| 3710 | static inline void zig_increment_big(void *res, bool is_signed, uint16_t bits) { | ||
| 3711 | uint8_t *res_bytes = res; | ||
| 3712 | uint16_t byte_offset = 0; | ||
| 3713 | uint16_t remaining_bytes = zig_int_bytes(bits); | ||
| 3714 | uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits); | ||
| 3715 | |||
| 3716 | #if zig_big_endian | ||
| 3717 | byte_offset = remaining_bytes; | ||
| 3718 | #endif | ||
| 3719 | |||
| 3720 | while (remaining_bytes >= 128 / CHAR_BIT) { | ||
| 3721 | uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0); | ||
| 3722 | |||
| 3723 | #if zig_big_endian | ||
| 3724 | byte_offset -= 128 / CHAR_BIT; | ||
| 3725 | #endif | ||
| 3726 | |||
| 3727 | { | ||
| 3728 | zig_u128 res_limb; | ||
| 3729 | bool limb_overflow; | ||
| 3730 | |||
| 3731 | memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb)); | ||
| 3732 | limb_overflow = zig_addo_u128(&res_limb, res_limb, zig_make_u128(UINT64_C(0), UINT64_C(1)), limb_bits); | ||
| 3733 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3734 | if (!limb_overflow) return; | ||
| 3735 | } | ||
| 3736 | |||
| 3737 | remaining_bytes -= 128 / CHAR_BIT; | ||
| 3738 | |||
| 3739 | #if zig_little_endian | ||
| 3740 | byte_offset += 128 / CHAR_BIT; | ||
| 3741 | #endif | ||
| 3742 | } | ||
| 3743 | |||
| 3744 | while (remaining_bytes >= 64 / CHAR_BIT) { | ||
| 3745 | uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0); | ||
| 3746 | |||
| 3747 | #if zig_big_endian | ||
| 3748 | byte_offset -= 64 / CHAR_BIT; | ||
| 3749 | #endif | ||
| 3750 | |||
| 3751 | { | ||
| 3752 | uint64_t res_limb; | ||
| 3753 | bool limb_overflow; | ||
| 3754 | |||
| 3755 | memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb)); | ||
| 3756 | limb_overflow = zig_addo_u64(&res_limb, res_limb, UINT64_C(1), limb_bits); | ||
| 3757 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3758 | if (!limb_overflow) return; | ||
| 3759 | } | ||
| 3760 | |||
| 3761 | remaining_bytes -= 64 / CHAR_BIT; | ||
| 3762 | |||
| 3763 | #if zig_little_endian | ||
| 3764 | byte_offset += 64 / CHAR_BIT; | ||
| 3765 | #endif | ||
| 3766 | } | ||
| 3767 | |||
| 3768 | while (remaining_bytes >= 32 / CHAR_BIT) { | ||
| 3769 | uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0); | ||
| 3770 | |||
| 3771 | #if zig_big_endian | ||
| 3772 | byte_offset -= 32 / CHAR_BIT; | ||
| 3773 | #endif | ||
| 3774 | |||
| 3775 | { | ||
| 3776 | uint32_t res_limb; | ||
| 3777 | bool limb_overflow; | ||
| 3778 | |||
| 3779 | memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb)); | ||
| 3780 | limb_overflow = zig_addo_u32(&res_limb, res_limb, UINT32_C(1), limb_bits); | ||
| 3781 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3782 | if (!limb_overflow) return; | ||
| 3783 | } | ||
| 3784 | |||
| 3785 | remaining_bytes -= 32 / CHAR_BIT; | ||
| 3786 | |||
| 3787 | #if zig_little_endian | ||
| 3788 | byte_offset += 32 / CHAR_BIT; | ||
| 3789 | #endif | ||
| 3790 | } | ||
| 3791 | |||
| 3792 | while (remaining_bytes >= 16 / CHAR_BIT) { | ||
| 3793 | uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0); | ||
| 3794 | |||
| 3795 | #if zig_big_endian | ||
| 3796 | byte_offset -= 16 / CHAR_BIT; | ||
| 3797 | #endif | ||
| 3798 | |||
| 3799 | { | ||
| 3800 | uint16_t res_limb; | ||
| 3801 | bool limb_overflow; | ||
| 3802 | |||
| 3803 | memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb)); | ||
| 3804 | limb_overflow = zig_addo_u16(&res_limb, res_limb, UINT16_C(1), limb_bits); | ||
| 3805 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3806 | if (!limb_overflow) return; | ||
| 3807 | } | ||
| 3808 | |||
| 3809 | remaining_bytes -= 16 / CHAR_BIT; | ||
| 3810 | |||
| 3811 | #if zig_little_endian | ||
| 3812 | byte_offset += 16 / CHAR_BIT; | ||
| 3813 | #endif | ||
| 3814 | } | ||
| 3815 | |||
| 3816 | while (remaining_bytes >= 8 / CHAR_BIT) { | ||
| 3817 | uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0); | ||
| 3818 | |||
| 3819 | #if zig_big_endian | ||
| 3820 | byte_offset -= 8 / CHAR_BIT; | ||
| 3821 | #endif | ||
| 3822 | |||
| 3823 | { | ||
| 3824 | uint8_t res_limb; | ||
| 3825 | bool limb_overflow; | ||
| 3826 | |||
| 3827 | memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb)); | ||
| 3828 | limb_overflow = zig_addo_u8(&res_limb, res_limb, UINT8_C(1), limb_bits); | ||
| 3829 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3830 | if (!limb_overflow) return; | ||
| 3831 | } | ||
| 3832 | |||
| 3833 | remaining_bytes -= 8 / CHAR_BIT; | ||
| 3834 | |||
| 3835 | #if zig_little_endian | ||
| 3836 | byte_offset += 8 / CHAR_BIT; | ||
| 3837 | #endif | ||
| 3838 | } | ||
| 3839 | } | ||
| 3840 | |||
| 3841 | static inline void zig_decrement_big(void *res, bool is_signed, uint16_t bits) { | ||
| 3842 | uint8_t *res_bytes = res; | ||
| 3843 | uint16_t byte_offset = 0; | ||
| 3844 | uint16_t remaining_bytes = zig_int_bytes(bits); | ||
| 3845 | uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits); | ||
| 3846 | |||
| 3847 | #if zig_big_endian | ||
| 3848 | byte_offset = remaining_bytes; | ||
| 3849 | #endif | ||
| 3850 | |||
| 3851 | while (remaining_bytes >= 128 / CHAR_BIT) { | ||
| 3852 | uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0); | ||
| 3853 | |||
| 3854 | #if zig_big_endian | ||
| 3855 | byte_offset -= 128 / CHAR_BIT; | ||
| 3856 | #endif | ||
| 3857 | |||
| 3858 | { | ||
| 3859 | zig_u128 res_limb; | ||
| 3860 | bool limb_overflow; | ||
| 3861 | |||
| 3862 | memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb)); | ||
| 3863 | limb_overflow = zig_subo_u128(&res_limb, res_limb, zig_make_u128(UINT64_C(0), UINT64_C(1)), limb_bits); | ||
| 3864 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3865 | if (!limb_overflow) return; | ||
| 3866 | } | ||
| 3867 | |||
| 3868 | remaining_bytes -= 128 / CHAR_BIT; | ||
| 3869 | |||
| 3870 | #if zig_little_endian | ||
| 3871 | byte_offset += 128 / CHAR_BIT; | ||
| 3872 | #endif | ||
| 3873 | } | ||
| 3874 | |||
| 3875 | while (remaining_bytes >= 64 / CHAR_BIT) { | ||
| 3876 | uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0); | ||
| 3877 | |||
| 3878 | #if zig_big_endian | ||
| 3879 | byte_offset -= 64 / CHAR_BIT; | ||
| 3880 | #endif | ||
| 3881 | |||
| 3882 | { | ||
| 3883 | uint64_t res_limb; | ||
| 3884 | bool limb_overflow; | ||
| 3885 | |||
| 3886 | memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb)); | ||
| 3887 | limb_overflow = zig_subo_u64(&res_limb, res_limb, UINT64_C(1), limb_bits); | ||
| 3888 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3889 | if (!limb_overflow) return; | ||
| 3890 | } | ||
| 3891 | |||
| 3892 | remaining_bytes -= 64 / CHAR_BIT; | ||
| 3893 | |||
| 3894 | #if zig_little_endian | ||
| 3895 | byte_offset += 64 / CHAR_BIT; | ||
| 3896 | #endif | ||
| 3897 | } | ||
| 3898 | |||
| 3899 | while (remaining_bytes >= 32 / CHAR_BIT) { | ||
| 3900 | uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0); | ||
| 3901 | |||
| 3902 | #if zig_big_endian | ||
| 3903 | byte_offset -= 32 / CHAR_BIT; | ||
| 3904 | #endif | ||
| 3905 | |||
| 3906 | { | ||
| 3907 | uint32_t res_limb; | ||
| 3908 | bool limb_overflow; | ||
| 3909 | |||
| 3910 | memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb)); | ||
| 3911 | limb_overflow = zig_subo_u32(&res_limb, res_limb, UINT32_C(1), limb_bits); | ||
| 3912 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3913 | if (!limb_overflow) return; | ||
| 3914 | } | ||
| 3915 | |||
| 3916 | remaining_bytes -= 32 / CHAR_BIT; | ||
| 3917 | |||
| 3918 | #if zig_little_endian | ||
| 3919 | byte_offset += 32 / CHAR_BIT; | ||
| 3920 | #endif | ||
| 3921 | } | ||
| 3922 | |||
| 3923 | while (remaining_bytes >= 16 / CHAR_BIT) { | ||
| 3924 | uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0); | ||
| 3925 | |||
| 3926 | #if zig_big_endian | ||
| 3927 | byte_offset -= 16 / CHAR_BIT; | ||
| 3928 | #endif | ||
| 3929 | |||
| 3930 | { | ||
| 3931 | uint16_t res_limb; | ||
| 3932 | bool limb_overflow; | ||
| 3933 | |||
| 3934 | memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb)); | ||
| 3935 | limb_overflow = zig_subo_u16(&res_limb, res_limb, UINT16_C(1), limb_bits); | ||
| 3936 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3937 | if (!limb_overflow) return; | ||
| 3938 | } | ||
| 3939 | |||
| 3940 | remaining_bytes -= 16 / CHAR_BIT; | ||
| 3941 | |||
| 3942 | #if zig_little_endian | ||
| 3943 | byte_offset += 16 / CHAR_BIT; | ||
| 3944 | #endif | ||
| 3945 | } | ||
| 3946 | |||
| 3947 | while (remaining_bytes >= 8 / CHAR_BIT) { | ||
| 3948 | uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0); | ||
| 3949 | |||
| 3950 | #if zig_big_endian | ||
| 3951 | byte_offset -= 8 / CHAR_BIT; | ||
| 3952 | #endif | ||
| 3953 | |||
| 3954 | { | ||
| 3955 | uint8_t res_limb; | ||
| 3956 | bool limb_overflow; | ||
| 3957 | |||
| 3958 | memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb)); | ||
| 3959 | limb_overflow = zig_subo_u8(&res_limb, res_limb, UINT8_C(1), limb_bits); | ||
| 3960 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3961 | if (!limb_overflow) return; | ||
| 3962 | } | ||
| 3963 | |||
| 3964 | remaining_bytes -= 8 / CHAR_BIT; | ||
| 3965 | |||
| 3966 | #if zig_little_endian | ||
| 3967 | byte_offset += 8 / CHAR_BIT; | ||
| 3968 | #endif | ||
| 3969 | } | ||
| 3970 | } | ||
| 3971 | |||
| 3972 | static inline void zig_abs_big(void *res, const void *arg, bool is_signed, uint16_t bits) { | ||
| 3973 | uint8_t *res_bytes = res; | ||
| 3974 | const uint8_t *arg_bytes = arg; | ||
| 3975 | uint16_t byte_offset = 0; | ||
| 3976 | uint16_t remaining_bytes = zig_int_bytes(bits); | ||
| 3977 | if (zig_signFill_big(arg, is_signed, bits) >= INT8_C(0)) { | ||
| 3978 | memcpy(res, arg, remaining_bytes); | ||
| 3979 | return; | ||
| 3980 | } | ||
| 3981 | uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits); | ||
| 3982 | bool overflow = true; | ||
| 3983 | |||
| 3984 | #if zig_big_endian | ||
| 3985 | byte_offset = remaining_bytes; | ||
| 3986 | #endif | ||
| 3987 | |||
| 3988 | while (remaining_bytes >= 128 / CHAR_BIT) { | ||
| 3989 | uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0); | ||
| 3990 | |||
| 3991 | #if zig_big_endian | ||
| 3992 | byte_offset -= 128 / CHAR_BIT; | ||
| 3993 | #endif | ||
| 3994 | |||
| 3995 | { | ||
| 3996 | zig_u128 res_limb; | ||
| 3997 | zig_u128 arg_limb; | ||
| 3998 | |||
| 3999 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); | ||
| 4000 | overflow = zig_addo_u128(&res_limb, zig_not_u128(arg_limb, UINT8_C(128)), zig_make_u128(UINT64_C(0), overflow ? UINT64_C(1) : UINT64_C(0)), limb_bits); | ||
| 4001 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 4002 | } | ||
| 4003 | |||
| 4004 | remaining_bytes -= 128 / CHAR_BIT; | ||
| 4005 | |||
| 4006 | #if zig_little_endian | ||
| 4007 | byte_offset += 128 / CHAR_BIT; | ||
| 4008 | #endif | ||
| 4009 | } | ||
| 4010 | |||
| 4011 | while (remaining_bytes >= 64 / CHAR_BIT) { | ||
| 4012 | uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0); | ||
| 4013 | |||
| 4014 | #if zig_big_endian | ||
| 4015 | byte_offset -= 64 / CHAR_BIT; | ||
| 4016 | #endif | ||
| 4017 | |||
| 4018 | { | ||
| 4019 | uint64_t res_limb; | ||
| 4020 | uint64_t arg_limb; | ||
| 4021 | |||
| 4022 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); | ||
| 4023 | overflow = zig_addo_u64(&res_limb, zig_not_u64(arg_limb, UINT8_C(64)), overflow ? UINT64_C(1) : UINT64_C(0), limb_bits); | ||
| 4024 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 4025 | } | ||
| 4026 | |||
| 4027 | remaining_bytes -= 64 / CHAR_BIT; | ||
| 4028 | |||
| 4029 | #if zig_little_endian | ||
| 4030 | byte_offset += 64 / CHAR_BIT; | ||
| 4031 | #endif | ||
| 4032 | } | ||
| 4033 | |||
| 4034 | while (remaining_bytes >= 32 / CHAR_BIT) { | ||
| 4035 | uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0); | ||
| 4036 | |||
| 4037 | #if zig_big_endian | ||
| 4038 | byte_offset -= 32 / CHAR_BIT; | ||
| 4039 | #endif | ||
| 4040 | |||
| 4041 | { | ||
| 4042 | uint32_t res_limb; | ||
| 4043 | uint32_t arg_limb; | ||
| 4044 | |||
| 4045 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); | ||
| 4046 | overflow = zig_addo_u32(&res_limb, zig_not_u32(arg_limb, UINT8_C(32)), overflow ? UINT32_C(1) : UINT32_C(0), limb_bits); | ||
| 4047 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 4048 | } | ||
| 4049 | |||
| 4050 | remaining_bytes -= 32 / CHAR_BIT; | ||
| 4051 | |||
| 4052 | #if zig_little_endian | ||
| 4053 | byte_offset += 32 / CHAR_BIT; | ||
| 4054 | #endif | ||
| 4055 | } | ||
| 4056 | |||
| 4057 | while (remaining_bytes >= 16 / CHAR_BIT) { | ||
| 4058 | uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0); | ||
| 4059 | |||
| 4060 | #if zig_big_endian | ||
| 4061 | byte_offset -= 16 / CHAR_BIT; | ||
| 4062 | #endif | ||
| 4063 | |||
| 4064 | { | ||
| 4065 | uint16_t res_limb; | ||
| 4066 | uint16_t arg_limb; | ||
| 4067 | |||
| 4068 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); | ||
| 4069 | overflow = zig_addo_u16(&res_limb, zig_not_u16(arg_limb, UINT8_C(16)), overflow ? UINT16_C(1) : UINT16_C(0), limb_bits); | ||
| 4070 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 4071 | } | ||
| 4072 | |||
| 4073 | remaining_bytes -= 16 / CHAR_BIT; | ||
| 4074 | |||
| 4075 | #if zig_little_endian | ||
| 4076 | byte_offset += 16 / CHAR_BIT; | ||
| 4077 | #endif | ||
| 4078 | } | ||
| 4079 | |||
| 4080 | while (remaining_bytes >= 8 / CHAR_BIT) { | ||
| 4081 | uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0); | ||
| 4082 | |||
| 4083 | #if zig_big_endian | ||
| 4084 | byte_offset -= 8 / CHAR_BIT; | ||
| 4085 | #endif | ||
| 4086 | |||
| 4087 | { | ||
| 4088 | uint8_t res_limb; | ||
| 4089 | uint8_t arg_limb; | ||
| 4090 | |||
| 4091 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); | ||
| 4092 | overflow = zig_addo_u8(&res_limb, zig_not_u8(arg_limb, UINT8_C(8)), overflow ? UINT8_C(1) : UINT8_C(0), limb_bits); | ||
| 4093 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 4094 | } | ||
| 4095 | |||
| 4096 | remaining_bytes -= 8 / CHAR_BIT; | ||
| 4097 | |||
| 4098 | #if zig_little_endian | ||
| 4099 | byte_offset += 8 / CHAR_BIT; | ||
| 4100 | #endif | ||
| 4101 | } | ||
| 4102 | } | ||
| 4103 | |||
| 4104 | static inline void zig_min_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | ||
| 4105 | memcpy(res, zig_cmp_big(lhs, rhs, is_signed, bits) < INT32_C(0) ? lhs : rhs, zig_int_bytes(bits)); | ||
| 4106 | } | ||
| 4107 | |||
| 4108 | static inline void zig_max_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | ||
| 4109 | memcpy(res, zig_cmp_big(lhs, rhs, is_signed, bits) >= INT32_C(0) ? lhs : rhs, zig_int_bytes(bits)); | ||
| 4110 | } | ||
| 4111 | |||
| 2819 | static inline bool zig_addo_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | 4112 | static inline bool zig_addo_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { |
| 2820 | uint8_t *res_bytes = res; | 4113 | uint8_t *res_bytes = res; |
| 2821 | const uint8_t *lhs_bytes = lhs; | 4114 | const uint8_t *lhs_bytes = lhs; |
| 2822 | const uint8_t *rhs_bytes = rhs; | 4115 | const uint8_t *rhs_bytes = rhs; |
| 2823 | uint16_t byte_offset = 0; | 4116 | uint16_t byte_offset = 0; |
| 2824 | uint16_t remaining_bytes = zig_int_bytes(bits); | 4117 | uint16_t remaining_bytes = zig_int_bytes(bits); |
| 2825 | uint8_t top_bits = (uint8_t)(remaining_bytes * 8 - bits); | 4118 | uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits); |
| 2826 | bool overflow = false; | 4119 | bool overflow = false; |
| 2827 | 4120 | ||
| 2828 | #if zig_big_endian | 4121 | #if zig_big_endian |
| ... | @@ -3038,7 +4331,7 @@ static inline bool zig_subo_big(void *res, const void *lhs, const void *rhs, boo | ... | @@ -3038,7 +4331,7 @@ static inline bool zig_subo_big(void *res, const void *lhs, const void *rhs, boo |
| 3038 | const uint8_t *rhs_bytes = rhs; | 4331 | const uint8_t *rhs_bytes = rhs; |
| 3039 | uint16_t byte_offset = 0; | 4332 | uint16_t byte_offset = 0; |
| 3040 | uint16_t remaining_bytes = zig_int_bytes(bits); | 4333 | uint16_t remaining_bytes = zig_int_bytes(bits); |
| 3041 | uint8_t top_bits = (uint8_t)(remaining_bytes * 8 - bits); | 4334 | uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits); |
| 3042 | bool overflow = false; | 4335 | bool overflow = false; |
| 3043 | 4336 | ||
| 3044 | #if zig_big_endian | 4337 | #if zig_big_endian |
| ... | @@ -3238,218 +4531,890 @@ static inline bool zig_subo_big(void *res, const void *lhs, const void *rhs, boo | ... | @@ -3238,218 +4531,890 @@ static inline bool zig_subo_big(void *res, const void *lhs, const void *rhs, boo |
| 3238 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | 4531 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); |
| 3239 | } | 4532 | } |
| 3240 | 4533 | ||
| 3241 | remaining_bytes -= 8 / CHAR_BIT; | 4534 | remaining_bytes -= 8 / CHAR_BIT; |
| 4535 | |||
| 4536 | #if zig_little_endian | ||
| 4537 | byte_offset += 8 / CHAR_BIT; | ||
| 4538 | #endif | ||
| 4539 | } | ||
| 4540 | |||
| 4541 | return overflow; | ||
| 4542 | } | ||
| 4543 | |||
| 4544 | static inline void zig_add_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | ||
| 4545 | if (zig_addo_big(res, lhs, rhs, is_signed, bits)) zig_trap(); // panic: integer overflow | ||
| 4546 | } | ||
| 4547 | |||
| 4548 | static inline void zig_addw_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | ||
| 4549 | (void)zig_addo_big(res, lhs, rhs, is_signed, bits); | ||
| 4550 | } | ||
| 4551 | |||
| 4552 | static inline void zig_adds_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | ||
| 4553 | int8_t sat_sign = zig_signFill_big(lhs, is_signed, bits); | ||
| 4554 | |||
| 4555 | if (!zig_addo_big(res, lhs, rhs, is_signed, bits)) return; | ||
| 4556 | switch (sat_sign) { | ||
| 4557 | case -INT8_C(1): return zig_minInt_big(res, is_signed, bits); | ||
| 4558 | case INT8_C(0): return zig_maxInt_big(res, is_signed, bits); | ||
| 4559 | } | ||
| 4560 | } | ||
| 4561 | |||
| 4562 | static inline void zig_sub_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | ||
| 4563 | if (zig_subo_big(res, lhs, rhs, is_signed, bits)) zig_trap(); // panic: integer overflow | ||
| 4564 | } | ||
| 4565 | |||
| 4566 | static inline void zig_subw_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | ||
| 4567 | (void)zig_subo_big(res, lhs, rhs, is_signed, bits); | ||
| 4568 | } | ||
| 4569 | |||
| 4570 | static inline void zig_subs_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | ||
| 4571 | int8_t sat_sign = is_signed ? zig_signFill_big(lhs, is_signed, bits) : -INT8_C(1); | ||
| 4572 | |||
| 4573 | if (!zig_subo_big(res, lhs, rhs, is_signed, bits)) return; | ||
| 4574 | switch (sat_sign) { | ||
| 4575 | case -INT8_C(1): return zig_minInt_big(res, is_signed, bits); | ||
| 4576 | case INT8_C(0): return zig_maxInt_big(res, is_signed, bits); | ||
| 4577 | } | ||
| 4578 | } | ||
| 4579 | |||
| 4580 | static inline bool zig_mulo_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | ||
| 4581 | uint8_t *res_bytes = res; | ||
| 4582 | const uint8_t *lhs_bytes = lhs; | ||
| 4583 | const uint8_t *rhs_bytes = rhs; | ||
| 4584 | uint16_t size = zig_int_bytes(bits); | ||
| 4585 | uint16_t sign_byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1); | ||
| 4586 | uint8_t lhs_sign_fill = zig_u8_bitCast_i8(zig_signFill_big(lhs, is_signed, bits), UINT8_C(8)); | ||
| 4587 | uint8_t rhs_sign_fill = zig_u8_bitCast_i8(zig_signFill_big(rhs, is_signed, bits), UINT8_C(8)); | ||
| 4588 | uint16_t lhs_byte_offset = sign_byte_offset; | ||
| 4589 | uint16_t lhs_end_byte_offset = UINT16_C(0); | ||
| 4590 | bool overflow = false; | ||
| 4591 | |||
| 4592 | #if zig_big_endian | ||
| 4593 | lhs_byte_offset = size - lhs_byte_offset; | ||
| 4594 | lhs_end_byte_offset = size - lhs_end_byte_offset; | ||
| 4595 | #endif | ||
| 4596 | |||
| 4597 | while (lhs_byte_offset != lhs_end_byte_offset) { | ||
| 4598 | uint16_t rhs_byte_offset = UINT16_C(0); | ||
| 4599 | uint16_t end_byte_offset = sign_byte_offset; | ||
| 4600 | uint16_t res_byte_offset; | ||
| 4601 | uint16_t lhs_byte; | ||
| 4602 | uint8_t res_byte = UINT8_C(0); | ||
| 4603 | uint16_t mul_res = UINT16_C(0); | ||
| 4604 | uint8_t carry = UINT8_C(0); | ||
| 4605 | |||
| 4606 | #if zig_little_endian | ||
| 4607 | lhs_byte_offset -= UINT16_C(1); | ||
| 4608 | #else | ||
| 4609 | rhs_byte_offset = size - rhs_byte_offset; | ||
| 4610 | end_byte_offset = size - end_byte_offset; | ||
| 4611 | #endif | ||
| 4612 | |||
| 4613 | lhs_byte = zig_u16_intCast_u8(lhs_bytes[lhs_byte_offset]) ^ lhs_sign_fill; | ||
| 4614 | |||
| 4615 | #if zig_big_endian | ||
| 4616 | lhs_byte_offset += UINT16_C(1); | ||
| 4617 | #endif | ||
| 4618 | |||
| 4619 | res_byte_offset = lhs_byte_offset; | ||
| 4620 | |||
| 4621 | while (res_byte_offset != end_byte_offset) { | ||
| 4622 | bool res_byte_initialized = res_byte_offset != lhs_byte_offset; | ||
| 4623 | |||
| 4624 | #if zig_big_endian | ||
| 4625 | rhs_byte_offset -= UINT16_C(1); | ||
| 4626 | res_byte_offset -= UINT16_C(1); | ||
| 4627 | #endif | ||
| 4628 | |||
| 4629 | if (res_byte_initialized) res_byte = res_bytes[res_byte_offset]; | ||
| 4630 | carry = zig_addo_u8(&res_byte, res_byte, carry, UINT8_C(8)); | ||
| 4631 | carry += zig_addo_u8(&res_byte, res_byte, zig_u8_intCast_u16( | ||
| 4632 | zig_shr_u16(mul_res, UINT8_C(8)) | ||
| 4633 | ), UINT8_C(8)); | ||
| 4634 | mul_res = lhs_byte * zig_u16_intCast_u8(rhs_bytes[rhs_byte_offset] ^ rhs_sign_fill); | ||
| 4635 | carry += zig_addo_u8(&res_bytes[res_byte_offset], res_byte, zig_u8_truncate_u16( | ||
| 4636 | mul_res, | ||
| 4637 | UINT8_C(8) | ||
| 4638 | ), UINT8_C(8)); | ||
| 4639 | |||
| 4640 | #if zig_little_endian | ||
| 4641 | rhs_byte_offset += UINT16_C(1); | ||
| 4642 | res_byte_offset += UINT16_C(1); | ||
| 4643 | #endif | ||
| 4644 | } | ||
| 4645 | |||
| 4646 | while (rhs_byte_offset != end_byte_offset) { | ||
| 4647 | #if zig_big_endian | ||
| 4648 | rhs_byte_offset -= UINT16_C(1); | ||
| 4649 | #endif | ||
| 4650 | |||
| 4651 | carry = zig_addo_u8( | ||
| 4652 | &res_byte, | ||
| 4653 | zig_u8_intCast_u16(zig_shr_u16(mul_res, UINT8_C(8))), | ||
| 4654 | carry, | ||
| 4655 | UINT8_C(8) | ||
| 4656 | ); | ||
| 4657 | mul_res = lhs_byte * zig_u16_intCast_u8(rhs_bytes[rhs_byte_offset] ^ rhs_sign_fill); | ||
| 4658 | carry += zig_addo_u8(&res_byte, res_byte, zig_u8_truncate_u16( | ||
| 4659 | mul_res, | ||
| 4660 | UINT8_C(8) | ||
| 4661 | ), UINT8_C(8)); | ||
| 4662 | overflow |= res_byte != UINT8_C(0); | ||
| 4663 | |||
| 4664 | #if zig_little_endian | ||
| 4665 | rhs_byte_offset += UINT16_C(1); | ||
| 4666 | #endif | ||
| 4667 | } | ||
| 4668 | |||
| 4669 | overflow |= zig_shr_u16(mul_res, UINT8_C(8)) != UINT16_C(0); | ||
| 4670 | overflow |= carry != UINT8_C(0); | ||
| 4671 | } | ||
| 4672 | |||
| 4673 | #if zig_little_endian | ||
| 4674 | sign_byte_offset -= UINT64_C(1); | ||
| 4675 | #else | ||
| 4676 | sign_byte_offset = size - sign_byte_offset; | ||
| 4677 | #endif | ||
| 4678 | |||
| 4679 | if (lhs_sign_fill != rhs_sign_fill) { | ||
| 4680 | uint16_t byte_offset = UINT16_C(0); | ||
| 4681 | uint16_t end_byte_offset = sign_byte_offset; | ||
| 4682 | uint8_t res_byte; | ||
| 4683 | int8_t signed_res_byte; | ||
| 4684 | uint8_t carry = UINT8_C(0); | ||
| 4685 | |||
| 4686 | #if zig_big_endian | ||
| 4687 | byte_offset = size - byte_offset; | ||
| 4688 | end_byte_offset += UINT16_C(1); | ||
| 4689 | #endif | ||
| 4690 | |||
| 4691 | while (byte_offset != end_byte_offset) { | ||
| 4692 | #if zig_big_endian | ||
| 4693 | byte_offset -= UINT16_C(1); | ||
| 4694 | #endif | ||
| 4695 | |||
| 4696 | carry = zig_subo_u8(&res_byte, UINT8_C(0), carry, UINT8_C(8)); | ||
| 4697 | carry += zig_subo_u8(&res_byte, res_byte, res_bytes[byte_offset], UINT8_C(8)); | ||
| 4698 | carry += zig_subo_u8( | ||
| 4699 | &res_bytes[byte_offset], | ||
| 4700 | res_byte, | ||
| 4701 | (lhs_sign_fill == UINT8_C(0) ? lhs_bytes : rhs_bytes)[byte_offset], | ||
| 4702 | UINT8_C(8) | ||
| 4703 | ); | ||
| 4704 | |||
| 4705 | #if zig_little_endian | ||
| 4706 | byte_offset += UINT16_C(1); | ||
| 4707 | #endif | ||
| 4708 | } | ||
| 4709 | |||
| 4710 | #if zig_big_endian | ||
| 4711 | byte_offset -= UINT16_C(1); | ||
| 4712 | #endif | ||
| 4713 | |||
| 4714 | signed_res_byte = zig_i8_bitCast_u8(res_bytes[byte_offset], UINT8_C(8)); | ||
| 4715 | overflow |= signed_res_byte < INT8_C(0); | ||
| 4716 | overflow |= zig_subo_i8(&signed_res_byte, INT8_C(0), signed_res_byte, UINT8_C(8)); | ||
| 4717 | overflow |= zig_subo_i8(&signed_res_byte, signed_res_byte, zig_i8_intCast_u8(carry), UINT8_C(8)); | ||
| 4718 | overflow |= zig_subo_i8(&signed_res_byte, signed_res_byte, zig_i8_bitCast_u8( | ||
| 4719 | (lhs_sign_fill == UINT8_C(0) ? lhs_bytes : rhs_bytes)[byte_offset], | ||
| 4720 | UINT8_C(8) | ||
| 4721 | ), UINT8_C(8)); | ||
| 4722 | res_bytes[byte_offset] = zig_i8_bitCast_u8(signed_res_byte, UINT8_C(8)); | ||
| 4723 | } else if (lhs_sign_fill != UINT8_C(0)) { | ||
| 4724 | uint16_t byte_offset = UINT16_C(0); | ||
| 4725 | uint16_t end_byte_offset = sign_byte_offset; | ||
| 4726 | uint8_t res_byte; | ||
| 4727 | int8_t signed_res_byte; | ||
| 4728 | uint8_t carry = UINT8_C(1); | ||
| 4729 | |||
| 4730 | #if zig_big_endian | ||
| 4731 | byte_offset = size - byte_offset; | ||
| 4732 | end_byte_offset += UINT16_C(1); | ||
| 4733 | #endif | ||
| 4734 | |||
| 4735 | while (byte_offset != end_byte_offset) { | ||
| 4736 | #if zig_big_endian | ||
| 4737 | byte_offset -= UINT16_C(1); | ||
| 4738 | #endif | ||
| 4739 | |||
| 4740 | carry = zig_subo_u8(&res_byte, res_bytes[byte_offset], carry, UINT8_C(8)); | ||
| 4741 | carry += zig_subo_u8(&res_byte, res_byte, lhs_bytes[byte_offset], UINT8_C(8)); | ||
| 4742 | carry += zig_subo_u8(&res_bytes[byte_offset], res_byte, rhs_bytes[byte_offset], UINT8_C(8)); | ||
| 4743 | |||
| 4744 | #if zig_little_endian | ||
| 4745 | byte_offset += UINT16_C(1); | ||
| 4746 | #endif | ||
| 4747 | } | ||
| 4748 | |||
| 4749 | #if zig_big_endian | ||
| 4750 | byte_offset -= UINT16_C(1); | ||
| 4751 | #endif | ||
| 4752 | |||
| 4753 | signed_res_byte = zig_i8_bitCast_u8(res_bytes[byte_offset], UINT8_C(8)); | ||
| 4754 | overflow |= signed_res_byte < INT8_C(0); | ||
| 4755 | overflow |= zig_subo_i8(&signed_res_byte, signed_res_byte, zig_i8_intCast_u8(carry), UINT8_C(8)); | ||
| 4756 | overflow |= zig_subo_i8(&signed_res_byte, signed_res_byte, zig_i8_bitCast_u8( | ||
| 4757 | lhs_bytes[byte_offset], | ||
| 4758 | UINT8_C(8) | ||
| 4759 | ), UINT8_C(8)); | ||
| 4760 | overflow |= zig_subo_i8(&signed_res_byte, signed_res_byte, zig_i8_bitCast_u8( | ||
| 4761 | rhs_bytes[byte_offset], | ||
| 4762 | UINT8_C(8) | ||
| 4763 | ), UINT8_C(8)); | ||
| 4764 | res_bytes[byte_offset] = zig_i8_bitCast_u8(signed_res_byte, UINT8_C(8)); | ||
| 4765 | } else if (is_signed) { | ||
| 4766 | int8_t signed_res_byte = zig_i8_bitCast_u8(res_bytes[sign_byte_offset], UINT8_C(8)); | ||
| 4767 | |||
| 4768 | overflow |= signed_res_byte < INT8_C(0); | ||
| 4769 | } | ||
| 4770 | |||
| 4771 | { | ||
| 4772 | uint8_t truncate_bits = zig_u8_truncate_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1); | ||
| 4773 | uint8_t fill_byte = UINT8_C(0); | ||
| 4774 | |||
| 4775 | if (is_signed) { | ||
| 4776 | int8_t sign_byte = zig_i8_bitCast_u8(res_bytes[sign_byte_offset], UINT8_C(8)); | ||
| 4777 | int8_t truncated = zig_i8_truncate_i8(sign_byte, truncate_bits); | ||
| 4778 | |||
| 4779 | overflow |= sign_byte != truncated; | ||
| 4780 | res_bytes[sign_byte_offset] = zig_u8_bitCast_i8(truncated, UINT8_C(8)); | ||
| 4781 | fill_byte = zig_u8_bitCast_i8(zig_shr_i8(truncated, UINT8_C(7)), UINT8_C(8)); | ||
| 4782 | } else { | ||
| 4783 | uint8_t sign_byte = res_bytes[sign_byte_offset]; | ||
| 4784 | uint8_t truncated = zig_u8_truncate_u8(sign_byte, truncate_bits); | ||
| 4785 | |||
| 4786 | overflow |= sign_byte != truncated; | ||
| 4787 | res_bytes[sign_byte_offset] = truncated; | ||
| 4788 | } | ||
| 4789 | |||
| 4790 | #if zig_little_endian | ||
| 4791 | sign_byte_offset += UINT16_C(1); | ||
| 4792 | memset(&res_bytes[sign_byte_offset], fill_byte, size - sign_byte_offset); | ||
| 4793 | #else | ||
| 4794 | memset(&res_bytes[0], fill_byte, sign_byte_offset); | ||
| 4795 | #endif | ||
| 4796 | } | ||
| 4797 | |||
| 4798 | return overflow; | ||
| 4799 | } | ||
| 4800 | |||
| 4801 | static inline void zig_mul_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | ||
| 4802 | if (zig_mulo_big(res, lhs, rhs, is_signed, bits)) zig_trap(); // panic: integer overflow | ||
| 4803 | } | ||
| 4804 | |||
| 4805 | static inline void zig_mulw_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | ||
| 4806 | (void)zig_mulo_big(res, lhs, rhs, is_signed, bits); | ||
| 4807 | } | ||
| 4808 | |||
| 4809 | static inline void zig_muls_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | ||
| 4810 | int8_t sat_sign = zig_signFill_big(lhs, is_signed, bits) ^ zig_signFill_big(rhs, is_signed, bits); | ||
| 4811 | |||
| 4812 | if (!zig_mulo_big(res, lhs, rhs, is_signed, bits)) return; | ||
| 4813 | switch (sat_sign) { | ||
| 4814 | case -INT8_C(1): return zig_minInt_big(res, is_signed, bits); | ||
| 4815 | case INT8_C(0): return zig_maxInt_big(res, is_signed, bits); | ||
| 4816 | } | ||
| 4817 | } | ||
| 4818 | |||
| 4819 | static inline void zig_divTrunc_big(void *res, const void *lhs, const void *rhs, void *temp, bool is_signed, uint16_t bits) { | ||
| 4820 | if (is_signed) { | ||
| 4821 | zig_extern void __divei5(uint32_t *res, const uint32_t *lhs, const uint32_t *rhs, uint32_t *temp, uintptr_t bits); | ||
| 4822 | __divei5(res, lhs, rhs, temp, bits); | ||
| 4823 | } else { | ||
| 4824 | zig_extern void __udivei5(uint32_t *res, const uint32_t *lhs, const uint32_t *rhs, uint32_t *temp, uintptr_t bits); | ||
| 4825 | __udivei5(res, lhs, rhs, temp, bits); | ||
| 4826 | } | ||
| 4827 | } | ||
| 4828 | |||
| 4829 | static inline void zig_rem_big(void *res, const void *lhs, const void *rhs, void *temp, bool is_signed, uint16_t bits) { | ||
| 4830 | if (is_signed) { | ||
| 4831 | zig_extern void __modei5(uint32_t *res, const uint32_t *lhs, const uint32_t *rhs, uint32_t *temp, uintptr_t bits); | ||
| 4832 | __modei5(res, lhs, rhs, temp, bits); | ||
| 4833 | } else { | ||
| 4834 | zig_extern void __umodei5(uint32_t *res, const uint32_t *lhs, const uint32_t *rhs, uint32_t *temp, uintptr_t bits); | ||
| 4835 | __umodei5(res, lhs, rhs, temp, bits); | ||
| 4836 | } | ||
| 4837 | } | ||
| 4838 | |||
| 4839 | static inline void zig_divFloor_big(void *res, const void *lhs, const void *rhs, void *temp, bool is_signed, uint16_t bits) { | ||
| 4840 | bool decrement = false; | ||
| 4841 | |||
| 4842 | if (is_signed) { | ||
| 4843 | zig_rem_big(res, lhs, rhs, temp, is_signed, bits); | ||
| 4844 | decrement = zig_u32_bitCast_i32(zig_xor_i32( | ||
| 4845 | zig_cmp_big_u8(res, UINT8_C(0), is_signed, bits), | ||
| 4846 | zig_and_i32(zig_i32_intCast_i8(zig_signFill_big(rhs, is_signed, bits)), zig_minInt_i32) | ||
| 4847 | ), UINT8_C(32)) > zig_u32_bitCast_i32(zig_minInt_i32, UINT8_C(32)); | ||
| 4848 | } | ||
| 4849 | zig_divTrunc_big(res, lhs, rhs, temp, is_signed, bits); | ||
| 4850 | if (decrement) zig_decrement_big(res, is_signed, bits); | ||
| 4851 | } | ||
| 4852 | |||
| 4853 | static inline void zig_divCeil_big(void *res, const void *lhs, const void *rhs, void *temp, bool is_signed, uint16_t bits) { | ||
| 4854 | bool increment = false; | ||
| 4855 | |||
| 4856 | zig_rem_big(res, lhs, rhs, temp, is_signed, bits); | ||
| 4857 | increment = zig_xor_i32( | ||
| 4858 | zig_cmp_big_u8(res, UINT8_C(0), is_signed, bits), | ||
| 4859 | zig_and_i32(zig_i32_intCast_i8(zig_signFill_big(rhs, is_signed, bits)), zig_minInt_i32) | ||
| 4860 | ) > INT32_C(0); | ||
| 4861 | zig_divTrunc_big(res, lhs, rhs, temp, is_signed, bits); | ||
| 4862 | if (increment) zig_increment_big(res, is_signed, bits); | ||
| 4863 | } | ||
| 4864 | |||
| 4865 | static inline void zig_mod_big(void *res, const void *lhs, const void *rhs, void *temp, bool is_signed, uint16_t bits) { | ||
| 4866 | bool fixup = false; | ||
| 4867 | |||
| 4868 | zig_rem_big(res, lhs, rhs, temp, is_signed, bits); | ||
| 4869 | if (is_signed && zig_u32_bitCast_i32(zig_xor_i32( | ||
| 4870 | zig_cmp_big_u8(res, UINT8_C(0), is_signed, bits), | ||
| 4871 | zig_and_i32(zig_i32_intCast_i8(zig_signFill_big(rhs, is_signed, bits)), zig_minInt_i32) | ||
| 4872 | ), UINT8_C(32)) > zig_u32_bitCast_i32(zig_minInt_i32, UINT8_C(32))) zig_add_big(res, res, rhs, is_signed, bits); | ||
| 4873 | } | ||
| 4874 | |||
| 4875 | static inline void zig_shr_big(void *res, const void *lhs, uint16_t rhs, bool is_signed, uint16_t bits) { | ||
| 4876 | uint8_t *res_bytes = res; | ||
| 4877 | const uint8_t *lhs_bytes = lhs; | ||
| 4878 | uint16_t size = zig_int_bytes(bits); | ||
| 4879 | uint16_t res_byte_offset = UINT16_C(0); | ||
| 4880 | uint16_t lhs_byte_offset = zig_shr_u16(rhs, UINT8_C(3)); | ||
| 4881 | uint16_t end_byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1); | ||
| 4882 | uint8_t lhs_prev_byte; | ||
| 4883 | uint8_t byte_shift = zig_u8_truncate_u16(rhs, UINT8_C(3)); | ||
| 4884 | |||
| 4885 | #if zig_big_endian | ||
| 4886 | res_byte_offset = size - res_byte_offset; | ||
| 4887 | lhs_byte_offset = size - lhs_byte_offset; | ||
| 4888 | end_byte_offset = size - end_byte_offset; | ||
| 4889 | #endif | ||
| 4890 | |||
| 4891 | { | ||
| 4892 | #if zig_big_endian | ||
| 4893 | lhs_byte_offset -= UINT16_C(1); | ||
| 4894 | #endif | ||
| 4895 | |||
| 4896 | lhs_prev_byte = lhs_bytes[lhs_byte_offset]; | ||
| 4897 | |||
| 4898 | #if zig_little_endian | ||
| 4899 | lhs_byte_offset += UINT16_C(1); | ||
| 4900 | #endif | ||
| 4901 | } | ||
| 4902 | |||
| 4903 | while (lhs_byte_offset != end_byte_offset) { | ||
| 4904 | #if zig_big_endian | ||
| 4905 | res_byte_offset -= UINT16_C(1); | ||
| 4906 | lhs_byte_offset -= UINT16_C(1); | ||
| 4907 | #endif | ||
| 4908 | |||
| 4909 | { | ||
| 4910 | uint8_t lhs_byte = lhs_bytes[lhs_byte_offset]; | ||
| 4911 | |||
| 4912 | res_bytes[res_byte_offset] = zig_u8_intCast_u16(zig_shr_u16(zig_or_u16( | ||
| 4913 | zig_shl_u16(zig_u16_intCast_u8(lhs_byte), UINT8_C(8)), | ||
| 4914 | zig_u16_intCast_u8(lhs_prev_byte) | ||
| 4915 | ), byte_shift)); | ||
| 4916 | lhs_prev_byte = lhs_byte; | ||
| 4917 | } | ||
| 4918 | |||
| 4919 | #if zig_little_endian | ||
| 4920 | res_byte_offset += UINT16_C(1); | ||
| 4921 | lhs_byte_offset += UINT16_C(1); | ||
| 4922 | #endif | ||
| 4923 | } | ||
| 4924 | |||
| 4925 | { | ||
| 4926 | uint8_t lhs_sign_fill = UINT8_C(0); | ||
| 4927 | |||
| 4928 | #if zig_big_endian | ||
| 4929 | res_byte_offset -= UINT16_C(1); | ||
| 4930 | #endif | ||
| 4931 | |||
| 4932 | if (is_signed) { | ||
| 4933 | int8_t signed_byte = zig_i8_bitCast_u8(lhs_prev_byte, UINT8_C(8)); | ||
| 4934 | |||
| 4935 | res_bytes[res_byte_offset] = zig_shr_i8(signed_byte, byte_shift); | ||
| 4936 | lhs_sign_fill = zig_u8_bitCast_i8(zig_shr_i8(signed_byte, UINT8_C(7)), UINT8_C(8)); | ||
| 4937 | } else { | ||
| 4938 | res_bytes[res_byte_offset] = zig_shr_u8(lhs_prev_byte, byte_shift); | ||
| 4939 | } | ||
| 4940 | |||
| 4941 | #if zig_little_endian | ||
| 4942 | res_byte_offset += UINT16_C(1); | ||
| 4943 | memset(&res_bytes[res_byte_offset], lhs_sign_fill, size - res_byte_offset); | ||
| 4944 | #else | ||
| 4945 | memset(&res_bytes[0], lhs_sign_fill, res_byte_offset); | ||
| 4946 | #endif | ||
| 4947 | } | ||
| 4948 | } | ||
| 4949 | |||
| 4950 | static inline bool zig_shlo_big(void *res, const void *lhs, uint16_t rhs, bool is_signed, uint16_t bits) { | ||
| 4951 | uint8_t *res_bytes = res; | ||
| 4952 | const uint8_t *lhs_bytes = lhs; | ||
| 4953 | uint8_t lhs_sign_fill = zig_u8_bitCast_i8(zig_signFill_big(lhs, is_signed, bits), UINT8_C(8)); | ||
| 4954 | uint16_t size = zig_int_bytes(bits); | ||
| 4955 | uint16_t res_byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1); | ||
| 4956 | uint16_t lhs_byte_offset = UINT16_C(0); | ||
| 4957 | uint16_t end_byte_offset = res_byte_offset - UINT16_C(1) - zig_shr_u16(rhs, UINT8_C(3)); | ||
| 4958 | uint8_t lhs_prev_byte = lhs_sign_fill; | ||
| 4959 | uint8_t byte_shift = UINT8_C(8) - zig_u8_truncate_u16(rhs, UINT8_C(3)); | ||
| 4960 | bool overflow = false; | ||
| 4961 | |||
| 4962 | #if zig_little_endian | ||
| 4963 | lhs_byte_offset = size - lhs_byte_offset; | ||
| 4964 | #else | ||
| 4965 | res_byte_offset = size - res_byte_offset; | ||
| 4966 | end_byte_offset = size - end_byte_offset; | ||
| 4967 | #endif | ||
| 4968 | |||
| 4969 | while (lhs_byte_offset != end_byte_offset) { | ||
| 4970 | #if zig_little_endian | ||
| 4971 | lhs_byte_offset -= UINT16_C(1); | ||
| 4972 | #endif | ||
| 4973 | |||
| 4974 | overflow |= lhs_prev_byte != lhs_sign_fill; | ||
| 4975 | lhs_prev_byte = lhs_bytes[lhs_byte_offset]; | ||
| 4976 | |||
| 4977 | #if zig_big_endian | ||
| 4978 | lhs_byte_offset += UINT16_C(1); | ||
| 4979 | #endif | ||
| 4980 | } | ||
| 4981 | |||
| 4982 | #if zig_little_endian | ||
| 4983 | end_byte_offset = UINT16_C(0); | ||
| 4984 | #else | ||
| 4985 | end_byte_offset = size; | ||
| 4986 | #endif | ||
| 4987 | |||
| 4988 | { | ||
| 4989 | bool lhs_more_bytes = lhs_byte_offset != end_byte_offset; | ||
| 4990 | |||
| 4991 | #if zig_little_endian | ||
| 4992 | if (lhs_more_bytes) lhs_byte_offset -= UINT16_C(1); | ||
| 4993 | #endif | ||
| 4994 | |||
| 4995 | { | ||
| 4996 | uint8_t lhs_byte = UINT8_C(0); | ||
| 4997 | |||
| 4998 | if (lhs_more_bytes) lhs_byte = lhs_bytes[lhs_byte_offset]; | ||
| 4999 | |||
| 5000 | if (is_signed) { | ||
| 5001 | int16_t shifted = zig_shr_i16(zig_or_i16( | ||
| 5002 | zig_shl_i16(zig_i16_intCast_u8(lhs_prev_byte), UINT8_C(8)), | ||
| 5003 | zig_i16_intCast_u8(lhs_byte) | ||
| 5004 | ), byte_shift); | ||
| 5005 | int8_t truncated = zig_i8_truncate_i16( | ||
| 5006 | shifted, | ||
| 5007 | zig_u8_truncate_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT8_C(1) | ||
| 5008 | ); | ||
| 5009 | uint8_t fill = zig_u8_bitCast_i8(zig_shr_i8(truncated, UINT8_C(7)), UINT8_C(8)); | ||
| 5010 | |||
| 5011 | overflow |= zig_i16_intCast_i8(truncated) != shifted; | ||
| 5012 | #if zig_little_endian | ||
| 5013 | memset(&res_bytes[res_byte_offset], fill, size - res_byte_offset); | ||
| 5014 | res_byte_offset -= UINT16_C(1); | ||
| 5015 | #else | ||
| 5016 | memset(&res_bytes[0], fill, res_byte_offset); | ||
| 5017 | #endif | ||
| 5018 | res_bytes[res_byte_offset] = zig_u8_bitCast_i8(truncated, UINT8_C(8)); | ||
| 5019 | } else { | ||
| 5020 | uint16_t shifted = zig_shr_u16(zig_or_u16( | ||
| 5021 | zig_shl_u16(zig_u16_intCast_u8(lhs_prev_byte), UINT8_C(8)), | ||
| 5022 | zig_u16_intCast_u8(lhs_byte) | ||
| 5023 | ), byte_shift); | ||
| 5024 | uint8_t truncated = zig_u8_truncate_u16( | ||
| 5025 | shifted, | ||
| 5026 | zig_u8_truncate_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT8_C(1) | ||
| 5027 | ); | ||
| 5028 | |||
| 5029 | overflow |= zig_u16_intCast_u8(truncated) != shifted; | ||
| 5030 | #if zig_little_endian | ||
| 5031 | memset(&res_bytes[res_byte_offset], zig_minInt_u8, size - res_byte_offset); | ||
| 5032 | res_byte_offset -= UINT16_C(1); | ||
| 5033 | #else | ||
| 5034 | memset(&res_bytes[0], zig_minInt_u8, res_byte_offset); | ||
| 5035 | #endif | ||
| 5036 | res_bytes[res_byte_offset] = truncated; | ||
| 5037 | } | ||
| 5038 | |||
| 5039 | lhs_prev_byte = lhs_byte; | ||
| 5040 | } | ||
| 5041 | |||
| 5042 | #if zig_big_endian | ||
| 5043 | res_byte_offset += UINT16_C(1); | ||
| 5044 | if (lhs_more_bytes) lhs_byte_offset += UINT16_C(1); | ||
| 5045 | #endif | ||
| 5046 | } | ||
| 5047 | |||
| 5048 | while (lhs_byte_offset != end_byte_offset) { | ||
| 5049 | #if zig_little_endian | ||
| 5050 | res_byte_offset -= UINT16_C(1); | ||
| 5051 | lhs_byte_offset -= UINT16_C(1); | ||
| 5052 | #endif | ||
| 5053 | |||
| 5054 | { | ||
| 5055 | uint8_t lhs_byte = lhs_bytes[lhs_byte_offset]; | ||
| 5056 | |||
| 5057 | res_bytes[res_byte_offset] = zig_u8_intCast_u16(zig_shr_u16(zig_or_u16( | ||
| 5058 | zig_shl_u16(zig_u16_intCast_u8(lhs_prev_byte), UINT8_C(8)), | ||
| 5059 | zig_u16_intCast_u8(lhs_byte) | ||
| 5060 | ), byte_shift)); | ||
| 5061 | lhs_prev_byte = lhs_byte; | ||
| 5062 | } | ||
| 5063 | |||
| 5064 | #if zig_big_endian | ||
| 5065 | res_byte_offset += UINT16_C(1); | ||
| 5066 | lhs_byte_offset += UINT16_C(1); | ||
| 5067 | #endif | ||
| 5068 | } | ||
| 5069 | |||
| 5070 | { | ||
| 5071 | #if zig_little_endian | ||
| 5072 | res_byte_offset -= UINT16_C(1); | ||
| 5073 | #endif | ||
| 5074 | |||
| 5075 | res_bytes[res_byte_offset] = zig_u8_intCast_u16(zig_shr_u16( | ||
| 5076 | zig_shl_u16(zig_u16_intCast_u8(lhs_prev_byte), UINT8_C(8)), | ||
| 5077 | byte_shift | ||
| 5078 | )); | ||
| 5079 | |||
| 5080 | #if zig_big_endian | ||
| 5081 | res_byte_offset += UINT16_C(1); | ||
| 5082 | #endif | ||
| 5083 | } | ||
| 5084 | |||
| 5085 | #if zig_little_endian | ||
| 5086 | memset(&res_bytes[0], zig_minInt_u8, res_byte_offset); | ||
| 5087 | #else | ||
| 5088 | memset(&res_bytes[res_byte_offset], zig_minInt_u8, size - res_byte_offset); | ||
| 5089 | #endif | ||
| 5090 | |||
| 5091 | return overflow; | ||
| 5092 | } | ||
| 5093 | |||
| 5094 | static inline void zig_shl_big(void *res, const void *lhs, uint16_t rhs, bool is_signed, uint16_t bits) { | ||
| 5095 | if (zig_shlo_big(res, lhs, rhs, is_signed, bits)) zig_trap(); // panic: left shift overflowed bits | ||
| 5096 | } | ||
| 5097 | |||
| 5098 | static inline void zig_shlw_big(void *res, const void *lhs, uint16_t rhs, bool is_signed, uint16_t bits) { | ||
| 5099 | (void)zig_shlo_big(res, lhs, rhs, is_signed, bits); | ||
| 5100 | } | ||
| 5101 | |||
| 5102 | #define zig_big_shls_builtin(w) \ | ||
| 5103 | static inline uint##w##_t zig_shls_u##w##_big(uint##w##_t lhs, const void *rhs, \ | ||
| 5104 | uint8_t lhs_bits, bool rhs_is_signed, uint16_t rhs_bits) { \ | ||
| 5105 | uint##w##_t res; \ | ||
| 5106 | const uint8_t *rhs_bytes = rhs; \ | ||
| 5107 | if (zig_cmp_big_u8(rhs, lhs_bits, rhs_is_signed, rhs_bits) < INT32_C(0) && \ | ||
| 5108 | !zig_shlo_u##w(&res, lhs, rhs_bytes[0], lhs_bits)) return res; \ | ||
| 5109 | return lhs == INT##w##_C(0) ? zig_minInt_u(w, lhs_bits) : zig_maxInt_u(w, lhs_bits); \ | ||
| 5110 | } \ | ||
| 5111 | \ | ||
| 5112 | static inline int##w##_t zig_shls_i##w##_big(int##w##_t lhs, const void *rhs, \ | ||
| 5113 | uint8_t lhs_bits, bool rhs_is_signed, uint16_t rhs_bits) { \ | ||
| 5114 | int##w##_t res; \ | ||
| 5115 | const uint8_t *rhs_bytes = rhs; \ | ||
| 5116 | if (zig_cmp_big_u8(rhs, lhs_bits, rhs_is_signed, rhs_bits) < INT32_C(0) && \ | ||
| 5117 | !zig_shlo_i##w(&res, lhs, rhs_bytes[0], lhs_bits)) return res; \ | ||
| 5118 | return lhs == INT##w##_C(0) ? INT##w##_C(0) : \ | ||
| 5119 | lhs < INT##w##_C(0) ? zig_minInt_i(w, lhs_bits) : zig_maxInt_i(w, lhs_bits); \ | ||
| 5120 | } \ | ||
| 5121 | \ | ||
| 5122 | static inline void zig_shls_big_u##w(void *res, const void *lhs, uint##w##_t rhs, bool is_signed, uint16_t bits) { \ | ||
| 5123 | const uint8_t *lhs_bytes = lhs; \ | ||
| 5124 | if (rhs < bits && !zig_shlo_big(res, lhs, zig_u16_intCast_u##w(rhs), is_signed, bits)) return; \ | ||
| 5125 | switch (zig_cmp_big_u8(lhs, UINT8_C(0), is_signed, bits)) { \ | ||
| 5126 | case -INT32_C(1): return zig_minInt_big(res, is_signed, bits); \ | ||
| 5127 | case INT32_C(0): return zig_minInt_big(res, false, bits); \ | ||
| 5128 | case INT32_C(1): return zig_maxInt_big(res, is_signed, bits); \ | ||
| 5129 | default: zig_unreachable(); \ | ||
| 5130 | } \ | ||
| 5131 | } | ||
| 5132 | zig_big_shls_builtin(8) | ||
| 5133 | zig_big_shls_builtin(16) | ||
| 5134 | zig_big_shls_builtin(32) | ||
| 5135 | zig_big_shls_builtin(64) | ||
| 5136 | |||
| 5137 | static inline void zig_byteSwap_big(void *res, const void *arg, bool is_signed, uint16_t bits) { | ||
| 5138 | uint8_t *res_bytes = res; | ||
| 5139 | const uint8_t *arg_bytes = arg; | ||
| 5140 | uint16_t res_byte_offset = UINT16_C(0); | ||
| 5141 | uint16_t arg_byte_offset = bits / CHAR_BIT; | ||
| 5142 | uint16_t end_byte_offset = UINT16_C(1); | ||
| 5143 | uint16_t size = zig_int_bytes(bits); | ||
| 5144 | |||
| 5145 | #if zig_big_endian | ||
| 5146 | res_byte_offset = size - res_byte_offset; | ||
| 5147 | arg_byte_offset = size - arg_byte_offset; | ||
| 5148 | end_byte_offset = size - end_byte_offset; | ||
| 5149 | #endif | ||
| 5150 | |||
| 5151 | while (arg_byte_offset != end_byte_offset) { | ||
| 5152 | #if zig_little_endian | ||
| 5153 | arg_byte_offset -= UINT16_C(1); | ||
| 5154 | #else | ||
| 5155 | res_byte_offset -= UINT16_C(1); | ||
| 5156 | #endif | ||
| 5157 | |||
| 5158 | res_bytes[res_byte_offset] = arg_bytes[arg_byte_offset]; | ||
| 3242 | 5159 | ||
| 3243 | #if zig_little_endian | 5160 | #if zig_little_endian |
| 3244 | byte_offset += 8 / CHAR_BIT; | 5161 | res_byte_offset += UINT16_C(1); |
| 5162 | #else | ||
| 5163 | arg_byte_offset += UINT16_C(1); | ||
| 3245 | #endif | 5164 | #endif |
| 3246 | } | 5165 | } |
| 3247 | 5166 | ||
| 3248 | return overflow; | 5167 | { |
| 3249 | } | 5168 | #if zig_little_endian |
| 5169 | arg_byte_offset -= UINT16_C(1); | ||
| 5170 | #else | ||
| 5171 | res_byte_offset -= UINT16_C(1); | ||
| 5172 | #endif | ||
| 3250 | 5173 | ||
| 3251 | static inline void zig_addw_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | 5174 | { |
| 3252 | (void)zig_addo_big(res, lhs, rhs, is_signed, bits); | 5175 | uint8_t byte = arg_bytes[arg_byte_offset]; |
| 3253 | } | 5176 | uint8_t fill = is_signed |
| 5177 | ? zig_u8_bitCast_i8(zig_shr_i8(zig_i8_bitCast_u8(byte, UINT8_C(8)), UINT8_C(7)), UINT8_C(8)) | ||
| 5178 | : UINT8_C(0); | ||
| 3254 | 5179 | ||
| 3255 | static inline void zig_subw_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | 5180 | res_bytes[res_byte_offset] = byte; |
| 3256 | (void)zig_subo_big(res, lhs, rhs, is_signed, bits); | ||
| 3257 | } | ||
| 3258 | 5181 | ||
| 3259 | zig_extern void __udivei4(uint32_t *res, const uint32_t *lhs, const uint32_t *rhs, uintptr_t bits); | 5182 | #if zig_little_endian |
| 3260 | static inline void zig_div_trunc_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | 5183 | res_byte_offset += UINT16_C(1); |
| 3261 | if (!is_signed) { | 5184 | memset(&res_bytes[res_byte_offset], fill, size - res_byte_offset); |
| 3262 | __udivei4(res, lhs, rhs, bits); | 5185 | #else |
| 3263 | return; | 5186 | memset(&res_bytes[0], fill, res_byte_offset); |
| 5187 | #endif | ||
| 5188 | } | ||
| 3264 | } | 5189 | } |
| 3265 | |||
| 3266 | zig_trap(); | ||
| 3267 | } | 5190 | } |
| 3268 | 5191 | ||
| 3269 | static inline void zig_div_floor_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | 5192 | static inline void zig_bitReverse_big(void *res, const void *arg, bool is_signed, uint16_t bits) { |
| 3270 | if (!is_signed) { | 5193 | uint8_t *res_bytes = res; |
| 3271 | zig_div_trunc_big(res, lhs, rhs, is_signed, bits); | 5194 | const uint8_t *arg_bytes = arg; |
| 3272 | return; | 5195 | uint16_t size = zig_int_bytes(bits); |
| 3273 | } | 5196 | uint16_t res_byte_offset = UINT16_C(0); |
| 5197 | uint16_t arg_byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1); | ||
| 5198 | uint16_t end_byte_offset = UINT16_C(0); | ||
| 5199 | uint8_t arg_prev_byte; | ||
| 5200 | uint8_t byte_shift = zig_u8_intCast_u16(zig_subw_u16(UINT16_C(0), bits, UINT8_C(3))); | ||
| 3274 | 5201 | ||
| 3275 | zig_trap(); | 5202 | #if zig_big_endian |
| 3276 | } | 5203 | res_byte_offset = size - res_byte_offset; |
| 5204 | arg_byte_offset = size - arg_byte_offset; | ||
| 5205 | end_byte_offset = size - end_byte_offset; | ||
| 5206 | #endif | ||
| 3277 | 5207 | ||
| 3278 | static inline void zig_div_ceil_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | 5208 | { |
| 3279 | zig_trap(); | 5209 | #if zig_little_endian |
| 3280 | } | 5210 | arg_byte_offset -= UINT16_C(1); |
| 5211 | #endif | ||
| 3281 | 5212 | ||
| 3282 | zig_extern void __umodei4(uint32_t *res, const uint32_t *lhs, const uint32_t *rhs, uintptr_t bits); | 5213 | arg_prev_byte = zig_bitReverse_u8(arg_bytes[arg_byte_offset], UINT8_C(8)); |
| 3283 | static inline void zig_rem_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | 5214 | |
| 3284 | if (!is_signed) { | 5215 | #if zig_big_endian |
| 3285 | __umodei4(res, lhs, rhs, bits); | 5216 | arg_byte_offset += UINT16_C(1); |
| 3286 | return; | 5217 | #endif |
| 3287 | } | 5218 | } |
| 3288 | 5219 | ||
| 3289 | zig_trap(); | 5220 | while (arg_byte_offset != end_byte_offset) { |
| 3290 | } | 5221 | #if zig_big_endian |
| 5222 | res_byte_offset -= UINT16_C(1); | ||
| 5223 | #else | ||
| 5224 | arg_byte_offset -= UINT16_C(1); | ||
| 5225 | #endif | ||
| 3291 | 5226 | ||
| 3292 | static inline void zig_mod_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | 5227 | { |
| 3293 | if (!is_signed) { | 5228 | uint8_t arg_byte = zig_bitReverse_u8(arg_bytes[arg_byte_offset], UINT8_C(8)); |
| 3294 | zig_rem_big(res, lhs, rhs, is_signed, bits); | 5229 | |
| 3295 | return; | 5230 | res_bytes[res_byte_offset] = zig_u8_intCast_u16(zig_shr_u16(zig_or_u16( |
| 5231 | zig_shl_u16(zig_u16_intCast_u8(arg_byte), UINT8_C(8)), | ||
| 5232 | zig_u16_intCast_u8(arg_prev_byte) | ||
| 5233 | ), byte_shift)); | ||
| 5234 | arg_prev_byte = arg_byte; | ||
| 5235 | } | ||
| 5236 | |||
| 5237 | #if zig_little_endian | ||
| 5238 | res_byte_offset += UINT16_C(1); | ||
| 5239 | #else | ||
| 5240 | arg_byte_offset += UINT16_C(1); | ||
| 5241 | #endif | ||
| 3296 | } | 5242 | } |
| 3297 | 5243 | ||
| 3298 | zig_trap(); | 5244 | { |
| 5245 | uint8_t arg_sign_fill = UINT8_C(0); | ||
| 5246 | |||
| 5247 | #if zig_big_endian | ||
| 5248 | res_byte_offset -= UINT16_C(1); | ||
| 5249 | #endif | ||
| 5250 | |||
| 5251 | if (is_signed) { | ||
| 5252 | int8_t signed_byte = zig_i8_bitCast_u8(arg_prev_byte, UINT8_C(8)); | ||
| 5253 | |||
| 5254 | res_bytes[res_byte_offset] = zig_shr_i8(signed_byte, byte_shift); | ||
| 5255 | arg_sign_fill = zig_u8_bitCast_i8(zig_shr_i8(signed_byte, UINT8_C(7)), UINT8_C(8)); | ||
| 5256 | } else { | ||
| 5257 | res_bytes[res_byte_offset] = zig_shr_u8(arg_prev_byte, byte_shift); | ||
| 5258 | } | ||
| 5259 | |||
| 5260 | #if zig_little_endian | ||
| 5261 | res_byte_offset += UINT16_C(1); | ||
| 5262 | memset(&res_bytes[res_byte_offset], arg_sign_fill, size - res_byte_offset); | ||
| 5263 | #else | ||
| 5264 | memset(&res_bytes[0], arg_sign_fill, res_byte_offset); | ||
| 5265 | #endif | ||
| 5266 | } | ||
| 3299 | } | 5267 | } |
| 3300 | 5268 | ||
| 3301 | static inline uint16_t zig_clz_big(const void *val, bool is_signed, uint16_t bits) { | 5269 | static inline uint16_t zig_popCount_big(const void *arg, bool is_signed, uint16_t bits) { |
| 3302 | const uint8_t *val_bytes = val; | 5270 | const uint8_t *arg_bytes = arg; |
| 3303 | uint16_t byte_offset = 0; | 5271 | uint16_t byte_offset = 0; |
| 3304 | uint16_t remaining_bytes = zig_int_bytes(bits); | 5272 | uint16_t remaining_bytes = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1); |
| 3305 | uint16_t skip_bits = remaining_bytes * 8 - bits; | 5273 | uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits); |
| 3306 | uint16_t total_lz = 0; | 5274 | uint16_t total_pc = 0; |
| 3307 | uint16_t limb_lz; | ||
| 3308 | (void)is_signed; | 5275 | (void)is_signed; |
| 3309 | 5276 | ||
| 3310 | #if zig_little_endian | 5277 | #if zig_big_endian |
| 3311 | byte_offset = remaining_bytes; | 5278 | byte_offset = zig_int_bytes(bits); |
| 3312 | #endif | 5279 | #endif |
| 3313 | 5280 | ||
| 3314 | while (remaining_bytes >= 128 / CHAR_BIT) { | 5281 | while (remaining_bytes >= 128 / CHAR_BIT) { |
| 3315 | #if zig_little_endian | 5282 | uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0); |
| 5283 | |||
| 5284 | #if zig_big_endian | ||
| 3316 | byte_offset -= 128 / CHAR_BIT; | 5285 | byte_offset -= 128 / CHAR_BIT; |
| 3317 | #endif | 5286 | #endif |
| 3318 | 5287 | ||
| 3319 | { | 5288 | { |
| 3320 | zig_u128 val_limb; | 5289 | zig_u128 arg_limb; |
| 3321 | 5290 | ||
| 3322 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | 5291 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); |
| 3323 | limb_lz = zig_clz_u128(val_limb, 128 - skip_bits); | 5292 | total_pc += zig_popCount_u128(zig_u128_truncate_u128(arg_limb, limb_bits), limb_bits); |
| 3324 | } | 5293 | } |
| 3325 | 5294 | ||
| 3326 | total_lz += limb_lz; | ||
| 3327 | if (limb_lz < 128 - skip_bits) return total_lz; | ||
| 3328 | skip_bits = 0; | ||
| 3329 | remaining_bytes -= 128 / CHAR_BIT; | 5295 | remaining_bytes -= 128 / CHAR_BIT; |
| 3330 | 5296 | ||
| 3331 | #if zig_big_endian | 5297 | #if zig_little_endian |
| 3332 | byte_offset += 128 / CHAR_BIT; | 5298 | byte_offset += 128 / CHAR_BIT; |
| 3333 | #endif | 5299 | #endif |
| 3334 | } | 5300 | } |
| 3335 | 5301 | ||
| 3336 | while (remaining_bytes >= 64 / CHAR_BIT) { | 5302 | while (remaining_bytes >= 64 / CHAR_BIT) { |
| 3337 | #if zig_little_endian | 5303 | uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0); |
| 5304 | |||
| 5305 | #if zig_big_endian | ||
| 3338 | byte_offset -= 64 / CHAR_BIT; | 5306 | byte_offset -= 64 / CHAR_BIT; |
| 3339 | #endif | 5307 | #endif |
| 3340 | 5308 | ||
| 3341 | { | 5309 | { |
| 3342 | uint64_t val_limb; | 5310 | uint64_t arg_limb; |
| 3343 | 5311 | ||
| 3344 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | 5312 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); |
| 3345 | limb_lz = zig_clz_u64(val_limb, 64 - skip_bits); | 5313 | total_pc += zig_popCount_u64(zig_u64_truncate_u64(arg_limb, limb_bits), limb_bits); |
| 3346 | } | 5314 | } |
| 3347 | 5315 | ||
| 3348 | total_lz += limb_lz; | ||
| 3349 | if (limb_lz < 64 - skip_bits) return total_lz; | ||
| 3350 | skip_bits = 0; | ||
| 3351 | remaining_bytes -= 64 / CHAR_BIT; | 5316 | remaining_bytes -= 64 / CHAR_BIT; |
| 3352 | 5317 | ||
| 3353 | #if zig_big_endian | 5318 | #if zig_little_endian |
| 3354 | byte_offset += 64 / CHAR_BIT; | 5319 | byte_offset += 64 / CHAR_BIT; |
| 3355 | #endif | 5320 | #endif |
| 3356 | } | 5321 | } |
| 3357 | 5322 | ||
| 3358 | while (remaining_bytes >= 32 / CHAR_BIT) { | 5323 | while (remaining_bytes >= 32 / CHAR_BIT) { |
| 3359 | #if zig_little_endian | 5324 | uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0); |
| 5325 | |||
| 5326 | #if zig_big_endian | ||
| 3360 | byte_offset -= 32 / CHAR_BIT; | 5327 | byte_offset -= 32 / CHAR_BIT; |
| 3361 | #endif | 5328 | #endif |
| 3362 | 5329 | ||
| 3363 | { | 5330 | { |
| 3364 | uint32_t val_limb; | 5331 | uint32_t arg_limb; |
| 3365 | 5332 | ||
| 3366 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | 5333 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); |
| 3367 | limb_lz = zig_clz_u32(val_limb, 32 - skip_bits); | 5334 | total_pc += zig_popCount_u32(zig_u32_truncate_u32(arg_limb, limb_bits), limb_bits); |
| 3368 | } | 5335 | } |
| 3369 | 5336 | ||
| 3370 | total_lz += limb_lz; | ||
| 3371 | if (limb_lz < 32 - skip_bits) return total_lz; | ||
| 3372 | skip_bits = 0; | ||
| 3373 | remaining_bytes -= 32 / CHAR_BIT; | 5337 | remaining_bytes -= 32 / CHAR_BIT; |
| 3374 | 5338 | ||
| 3375 | #if zig_big_endian | 5339 | #if zig_little_endian |
| 3376 | byte_offset += 32 / CHAR_BIT; | 5340 | byte_offset += 32 / CHAR_BIT; |
| 3377 | #endif | 5341 | #endif |
| 3378 | } | 5342 | } |
| 3379 | 5343 | ||
| 3380 | while (remaining_bytes >= 16 / CHAR_BIT) { | 5344 | while (remaining_bytes >= 16 / CHAR_BIT) { |
| 3381 | #if zig_little_endian | 5345 | uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0); |
| 5346 | |||
| 5347 | #if zig_big_endian | ||
| 3382 | byte_offset -= 16 / CHAR_BIT; | 5348 | byte_offset -= 16 / CHAR_BIT; |
| 3383 | #endif | 5349 | #endif |
| 3384 | 5350 | ||
| 3385 | { | 5351 | { |
| 3386 | uint16_t val_limb; | 5352 | uint16_t arg_limb; |
| 3387 | 5353 | ||
| 3388 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | 5354 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); |
| 3389 | limb_lz = zig_clz_u16(val_limb, 16 - skip_bits); | 5355 | total_pc += zig_popCount_u16(zig_u16_truncate_u16(arg_limb, limb_bits), limb_bits); |
| 3390 | } | 5356 | } |
| 3391 | 5357 | ||
| 3392 | total_lz += limb_lz; | ||
| 3393 | if (limb_lz < 16 - skip_bits) return total_lz; | ||
| 3394 | skip_bits = 0; | ||
| 3395 | remaining_bytes -= 16 / CHAR_BIT; | 5358 | remaining_bytes -= 16 / CHAR_BIT; |
| 3396 | 5359 | ||
| 3397 | #if zig_big_endian | 5360 | #if zig_little_endian |
| 3398 | byte_offset += 16 / CHAR_BIT; | 5361 | byte_offset += 16 / CHAR_BIT; |
| 3399 | #endif | 5362 | #endif |
| 3400 | } | 5363 | } |
| 3401 | 5364 | ||
| 3402 | while (remaining_bytes >= 8 / CHAR_BIT) { | 5365 | while (remaining_bytes >= 8 / CHAR_BIT) { |
| 3403 | #if zig_little_endian | 5366 | uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0); |
| 5367 | |||
| 5368 | #if zig_big_endian | ||
| 3404 | byte_offset -= 8 / CHAR_BIT; | 5369 | byte_offset -= 8 / CHAR_BIT; |
| 3405 | #endif | 5370 | #endif |
| 3406 | 5371 | ||
| 3407 | { | 5372 | { |
| 3408 | uint8_t val_limb; | 5373 | uint8_t arg_limb; |
| 3409 | 5374 | ||
| 3410 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | 5375 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); |
| 3411 | limb_lz = zig_clz_u8(val_limb, 8 - skip_bits); | 5376 | total_pc += zig_popCount_u8(zig_u8_truncate_u8(arg_limb, limb_bits), limb_bits); |
| 3412 | } | 5377 | } |
| 3413 | 5378 | ||
| 3414 | total_lz += limb_lz; | ||
| 3415 | if (limb_lz < 8 - skip_bits) return total_lz; | ||
| 3416 | skip_bits = 0; | ||
| 3417 | remaining_bytes -= 8 / CHAR_BIT; | 5379 | remaining_bytes -= 8 / CHAR_BIT; |
| 3418 | 5380 | ||
| 3419 | #if zig_big_endian | 5381 | #if zig_little_endian |
| 3420 | byte_offset += 8 / CHAR_BIT; | 5382 | byte_offset += 8 / CHAR_BIT; |
| 3421 | #endif | 5383 | #endif |
| 3422 | } | 5384 | } |
| 3423 | 5385 | ||
| 3424 | return total_lz; | 5386 | return total_pc; |
| 3425 | } | 5387 | } |
| 3426 | 5388 | ||
| 3427 | static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bits) { | 5389 | static inline uint16_t zig_ctz_big(const void *arg, bool is_signed, uint16_t bits) { |
| 3428 | const uint8_t *val_bytes = val; | 5390 | const uint8_t *arg_bytes = arg; |
| 3429 | uint16_t byte_offset = 0; | 5391 | uint16_t byte_offset = UINT16_C(0); |
| 3430 | uint16_t remaining_bytes = zig_int_bytes(bits); | 5392 | uint16_t remaining_bytes = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1); |
| 3431 | uint16_t total_tz = 0; | 5393 | uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits); |
| 5394 | uint16_t total_tz = UINT16_C(0); | ||
| 3432 | uint16_t limb_tz; | 5395 | uint16_t limb_tz; |
| 3433 | (void)is_signed; | 5396 | (void)is_signed; |
| 3434 | 5397 | ||
| 3435 | #if zig_big_endian | 5398 | #if zig_big_endian |
| 3436 | byte_offset = remaining_bytes; | 5399 | byte_offset = zig_int_bytes(bits); |
| 3437 | #endif | 5400 | #endif |
| 3438 | 5401 | ||
| 3439 | while (remaining_bytes >= 128 / CHAR_BIT) { | 5402 | while (remaining_bytes >= 128 / CHAR_BIT) { |
| 5403 | uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0); | ||
| 5404 | |||
| 3440 | #if zig_big_endian | 5405 | #if zig_big_endian |
| 3441 | byte_offset -= 128 / CHAR_BIT; | 5406 | byte_offset -= 128 / CHAR_BIT; |
| 3442 | #endif | 5407 | #endif |
| 3443 | 5408 | ||
| 3444 | { | 5409 | { |
| 3445 | zig_u128 val_limb; | 5410 | zig_u128 arg_limb; |
| 3446 | 5411 | ||
| 3447 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | 5412 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); |
| 3448 | limb_tz = zig_ctz_u128(val_limb, 128); | 5413 | limb_tz = zig_ctz_u128(zig_u128_truncate_u128(arg_limb, limb_bits), limb_bits); |
| 3449 | } | 5414 | } |
| 3450 | 5415 | ||
| 3451 | total_tz += limb_tz; | 5416 | total_tz += limb_tz; |
| 3452 | if (limb_tz < 128) return total_tz; | 5417 | if (limb_tz < limb_bits) return total_tz; |
| 3453 | remaining_bytes -= 128 / CHAR_BIT; | 5418 | remaining_bytes -= 128 / CHAR_BIT; |
| 3454 | 5419 | ||
| 3455 | #if zig_little_endian | 5420 | #if zig_little_endian |
| ... | @@ -3458,19 +5423,21 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit | ... | @@ -3458,19 +5423,21 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit |
| 3458 | } | 5423 | } |
| 3459 | 5424 | ||
| 3460 | while (remaining_bytes >= 64 / CHAR_BIT) { | 5425 | while (remaining_bytes >= 64 / CHAR_BIT) { |
| 5426 | uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0); | ||
| 5427 | |||
| 3461 | #if zig_big_endian | 5428 | #if zig_big_endian |
| 3462 | byte_offset -= 64 / CHAR_BIT; | 5429 | byte_offset -= 64 / CHAR_BIT; |
| 3463 | #endif | 5430 | #endif |
| 3464 | 5431 | ||
| 3465 | { | 5432 | { |
| 3466 | uint64_t val_limb; | 5433 | uint64_t arg_limb; |
| 3467 | 5434 | ||
| 3468 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | 5435 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); |
| 3469 | limb_tz = zig_ctz_u64(val_limb, 64); | 5436 | limb_tz = zig_ctz_u64(zig_u64_truncate_u64(arg_limb, limb_bits), limb_bits); |
| 3470 | } | 5437 | } |
| 3471 | 5438 | ||
| 3472 | total_tz += limb_tz; | 5439 | total_tz += limb_tz; |
| 3473 | if (limb_tz < 64) return total_tz; | 5440 | if (limb_tz < limb_bits) return total_tz; |
| 3474 | remaining_bytes -= 64 / CHAR_BIT; | 5441 | remaining_bytes -= 64 / CHAR_BIT; |
| 3475 | 5442 | ||
| 3476 | #if zig_little_endian | 5443 | #if zig_little_endian |
| ... | @@ -3479,19 +5446,21 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit | ... | @@ -3479,19 +5446,21 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit |
| 3479 | } | 5446 | } |
| 3480 | 5447 | ||
| 3481 | while (remaining_bytes >= 32 / CHAR_BIT) { | 5448 | while (remaining_bytes >= 32 / CHAR_BIT) { |
| 5449 | uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0); | ||
| 5450 | |||
| 3482 | #if zig_big_endian | 5451 | #if zig_big_endian |
| 3483 | byte_offset -= 32 / CHAR_BIT; | 5452 | byte_offset -= 32 / CHAR_BIT; |
| 3484 | #endif | 5453 | #endif |
| 3485 | 5454 | ||
| 3486 | { | 5455 | { |
| 3487 | uint32_t val_limb; | 5456 | uint32_t arg_limb; |
| 3488 | 5457 | ||
| 3489 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | 5458 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); |
| 3490 | limb_tz = zig_ctz_u32(val_limb, 32); | 5459 | limb_tz = zig_ctz_u32(zig_u32_truncate_u32(arg_limb, limb_bits), limb_bits); |
| 3491 | } | 5460 | } |
| 3492 | 5461 | ||
| 3493 | total_tz += limb_tz; | 5462 | total_tz += limb_tz; |
| 3494 | if (limb_tz < 32) return total_tz; | 5463 | if (limb_tz < limb_bits) return total_tz; |
| 3495 | remaining_bytes -= 32 / CHAR_BIT; | 5464 | remaining_bytes -= 32 / CHAR_BIT; |
| 3496 | 5465 | ||
| 3497 | #if zig_little_endian | 5466 | #if zig_little_endian |
| ... | @@ -3500,19 +5469,21 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit | ... | @@ -3500,19 +5469,21 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit |
| 3500 | } | 5469 | } |
| 3501 | 5470 | ||
| 3502 | while (remaining_bytes >= 16 / CHAR_BIT) { | 5471 | while (remaining_bytes >= 16 / CHAR_BIT) { |
| 5472 | uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0); | ||
| 5473 | |||
| 3503 | #if zig_big_endian | 5474 | #if zig_big_endian |
| 3504 | byte_offset -= 16 / CHAR_BIT; | 5475 | byte_offset -= 16 / CHAR_BIT; |
| 3505 | #endif | 5476 | #endif |
| 3506 | 5477 | ||
| 3507 | { | 5478 | { |
| 3508 | uint16_t val_limb; | 5479 | uint16_t arg_limb; |
| 3509 | 5480 | ||
| 3510 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | 5481 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); |
| 3511 | limb_tz = zig_ctz_u16(val_limb, 16); | 5482 | limb_tz = zig_ctz_u16(zig_u16_truncate_u16(arg_limb, limb_bits), limb_bits); |
| 3512 | } | 5483 | } |
| 3513 | 5484 | ||
| 3514 | total_tz += limb_tz; | 5485 | total_tz += limb_tz; |
| 3515 | if (limb_tz < 16) return total_tz; | 5486 | if (limb_tz < limb_bits) return total_tz; |
| 3516 | remaining_bytes -= 16 / CHAR_BIT; | 5487 | remaining_bytes -= 16 / CHAR_BIT; |
| 3517 | 5488 | ||
| 3518 | #if zig_little_endian | 5489 | #if zig_little_endian |
| ... | @@ -3521,19 +5492,21 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit | ... | @@ -3521,19 +5492,21 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit |
| 3521 | } | 5492 | } |
| 3522 | 5493 | ||
| 3523 | while (remaining_bytes >= 8 / CHAR_BIT) { | 5494 | while (remaining_bytes >= 8 / CHAR_BIT) { |
| 5495 | uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0); | ||
| 5496 | |||
| 3524 | #if zig_big_endian | 5497 | #if zig_big_endian |
| 3525 | byte_offset -= 8 / CHAR_BIT; | 5498 | byte_offset -= 8 / CHAR_BIT; |
| 3526 | #endif | 5499 | #endif |
| 3527 | 5500 | ||
| 3528 | { | 5501 | { |
| 3529 | uint8_t val_limb; | 5502 | uint8_t arg_limb; |
| 3530 | 5503 | ||
| 3531 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | 5504 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); |
| 3532 | limb_tz = zig_ctz_u8(val_limb, 8); | 5505 | limb_tz = zig_ctz_u8(zig_u8_truncate_u8(arg_limb, limb_bits), limb_bits); |
| 3533 | } | 5506 | } |
| 3534 | 5507 | ||
| 3535 | total_tz += limb_tz; | 5508 | total_tz += limb_tz; |
| 3536 | if (limb_tz < 8) return total_tz; | 5509 | if (limb_tz < limb_bits) return total_tz; |
| 3537 | remaining_bytes -= 8 / CHAR_BIT; | 5510 | remaining_bytes -= 8 / CHAR_BIT; |
| 3538 | 5511 | ||
| 3539 | #if zig_little_endian | 5512 | #if zig_little_endian |
| ... | @@ -3544,113 +5517,141 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit | ... | @@ -3544,113 +5517,141 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit |
| 3544 | return total_tz; | 5517 | return total_tz; |
| 3545 | } | 5518 | } |
| 3546 | 5519 | ||
| 3547 | static inline uint16_t zig_popcount_big(const void *val, bool is_signed, uint16_t bits) { | 5520 | static inline uint16_t zig_clz_big(const void *arg, bool is_signed, uint16_t bits) { |
| 3548 | const uint8_t *val_bytes = val; | 5521 | const uint8_t *arg_bytes = arg; |
| 3549 | uint16_t byte_offset = 0; | 5522 | uint16_t byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1); |
| 3550 | uint16_t remaining_bytes = zig_int_bytes(bits); | 5523 | uint16_t remaining_bytes = byte_offset; |
| 3551 | uint16_t total_pc = 0; | 5524 | uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits); |
| 5525 | bool sign_limb = true; | ||
| 5526 | uint16_t total_lz = UINT16_C(0); | ||
| 5527 | uint16_t limb_lz; | ||
| 3552 | (void)is_signed; | 5528 | (void)is_signed; |
| 3553 | 5529 | ||
| 3554 | #if zig_big_endian | 5530 | #if zig_big_endian |
| 3555 | byte_offset = remaining_bytes; | 5531 | byte_offset = zig_int_bytes(bits) - remaining_bytes; |
| 3556 | #endif | 5532 | #endif |
| 3557 | 5533 | ||
| 3558 | while (remaining_bytes >= 128 / CHAR_BIT) { | 5534 | while (remaining_bytes >= 128 / CHAR_BIT) { |
| 3559 | #if zig_big_endian | 5535 | uint8_t limb_bits = UINT8_C(128) - (sign_limb ? top_bits : UINT8_C(0)); |
| 5536 | |||
| 5537 | #if zig_little_endian | ||
| 3560 | byte_offset -= 128 / CHAR_BIT; | 5538 | byte_offset -= 128 / CHAR_BIT; |
| 3561 | #endif | 5539 | #endif |
| 3562 | 5540 | ||
| 3563 | { | 5541 | { |
| 3564 | zig_u128 val_limb; | 5542 | zig_u128 arg_limb; |
| 3565 | 5543 | ||
| 3566 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | 5544 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); |
| 3567 | total_pc += zig_popcount_u128(val_limb, 128); | 5545 | limb_lz = zig_clz_u128(zig_u128_truncate_u128(arg_limb, limb_bits), limb_bits); |
| 3568 | } | 5546 | } |
| 3569 | 5547 | ||
| 5548 | total_lz += limb_lz; | ||
| 5549 | if (limb_lz < limb_bits) return total_lz; | ||
| 5550 | sign_limb = false; | ||
| 3570 | remaining_bytes -= 128 / CHAR_BIT; | 5551 | remaining_bytes -= 128 / CHAR_BIT; |
| 3571 | 5552 | ||
| 3572 | #if zig_little_endian | 5553 | #if zig_big_endian |
| 3573 | byte_offset += 128 / CHAR_BIT; | 5554 | byte_offset += 128 / CHAR_BIT; |
| 3574 | #endif | 5555 | #endif |
| 3575 | } | 5556 | } |
| 3576 | 5557 | ||
| 3577 | while (remaining_bytes >= 64 / CHAR_BIT) { | 5558 | while (remaining_bytes >= 64 / CHAR_BIT) { |
| 3578 | #if zig_big_endian | 5559 | uint8_t limb_bits = UINT8_C(64) - (sign_limb ? top_bits : UINT8_C(0)); |
| 5560 | |||
| 5561 | #if zig_little_endian | ||
| 3579 | byte_offset -= 64 / CHAR_BIT; | 5562 | byte_offset -= 64 / CHAR_BIT; |
| 3580 | #endif | 5563 | #endif |
| 3581 | 5564 | ||
| 3582 | { | 5565 | { |
| 3583 | uint64_t val_limb; | 5566 | uint64_t arg_limb; |
| 3584 | 5567 | ||
| 3585 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | 5568 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); |
| 3586 | total_pc += zig_popcount_u64(val_limb, 64); | 5569 | limb_lz = zig_clz_u64(zig_u64_truncate_u64(arg_limb, limb_bits), limb_bits); |
| 3587 | } | 5570 | } |
| 3588 | 5571 | ||
| 5572 | total_lz += limb_lz; | ||
| 5573 | if (limb_lz < limb_bits) return total_lz; | ||
| 5574 | sign_limb = false; | ||
| 3589 | remaining_bytes -= 64 / CHAR_BIT; | 5575 | remaining_bytes -= 64 / CHAR_BIT; |
| 3590 | 5576 | ||
| 3591 | #if zig_little_endian | 5577 | #if zig_big_endian |
| 3592 | byte_offset += 64 / CHAR_BIT; | 5578 | byte_offset += 64 / CHAR_BIT; |
| 3593 | #endif | 5579 | #endif |
| 3594 | } | 5580 | } |
| 3595 | 5581 | ||
| 3596 | while (remaining_bytes >= 32 / CHAR_BIT) { | 5582 | while (remaining_bytes >= 32 / CHAR_BIT) { |
| 3597 | #if zig_big_endian | 5583 | uint8_t limb_bits = UINT8_C(32) - (sign_limb ? top_bits : UINT8_C(0)); |
| 5584 | |||
| 5585 | #if zig_little_endian | ||
| 3598 | byte_offset -= 32 / CHAR_BIT; | 5586 | byte_offset -= 32 / CHAR_BIT; |
| 3599 | #endif | 5587 | #endif |
| 3600 | 5588 | ||
| 3601 | { | 5589 | { |
| 3602 | uint32_t val_limb; | 5590 | uint32_t arg_limb; |
| 3603 | 5591 | ||
| 3604 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | 5592 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); |
| 3605 | total_pc += zig_popcount_u32(val_limb, 32); | 5593 | limb_lz = zig_clz_u32(zig_u32_truncate_u32(arg_limb, limb_bits), limb_bits); |
| 3606 | } | 5594 | } |
| 3607 | 5595 | ||
| 5596 | total_lz += limb_lz; | ||
| 5597 | if (limb_lz < limb_bits) return total_lz; | ||
| 5598 | sign_limb = false; | ||
| 3608 | remaining_bytes -= 32 / CHAR_BIT; | 5599 | remaining_bytes -= 32 / CHAR_BIT; |
| 3609 | 5600 | ||
| 3610 | #if zig_little_endian | 5601 | #if zig_big_endian |
| 3611 | byte_offset += 32 / CHAR_BIT; | 5602 | byte_offset += 32 / CHAR_BIT; |
| 3612 | #endif | 5603 | #endif |
| 3613 | } | 5604 | } |
| 3614 | 5605 | ||
| 3615 | while (remaining_bytes >= 16 / CHAR_BIT) { | 5606 | while (remaining_bytes >= 16 / CHAR_BIT) { |
| 3616 | #if zig_big_endian | 5607 | uint8_t limb_bits = UINT8_C(16) - (sign_limb ? top_bits : UINT8_C(0)); |
| 5608 | |||
| 5609 | #if zig_little_endian | ||
| 3617 | byte_offset -= 16 / CHAR_BIT; | 5610 | byte_offset -= 16 / CHAR_BIT; |
| 3618 | #endif | 5611 | #endif |
| 3619 | 5612 | ||
| 3620 | { | 5613 | { |
| 3621 | uint16_t val_limb; | 5614 | uint16_t arg_limb; |
| 3622 | 5615 | ||
| 3623 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | 5616 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); |
| 3624 | total_pc = zig_popcount_u16(val_limb, 16); | 5617 | limb_lz = zig_clz_u16(zig_u16_truncate_u16(arg_limb, limb_bits), limb_bits); |
| 3625 | } | 5618 | } |
| 3626 | 5619 | ||
| 5620 | total_lz += limb_lz; | ||
| 5621 | if (limb_lz < limb_bits) return total_lz; | ||
| 5622 | sign_limb = false; | ||
| 3627 | remaining_bytes -= 16 / CHAR_BIT; | 5623 | remaining_bytes -= 16 / CHAR_BIT; |
| 3628 | 5624 | ||
| 3629 | #if zig_little_endian | 5625 | #if zig_big_endian |
| 3630 | byte_offset += 16 / CHAR_BIT; | 5626 | byte_offset += 16 / CHAR_BIT; |
| 3631 | #endif | 5627 | #endif |
| 3632 | } | 5628 | } |
| 3633 | 5629 | ||
| 3634 | while (remaining_bytes >= 8 / CHAR_BIT) { | 5630 | while (remaining_bytes >= 8 / CHAR_BIT) { |
| 3635 | #if zig_big_endian | 5631 | uint8_t limb_bits = UINT8_C(8) - (sign_limb ? top_bits : UINT8_C(0)); |
| 5632 | |||
| 5633 | #if zig_little_endian | ||
| 3636 | byte_offset -= 8 / CHAR_BIT; | 5634 | byte_offset -= 8 / CHAR_BIT; |
| 3637 | #endif | 5635 | #endif |
| 3638 | 5636 | ||
| 3639 | { | 5637 | { |
| 3640 | uint8_t val_limb; | 5638 | uint8_t arg_limb; |
| 3641 | 5639 | ||
| 3642 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | 5640 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); |
| 3643 | total_pc = zig_popcount_u8(val_limb, 8); | 5641 | limb_lz = zig_clz_u8(zig_u8_truncate_u8(arg_limb, limb_bits), limb_bits); |
| 3644 | } | 5642 | } |
| 3645 | 5643 | ||
| 5644 | total_lz += limb_lz; | ||
| 5645 | if (limb_lz < limb_bits) return total_lz; | ||
| 5646 | sign_limb = false; | ||
| 3646 | remaining_bytes -= 8 / CHAR_BIT; | 5647 | remaining_bytes -= 8 / CHAR_BIT; |
| 3647 | 5648 | ||
| 3648 | #if zig_little_endian | 5649 | #if zig_big_endian |
| 3649 | byte_offset += 8 / CHAR_BIT; | 5650 | byte_offset += 8 / CHAR_BIT; |
| 3650 | #endif | 5651 | #endif |
| 3651 | } | 5652 | } |
| 3652 | 5653 | ||
| 3653 | return total_pc; | 5654 | return total_lz; |
| 3654 | } | 5655 | } |
| 3655 | 5656 | ||
| 3656 | /* ========================= Floating Point Support ========================= */ | 5657 | /* ========================= Floating Point Support ========================= */ |
| ... | @@ -3687,29 +5688,29 @@ long double __cdecl nanl(char const* input); | ... | @@ -3687,29 +5688,29 @@ long double __cdecl nanl(char const* input); |
| 3687 | #define zig_make_special_f80(sign, name, arg, repr) sign zig_make_f80 (__builtin_##name, )(arg) | 5688 | #define zig_make_special_f80(sign, name, arg, repr) sign zig_make_f80 (__builtin_##name, )(arg) |
| 3688 | #define zig_make_special_f128(sign, name, arg, repr) sign zig_make_f128(__builtin_##name, )(arg) | 5689 | #define zig_make_special_f128(sign, name, arg, repr) sign zig_make_f128(__builtin_##name, )(arg) |
| 3689 | #else | 5690 | #else |
| 3690 | #define zig_make_special_f16(sign, name, arg, repr) zig_bitCast_f16 (repr) | 5691 | #define zig_make_special_f16(sign, name, arg, repr) zig_f16_bitCast_u16 (repr) |
| 3691 | #define zig_make_special_f32(sign, name, arg, repr) zig_bitCast_f32 (repr) | 5692 | #define zig_make_special_f32(sign, name, arg, repr) zig_f32_bitCast_u32 (repr) |
| 3692 | #define zig_make_special_f64(sign, name, arg, repr) zig_bitCast_f64 (repr) | 5693 | #define zig_make_special_f64(sign, name, arg, repr) zig_f64_bitCast_u64 (repr) |
| 3693 | #define zig_make_special_f80(sign, name, arg, repr) zig_bitCast_f80 (repr) | 5694 | #define zig_make_special_f80(sign, name, arg, repr) zig_f80_bitCast_u128(repr) |
| 3694 | #define zig_make_special_f128(sign, name, arg, repr) zig_bitCast_f128(repr) | 5695 | #define zig_make_special_f128(sign, name, arg, repr) zig_f128_bitCast_u128(repr) |
| 3695 | #endif | 5696 | #endif |
| 3696 | 5697 | ||
| 3697 | #define zig_has_f16 1 | 5698 | #define zig_has_f16 1 |
| 3698 | #define zig_libc_name_f16(name) __##name##h | 5699 | #define zig_libc_name_f16(name) __##name##h |
| 3699 | #define zig_init_special_f16(sign, name, arg, repr) zig_make_special_f16(sign, name, arg, repr) | 5700 | #define zig_init_special_f16(sign, name, arg, repr) zig_make_special_f16(sign, name, arg, repr) |
| 3700 | #if FLT_MANT_DIG == 11 | 5701 | #if !defined(ZIG_TARGET_SOFT_COMPILER_RT_F16_ABI) && FLT_MANT_DIG == 11 |
| 3701 | typedef float zig_f16; | 5702 | typedef float zig_f16; |
| 3702 | #define zig_make_f16(fp, repr) fp##f | 5703 | #define zig_make_f16(fp, repr) fp##f |
| 3703 | #elif DBL_MANT_DIG == 11 | 5704 | #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F16_ABI) && DBL_MANT_DIG == 11 |
| 3704 | typedef double zig_f16; | 5705 | typedef double zig_f16; |
| 3705 | #define zig_make_f16(fp, repr) fp | 5706 | #define zig_make_f16(fp, repr) fp |
| 3706 | #elif LDBL_MANT_DIG == 11 | 5707 | #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F16_ABI) && LDBL_MANT_DIG == 11 |
| 3707 | typedef long double zig_f16; | 5708 | typedef long double zig_f16; |
| 3708 | #define zig_make_f16(fp, repr) fp##l | 5709 | #define zig_make_f16(fp, repr) fp##l |
| 3709 | #elif FLT16_MANT_DIG == 11 && (zig_has_builtin(inff16) || defined(zig_gcc)) | 5710 | #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F16_ABI) && FLT16_MANT_DIG == 11 && (zig_has_builtin(inff16) || defined(zig_gcc)) |
| 3710 | typedef _Float16 zig_f16; | 5711 | typedef _Float16 zig_f16; |
| 3711 | #define zig_make_f16(fp, repr) fp##f16 | 5712 | #define zig_make_f16(fp, repr) fp##f16 |
| 3712 | #elif defined(__SIZEOF_FP16__) | 5713 | #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F16_ABI) && defined(__SIZEOF_FP16__) |
| 3713 | typedef __fp16 zig_f16; | 5714 | typedef __fp16 zig_f16; |
| 3714 | #define zig_make_f16(fp, repr) fp##f16 | 5715 | #define zig_make_f16(fp, repr) fp##f16 |
| 3715 | #else | 5716 | #else |
| ... | @@ -3723,11 +5724,6 @@ typedef uint16_t zig_f16; | ... | @@ -3723,11 +5724,6 @@ typedef uint16_t zig_f16; |
| 3723 | #undef zig_init_special_f16 | 5724 | #undef zig_init_special_f16 |
| 3724 | #define zig_init_special_f16(sign, name, arg, repr) repr | 5725 | #define zig_init_special_f16(sign, name, arg, repr) repr |
| 3725 | #endif | 5726 | #endif |
| 3726 | #if defined(zig_darwin) && defined(zig_x86) | ||
| 3727 | typedef uint16_t zig_compiler_rt_f16; | ||
| 3728 | #else | ||
| 3729 | typedef zig_f16 zig_compiler_rt_f16; | ||
| 3730 | #endif | ||
| 3731 | 5727 | ||
| 3732 | #define zig_has_f32 1 | 5728 | #define zig_has_f32 1 |
| 3733 | #define zig_libc_name_f32(name) name##f | 5729 | #define zig_libc_name_f32(name) name##f |
| ... | @@ -3736,16 +5732,16 @@ typedef zig_f16 zig_compiler_rt_f16; | ... | @@ -3736,16 +5732,16 @@ typedef zig_f16 zig_compiler_rt_f16; |
| 3736 | #else | 5732 | #else |
| 3737 | #define zig_init_special_f32(sign, name, arg, repr) zig_make_special_f32(sign, name, arg, repr) | 5733 | #define zig_init_special_f32(sign, name, arg, repr) zig_make_special_f32(sign, name, arg, repr) |
| 3738 | #endif | 5734 | #endif |
| 3739 | #if FLT_MANT_DIG == 24 | 5735 | #if !defined(ZIG_TARGET_SOFT_COMPILER_RT_F32_ABI) && FLT_MANT_DIG == 24 |
| 3740 | typedef float zig_f32; | 5736 | typedef float zig_f32; |
| 3741 | #define zig_make_f32(fp, repr) fp##f | 5737 | #define zig_make_f32(fp, repr) fp##f |
| 3742 | #elif DBL_MANT_DIG == 24 | 5738 | #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F32_ABI) && DBL_MANT_DIG == 24 |
| 3743 | typedef double zig_f32; | 5739 | typedef double zig_f32; |
| 3744 | #define zig_make_f32(fp, repr) fp | 5740 | #define zig_make_f32(fp, repr) fp |
| 3745 | #elif LDBL_MANT_DIG == 24 | 5741 | #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F32_ABI) && LDBL_MANT_DIG == 24 |
| 3746 | typedef long double zig_f32; | 5742 | typedef long double zig_f32; |
| 3747 | #define zig_make_f32(fp, repr) fp##l | 5743 | #define zig_make_f32(fp, repr) fp##l |
| 3748 | #elif FLT32_MANT_DIG == 24 | 5744 | #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F32_ABI) && FLT32_MANT_DIG == 24 |
| 3749 | typedef _Float32 zig_f32; | 5745 | typedef _Float32 zig_f32; |
| 3750 | #define zig_make_f32(fp, repr) fp##f32 | 5746 | #define zig_make_f32(fp, repr) fp##f32 |
| 3751 | #else | 5747 | #else |
| ... | @@ -3768,19 +5764,19 @@ typedef uint32_t zig_f32; | ... | @@ -3768,19 +5764,19 @@ typedef uint32_t zig_f32; |
| 3768 | #else | 5764 | #else |
| 3769 | #define zig_init_special_f64(sign, name, arg, repr) zig_make_special_f64(sign, name, arg, repr) | 5765 | #define zig_init_special_f64(sign, name, arg, repr) zig_make_special_f64(sign, name, arg, repr) |
| 3770 | #endif | 5766 | #endif |
| 3771 | #if FLT_MANT_DIG == 53 | 5767 | #if !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && FLT_MANT_DIG == 53 |
| 3772 | typedef float zig_f64; | 5768 | typedef float zig_f64; |
| 3773 | #define zig_make_f64(fp, repr) fp##f | 5769 | #define zig_make_f64(fp, repr) fp##f |
| 3774 | #elif DBL_MANT_DIG == 53 | 5770 | #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && DBL_MANT_DIG == 53 |
| 3775 | typedef double zig_f64; | 5771 | typedef double zig_f64; |
| 3776 | #define zig_make_f64(fp, repr) fp | 5772 | #define zig_make_f64(fp, repr) fp |
| 3777 | #elif LDBL_MANT_DIG == 53 | 5773 | #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && LDBL_MANT_DIG == 53 |
| 3778 | typedef long double zig_f64; | 5774 | typedef long double zig_f64; |
| 3779 | #define zig_make_f64(fp, repr) fp##l | 5775 | #define zig_make_f64(fp, repr) fp##l |
| 3780 | #elif FLT64_MANT_DIG == 53 | 5776 | #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && FLT64_MANT_DIG == 53 |
| 3781 | typedef _Float64 zig_f64; | 5777 | typedef _Float64 zig_f64; |
| 3782 | #define zig_make_f64(fp, repr) fp##f64 | 5778 | #define zig_make_f64(fp, repr) fp##f64 |
| 3783 | #elif FLT32X_MANT_DIG == 53 | 5779 | #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && FLT32X_MANT_DIG == 53 |
| 3784 | typedef _Float32x zig_f64; | 5780 | typedef _Float32x zig_f64; |
| 3785 | #define zig_make_f64(fp, repr) fp##f32x | 5781 | #define zig_make_f64(fp, repr) fp##f32x |
| 3786 | #else | 5782 | #else |
| ... | @@ -3798,7 +5794,14 @@ typedef uint64_t zig_f64; | ... | @@ -3798,7 +5794,14 @@ typedef uint64_t zig_f64; |
| 3798 | #define zig_has_f80 1 | 5794 | #define zig_has_f80 1 |
| 3799 | #define zig_libc_name_f80(name) __##name##x | 5795 | #define zig_libc_name_f80(name) __##name##x |
| 3800 | #define zig_init_special_f80(sign, name, arg, repr) zig_make_special_f80(sign, name, arg, repr) | 5796 | #define zig_init_special_f80(sign, name, arg, repr) zig_make_special_f80(sign, name, arg, repr) |
| 3801 | #if FLT_MANT_DIG == 64 | 5797 | #ifdef ZIG_TARGET_SOFT_COMPILER_RT_F80_ABI |
| 5798 | #undef zig_has_f80 | ||
| 5799 | typedef struct { uint64_t mantissa; uint16_t exponent; } zig_f80; | ||
| 5800 | #define zig_init_repr_f80(mantissa, exponent) { .mant##issa = mantissa, .expo##nent = exponent } | ||
| 5801 | #define zig_make_repr_f80(mantissa, exponent) (zig_f80)zig_init_repr_f80(mantissa, exponent) | ||
| 5802 | #define zig_mantissa_repr_f80(arg) (arg).mantissa | ||
| 5803 | #define zig_exponent_repr_f80(arg) (arg).exponent | ||
| 5804 | #elif FLT_MANT_DIG == 64 | ||
| 3802 | typedef float zig_f80; | 5805 | typedef float zig_f80; |
| 3803 | #define zig_make_f80(fp, repr) fp##f | 5806 | #define zig_make_f80(fp, repr) fp##f |
| 3804 | #elif DBL_MANT_DIG == 64 | 5807 | #elif DBL_MANT_DIG == 64 |
| ... | @@ -3818,68 +5821,91 @@ typedef __float80 zig_f80; | ... | @@ -3818,68 +5821,91 @@ typedef __float80 zig_f80; |
| 3818 | #define zig_make_f80(fp, repr) fp##l | 5821 | #define zig_make_f80(fp, repr) fp##l |
| 3819 | #else | 5822 | #else |
| 3820 | #undef zig_has_f80 | 5823 | #undef zig_has_f80 |
| 3821 | #define zig_has_f80 0 | ||
| 3822 | #define zig_repr_f80 u128 | ||
| 3823 | typedef zig_u128 zig_f80; | 5824 | typedef zig_u128 zig_f80; |
| 5825 | #define zig_init_repr_f80(mantissa, exponent) zig_init_u128(exponent, mantissa) | ||
| 5826 | #define zig_make_repr_f80(mantissa, exponent) zig_make_u128(exponent, mantissa) | ||
| 5827 | #define zig_mantissa_repr_f80(arg) zig_lo_u128(arg) | ||
| 5828 | #define zig_exponent_repr_f80(arg) (uint16_t)zig_hi_u128(arg) | ||
| 5829 | #endif | ||
| 5830 | #ifndef zig_has_f80 | ||
| 5831 | #define zig_has_f80 0 | ||
| 3824 | #define zig_make_f80(fp, repr) repr | 5832 | #define zig_make_f80(fp, repr) repr |
| 5833 | #ifndef zig_make_repr_f80 | ||
| 5834 | #define zig_make_repr_f80(mantissa, exponent) (zig_f80)zig_init_repr_f80(mantissa, exponent) | ||
| 5835 | #endif | ||
| 3825 | #undef zig_make_special_f80 | 5836 | #undef zig_make_special_f80 |
| 3826 | #define zig_make_special_f80(sign, name, arg, repr) repr | 5837 | #define zig_make_special_f80(sign, name, arg, repr) repr |
| 3827 | #undef zig_init_special_f80 | 5838 | #undef zig_init_special_f80 |
| 3828 | #define zig_init_special_f80(sign, name, arg, repr) repr | 5839 | #define zig_init_special_f80(sign, name, arg, repr) repr |
| 3829 | #endif | 5840 | #endif |
| 3830 | 5841 | ||
| 3831 | #if defined(zig_gcc) && defined(zig_x86) | ||
| 3832 | #define zig_f128_has_miscompilations 1 | ||
| 3833 | #else | ||
| 3834 | #define zig_f128_has_miscompilations 0 | ||
| 3835 | #endif | ||
| 3836 | |||
| 3837 | #define zig_has_f128 1 | 5842 | #define zig_has_f128 1 |
| 3838 | #define zig_libc_name_f128(name) name##q | 5843 | #define zig_libc_name_f128(name) name##f128 |
| 3839 | #define zig_init_special_f128(sign, name, arg, repr) zig_make_special_f128(sign, name, arg, repr) | 5844 | #define zig_init_special_f128(sign, name, arg, repr) zig_make_special_f128(sign, name, arg, repr) |
| 3840 | #if !zig_f128_has_miscompilations && FLT_MANT_DIG == 113 | 5845 | #ifdef ZIG_TARGET_SOFT_COMPILER_RT_F128_ABI |
| 5846 | #undef zig_has_f128 | ||
| 5847 | #if zig_little_endian | ||
| 5848 | typedef struct { uint64_t lo, hi; } zig_f128; | ||
| 5849 | #else | ||
| 5850 | typedef struct { uint64_t hi, lo; } zig_f128; | ||
| 5851 | #endif | ||
| 5852 | #define zig_init_repr_f128(hi, lo) { .h##i = hi, .l##o = lo } | ||
| 5853 | #define zig_lo_repr_f128(arg) (arg).lo | ||
| 5854 | #define zig_hi_repr_f128(arg) (arg).hi | ||
| 5855 | #elif FLT_MANT_DIG == 113 | ||
| 3841 | typedef float zig_f128; | 5856 | typedef float zig_f128; |
| 3842 | #define zig_make_f128(fp, repr) fp##f | 5857 | #define zig_make_f128(fp, repr) fp##f |
| 3843 | #elif !zig_f128_has_miscompilations && DBL_MANT_DIG == 113 | 5858 | #elif DBL_MANT_DIG == 113 |
| 3844 | typedef double zig_f128; | 5859 | typedef double zig_f128; |
| 3845 | #define zig_make_f128(fp, repr) fp | 5860 | #define zig_make_f128(fp, repr) fp |
| 3846 | #elif !zig_f128_has_miscompilations && LDBL_MANT_DIG == 113 | 5861 | #elif LDBL_MANT_DIG == 113 |
| 3847 | typedef long double zig_f128; | 5862 | typedef long double zig_f128; |
| 3848 | #define zig_make_f128(fp, repr) fp##l | 5863 | #define zig_make_f128(fp, repr) fp##l |
| 3849 | #elif !zig_f128_has_miscompilations && FLT128_MANT_DIG == 113 | 5864 | #elif FLT128_MANT_DIG == 113 |
| 3850 | typedef _Float128 zig_f128; | 5865 | typedef _Float128 zig_f128; |
| 3851 | #define zig_make_f128(fp, repr) fp##f128 | 5866 | #define zig_make_f128(fp, repr) fp##f128 |
| 3852 | #elif !zig_f128_has_miscompilations && FLT64X_MANT_DIG == 113 | 5867 | #elif FLT64X_MANT_DIG == 113 |
| 3853 | typedef _Float64x zig_f128; | 5868 | typedef _Float64x zig_f128; |
| 3854 | #define zig_make_f128(fp, repr) fp##f64x | 5869 | #define zig_make_f128(fp, repr) fp##f64x |
| 3855 | #elif !zig_f128_has_miscompilations && defined(__SIZEOF_FLOAT128__) | 5870 | #elif defined(__SIZEOF_FLOAT128__) |
| 3856 | typedef __float128 zig_f128; | 5871 | typedef __float128 zig_f128; |
| 3857 | #define zig_make_f128(fp, repr) fp##q | 5872 | #define zig_make_f128(fp, repr) fp##q |
| 3858 | #undef zig_make_special_f128 | 5873 | #undef zig_make_special_f128 |
| 3859 | #define zig_make_special_f128(sign, name, arg, repr) sign __builtin_##name##f128(arg) | 5874 | #define zig_make_special_f128(sign, name, arg, repr) sign __builtin_##name##f128(arg) |
| 3860 | #else | 5875 | #else |
| 3861 | #undef zig_has_f128 | 5876 | #undef zig_has_f128 |
| 3862 | #define zig_has_f128 0 | 5877 | #if defined(zig_x86_64) && defined(ZIG_TARGET_ABI_MSVC) |
| 3863 | #undef zig_make_special_f128 | 5878 | #if defined(zig_msvc) && !defined(__clang__) |
| 3864 | #undef zig_init_special_f128 | 5879 | #include <emmintrin.h> |
| 3865 | #if defined(zig_darwin) || defined(zig_aarch64) | 5880 | typedef __m128i zig_f128; |
| 3866 | typedef __attribute__((__vector_size__(2 * sizeof(uint64_t)))) uint64_t zig_v2u64; | 5881 | #define zig_init_repr_f128(hi, lo) { .m128i_u64 = { lo, hi } } |
| 3867 | zig_basic_operator(zig_v2u64, xor_v2u64, ^) | 5882 | #define zig_lo_repr_f128(arg) (arg).m128i_u64[0] |
| 3868 | #define zig_repr_f128 v2u64 | 5883 | #define zig_hi_repr_f128(arg) (arg).m128i_u64[1] |
| 3869 | typedef zig_v2u64 zig_f128; | 5884 | #else |
| 3870 | #define zig_make_f128_zig_make_u128(hi, lo) (zig_f128){ lo, hi } | 5885 | typedef __attribute__((__vector_size__(2 * sizeof(uint64_t)))) uint64_t zig_f128; |
| 3871 | #define zig_make_f128_zig_init_u128 zig_make_f128_zig_make_u128 | 5886 | #define zig_init_repr_f128(hi, lo) { lo, hi } |
| 3872 | #define zig_make_f128(fp, repr) zig_make_f128_##repr | 5887 | #define zig_lo_repr_f128(arg) (arg)[0] |
| 3873 | #define zig_make_special_f128(sign, name, arg, repr) zig_make_f128_##repr | 5888 | #define zig_hi_repr_f128(arg) (arg)[1] |
| 3874 | #define zig_init_special_f128(sign, name, arg, repr) zig_make_f128_##repr | 5889 | #endif |
| 3875 | #else | 5890 | #else |
| 3876 | #define zig_repr_f128 u128 | ||
| 3877 | typedef zig_u128 zig_f128; | 5891 | typedef zig_u128 zig_f128; |
| 5892 | #define zig_init_repr_f128(hi, lo) zig_init_u128(hi, lo) | ||
| 5893 | #define zig_make_repr_f128(hi, lo) zig_make_u128(hi, lo) | ||
| 5894 | #define zig_lo_repr_f128(arg) zig_lo_u128(arg) | ||
| 5895 | #define zig_hi_repr_f128(arg) zig_hi_u128(arg) | ||
| 5896 | #endif | ||
| 5897 | #endif | ||
| 5898 | #ifndef zig_has_f128 | ||
| 5899 | #define zig_has_f128 0 | ||
| 3878 | #define zig_make_f128(fp, repr) repr | 5900 | #define zig_make_f128(fp, repr) repr |
| 5901 | #ifndef zig_make_repr_f128 | ||
| 5902 | #define zig_make_repr_f128(hi, lo) (zig_f128)zig_init_repr_f128(hi, lo) | ||
| 5903 | #endif | ||
| 5904 | #undef zig_make_special_f128 | ||
| 3879 | #define zig_make_special_f128(sign, name, arg, repr) repr | 5905 | #define zig_make_special_f128(sign, name, arg, repr) repr |
| 5906 | #undef zig_init_special_f128 | ||
| 3880 | #define zig_init_special_f128(sign, name, arg, repr) repr | 5907 | #define zig_init_special_f128(sign, name, arg, repr) repr |
| 3881 | #endif | 5908 | #endif |
| 3882 | #endif | ||
| 3883 | 5909 | ||
| 3884 | #if !defined(zig_msvc) && defined(ZIG_TARGET_ABI_MSVC) | 5910 | #if !defined(zig_msvc) && defined(ZIG_TARGET_ABI_MSVC) |
| 3885 | /* Emulate msvc abi on a gnu compiler */ | 5911 | /* Emulate msvc abi on a gnu compiler */ |
| ... | @@ -3892,84 +5918,141 @@ typedef zig_f128 zig_c_longdouble; | ... | @@ -3892,84 +5918,141 @@ typedef zig_f128 zig_c_longdouble; |
| 3892 | typedef long double zig_c_longdouble; | 5918 | typedef long double zig_c_longdouble; |
| 3893 | #endif | 5919 | #endif |
| 3894 | 5920 | ||
| 3895 | #define zig_bitCast_float(Type, ReprType) \ | 5921 | #if __AVR__ |
| 3896 | static inline zig_##Type zig_bitCast_##Type(ReprType repr) { \ | 5922 | typedef signed char zig_FloatCompareResult; |
| 3897 | zig_##Type result; \ | 5923 | #elif defined(zig_aarch64) |
| 3898 | memcpy(&result, &repr, sizeof(result)); \ | 5924 | typedef signed int zig_FloatCompareResult; |
| 3899 | return result; \ | 5925 | #elif __SIZEOF_LONG__ >= __SIZEOF_POINTER__ |
| 5926 | typedef signed long zig_FloatCompareResult; | ||
| 5927 | #else | ||
| 5928 | typedef signed long long zig_FloatCompareResult; | ||
| 5929 | #endif | ||
| 5930 | |||
| 5931 | #define zig_bitCast_float(w, iw, UnsignedReprType, SignedReprType) \ | ||
| 5932 | static inline zig_f##w zig_f##w##_bitCast_u##iw(UnsignedReprType arg) { \ | ||
| 5933 | zig_f##w res; \ | ||
| 5934 | memcpy(&res, &arg, sizeof(zig_f##w)); \ | ||
| 5935 | return res; \ | ||
| 5936 | } \ | ||
| 5937 | static inline zig_f##w zig_f##w##_bitCast_i##iw(SignedReprType arg) { \ | ||
| 5938 | zig_f##w res; \ | ||
| 5939 | memcpy(&res, &arg, sizeof(zig_f##w)); \ | ||
| 5940 | return res; \ | ||
| 5941 | } \ | ||
| 5942 | static inline UnsignedReprType zig_u##iw##_bitCast_f##w(zig_f##w arg) { \ | ||
| 5943 | UnsignedReprType res; \ | ||
| 5944 | memcpy(&res, &arg, sizeof(zig_f##w)); \ | ||
| 5945 | return zig_u##iw##_truncate_u##iw(res, w); \ | ||
| 5946 | } \ | ||
| 5947 | static inline SignedReprType zig_i##iw##_bitCast_f##w(zig_f##w arg) { \ | ||
| 5948 | SignedReprType res; \ | ||
| 5949 | memcpy(&res, &arg, sizeof(zig_f##w)); \ | ||
| 5950 | return zig_i##iw##_truncate_i##iw(res, w); \ | ||
| 3900 | } | 5951 | } |
| 3901 | zig_bitCast_float(f16, uint16_t) | 5952 | zig_bitCast_float(16, 16, uint16_t, int16_t) |
| 3902 | zig_bitCast_float(f32, uint32_t) | 5953 | zig_bitCast_float(32, 32, uint32_t, int32_t) |
| 3903 | zig_bitCast_float(f64, uint64_t) | 5954 | zig_bitCast_float(64, 64, uint64_t, int64_t) |
| 3904 | zig_bitCast_float(f80, zig_u128) | 5955 | #if zig_has_f80 |
| 3905 | zig_bitCast_float(f128, zig_u128) | 5956 | zig_bitCast_float(80, 128, zig_u128, zig_i128) |
| 5957 | #else | ||
| 5958 | static inline zig_f80 zig_f80_bitCast_u128(zig_u128 arg) { | ||
| 5959 | return zig_make_repr_f80(zig_lo_u128(arg), (uint16_t)zig_hi_u128(arg)); | ||
| 5960 | } | ||
| 5961 | static inline zig_f80 zig_f80_bitCast_i128(zig_i128 arg) { | ||
| 5962 | return zig_make_repr_f80(zig_lo_i128(arg), (uint16_t)zig_hi_i128(arg)); | ||
| 5963 | } | ||
| 5964 | static inline zig_u128 zig_u128_bitCast_f80(zig_f80 arg) { | ||
| 5965 | return zig_make_u128(zig_exponent_repr_f80(arg), zig_mantissa_repr_f80(arg)); | ||
| 5966 | } | ||
| 5967 | static inline zig_i128 zig_i128_bitCast_f80(zig_f80 arg) { | ||
| 5968 | return zig_make_i128((int16_t)zig_exponent_repr_f80(arg), zig_mantissa_repr_f80(arg)); | ||
| 5969 | } | ||
| 5970 | #endif | ||
| 5971 | static inline zig_f80 zig_f80_bitCast_big(const void *arg) { | ||
| 5972 | return zig_f80_bitCast_u128(zig_u128_truncate_big(arg, UINT8_C(80), false, UINT16_C(80))); | ||
| 5973 | } | ||
| 5974 | static inline void zig_big_bitCast_f80(void *res, zig_f80 arg, bool res_is_signed, uint16_t res_bits) { | ||
| 5975 | if (res_is_signed) { | ||
| 5976 | zig_big_truncate_i128(res, zig_i128_bitCast_f80(arg), res_is_signed, res_bits); | ||
| 5977 | } else { | ||
| 5978 | zig_big_truncate_u128(res, zig_u128_bitCast_f80(arg), res_is_signed, res_bits); | ||
| 5979 | } | ||
| 5980 | } | ||
| 5981 | #if zig_has_f128 | ||
| 5982 | zig_bitCast_float(128, 128, zig_u128, zig_i128) | ||
| 5983 | #else | ||
| 5984 | static inline zig_f128 zig_f128_bitCast_u128(zig_u128 arg) { | ||
| 5985 | return zig_make_repr_f128(zig_hi_u128(arg), zig_lo_u128(arg)); | ||
| 5986 | } | ||
| 5987 | static inline zig_f128 zig_f128_bitCast_i128(zig_i128 arg) { | ||
| 5988 | return zig_make_repr_f128((uint64_t)zig_hi_i128(arg), zig_lo_i128(arg)); | ||
| 5989 | } | ||
| 5990 | static inline zig_u128 zig_u128_bitCast_f128(zig_f128 arg) { | ||
| 5991 | return zig_make_u128(zig_hi_repr_f128(arg), zig_lo_repr_f128(arg)); | ||
| 5992 | } | ||
| 5993 | static inline zig_i128 zig_i128_bitCast_f128(zig_f128 arg) { | ||
| 5994 | return zig_make_i128((int64_t)zig_hi_repr_f128(arg), zig_lo_repr_f128(arg)); | ||
| 5995 | } | ||
| 5996 | #endif | ||
| 3906 | 5997 | ||
| 3907 | #define zig_convert_builtin(ExternResType, ResType, operation, ExternArgType, ArgType, version) \ | 5998 | #define zig_convert_float_00(ResType, operation, ArgType, version) \ |
| 3908 | zig_extern ExternResType zig_expand_concat(zig_expand_concat(zig_expand_concat(__##operation, \ | 5999 | zig_extern ResType zig_expand_concat(zig_expand_concat(zig_expand_concat(__##operation, \ |
| 3909 | zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType), version)(ExternArgType); \ | 6000 | zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType), version)(ArgType arg); \ |
| 6001 | return zig_expand_concat(zig_expand_concat(zig_expand_concat(__##operation, \ | ||
| 6002 | zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType), version)(arg) | ||
| 6003 | #define zig_convert_float_01(ResType, operation, ArgType, version) \ | ||
| 6004 | zig_convert_float_00(ResType, operation, ArgType, version) | ||
| 6005 | #define zig_convert_float_10(ResType, operation, ArgType, version) \ | ||
| 6006 | zig_convert_float_00(ResType, operation, ArgType, version) | ||
| 6007 | #define zig_convert_float_11(ResType, operation, ArgType, version) \ | ||
| 6008 | return (ResType)arg | ||
| 6009 | #define zig_convert_float(res_when, ResType, operation, arg_when, ArgType, version) \ | ||
| 3910 | static inline ResType zig_expand_concat(zig_expand_concat(zig_##operation, \ | 6010 | static inline ResType zig_expand_concat(zig_expand_concat(zig_##operation, \ |
| 3911 | zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType)(ArgType arg) { \ | 6011 | zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType)(ArgType arg) { \ |
| 3912 | ResType res; \ | 6012 | zig_expand_concat(zig_expand_concat(zig_convert_float_, zig_has_##res_when), \ |
| 3913 | ExternResType extern_res; \ | 6013 | zig_has_##arg_when)(ResType, operation, ArgType, version); \ |
| 3914 | ExternArgType extern_arg; \ | 6014 | } |
| 3915 | memcpy(&extern_arg, &arg, sizeof(extern_arg)); \ | 6015 | |
| 3916 | extern_res = zig_expand_concat(zig_expand_concat(zig_expand_concat(__##operation, \ | 6016 | #define zig_convert_floats(SmallType, BigType) \ |
| 3917 | zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType), version)(extern_arg); \ | 6017 | zig_convert_float(SmallType, zig_##SmallType, trunc, BigType, zig_##BigType, 2) \ |
| 3918 | memcpy(&res, &extern_res, sizeof(res)); \ | 6018 | zig_convert_float(BigType, zig_##BigType, extend, SmallType, zig_##SmallType, 2) |
| 3919 | return extern_res; \ | 6019 | zig_convert_floats(f16, f32) |
| 3920 | } | 6020 | zig_convert_floats(f16, f64) |
| 3921 | zig_convert_builtin(zig_compiler_rt_f16, zig_f16, trunc, zig_f32, zig_f32, 2) | 6021 | zig_convert_floats(f16, f80) |
| 3922 | zig_convert_builtin(zig_compiler_rt_f16, zig_f16, trunc, zig_f64, zig_f64, 2) | 6022 | zig_convert_floats(f16, f128) |
| 3923 | zig_convert_builtin(zig_f16, zig_f16, trunc, zig_f80, zig_f80, 2) | 6023 | zig_convert_floats(f32, f64) |
| 3924 | zig_convert_builtin(zig_f16, zig_f16, trunc, zig_f128, zig_f128, 2) | 6024 | zig_convert_floats(f32, f80) |
| 3925 | zig_convert_builtin(zig_f32, zig_f32, extend, zig_compiler_rt_f16, zig_f16, 2) | 6025 | zig_convert_floats(f32, f128) |
| 3926 | zig_convert_builtin(zig_f32, zig_f32, trunc, zig_f80, zig_f80, 2) | 6026 | zig_convert_floats(f64, f80) |
| 3927 | zig_convert_builtin(zig_f32, zig_f32, trunc, zig_f128, zig_f128, 2) | 6027 | zig_convert_floats(f64, f128) |
| 3928 | zig_convert_builtin(zig_f64, zig_f64, extend, zig_compiler_rt_f16, zig_f16, 2) | 6028 | zig_convert_floats(f80, f128) |
| 3929 | zig_convert_builtin(zig_f64, zig_f64, trunc, zig_f80, zig_f80, 2) | 6029 | |
| 3930 | zig_convert_builtin(zig_f64, zig_f64, trunc, zig_f128, zig_f128, 2) | 6030 | #define zig_float_negate_builtin_0(w, sb) \ |
| 3931 | zig_convert_builtin(zig_f80, zig_f80, extend, zig_f16, zig_f16, 2) | 6031 | zig_expand_concat(zig_xor_, zig_repr_f##w)(arg, zig_make_f##w(-0x0.0p0, sb)) |
| 3932 | zig_convert_builtin(zig_f80, zig_f80, extend, zig_f32, zig_f32, 2) | 6032 | #define zig_float_negate_builtin_1(w, sb) -arg |
| 3933 | zig_convert_builtin(zig_f80, zig_f80, extend, zig_f64, zig_f64, 2) | 6033 | #define zig_float_negate_builtin(w, sb) \ |
| 3934 | zig_convert_builtin(zig_f80, zig_f80, trunc, zig_f128, zig_f128, 2) | ||
| 3935 | zig_convert_builtin(zig_f128, zig_f128, extend, zig_f16, zig_f16, 2) | ||
| 3936 | zig_convert_builtin(zig_f128, zig_f128, extend, zig_f32, zig_f32, 2) | ||
| 3937 | zig_convert_builtin(zig_f128, zig_f128, extend, zig_f64, zig_f64, 2) | ||
| 3938 | zig_convert_builtin(zig_f128, zig_f128, extend, zig_f80, zig_f80, 2) | ||
| 3939 | |||
| 3940 | #ifdef __ARM_EABI__ | ||
| 3941 | |||
| 3942 | zig_extern zig_callconv(pcs("aapcs")) zig_f32 __aeabi_d2f(zig_f64); | ||
| 3943 | static inline zig_f32 zig_truncdfsf(zig_f64 arg) { return __aeabi_d2f(arg); } | ||
| 3944 | |||
| 3945 | zig_extern zig_callconv(pcs("aapcs")) zig_f64 __aeabi_f2d(zig_f32); | ||
| 3946 | static inline zig_f64 zig_extendsfdf(zig_f32 arg) { return __aeabi_f2d(arg); } | ||
| 3947 | |||
| 3948 | #else /* __ARM_EABI__ */ | ||
| 3949 | |||
| 3950 | zig_convert_builtin(zig_f32, zig_f32, trunc, zig_f64, zig_f64, 2) | ||
| 3951 | zig_convert_builtin(zig_f64, zig_f64, extend, zig_f32, zig_f32, 2) | ||
| 3952 | |||
| 3953 | #endif /* __ARM_EABI__ */ | ||
| 3954 | |||
| 3955 | #define zig_float_negate_builtin_0(w, c, sb) \ | ||
| 3956 | zig_expand_concat(zig_xor_, zig_repr_f##w)(arg, zig_make_f##w(-0x0.0p0, c sb)) | ||
| 3957 | #define zig_float_negate_builtin_1(w, c, sb) -arg | ||
| 3958 | #define zig_float_negate_builtin(w, c, sb) \ | ||
| 3959 | static inline zig_f##w zig_neg_f##w(zig_f##w arg) { \ | 6034 | static inline zig_f##w zig_neg_f##w(zig_f##w arg) { \ |
| 3960 | return zig_expand_concat(zig_float_negate_builtin_, zig_has_f##w)(w, c, sb); \ | 6035 | return zig_expand_concat(zig_float_negate_builtin_, zig_has_f##w)(w, sb); \ |
| 3961 | } | 6036 | } |
| 3962 | zig_float_negate_builtin(16, , UINT16_C(1) << 15 ) | 6037 | zig_float_negate_builtin(16, UINT16_C(1) << 15) |
| 3963 | zig_float_negate_builtin(32, , UINT32_C(1) << 31 ) | 6038 | zig_float_negate_builtin(32, UINT32_C(1) << 31) |
| 3964 | zig_float_negate_builtin(64, , UINT64_C(1) << 63 ) | 6039 | zig_float_negate_builtin(64, UINT64_C(1) << 63) |
| 3965 | zig_float_negate_builtin(80, zig_make_u128, (UINT64_C(1) << 15, UINT64_C(0))) | 6040 | |
| 3966 | zig_float_negate_builtin(128, zig_make_u128, (UINT64_C(1) << 63, UINT64_C(0))) | 6041 | #undef zig_float_negate_builtin_0 |
| 6042 | #define zig_float_negate_builtin_0(w, sb) \ | ||
| 6043 | zig_make_repr_f##w(zig_mantissa_repr_f##w(arg), zig_xor_u16(zig_exponent_repr_f##w(arg), sb)) | ||
| 6044 | zig_float_negate_builtin(80, UINT16_C(1) << 15) | ||
| 6045 | |||
| 6046 | #undef zig_float_negate_builtin_0 | ||
| 6047 | #define zig_float_negate_builtin_0(w, sb) \ | ||
| 6048 | zig_make_repr_f##w(zig_xor_u64(zig_hi_repr_f##w(arg), sb), zig_lo_repr_f##w(arg)) | ||
| 6049 | zig_float_negate_builtin(128, UINT64_C(1) << 63) | ||
| 3967 | 6050 | ||
| 3968 | #define zig_float_less_builtin_0(Type, operation) \ | 6051 | #define zig_float_less_builtin_0(Type, operation) \ |
| 3969 | zig_extern int32_t zig_expand_concat(zig_expand_concat(__##operation, \ | 6052 | zig_extern zig_FloatCompareResult zig_expand_concat(zig_expand_concat(__##operation, \ |
| 3970 | zig_compiler_rt_abbrev_zig_##Type), 2)(zig_##Type, zig_##Type); \ | 6053 | zig_compiler_rt_abbrev_zig_##Type), 2)(zig_##Type, zig_##Type); \ |
| 3971 | static inline int32_t zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \ | 6054 | static inline int32_t zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \ |
| 3972 | return zig_expand_concat(zig_expand_concat(__##operation, zig_compiler_rt_abbrev_zig_##Type), 2)(lhs, rhs); \ | 6055 | return (int32_t)zig_expand_concat(zig_expand_concat(__##operation, zig_compiler_rt_abbrev_zig_##Type), 2)(lhs, rhs); \ |
| 3973 | } | 6056 | } |
| 3974 | #define zig_float_less_builtin_1(Type, operation) \ | 6057 | #define zig_float_less_builtin_1(Type, operation) \ |
| 3975 | static inline int32_t zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \ | 6058 | static inline int32_t zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \ |
| ... | @@ -3994,13 +6077,52 @@ zig_float_negate_builtin(128, zig_make_u128, (UINT64_C(1) << 63, UINT64_C(0))) | ... | @@ -3994,13 +6077,52 @@ zig_float_negate_builtin(128, zig_make_u128, (UINT64_C(1) << 63, UINT64_C(0))) |
| 3994 | return lhs operator rhs; \ | 6077 | return lhs operator rhs; \ |
| 3995 | } | 6078 | } |
| 3996 | 6079 | ||
| 6080 | #define zig_float_builtins(w) \ | ||
| 6081 | zig_common_float_builtins(w) \ | ||
| 6082 | zig_convert_float(f##w, zig_f##w, float, int128, zig_i128, ) \ | ||
| 6083 | zig_convert_float(f##w, zig_f##w, floatun, int128, zig_u128, ) | ||
| 3997 | #define zig_common_float_builtins(w) \ | 6084 | #define zig_common_float_builtins(w) \ |
| 3998 | zig_convert_builtin( int64_t, int64_t, fix, zig_f##w, zig_f##w, ) \ | 6085 | zig_convert_float(always, int32_t, fix, f##w, zig_f##w, ) \ |
| 3999 | zig_convert_builtin(zig_i128, zig_i128, fix, zig_f##w, zig_f##w, ) \ | 6086 | zig_convert_float(always, int64_t, fix, f##w, zig_f##w, ) \ |
| 4000 | zig_convert_builtin(zig_u128, zig_u128, fixuns, zig_f##w, zig_f##w, ) \ | 6087 | zig_convert_float(int128, zig_i128, fix, f##w, zig_f##w, ) \ |
| 4001 | zig_convert_builtin(zig_f##w, zig_f##w, float, int64_t, int64_t, ) \ | 6088 | zig_convert_float(always, uint32_t, fixuns, f##w, zig_f##w, ) \ |
| 4002 | zig_convert_builtin(zig_f##w, zig_f##w, float, zig_i128, zig_i128, ) \ | 6089 | zig_convert_float(always, uint64_t, fixuns, f##w, zig_f##w, ) \ |
| 4003 | zig_convert_builtin(zig_f##w, zig_f##w, floatun, zig_u128, zig_u128, ) \ | 6090 | zig_convert_float(int128, zig_u128, fixuns, f##w, zig_f##w, ) \ |
| 6091 | zig_convert_float(f##w, zig_f##w, float, always, int32_t, ) \ | ||
| 6092 | zig_convert_float(f##w, zig_f##w, float, always, int64_t, ) \ | ||
| 6093 | zig_convert_float(f##w, zig_f##w, floatun, always, uint32_t, ) \ | ||
| 6094 | zig_convert_float(f##w, zig_f##w, floatun, always, uint64_t, ) \ | ||
| 6095 | \ | ||
| 6096 | static inline void zig_expand_concat(zig_expand_concat(zig_fix, \ | ||
| 6097 | zig_compiler_rt_abbrev_zig_f##w), ei)(void *res, zig_f##w arg, uint16_t bits) { \ | ||
| 6098 | zig_extern void zig_expand_concat(zig_expand_concat(__fix, \ | ||
| 6099 | zig_compiler_rt_abbrev_zig_f##w), ei)(uint8_t *res, uintptr_t bits, zig_f##w arg); \ | ||
| 6100 | zig_expand_concat(zig_expand_concat(__fix, \ | ||
| 6101 | zig_compiler_rt_abbrev_zig_f##w), ei)(res, bits, arg); \ | ||
| 6102 | } \ | ||
| 6103 | \ | ||
| 6104 | static inline void zig_expand_concat(zig_expand_concat(zig_fixuns, \ | ||
| 6105 | zig_compiler_rt_abbrev_zig_f##w), ei)(void *res, zig_f##w arg, uint16_t bits) { \ | ||
| 6106 | zig_extern void zig_expand_concat(zig_expand_concat(__fixuns, \ | ||
| 6107 | zig_compiler_rt_abbrev_zig_f##w), ei)(uint8_t *res, uintptr_t bits, zig_f##w arg); \ | ||
| 6108 | zig_expand_concat(zig_expand_concat(__fixuns, \ | ||
| 6109 | zig_compiler_rt_abbrev_zig_f##w), ei)(res, bits, arg); \ | ||
| 6110 | } \ | ||
| 6111 | \ | ||
| 6112 | static inline zig_f##w zig_expand_concat(zig_floatei, \ | ||
| 6113 | zig_compiler_rt_abbrev_zig_f##w)(void *res, uint16_t bits) { \ | ||
| 6114 | zig_extern zig_f##w zig_expand_concat(__floatei, \ | ||
| 6115 | zig_compiler_rt_abbrev_zig_f##w)(const uint8_t *arg, uintptr_t bits); \ | ||
| 6116 | return zig_expand_concat(__floatei, zig_compiler_rt_abbrev_zig_f##w)(res, bits); \ | ||
| 6117 | } \ | ||
| 6118 | \ | ||
| 6119 | static inline zig_f##w zig_expand_concat(zig_floatunei, \ | ||
| 6120 | zig_compiler_rt_abbrev_zig_f##w)(void *res, uint16_t bits) { \ | ||
| 6121 | zig_extern zig_f##w zig_expand_concat(__floatunei, \ | ||
| 6122 | zig_compiler_rt_abbrev_zig_f##w)(const uint8_t *arg, uintptr_t bits); \ | ||
| 6123 | return zig_expand_concat(__floatunei, zig_compiler_rt_abbrev_zig_f##w)(res, bits); \ | ||
| 6124 | } \ | ||
| 6125 | \ | ||
| 4004 | zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, cmp) \ | 6126 | zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, cmp) \ |
| 4005 | zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, ne) \ | 6127 | zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, ne) \ |
| 4006 | zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, eq) \ | 6128 | zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, eq) \ |
| ... | @@ -4031,82 +6153,48 @@ zig_float_negate_builtin(128, zig_make_u128, (UINT64_C(1) << 63, UINT64_C(0))) | ... | @@ -4031,82 +6153,48 @@ zig_float_negate_builtin(128, zig_make_u128, (UINT64_C(1) << 63, UINT64_C(0))) |
| 4031 | zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(fmax)))(zig_f##w, zig_max_f##w, zig_libc_name_f##w(fmax), (zig_f##w x, zig_f##w y), (x, y)) \ | 6153 | zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(fmax)))(zig_f##w, zig_max_f##w, zig_libc_name_f##w(fmax), (zig_f##w x, zig_f##w y), (x, y)) \ |
| 4032 | zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(fma)))(zig_f##w, zig_fma_f##w, zig_libc_name_f##w(fma), (zig_f##w x, zig_f##w y, zig_f##w z), (x, y, z)) \ | 6154 | zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(fma)))(zig_f##w, zig_fma_f##w, zig_libc_name_f##w(fma), (zig_f##w x, zig_f##w y, zig_f##w z), (x, y, z)) \ |
| 4033 | \ | 6155 | \ |
| 4034 | static inline zig_f##w zig_div_trunc_f##w(zig_f##w lhs, zig_f##w rhs) { \ | 6156 | static inline zig_f##w zig_divTrunc_f##w(zig_f##w lhs, zig_f##w rhs) { \ |
| 4035 | return zig_trunc_f##w(zig_div_f##w(lhs, rhs)); \ | 6157 | return zig_trunc_f##w(zig_div_f##w(lhs, rhs)); \ |
| 4036 | } \ | 6158 | } \ |
| 4037 | \ | 6159 | \ |
| 4038 | static inline zig_f##w zig_div_floor_f##w(zig_f##w lhs, zig_f##w rhs) { \ | 6160 | static inline zig_f##w zig_divFloor_f##w(zig_f##w lhs, zig_f##w rhs) { \ |
| 4039 | return zig_floor_f##w(zig_div_f##w(lhs, rhs)); \ | 6161 | return zig_floor_f##w(zig_div_f##w(lhs, rhs)); \ |
| 4040 | } \ | 6162 | } \ |
| 4041 | \ | 6163 | \ |
| 4042 | static inline zig_f##w zig_div_ceil_f##w(zig_f##w lhs, zig_f##w rhs) { \ | 6164 | static inline zig_f##w zig_divCeil_f##w(zig_f##w lhs, zig_f##w rhs) { \ |
| 4043 | return zig_ceil_f##w(zig_div_f##w(lhs, rhs)); \ | 6165 | return zig_ceil_f##w(zig_div_f##w(lhs, rhs)); \ |
| 4044 | } \ | 6166 | } \ |
| 4045 | \ | 6167 | \ |
| 4046 | static inline zig_f##w zig_mod_f##w(zig_f##w lhs, zig_f##w rhs) { \ | 6168 | static inline zig_f##w zig_mod_f##w(zig_f##w lhs, zig_f##w rhs) { \ |
| 4047 | return zig_sub_f##w(lhs, zig_mul_f##w(zig_div_floor_f##w(lhs, rhs), rhs)); \ | 6169 | return zig_sub_f##w(lhs, zig_mul_f##w(zig_divFloor_f##w(lhs, rhs), rhs)); \ |
| 4048 | } | 6170 | } |
| 4049 | zig_common_float_builtins(16) | ||
| 4050 | zig_common_float_builtins(32) | ||
| 4051 | zig_common_float_builtins(64) | ||
| 4052 | zig_common_float_builtins(80) | ||
| 4053 | zig_common_float_builtins(128) | ||
| 4054 | |||
| 4055 | #define zig_float_builtins(w) \ | ||
| 4056 | zig_convert_builtin( int32_t, int32_t, fix, zig_f##w, zig_f##w, ) \ | ||
| 4057 | zig_convert_builtin(uint32_t, uint32_t, fixuns, zig_f##w, zig_f##w, ) \ | ||
| 4058 | zig_convert_builtin(uint64_t, uint64_t, fixuns, zig_f##w, zig_f##w, ) \ | ||
| 4059 | zig_convert_builtin(zig_f##w, zig_f##w, float, int32_t, int32_t, ) \ | ||
| 4060 | zig_convert_builtin(zig_f##w, zig_f##w, floatun, uint32_t, uint32_t, ) \ | ||
| 4061 | zig_convert_builtin(zig_f##w, zig_f##w, floatun, uint64_t, uint64_t, ) | ||
| 4062 | zig_float_builtins(16) | 6171 | zig_float_builtins(16) |
| 4063 | zig_float_builtins(80) | ||
| 4064 | zig_float_builtins(128) | ||
| 4065 | |||
| 4066 | #ifdef __ARM_EABI__ | ||
| 4067 | |||
| 4068 | zig_extern zig_callconv(pcs("aapcs")) int32_t __aeabi_f2iz(zig_f32); | ||
| 4069 | static inline int32_t zig_fixsfsi(zig_f32 arg) { return __aeabi_f2iz(arg); } | ||
| 4070 | |||
| 4071 | zig_extern zig_callconv(pcs("aapcs")) uint32_t __aeabi_f2uiz(zig_f32); | ||
| 4072 | static inline uint32_t zig_fixunssfsi(zig_f32 arg) { return __aeabi_f2uiz(arg); } | ||
| 4073 | |||
| 4074 | zig_extern zig_callconv(pcs("aapcs")) uint64_t __aeabi_f2ulz(zig_f32); | ||
| 4075 | static inline uint64_t zig_fixunssfdi(zig_f32 arg) { return __aeabi_f2ulz(arg); } | ||
| 4076 | |||
| 4077 | zig_extern zig_callconv(pcs("aapcs")) zig_f32 __aeabi_i2f(int32_t); | ||
| 4078 | static inline zig_f32 zig_floatsisf(int32_t arg) { return __aeabi_i2f(arg); } | ||
| 4079 | |||
| 4080 | zig_extern zig_callconv(pcs("aapcs")) zig_f32 __aeabi_ui2f(uint32_t); | ||
| 4081 | static inline zig_f32 zig_floatunsisf(uint32_t arg) { return __aeabi_ui2f(arg); } | ||
| 4082 | |||
| 4083 | zig_extern zig_callconv(pcs("aapcs")) zig_f32 __aeabi_ul2f(uint64_t); | ||
| 4084 | static inline zig_f32 zig_floatundisf(uint64_t arg) { return __aeabi_ul2f(arg); } | ||
| 4085 | |||
| 4086 | zig_extern zig_callconv(pcs("aapcs")) int32_t __aeabi_d2iz(zig_f64); | ||
| 4087 | static inline int32_t zig_fixdfsi(zig_f64 arg) { return __aeabi_d2iz(arg); } | ||
| 4088 | |||
| 4089 | zig_extern zig_callconv(pcs("aapcs")) uint32_t __aeabi_d2uiz(zig_f64); | ||
| 4090 | static inline uint32_t zig_fixunsdfsi(zig_f64 arg) { return __aeabi_d2uiz(arg); } | ||
| 4091 | |||
| 4092 | zig_extern zig_callconv(pcs("aapcs")) uint64_t __aeabi_d2ulz(zig_f64); | ||
| 4093 | static inline uint64_t zig_fixunsdfdi(zig_f64 arg) { return __aeabi_d2ulz(arg); } | ||
| 4094 | |||
| 4095 | zig_extern zig_callconv(pcs("aapcs")) zig_f64 __aeabi_i2d(int32_t); | ||
| 4096 | static inline zig_f64 zig_floatsidf(int32_t arg) { return __aeabi_i2d(arg); } | ||
| 4097 | |||
| 4098 | zig_extern zig_callconv(pcs("aapcs")) zig_f64 __aeabi_ui2d(uint32_t); | ||
| 4099 | static inline zig_f64 zig_floatunsidf(uint32_t arg) { return __aeabi_ui2d(arg); } | ||
| 4100 | |||
| 4101 | zig_extern zig_callconv(pcs("aapcs")) zig_f64 __aeabi_ul2d(uint64_t); | ||
| 4102 | static inline zig_f64 zig_floatundidf(uint64_t arg) { return __aeabi_ul2d(arg); } | ||
| 4103 | |||
| 4104 | #else /* __ARM_EABI__ */ | ||
| 4105 | |||
| 4106 | zig_float_builtins(32) | 6172 | zig_float_builtins(32) |
| 4107 | zig_float_builtins(64) | 6173 | zig_float_builtins(64) |
| 4108 | 6174 | zig_float_builtins(80) | |
| 4109 | #endif /* __ARM_EABI__ */ | 6175 | #if defined(zig_x86_32) |
| 6176 | zig_common_float_builtins(128) | ||
| 6177 | static inline zig_f128 zig_floattitf(zig_i128 arg) { | ||
| 6178 | extern zig_f128 __floattitf(zig_f128 arg); | ||
| 6179 | return __floattitf(zig_f128_bitCast_i128(arg)); | ||
| 6180 | } | ||
| 6181 | static inline zig_f128 zig_floatuntitf(zig_u128 arg) { | ||
| 6182 | extern zig_f128 __floatuntitf(zig_f128 arg); | ||
| 6183 | return __floatuntitf(zig_f128_bitCast_u128(arg)); | ||
| 6184 | } | ||
| 6185 | #elif defined(zig_x86_64) && defined(zig_windows) | ||
| 6186 | zig_common_float_builtins(128) | ||
| 6187 | static inline zig_f128 zig_floattitf(zig_i128 arg) { | ||
| 6188 | extern zig_f128 __floattitf(zig_i128 arg); | ||
| 6189 | return __floattitf(arg); | ||
| 6190 | } | ||
| 6191 | static inline zig_f128 zig_floatuntitf(zig_u128 arg) { | ||
| 6192 | extern zig_f128 __floatuntitf(uint64_t arg_lo, uint64_t arg_hi); | ||
| 6193 | return __floatuntitf(zig_lo_u128(arg), zig_hi_u128(arg)); | ||
| 6194 | } | ||
| 6195 | #else | ||
| 6196 | zig_float_builtins(128) | ||
| 6197 | #endif | ||
| 4110 | 6198 | ||
| 4111 | /* ============================ Atomics Support ============================= */ | 6199 | /* ============================ Atomics Support ============================= */ |
| 4112 | 6200 | ||
| ... | @@ -4410,19 +6498,19 @@ typedef int zig_memory_order; | ... | @@ -4410,19 +6498,19 @@ typedef int zig_memory_order; |
| 4410 | } \ | 6498 | } \ |
| 4411 | static inline void zig_msvc_atomic_store_##ZigType(Type volatile* obj, Type value) { \ | 6499 | static inline void zig_msvc_atomic_store_##ZigType(Type volatile* obj, Type value) { \ |
| 4412 | (void)_InterlockedExchange##suffix((SigType volatile*)obj, (SigType)value); \ | 6500 | (void)_InterlockedExchange##suffix((SigType volatile*)obj, (SigType)value); \ |
| 4413 | } \ | 6501 | } \ |
| 4414 | static inline Type zig_msvc_atomic_load_zig_memory_order_relaxed_##ZigType(Type volatile* obj) { \ | 6502 | static inline Type zig_msvc_atomic_load_zig_memory_order_relaxed_##ZigType(Type volatile* obj) { \ |
| 4415 | return __iso_volatile_load##iso_suffix((SigType volatile*)obj); \ | 6503 | return __iso_volatile_load##iso_suffix((SigType volatile*)obj); \ |
| 4416 | } \ | 6504 | } \ |
| 4417 | static inline Type zig_msvc_atomic_load_zig_memory_order_acquire_##ZigType(Type volatile* obj) { \ | 6505 | static inline Type zig_msvc_atomic_load_zig_memory_order_acquire_##ZigType(Type volatile* obj) { \ |
| 4418 | Type val = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \ | 6506 | Type value = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \ |
| 4419 | _ReadWriteBarrier(); \ | 6507 | _ReadWriteBarrier(); \ |
| 4420 | return val; \ | 6508 | return value; \ |
| 4421 | } \ | 6509 | } \ |
| 4422 | static inline Type zig_msvc_atomic_load_zig_memory_order_seq_cst_##ZigType(Type volatile* obj) { \ | 6510 | static inline Type zig_msvc_atomic_load_zig_memory_order_seq_cst_##ZigType(Type volatile* obj) { \ |
| 4423 | Type val = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \ | 6511 | Type value = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \ |
| 4424 | _ReadWriteBarrier(); \ | 6512 | _ReadWriteBarrier(); \ |
| 4425 | return val; \ | 6513 | return value; \ |
| 4426 | } | 6514 | } |
| 4427 | 6515 | ||
| 4428 | zig_msvc_atomics( u8, uint8_t, char, 8, 8) | 6516 | zig_msvc_atomics( u8, uint8_t, char, 8, 8) |
| ... | @@ -4465,14 +6553,14 @@ zig_msvc_atomics(i64, int64_t, __int64, 64, 64) | ... | @@ -4465,14 +6553,14 @@ zig_msvc_atomics(i64, int64_t, __int64, 64, 64) |
| 4465 | zig_##Type result; \ | 6553 | zig_##Type result; \ |
| 4466 | SigType initial = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \ | 6554 | SigType initial = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \ |
| 4467 | _ReadWriteBarrier(); \ | 6555 | _ReadWriteBarrier(); \ |
| 4468 | memcpy(&result, &initial, sizeof(result)); \ | 6556 | memcpy(&result, &initial, sizeof(result)); \ |
| 4469 | return result; \ | 6557 | return result; \ |
| 4470 | } \ | 6558 | } \ |
| 4471 | static inline zig_##Type zig_msvc_atomic_load_zig_memory_order_seq_cst_##Type(zig_##Type volatile* obj) { \ | 6559 | static inline zig_##Type zig_msvc_atomic_load_zig_memory_order_seq_cst_##Type(zig_##Type volatile* obj) { \ |
| 4472 | zig_##Type result; \ | 6560 | zig_##Type result; \ |
| 4473 | SigType initial = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \ | 6561 | SigType initial = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \ |
| 4474 | _ReadWriteBarrier(); \ | 6562 | _ReadWriteBarrier(); \ |
| 4475 | memcpy(&result, &initial, sizeof(result)); \ | 6563 | memcpy(&result, &initial, sizeof(result)); \ |
| 4476 | return result; \ | 6564 | return result; \ |
| 4477 | } | 6565 | } |
| 4478 | 6566 | ||
| ... | @@ -4502,9 +6590,9 @@ static inline void* zig_msvc_atomic_load_zig_memory_order_relaxed_p32(void volat | ... | @@ -4502,9 +6590,9 @@ static inline void* zig_msvc_atomic_load_zig_memory_order_relaxed_p32(void volat |
| 4502 | } | 6590 | } |
| 4503 | 6591 | ||
| 4504 | static inline void* zig_msvc_atomic_load_zig_memory_order_acquire_p32(void volatile* obj) { | 6592 | static inline void* zig_msvc_atomic_load_zig_memory_order_acquire_p32(void volatile* obj) { |
| 4505 | void* val = (void*)__iso_volatile_load32(obj); | 6593 | void* value = (void*)__iso_volatile_load32(obj); |
| 4506 | _ReadWriteBarrier(); | 6594 | _ReadWriteBarrier(); |
| 4507 | return val; | 6595 | return value; |
| 4508 | } | 6596 | } |
| 4509 | 6597 | ||
| 4510 | static inline void* zig_msvc_atomic_load_zig_memory_order_seq_cst_p32(void volatile* obj) { | 6598 | static inline void* zig_msvc_atomic_load_zig_memory_order_seq_cst_p32(void volatile* obj) { |
| ... | @@ -4532,9 +6620,9 @@ static inline void* zig_msvc_atomic_load_zig_memory_order_relaxed_p64(void volat | ... | @@ -4532,9 +6620,9 @@ static inline void* zig_msvc_atomic_load_zig_memory_order_relaxed_p64(void volat |
| 4532 | } | 6620 | } |
| 4533 | 6621 | ||
| 4534 | static inline void* zig_msvc_atomic_load_zig_memory_order_acquire_p64(void volatile* obj) { | 6622 | static inline void* zig_msvc_atomic_load_zig_memory_order_acquire_p64(void volatile* obj) { |
| 4535 | void* val = (void*)__iso_volatile_load64(obj); | 6623 | void* value = (void*)__iso_volatile_load64(obj); |
| 4536 | _ReadWriteBarrier(); | 6624 | _ReadWriteBarrier(); |
| 4537 | return val; | 6625 | return value; |
| 4538 | } | 6626 | } |
| 4539 | 6627 | ||
| 4540 | static inline void* zig_msvc_atomic_load_zig_memory_order_seq_cst_p64(void volatile* obj) { | 6628 | static inline void* zig_msvc_atomic_load_zig_memory_order_seq_cst_p64(void volatile* obj) { |
src/Air.zig+1-1| ... | @@ -1907,7 +1907,7 @@ pub const NullTerminatedString = enum(u32) { | ... | @@ -1907,7 +1907,7 @@ pub const NullTerminatedString = enum(u32) { |
| 1907 | pub fn toSlice(nts: NullTerminatedString, air: Air) [:0]const u8 { | 1907 | pub fn toSlice(nts: NullTerminatedString, air: Air) [:0]const u8 { |
| 1908 | if (nts == .none) return ""; | 1908 | if (nts == .none) return ""; |
| 1909 | const bytes = std.mem.sliceAsBytes(air.extra.items[@backingInt(nts)..]); | 1909 | const bytes = std.mem.sliceAsBytes(air.extra.items[@backingInt(nts)..]); |
| 1910 | return bytes[0..std.mem.indexOfScalar(u8, bytes, 0).? :0]; | 1910 | return bytes[0..std.mem.findScalar(u8, bytes, 0).? :0]; |
| 1911 | } | 1911 | } |
| 1912 | }; | 1912 | }; |
| 1913 | 1913 |
src/Air/Legalize.zig+8-1| ... | @@ -2906,12 +2906,18 @@ fn packedAggregateInitBlockPayload(l: *Legalize, orig_inst: Air.Inst.Index) Erro | ... | @@ -2906,12 +2906,18 @@ fn packedAggregateInitBlockPayload(l: *Legalize, orig_inst: Air.Inst.Index) Erro |
| 2906 | const orig_ty_pl = l.air_instructions.items(.data)[@backingInt(orig_inst)].ty_pl; | 2906 | const orig_ty_pl = l.air_instructions.items(.data)[@backingInt(orig_inst)].ty_pl; |
| 2907 | const agg_ty = orig_ty_pl.ty.toType(); | 2907 | const agg_ty = orig_ty_pl.ty.toType(); |
| 2908 | const agg_field_count = agg_ty.structFieldCount(zcu); | 2908 | const agg_field_count = agg_ty.structFieldCount(zcu); |
| 2909 | var opv_field_count: u32 = 0; | ||
| 2910 | for (0..agg_field_count) |field_idx| { | ||
| 2911 | const field_ty = agg_ty.fieldType(field_idx, zcu); | ||
| 2912 | const field_bits: u16 = @intCast(field_ty.bitSize(zcu)); | ||
| 2913 | if (field_bits == 0) opv_field_count += 1; | ||
| 2914 | } | ||
| 2909 | 2915 | ||
| 2910 | var bfa_buf: [4 * 32 + 2]Air.Inst.Index = undefined; | 2916 | var bfa_buf: [4 * 32 + 2]Air.Inst.Index = undefined; |
| 2911 | var bfa_state: std.heap.BufferFirstAllocator = .init(@ptrCast(&bfa_buf), gpa); | 2917 | var bfa_state: std.heap.BufferFirstAllocator = .init(@ptrCast(&bfa_buf), gpa); |
| 2912 | const bfa = bfa_state.allocator(); | 2918 | const bfa = bfa_state.allocator(); |
| 2913 | 2919 | ||
| 2914 | const inst_buf = try bfa.alloc(Air.Inst.Index, 4 * agg_field_count + 2); | 2920 | const inst_buf = try bfa.alloc(Air.Inst.Index, 4 * (agg_field_count - opv_field_count) + 2); |
| 2915 | defer bfa.free(inst_buf); | 2921 | defer bfa.free(inst_buf); |
| 2916 | 2922 | ||
| 2917 | var main_block: Block = .init(inst_buf); | 2923 | var main_block: Block = .init(inst_buf); |
| ... | @@ -2927,6 +2933,7 @@ fn packedAggregateInitBlockPayload(l: *Legalize, orig_inst: Air.Inst.Index) Erro | ... | @@ -2927,6 +2933,7 @@ fn packedAggregateInitBlockPayload(l: *Legalize, orig_inst: Air.Inst.Index) Erro |
| 2927 | field_idx -= 1; | 2933 | field_idx -= 1; |
| 2928 | const field_ty = agg_ty.fieldType(field_idx, zcu); | 2934 | const field_ty = agg_ty.fieldType(field_idx, zcu); |
| 2929 | const field_bits: u16 = @intCast(field_ty.bitSize(zcu)); | 2935 | const field_bits: u16 = @intCast(field_ty.bitSize(zcu)); |
| 2936 | if (field_bits == 0) continue; | ||
| 2930 | assert(field_bits < num_bits); | 2937 | assert(field_bits < num_bits); |
| 2931 | const field_uint_ty = try pt.intType(.unsigned, field_bits); | 2938 | const field_uint_ty = try pt.intType(.unsigned, field_bits); |
| 2932 | const field_bit_size_ref: Air.Inst.Ref = .fromValue(try pt.intValue(shift_ty, field_bits)); | 2939 | const field_bit_size_ref: Air.Inst.Ref = .fromValue(try pt.intValue(shift_ty, field_bits)); |
src/Air/Liveness.zig+3-3| ... | @@ -351,7 +351,7 @@ const Analysis = struct { | ... | @@ -351,7 +351,7 @@ const Analysis = struct { |
| 351 | extra: std.ArrayList(u32), | 351 | extra: std.ArrayList(u32), |
| 352 | 352 | ||
| 353 | fn addExtra(a: *Analysis, extra: anytype) Allocator.Error!u32 { | 353 | fn addExtra(a: *Analysis, extra: anytype) Allocator.Error!u32 { |
| 354 | const field_count = std.meta.fieldNames(@TypeOf(extra)).len; | 354 | const field_count = @typeInfo(@TypeOf(extra)).@"struct".field_names.len; |
| 355 | try a.extra.ensureUnusedCapacity(a.gpa, field_count); | 355 | try a.extra.ensureUnusedCapacity(a.gpa, field_count); |
| 356 | return addExtraAssumeCapacity(a, extra); | 356 | return addExtraAssumeCapacity(a, extra); |
| 357 | } | 357 | } |
| ... | @@ -1012,7 +1012,7 @@ fn analyzeInstBlock( | ... | @@ -1012,7 +1012,7 @@ fn analyzeInstBlock( |
| 1012 | const block_scope = data.block_scopes.get(inst).?; | 1012 | const block_scope = data.block_scopes.get(inst).?; |
| 1013 | const num_deaths = data.live_set.count() - block_scope.live_set.count(); | 1013 | const num_deaths = data.live_set.count() - block_scope.live_set.count(); |
| 1014 | 1014 | ||
| 1015 | try a.extra.ensureUnusedCapacity(gpa, num_deaths + std.meta.fieldNames(Block).len); | 1015 | try a.extra.ensureUnusedCapacity(gpa, num_deaths + @typeInfo(Block).@"struct".field_names.len); |
| 1016 | const extra_index = a.addExtraAssumeCapacity(Block{ | 1016 | const extra_index = a.addExtraAssumeCapacity(Block{ |
| 1017 | .death_count = num_deaths, | 1017 | .death_count = num_deaths, |
| 1018 | }); | 1018 | }); |
| ... | @@ -1275,7 +1275,7 @@ fn analyzeInstCondBr( | ... | @@ -1275,7 +1275,7 @@ fn analyzeInstCondBr( |
| 1275 | // Write the mirrored deaths to `extra` | 1275 | // Write the mirrored deaths to `extra` |
| 1276 | const then_death_count = @as(u32, @intCast(then_mirrored_deaths.items.len)); | 1276 | const then_death_count = @as(u32, @intCast(then_mirrored_deaths.items.len)); |
| 1277 | const else_death_count = @as(u32, @intCast(else_mirrored_deaths.items.len)); | 1277 | const else_death_count = @as(u32, @intCast(else_mirrored_deaths.items.len)); |
| 1278 | try a.extra.ensureUnusedCapacity(gpa, std.meta.fieldNames(CondBr).len + then_death_count + else_death_count); | 1278 | try a.extra.ensureUnusedCapacity(gpa, @typeInfo(CondBr).@"struct".field_names.len + then_death_count + else_death_count); |
| 1279 | const extra_index = a.addExtraAssumeCapacity(CondBr{ | 1279 | const extra_index = a.addExtraAssumeCapacity(CondBr{ |
| 1280 | .then_death_count = then_death_count, | 1280 | .then_death_count = then_death_count, |
| 1281 | .else_death_count = else_death_count, | 1281 | .else_death_count = else_death_count, |
src/Builtin.zig+8-2| ... | @@ -7,7 +7,7 @@ is_test: bool, | ... | @@ -7,7 +7,7 @@ is_test: bool, |
| 7 | single_threaded: bool, | 7 | single_threaded: bool, |
| 8 | link_libc: bool, | 8 | link_libc: bool, |
| 9 | link_libcpp: bool, | 9 | link_libcpp: bool, |
| 10 | optimize_mode: std.lang.OptimizeMode, | 10 | optimize_mode: std.lang.Optimize, |
| 11 | error_tracing: bool, | 11 | error_tracing: bool, |
| 12 | valgrind: bool, | 12 | valgrind: bool, |
| 13 | sanitize_thread: bool, | 13 | sanitize_thread: bool, |
| ... | @@ -64,7 +64,9 @@ pub fn append(opts: @This(), buffer: *std.array_list.Managed(u8)) Allocator.Erro | ... | @@ -64,7 +64,9 @@ pub fn append(opts: @This(), buffer: *std.array_list.Managed(u8)) Allocator.Erro |
| 64 | \\pub const unwind_tables: std.lang.UnwindTables = .{f}; | 64 | \\pub const unwind_tables: std.lang.UnwindTables = .{f}; |
| 65 | \\pub const is_test = {}; | 65 | \\pub const is_test = {}; |
| 66 | \\pub const single_threaded = {}; | 66 | \\pub const single_threaded = {}; |
| 67 | \\/// Deprecated; to be removed in 0.18.0. Use `target.abi` instead. | ||
| 67 | \\pub const abi: std.Target.Abi = .{f}; | 68 | \\pub const abi: std.Target.Abi = .{f}; |
| 69 | \\/// Deprecated; to be removed in 0.18.0. Use `target.cpu` instead. | ||
| 68 | \\pub const cpu: std.Target.Cpu = .{{ | 70 | \\pub const cpu: std.Target.Cpu = .{{ |
| 69 | \\ .arch = .{f}, | 71 | \\ .arch = .{f}, |
| 70 | \\ .model = &std.Target.{f}.cpu.{f}, | 72 | \\ .model = &std.Target.{f}.cpu.{f}, |
| ... | @@ -95,6 +97,7 @@ pub fn append(opts: @This(), buffer: *std.array_list.Managed(u8)) Allocator.Erro | ... | @@ -95,6 +97,7 @@ pub fn append(opts: @This(), buffer: *std.array_list.Managed(u8)) Allocator.Erro |
| 95 | try buffer.print( | 97 | try buffer.print( |
| 96 | \\ }}), | 98 | \\ }}), |
| 97 | \\}}; | 99 | \\}}; |
| 100 | \\/// Deprecated; to be removed in 0.18.0. Use `target.os` instead. | ||
| 98 | \\pub const os: std.Target.Os = .{{ | 101 | \\pub const os: std.Target.Os = .{{ |
| 99 | \\ .tag = .{f}, | 102 | \\ .tag = .{f}, |
| 100 | \\ .version_range = .{{ | 103 | \\ .version_range = .{{ |
| ... | @@ -238,8 +241,11 @@ pub fn append(opts: @This(), buffer: *std.array_list.Managed(u8)) Allocator.Erro | ... | @@ -238,8 +241,11 @@ pub fn append(opts: @This(), buffer: *std.array_list.Managed(u8)) Allocator.Erro |
| 238 | const link_libc = opts.link_libc; | 241 | const link_libc = opts.link_libc; |
| 239 | 242 | ||
| 240 | try buffer.print( | 243 | try buffer.print( |
| 244 | \\/// Deprecated; to be removed in 0.18.0. Use `target.ofmt` instead. | ||
| 241 | \\pub const object_format: std.Target.ObjectFormat = .{f}; | 245 | \\pub const object_format: std.Target.ObjectFormat = .{f}; |
| 242 | \\pub const mode: std.lang.OptimizeMode = .{f}; | 246 | \\/// Deprecated, to be removed after 0.18.0 |
| 247 | \\pub const mode = optimize; | ||
| 248 | \\pub const optimize: std.lang.Optimize = .{f}; | ||
| 243 | \\pub const link_libc = {}; | 249 | \\pub const link_libc = {}; |
| 244 | \\pub const link_libcpp = {}; | 250 | \\pub const link_libcpp = {}; |
| 245 | \\pub const have_error_return_tracing = {}; | 251 | \\pub const have_error_return_tracing = {}; |
src/Compilation.zig+63-37| ... | @@ -172,7 +172,7 @@ verbose_link: bool, | ... | @@ -172,7 +172,7 @@ verbose_link: bool, |
| 172 | link_depfile: ?[]const u8, | 172 | link_depfile: ?[]const u8, |
| 173 | disable_c_depfile: bool, | 173 | disable_c_depfile: bool, |
| 174 | stack_report: bool, | 174 | stack_report: bool, |
| 175 | debug_compiler_runtime_libs: ?std.lang.OptimizeMode, | 175 | debug_compiler_runtime_libs: ?std.lang.Optimize, |
| 176 | debug_compile_errors: bool, | 176 | debug_compile_errors: bool, |
| 177 | /// Do not check this field directly. Instead, use the `debugIncremental` wrapper function. | 177 | /// Do not check this field directly. Instead, use the `debugIncremental` wrapper function. |
| 178 | debug_incremental: bool, | 178 | debug_incremental: bool, |
| ... | @@ -1232,7 +1232,6 @@ pub const cache_helpers = struct { | ... | @@ -1232,7 +1232,6 @@ pub const cache_helpers = struct { |
| 1232 | hh.add(mod.sanitize_thread); | 1232 | hh.add(mod.sanitize_thread); |
| 1233 | hh.add(mod.fuzz); | 1233 | hh.add(mod.fuzz); |
| 1234 | hh.add(mod.unwind_tables); | 1234 | hh.add(mod.unwind_tables); |
| 1235 | hh.add(mod.structured_cfg); | ||
| 1236 | hh.add(mod.no_builtin); | 1235 | hh.add(mod.no_builtin); |
| 1237 | hh.addListOfBytes(mod.cc_argv); | 1236 | hh.addListOfBytes(mod.cc_argv); |
| 1238 | } | 1237 | } |
| ... | @@ -1506,7 +1505,7 @@ pub const CreateOptions = struct { | ... | @@ -1506,7 +1505,7 @@ pub const CreateOptions = struct { |
| 1506 | verbose_llvm_bc: ?[]const u8 = null, | 1505 | verbose_llvm_bc: ?[]const u8 = null, |
| 1507 | link_depfile: ?[]const u8 = null, | 1506 | link_depfile: ?[]const u8 = null, |
| 1508 | verbose_llvm_cpu_features: bool = false, | 1507 | verbose_llvm_cpu_features: bool = false, |
| 1509 | debug_compiler_runtime_libs: ?std.lang.OptimizeMode = null, | 1508 | debug_compiler_runtime_libs: ?std.lang.Optimize = null, |
| 1510 | debug_compile_errors: bool = false, | 1509 | debug_compile_errors: bool = false, |
| 1511 | debug_incremental: bool = false, | 1510 | debug_incremental: bool = false, |
| 1512 | /// Normally when you create a `Compilation`, Zig will automatically build | 1511 | /// Normally when you create a `Compilation`, Zig will automatically build |
| ... | @@ -2134,6 +2133,9 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, | ... | @@ -2134,6 +2133,9 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, |
| 2134 | comp.config.any_fuzz = any_fuzz; | 2133 | comp.config.any_fuzz = any_fuzz; |
| 2135 | 2134 | ||
| 2136 | if (opt_zcu) |zcu| { | 2135 | if (opt_zcu) |zcu| { |
| 2136 | // Finish initializing the `zcu` after the fields on `comp` have been initialized. | ||
| 2137 | zcu.initAfterCompilation(); | ||
| 2138 | |||
| 2137 | // Populate `zcu.module_roots`. | 2139 | // Populate `zcu.module_roots`. |
| 2138 | const active = zcu.acquire(); | 2140 | const active = zcu.acquire(); |
| 2139 | defer active.release(); | 2141 | defer active.release(); |
| ... | @@ -2160,7 +2162,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, | ... | @@ -2160,7 +2162,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, |
| 2160 | .framework_dirs = options.framework_dirs, | 2162 | .framework_dirs = options.framework_dirs, |
| 2161 | .rpath_list = options.rpath_list, | 2163 | .rpath_list = options.rpath_list, |
| 2162 | .symbol_wrap_set = options.symbol_wrap_set, | 2164 | .symbol_wrap_set = options.symbol_wrap_set, |
| 2163 | .repro = options.linker_repro orelse (options.root_mod.optimize_mode != .Debug), | 2165 | .repro = options.linker_repro orelse (options.root_mod.optimize_mode != .debug), |
| 2164 | .allow_shlib_undefined = options.linker_allow_shlib_undefined, | 2166 | .allow_shlib_undefined = options.linker_allow_shlib_undefined, |
| 2165 | .bind_global_refs_locally = options.linker_bind_global_refs_locally orelse false, | 2167 | .bind_global_refs_locally = options.linker_bind_global_refs_locally orelse false, |
| 2166 | .compress_debug_sections = options.linker_compress_debug_sections orelse .none, | 2168 | .compress_debug_sections = options.linker_compress_debug_sections orelse .none, |
| ... | @@ -2911,7 +2913,20 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE | ... | @@ -2911,7 +2913,20 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE |
| 2911 | // The linker progress node is set up here instead of in `performAllTheWork`, because | 2913 | // The linker progress node is set up here instead of in `performAllTheWork`, because |
| 2912 | // we also want it around during `flush`. | 2914 | // we also want it around during `flush`. |
| 2913 | if (comp.bin_file) |lf| { | 2915 | if (comp.bin_file) |lf| { |
| 2914 | comp.link_prog_node = main_progress_node.start("Linking", 0); | 2916 | // mirrors logic in `Compilation.flush`: |
| 2917 | // Always: linker flush | ||
| 2918 | var initial_estimated_total: usize = 1; | ||
| 2919 | const llvm = if (comp.zcu) |zcu| zcu.llvm_object != null else false; | ||
| 2920 | // For llvm: "LLVM Emit Object" and "Parse Object" with the zcu object | ||
| 2921 | if (llvm) { | ||
| 2922 | initial_estimated_total += 2; | ||
| 2923 | } | ||
| 2924 | // Prelink | ||
| 2925 | if (!lf.post_prelink or llvm) { | ||
| 2926 | initial_estimated_total += 1; | ||
| 2927 | } | ||
| 2928 | |||
| 2929 | comp.link_prog_node = main_progress_node.start("Linking", initial_estimated_total); | ||
| 2915 | lf.startProgress(comp.link_prog_node); | 2930 | lf.startProgress(comp.link_prog_node); |
| 2916 | } | 2931 | } |
| 2917 | defer if (comp.bin_file) |lf| { | 2932 | defer if (comp.bin_file) |lf| { |
| ... | @@ -3189,8 +3204,8 @@ fn flush(comp: *Compilation, arena: Allocator) (Io.Cancelable || Allocator.Error | ... | @@ -3189,8 +3204,8 @@ fn flush(comp: *Compilation, arena: Allocator) (Io.Cancelable || Allocator.Error |
| 3189 | break :p try p.toStringZ(arena); | 3204 | break :p try p.toStringZ(arena); |
| 3190 | }, | 3205 | }, |
| 3191 | 3206 | ||
| 3192 | .is_debug = comp.root_mod.optimize_mode == .Debug, | 3207 | .is_debug = comp.root_mod.optimize_mode == .debug, |
| 3193 | .is_small = comp.root_mod.optimize_mode == .ReleaseSmall, | 3208 | .is_small = comp.root_mod.optimize_mode == .small, |
| 3194 | .time_report = if (comp.time_report) |*p| p else null, | 3209 | .time_report = if (comp.time_report) |*p| p else null, |
| 3195 | .sanitize_thread = comp.config.any_sanitize_thread, | 3210 | .sanitize_thread = comp.config.any_sanitize_thread, |
| 3196 | .fuzz = comp.config.any_fuzz, | 3211 | .fuzz = comp.config.any_fuzz, |
| ... | @@ -3660,11 +3675,11 @@ pub fn saveState(comp: *Compilation) !void { | ... | @@ -3660,11 +3675,11 @@ pub fn saveState(comp: *Compilation) !void { |
| 3660 | addBuf(&bufs, @ptrCast(wasm.object_relocations_table.values())); | 3675 | addBuf(&bufs, @ptrCast(wasm.object_relocations_table.values())); |
| 3661 | addBuf(&bufs, @ptrCast(wasm.object_comdat_symbols.items(.kind))); | 3676 | addBuf(&bufs, @ptrCast(wasm.object_comdat_symbols.items(.kind))); |
| 3662 | addBuf(&bufs, @ptrCast(wasm.object_comdat_symbols.items(.index))); | 3677 | addBuf(&bufs, @ptrCast(wasm.object_comdat_symbols.items(.index))); |
| 3663 | addBuf(&bufs, @ptrCast(wasm.out_relocs.items(.tag))); | 3678 | addBuf(&bufs, @ptrCast(wasm.zcu_relocations.items(.tag))); |
| 3664 | addBuf(&bufs, @ptrCast(wasm.out_relocs.items(.offset))); | 3679 | addBuf(&bufs, @ptrCast(wasm.zcu_relocations.items(.offset))); |
| 3665 | // TODO handle the union safety field | 3680 | // TODO handle the union safety field |
| 3666 | //addBuf(&bufs, @ptrCast(wasm.out_relocs.items(.pointee))); | 3681 | //addBuf(&bufs, @ptrCast(wasm.zcu_relocations.items(.pointee))); |
| 3667 | addBuf(&bufs, @ptrCast(wasm.out_relocs.items(.addend))); | 3682 | addBuf(&bufs, @ptrCast(wasm.zcu_relocations.items(.addend))); |
| 3668 | addBuf(&bufs, @ptrCast(wasm.uav_fixups.items)); | 3683 | addBuf(&bufs, @ptrCast(wasm.uav_fixups.items)); |
| 3669 | addBuf(&bufs, @ptrCast(wasm.nav_fixups.items)); | 3684 | addBuf(&bufs, @ptrCast(wasm.nav_fixups.items)); |
| 3670 | addBuf(&bufs, @ptrCast(wasm.func_table_fixups.items)); | 3685 | addBuf(&bufs, @ptrCast(wasm.func_table_fixups.items)); |
| ... | @@ -4061,7 +4076,14 @@ pub fn getAllErrorsAlloc(comp: *Compilation) error{OutOfMemory}!ErrorBundle { | ... | @@ -4061,7 +4076,14 @@ pub fn getAllErrorsAlloc(comp: *Compilation) error{OutOfMemory}!ErrorBundle { |
| 4061 | ref = refs.get(r.referencer).?; | 4076 | ref = refs.get(r.referencer).?; |
| 4062 | } | 4077 | } |
| 4063 | } | 4078 | } |
| 4064 | @panic("referenced transitive analysis errors, but none actually emitted"); | 4079 | if (comp.debugIncremental()) { |
| 4080 | std.debug.print("skipping compiler panic to allow incremental debug server usage", .{}); | ||
| 4081 | try bundle.addRootErrorMessage(.{ | ||
| 4082 | .msg = try bundle.addString("compiler bug: referenced transitive analysis errors, but none actually emitted"), | ||
| 4083 | }); | ||
| 4084 | } else { | ||
| 4085 | @panic("referenced transitive analysis errors, but none actually emitted"); | ||
| 4086 | } | ||
| 4065 | } | 4087 | } |
| 4066 | }; | 4088 | }; |
| 4067 | 4089 | ||
| ... | @@ -4744,7 +4766,7 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) SubU | ... | @@ -4744,7 +4766,7 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) SubU |
| 4744 | defer arena_allocator.deinit(); | 4766 | defer arena_allocator.deinit(); |
| 4745 | const arena = arena_allocator.allocator(); | 4767 | const arena = arena_allocator.allocator(); |
| 4746 | 4768 | ||
| 4747 | const optimize_mode = std.lang.OptimizeMode.ReleaseSmall; | 4769 | const optimize_mode: std.lang.Optimize = .small; |
| 4748 | const output_mode = std.lang.OutputMode.Exe; | 4770 | const output_mode = std.lang.OutputMode.Exe; |
| 4749 | const resolved_target: Module.ResolvedTarget = .{ | 4771 | const resolved_target: Module.ResolvedTarget = .{ |
| 4750 | .result = std.zig.system.resolveTargetQuery(io, .{ | 4772 | .result = std.zig.system.resolveTargetQuery(io, .{ |
| ... | @@ -5910,8 +5932,8 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 | ... | @@ -5910,8 +5932,8 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 |
| 5910 | // them being defined matches the behavior of how MSVC calls rc.exe which is the more | 5932 | // them being defined matches the behavior of how MSVC calls rc.exe which is the more |
| 5911 | // relevant behavior in this case. | 5933 | // relevant behavior in this case. |
| 5912 | switch (rc_src.owner.optimize_mode) { | 5934 | switch (rc_src.owner.optimize_mode) { |
| 5913 | .Debug, .ReleaseSafe => {}, | 5935 | .debug, .safe => {}, |
| 5914 | .ReleaseFast, .ReleaseSmall => try argv.append("-DNDEBUG"), | 5936 | .fast, .small => try argv.append("-DNDEBUG"), |
| 5915 | } | 5937 | } |
| 5916 | try argv.appendSlice(rc_src.extra_flags); | 5938 | try argv.appendSlice(rc_src.extra_flags); |
| 5917 | try argv.appendSlice(&.{ "--", rc_src.src_path, out_res_path }); | 5939 | try argv.appendSlice(&.{ "--", rc_src.src_path, out_res_path }); |
| ... | @@ -6006,26 +6028,30 @@ fn spawnZigRc( | ... | @@ -6006,26 +6028,30 @@ fn spawnZigRc( |
| 6006 | multi_reader.init(gpa, io, multi_reader_buffer.toStreams(), &.{ child.stdout.?, child.stderr.? }); | 6028 | multi_reader.init(gpa, io, multi_reader_buffer.toStreams(), &.{ child.stdout.?, child.stderr.? }); |
| 6007 | defer multi_reader.deinit(); | 6029 | defer multi_reader.deinit(); |
| 6008 | 6030 | ||
| 6009 | const stdout = multi_reader.fileReader(0); | 6031 | const stdout = multi_reader.reader(0); |
| 6010 | const MessageHeader = std.zig.Server.Message.Header; | ||
| 6011 | 6032 | ||
| 6012 | var eos_err: error{EndOfStream}!void = {}; | 6033 | var eos_err: error{EndOfStream}!void = {}; |
| 6013 | 6034 | ||
| 6035 | var client: std.zig.Client = .{ | ||
| 6036 | .in = stdout, | ||
| 6037 | .out = undefined, | ||
| 6038 | }; | ||
| 6039 | |||
| 6014 | while (true) { | 6040 | while (true) { |
| 6015 | const header = stdout.interface.takeStruct(MessageHeader, .little) catch |err| switch (err) { | 6041 | const header = client.receiveMessageWithMultiReader(&multi_reader, .none) catch |err| switch (err) { |
| 6016 | error.EndOfStream => break, | 6042 | error.Timeout => unreachable, |
| 6017 | error.ReadFailed => return stdout.err.?, | ||
| 6018 | }; | ||
| 6019 | const body = stdout.interface.take(header.bytes_len) catch |err| switch (err) { | ||
| 6020 | error.EndOfStream => |e| { | 6043 | error.EndOfStream => |e| { |
| 6044 | if (client.in.bufferedLen() == 0) break; | ||
| 6021 | // Better to report the crash with stderr below, but we set | 6045 | // Better to report the crash with stderr below, but we set |
| 6022 | // this in case the child exits successfully while violating | 6046 | // this in case the child exits successfully while violating |
| 6023 | // this protocol. | 6047 | // this protocol. |
| 6024 | eos_err = e; | 6048 | eos_err = e; |
| 6025 | break; | 6049 | break; |
| 6026 | }, | 6050 | }, |
| 6027 | error.ReadFailed => return stdout.err.?, | 6051 | else => |e| return e, |
| 6028 | }; | 6052 | }; |
| 6053 | const body = client.in.take(header.bytes_len) catch unreachable; | ||
| 6054 | |||
| 6029 | switch (header.tag) { | 6055 | switch (header.tag) { |
| 6030 | // We expect exactly one ErrorBundle, and if any error_bundle header is | 6056 | // We expect exactly one ErrorBundle, and if any error_bundle header is |
| 6031 | // sent then it's a fatal error. | 6057 | // sent then it's a fatal error. |
| ... | @@ -6178,11 +6204,11 @@ fn addCommonCCArgs( | ... | @@ -6178,11 +6204,11 @@ fn addCommonCCArgs( |
| 6178 | // LLVM IR files don't support these flags. | 6204 | // LLVM IR files don't support these flags. |
| 6179 | if (ext != .ll and ext != .bc) { | 6205 | if (ext != .ll and ext != .bc) { |
| 6180 | switch (mod.optimize_mode) { | 6206 | switch (mod.optimize_mode) { |
| 6181 | .Debug => {}, | 6207 | .debug => {}, |
| 6182 | .ReleaseSafe => { | 6208 | .safe => { |
| 6183 | try argv.append("-D_FORTIFY_SOURCE=2"); | 6209 | try argv.append("-D_FORTIFY_SOURCE=2"); |
| 6184 | }, | 6210 | }, |
| 6185 | .ReleaseFast, .ReleaseSmall => { | 6211 | .fast, .small => { |
| 6186 | try argv.append("-DNDEBUG"); | 6212 | try argv.append("-DNDEBUG"); |
| 6187 | }, | 6213 | }, |
| 6188 | } | 6214 | } |
| ... | @@ -6333,7 +6359,7 @@ fn addCommonCCArgs( | ... | @@ -6333,7 +6359,7 @@ fn addCommonCCArgs( |
| 6333 | } | 6359 | } |
| 6334 | } | 6360 | } |
| 6335 | 6361 | ||
| 6336 | if (mod.optimize_mode != .Debug) { | 6362 | if (mod.optimize_mode != .debug) { |
| 6337 | try argv.append("-Werror=date-time"); | 6363 | try argv.append("-Werror=date-time"); |
| 6338 | } | 6364 | } |
| 6339 | }, | 6365 | }, |
| ... | @@ -6412,18 +6438,18 @@ fn addCommonCCArgs( | ... | @@ -6412,18 +6438,18 @@ fn addCommonCCArgs( |
| 6412 | } | 6438 | } |
| 6413 | 6439 | ||
| 6414 | switch (mod.optimize_mode) { | 6440 | switch (mod.optimize_mode) { |
| 6415 | .Debug => { | 6441 | .debug => { |
| 6416 | // Clang has -Og for compatibility with GCC, but currently it is just equivalent | 6442 | // Clang has -Og for compatibility with GCC, but currently it is just equivalent |
| 6417 | // to -O1. Besides potentially impairing debugging, -O1/-Og significantly | 6443 | // to -O1. Besides potentially impairing debugging, -O1/-Og significantly |
| 6418 | // increases compile times. | 6444 | // increases compile times. |
| 6419 | try argv.append("-O0"); | 6445 | try argv.append("-O0"); |
| 6420 | }, | 6446 | }, |
| 6421 | .ReleaseSafe => { | 6447 | .safe => { |
| 6422 | // See the comment in the BuildModeFastRelease case for why we pass -O2 rather | 6448 | // See the comment in the BuildModeFastRelease case for why we pass -O2 rather |
| 6423 | // than -O3 here. | 6449 | // than -O3 here. |
| 6424 | try argv.append("-O2"); | 6450 | try argv.append("-O2"); |
| 6425 | }, | 6451 | }, |
| 6426 | .ReleaseFast => { | 6452 | .fast => { |
| 6427 | // Here we pass -O2 rather than -O3 because, although we do the equivalent of | 6453 | // Here we pass -O2 rather than -O3 because, although we do the equivalent of |
| 6428 | // -O3 in Zig code, the justification for the difference here is that Zig | 6454 | // -O3 in Zig code, the justification for the difference here is that Zig |
| 6429 | // has better detection and prevention of undefined behavior, so -O3 is safer for | 6455 | // has better detection and prevention of undefined behavior, so -O3 is safer for |
| ... | @@ -6431,7 +6457,7 @@ fn addCommonCCArgs( | ... | @@ -6431,7 +6457,7 @@ fn addCommonCCArgs( |
| 6431 | // running in -O2 and thus the -O3 path has been tested less. | 6457 | // running in -O2 and thus the -O3 path has been tested less. |
| 6432 | try argv.append("-O2"); | 6458 | try argv.append("-O2"); |
| 6433 | }, | 6459 | }, |
| 6434 | .ReleaseSmall => { | 6460 | .small => { |
| 6435 | try argv.append("-Os"); | 6461 | try argv.append("-Os"); |
| 6436 | }, | 6462 | }, |
| 6437 | } | 6463 | } |
| ... | @@ -6641,6 +6667,8 @@ pub fn addCCArgs( | ... | @@ -6641,6 +6667,8 @@ pub fn addCCArgs( |
| 6641 | 6667 | ||
| 6642 | // Only compiled files support these flags. | 6668 | // Only compiled files support these flags. |
| 6643 | switch (ext) { | 6669 | switch (ext) { |
| 6670 | .assembly, | ||
| 6671 | .assembly_with_cpp, | ||
| 6644 | .c, | 6672 | .c, |
| 6645 | .h, | 6673 | .h, |
| 6646 | .cpp, | 6674 | .cpp, |
| ... | @@ -7254,7 +7282,6 @@ fn buildOutputFromZig( | ... | @@ -7254,7 +7282,6 @@ fn buildOutputFromZig( |
| 7254 | .unwind_tables = comp.root_mod.unwind_tables, | 7282 | .unwind_tables = comp.root_mod.unwind_tables, |
| 7255 | .pic = comp.root_mod.pic, | 7283 | .pic = comp.root_mod.pic, |
| 7256 | .optimize_mode = optimize_mode, | 7284 | .optimize_mode = optimize_mode, |
| 7257 | .structured_cfg = comp.root_mod.structured_cfg, | ||
| 7258 | .no_builtin = true, | 7285 | .no_builtin = true, |
| 7259 | .code_model = comp.root_mod.code_model, | 7286 | .code_model = comp.root_mod.code_model, |
| 7260 | .error_tracing = false, | 7287 | .error_tracing = false, |
| ... | @@ -7403,7 +7430,6 @@ pub fn build_crt_file( | ... | @@ -7403,7 +7430,6 @@ pub fn build_crt_file( |
| 7403 | // Some CRT objects (e.g. musl's rcrt1.o and Scrt1.o) are opinionated about PIC. | 7430 | // Some CRT objects (e.g. musl's rcrt1.o and Scrt1.o) are opinionated about PIC. |
| 7404 | .pic = options.pic orelse comp.root_mod.pic, | 7431 | .pic = options.pic orelse comp.root_mod.pic, |
| 7405 | .optimize_mode = comp.compilerRtOptMode(), | 7432 | .optimize_mode = comp.compilerRtOptMode(), |
| 7406 | .structured_cfg = comp.root_mod.structured_cfg, | ||
| 7407 | // Some libcs (e.g. musl) are opinionated about -fno-builtin. | 7433 | // Some libcs (e.g. musl) are opinionated about -fno-builtin. |
| 7408 | .no_builtin = options.no_builtin orelse comp.root_mod.no_builtin, | 7434 | .no_builtin = options.no_builtin orelse comp.root_mod.no_builtin, |
| 7409 | .code_model = comp.root_mod.code_model, | 7435 | .code_model = comp.root_mod.code_model, |
| ... | @@ -7557,15 +7583,15 @@ pub fn addLinkLib(comp: *Compilation, lib_name: []const u8) !void { | ... | @@ -7557,15 +7583,15 @@ pub fn addLinkLib(comp: *Compilation, lib_name: []const u8) !void { |
| 7557 | 7583 | ||
| 7558 | /// This decides the optimization mode for all zig-provided libraries, including | 7584 | /// This decides the optimization mode for all zig-provided libraries, including |
| 7559 | /// compiler-rt, libcxx, libc, libunwind, etc. | 7585 | /// compiler-rt, libcxx, libc, libunwind, etc. |
| 7560 | pub fn compilerRtOptMode(comp: Compilation) std.lang.OptimizeMode { | 7586 | pub fn compilerRtOptMode(comp: Compilation) std.lang.Optimize { |
| 7561 | if (comp.debug_compiler_runtime_libs) |mode| { | 7587 | if (comp.debug_compiler_runtime_libs) |mode| { |
| 7562 | return mode; | 7588 | return mode; |
| 7563 | } | 7589 | } |
| 7564 | const target = &comp.root_mod.resolved_target.result; | 7590 | const target = &comp.root_mod.resolved_target.result; |
| 7565 | switch (comp.root_mod.optimize_mode) { | 7591 | switch (comp.root_mod.optimize_mode) { |
| 7566 | .Debug, .ReleaseSafe => return target_util.defaultCompilerRtOptimizeMode(target), | 7592 | .debug, .safe => return target_util.defaultCompilerRtOptimizeMode(target), |
| 7567 | .ReleaseFast => return .ReleaseFast, | 7593 | .fast => return .fast, |
| 7568 | .ReleaseSmall => return .ReleaseSmall, | 7594 | .small => return .small, |
| 7569 | } | 7595 | } |
| 7570 | } | 7596 | } |
| 7571 | 7597 |
src/Compilation/Config.zig+7-7| ... | @@ -59,7 +59,7 @@ export_memory: bool, | ... | @@ -59,7 +59,7 @@ export_memory: bool, |
| 59 | shared_memory: bool, | 59 | shared_memory: bool, |
| 60 | is_test: bool, | 60 | is_test: bool, |
| 61 | debug_format: DebugFormat, | 61 | debug_format: DebugFormat, |
| 62 | root_optimize_mode: std.lang.OptimizeMode, | 62 | root_optimize_mode: std.lang.Optimize, |
| 63 | root_strip: bool, | 63 | root_strip: bool, |
| 64 | root_error_tracing: bool, | 64 | root_error_tracing: bool, |
| 65 | dll_export_fns: bool, | 65 | dll_export_fns: bool, |
| ... | @@ -80,7 +80,7 @@ pub const Options = struct { | ... | @@ -80,7 +80,7 @@ pub const Options = struct { |
| 80 | is_test: bool, | 80 | is_test: bool, |
| 81 | have_zcu: bool, | 81 | have_zcu: bool, |
| 82 | emit_bin: bool, | 82 | emit_bin: bool, |
| 83 | root_optimize_mode: ?std.lang.OptimizeMode = null, | 83 | root_optimize_mode: ?std.lang.Optimize = null, |
| 84 | root_strip: ?bool = null, | 84 | root_strip: ?bool = null, |
| 85 | root_error_tracing: ?bool = null, | 85 | root_error_tracing: ?bool = null, |
| 86 | link_mode: ?std.lang.LinkMode = null, | 86 | link_mode: ?std.lang.LinkMode = null, |
| ... | @@ -196,7 +196,7 @@ pub fn resolve(options: Options) ResolveError!Config { | ... | @@ -196,7 +196,7 @@ pub fn resolve(options: Options) ResolveError!Config { |
| 196 | break :b options.use_lib_llvm orelse true; | 196 | break :b options.use_lib_llvm orelse true; |
| 197 | }; | 197 | }; |
| 198 | 198 | ||
| 199 | const root_optimize_mode = options.root_optimize_mode orelse .Debug; | 199 | const root_optimize_mode = options.root_optimize_mode orelse .debug; |
| 200 | 200 | ||
| 201 | // Make a decision on whether to use Clang or Aro for translate-c and compiling C files. | 201 | // Make a decision on whether to use Clang or Aro for translate-c and compiling C files. |
| 202 | const c_frontend: CFrontend = b: { | 202 | const c_frontend: CFrontend = b: { |
| ... | @@ -357,7 +357,7 @@ pub fn resolve(options: Options) ResolveError!Config { | ... | @@ -357,7 +357,7 @@ pub fn resolve(options: Options) ResolveError!Config { |
| 357 | if (!use_lib_llvm and options.emit_bin) break :b false; | 357 | if (!use_lib_llvm and options.emit_bin) break :b false; |
| 358 | 358 | ||
| 359 | // Prefer LLVM for release builds. | 359 | // Prefer LLVM for release builds. |
| 360 | if (root_optimize_mode != .Debug) break :b true; | 360 | if (root_optimize_mode != .debug) break :b true; |
| 361 | 361 | ||
| 362 | // load_dynamic_library standalone test not passing on this combination | 362 | // load_dynamic_library standalone test not passing on this combination |
| 363 | // https://github.com/ziglang/zig/issues/24080 | 363 | // https://github.com/ziglang/zig/issues/24080 |
| ... | @@ -486,7 +486,7 @@ pub fn resolve(options: Options) ResolveError!Config { | ... | @@ -486,7 +486,7 @@ pub fn resolve(options: Options) ResolveError!Config { |
| 486 | 486 | ||
| 487 | const root_strip = b: { | 487 | const root_strip = b: { |
| 488 | if (options.root_strip) |x| break :b x; | 488 | if (options.root_strip) |x| break :b x; |
| 489 | if (root_optimize_mode == .ReleaseSmall) break :b true; | 489 | if (root_optimize_mode == .small) break :b true; |
| 490 | if (!target_util.hasDebugInfo(target)) break :b true; | 490 | if (!target_util.hasDebugInfo(target)) break :b true; |
| 491 | break :b false; | 491 | break :b false; |
| 492 | }; | 492 | }; |
| ... | @@ -512,8 +512,8 @@ pub fn resolve(options: Options) ResolveError!Config { | ... | @@ -512,8 +512,8 @@ pub fn resolve(options: Options) ResolveError!Config { |
| 512 | if (root_strip) break :b false; | 512 | if (root_strip) break :b false; |
| 513 | if (!backend_supports_error_tracing) break :b false; | 513 | if (!backend_supports_error_tracing) break :b false; |
| 514 | break :b switch (root_optimize_mode) { | 514 | break :b switch (root_optimize_mode) { |
| 515 | .Debug => true, | 515 | .debug => true, |
| 516 | .ReleaseSafe, .ReleaseFast, .ReleaseSmall => false, | 516 | .safe, .fast, .small => false, |
| 517 | }; | 517 | }; |
| 518 | }; | 518 | }; |
| 519 | 519 |
src/IncrementalDebugServer.zig+24-11| ... | @@ -130,7 +130,7 @@ fn serveStream( | ... | @@ -130,7 +130,7 @@ fn serveStream( |
| 130 | try stream_writer.writeAll("zig> "); | 130 | try stream_writer.writeAll("zig> "); |
| 131 | const untrimmed = try stream_reader.takeSentinel('\n'); | 131 | const untrimmed = try stream_reader.takeSentinel('\n'); |
| 132 | const cmd_and_arg = std.mem.trim(u8, untrimmed, " \t\r\n"); | 132 | const cmd_and_arg = std.mem.trim(u8, untrimmed, " \t\r\n"); |
| 133 | const cmd: []const u8, const arg: []const u8 = if (std.mem.indexOfScalar(u8, cmd_and_arg, ' ')) |i| | 133 | const cmd: []const u8, const arg: []const u8 = if (std.mem.findScalar(u8, cmd_and_arg, ' ')) |i| |
| 134 | .{ cmd_and_arg[0..i], cmd_and_arg[i + 1 ..] } | 134 | .{ cmd_and_arg[0..i], cmd_and_arg[i + 1 ..] } |
| 135 | else | 135 | else |
| 136 | .{ cmd_and_arg, "" }; | 136 | .{ cmd_and_arg, "" }; |
| ... | @@ -244,7 +244,7 @@ fn handleCommand(zcu: *Zcu, w: *Io.Writer, cmd_str: []const u8, arg_str: []const | ... | @@ -244,7 +244,7 @@ fn handleCommand(zcu: *Zcu, w: *Io.Writer, cmd_str: []const u8, arg_str: []const |
| 244 | const ty: Type = .fromInterned(type_ip_index); | 244 | const ty: Type = .fromInterned(type_ip_index); |
| 245 | const ty_name = ty.containerTypeName(ip).toSlice(ip); | 245 | const ty_name = ty.containerTypeName(ip).toSlice(ip); |
| 246 | const success = switch (@as(u2, @intFromBool(anchor_start)) << 1 | @intFromBool(anchor_end)) { | 246 | const success = switch (@as(u2, @intFromBool(anchor_start)) << 1 | @intFromBool(anchor_end)) { |
| 247 | 0b00 => std.mem.indexOf(u8, ty_name, query) != null, | 247 | 0b00 => std.mem.find(u8, ty_name, query) != null, |
| 248 | 0b01 => std.mem.endsWith(u8, ty_name, query), | 248 | 0b01 => std.mem.endsWith(u8, ty_name, query), |
| 249 | 0b10 => std.mem.startsWith(u8, ty_name, query), | 249 | 0b10 => std.mem.startsWith(u8, ty_name, query), |
| 250 | 0b11 => std.mem.eql(u8, ty_name, query), | 250 | 0b11 => std.mem.eql(u8, ty_name, query), |
| ... | @@ -265,7 +265,7 @@ fn handleCommand(zcu: *Zcu, w: *Io.Writer, cmd_str: []const u8, arg_str: []const | ... | @@ -265,7 +265,7 @@ fn handleCommand(zcu: *Zcu, w: *Io.Writer, cmd_str: []const u8, arg_str: []const |
| 265 | const nav = ip.getNav(nav_index); | 265 | const nav = ip.getNav(nav_index); |
| 266 | const nav_fqn = nav.fqn.toSlice(ip); | 266 | const nav_fqn = nav.fqn.toSlice(ip); |
| 267 | const success = switch (@as(u2, @intFromBool(anchor_start)) << 1 | @intFromBool(anchor_end)) { | 267 | const success = switch (@as(u2, @intFromBool(anchor_start)) << 1 | @intFromBool(anchor_end)) { |
| 268 | 0b00 => std.mem.indexOf(u8, nav_fqn, query) != null, | 268 | 0b00 => std.mem.find(u8, nav_fqn, query) != null, |
| 269 | 0b01 => std.mem.endsWith(u8, nav_fqn, query), | 269 | 0b01 => std.mem.endsWith(u8, nav_fqn, query), |
| 270 | 0b10 => std.mem.startsWith(u8, nav_fqn, query), | 270 | 0b10 => std.mem.startsWith(u8, nav_fqn, query), |
| 271 | 0b11 => std.mem.eql(u8, nav_fqn, query), | 271 | 0b11 => std.mem.eql(u8, nav_fqn, query), |
| ... | @@ -286,21 +286,34 @@ fn handleCommand(zcu: *Zcu, w: *Io.Writer, cmd_str: []const u8, arg_str: []const | ... | @@ -286,21 +286,34 @@ fn handleCommand(zcu: *Zcu, w: *Io.Writer, cmd_str: []const u8, arg_str: []const |
| 286 | const referencer = (ref orelse break :ref "<analysis root>").referencer; | 286 | const referencer = (ref orelse break :ref "<analysis root>").referencer; |
| 287 | break :ref printAnalUnit(referencer, &ref_str_buf); | 287 | break :ref printAnalUnit(referencer, &ref_str_buf); |
| 288 | }; | 288 | }; |
| 289 | const has_err: []const u8 = err: { | ||
| 290 | if (zcu.failed_analysis.contains(unit)) break :err "true"; | ||
| 291 | if (zcu.transitive_failed_analysis.contains(unit)) break :err "true (transitive)"; | ||
| 292 | break :err "false"; | ||
| 293 | }; | ||
| 294 | try w.print( | 289 | try w.print( |
| 295 | \\last update generation: {d} | 290 | \\last update generation: {d} |
| 296 | \\current referencer: {s} | 291 | \\current referencer: {s} |
| 297 | \\has error: {s} | ||
| 298 | \\ | 292 | \\ |
| 299 | , .{ | 293 | , .{ |
| 300 | unit_info.last_update_gen, | 294 | unit_info.last_update_gen, |
| 301 | ref_str, | 295 | ref_str, |
| 302 | has_err, | ||
| 303 | }); | 296 | }); |
| 297 | if (zcu.failed_analysis.get(unit)) |err_msg| { | ||
| 298 | try w.print("analysis result: failure ({q})\n", .{err_msg.msg}); | ||
| 299 | } else if (zcu.transitive_failed_analysis.get(unit)) |reason| { | ||
| 300 | switch (reason) { | ||
| 301 | .astgen_error => try w.writeAll("analysis result: transitive failure (astgen error)\n"), | ||
| 302 | .dependency_loop => try w.writeAll("analysis result: transitive failure (dependency loop)\n"), | ||
| 303 | .lost_tracking => try w.writeAll("analysis result: transitive failure (lost tracking for zir inst)\n"), | ||
| 304 | .failed_unit => |other_unit| { | ||
| 305 | var buf: [32]u8 = undefined; | ||
| 306 | try w.print("analysis result: transitive failure (failed unit: {s})\n", .{printAnalUnit(other_unit, &buf)}); | ||
| 307 | }, | ||
| 308 | .func_nav_val_changed => |func_index| try w.print("analysis result: transitive failure (owner nav of func '{d}' changed value)\n", .{@backingInt(func_index)}), | ||
| 309 | } | ||
| 310 | } else { | ||
| 311 | try w.writeAll("analysis result: success\n"); | ||
| 312 | } | ||
| 313 | if (unit.unwrap() == .func) { | ||
| 314 | const nav_id = zcu.intern_pool.indexToKey(unit.unwrap().func).func.owner_nav; | ||
| 315 | try w.print("owner nav: {d}\n", .{@backingInt(nav_id)}); | ||
| 316 | } | ||
| 304 | } else if (std.mem.eql(u8, cmd_str, "unit_dependencies")) { | 317 | } else if (std.mem.eql(u8, cmd_str, "unit_dependencies")) { |
| 305 | const unit = parseAnalUnit(arg_str) orelse return w.writeAll("malformed anal unit"); | 318 | const unit = parseAnalUnit(arg_str) orelse return w.writeAll("malformed anal unit"); |
| 306 | const unit_info = zcu.incremental_debug_state.units.get(unit) orelse return w.writeAll("unknown anal unit"); | 319 | const unit_info = zcu.incremental_debug_state.units.get(unit) orelse return w.writeAll("unknown anal unit"); |
| ... | @@ -365,7 +378,7 @@ fn parseIndex(str: []const u8) ?u32 { | ... | @@ -365,7 +378,7 @@ fn parseIndex(str: []const u8) ?u32 { |
| 365 | return std.fmt.parseInt(u32, str, 10) catch null; | 378 | return std.fmt.parseInt(u32, str, 10) catch null; |
| 366 | } | 379 | } |
| 367 | fn parseAnalUnit(str: []const u8) ?AnalUnit { | 380 | fn parseAnalUnit(str: []const u8) ?AnalUnit { |
| 368 | const split_idx = std.mem.indexOfScalar(u8, str, ' ') orelse return null; | 381 | const split_idx = std.mem.findScalar(u8, str, ' ') orelse return null; |
| 369 | const kind = str[0..split_idx]; | 382 | const kind = str[0..split_idx]; |
| 370 | const idx_str = str[split_idx + 1 ..]; | 383 | const idx_str = str[split_idx + 1 ..]; |
| 371 | if (std.mem.eql(u8, kind, "comptime")) { | 384 | if (std.mem.eql(u8, kind, "comptime")) { |
src/InternPool.zig+30-30| ... | @@ -1737,7 +1737,7 @@ pub const String = enum(u32) { | ... | @@ -1737,7 +1737,7 @@ pub const String = enum(u32) { |
| 1737 | } | 1737 | } |
| 1738 | 1738 | ||
| 1739 | pub fn toNullTerminatedString(string: String, len: u64, ip: *const InternPool) NullTerminatedString { | 1739 | pub fn toNullTerminatedString(string: String, len: u64, ip: *const InternPool) NullTerminatedString { |
| 1740 | assert(std.mem.indexOfScalar(u8, string.toSlice(len, ip), 0) == null); | 1740 | assert(std.mem.findScalar(u8, string.toSlice(len, ip), 0) == null); |
| 1741 | assert(string.at(len, ip) == 0); | 1741 | assert(string.at(len, ip) == 0); |
| 1742 | return @fromBackingInt(@intCast(@backingInt(string))); | 1742 | return @fromBackingInt(@intCast(@backingInt(string))); |
| 1743 | } | 1743 | } |
| ... | @@ -1864,7 +1864,7 @@ pub const NullTerminatedString = enum(u32) { | ... | @@ -1864,7 +1864,7 @@ pub const NullTerminatedString = enum(u32) { |
| 1864 | pub fn toUnsigned(string: NullTerminatedString, ip: *const InternPool) ?u32 { | 1864 | pub fn toUnsigned(string: NullTerminatedString, ip: *const InternPool) ?u32 { |
| 1865 | const slice = string.toSlice(ip); | 1865 | const slice = string.toSlice(ip); |
| 1866 | if (slice.len > 1 and slice[0] == '0') return null; | 1866 | if (slice.len > 1 and slice[0] == '0') return null; |
| 1867 | if (std.mem.indexOfScalar(u8, slice, '_')) |_| return null; | 1867 | if (std.mem.findScalar(u8, slice, '_')) |_| return null; |
| 1868 | return std.fmt.parseUnsigned(u32, slice, 10) catch null; | 1868 | return std.fmt.parseUnsigned(u32, slice, 10) catch null; |
| 1869 | } | 1869 | } |
| 1870 | 1870 | ||
| ... | @@ -4193,7 +4193,7 @@ pub const Index = enum(u32) { | ... | @@ -4193,7 +4193,7 @@ pub const Index = enum(u32) { |
| 4193 | }; | 4193 | }; |
| 4194 | } | 4194 | } |
| 4195 | 4195 | ||
| 4196 | /// This function is used in the debugger pretty formatters in tools/ to fetch the | 4196 | /// This function is used in the debugger pretty formatters in lib/lldb/ to fetch the |
| 4197 | /// Tag to encoding mapping to facilitate fancy debug printing for this type. | 4197 | /// Tag to encoding mapping to facilitate fancy debug printing for this type. |
| 4198 | fn dbHelper(self: *Index, tag_to_encoding_map: *struct { | 4198 | fn dbHelper(self: *Index, tag_to_encoding_map: *struct { |
| 4199 | const DataIsIndex = struct { data: Index }; | 4199 | const DataIsIndex = struct { data: Index }; |
| ... | @@ -4219,26 +4219,17 @@ pub const Index = enum(u32) { | ... | @@ -4219,26 +4219,17 @@ pub const Index = enum(u32) { |
| 4219 | type_inferred_error_set: DataIsIndex, | 4219 | type_inferred_error_set: DataIsIndex, |
| 4220 | simple_type: void, | 4220 | simple_type: void, |
| 4221 | type_function: struct { | 4221 | type_function: struct { |
| 4222 | const @"data.flags.has_comptime_bits" = opaque {}; | ||
| 4223 | const @"data.flags.has_noalias_bits" = opaque {}; | ||
| 4224 | const @"data.flags.cc.extraLen()" = opaque {}; | ||
| 4225 | const @"data.params_len" = opaque {}; | 4222 | const @"data.params_len" = opaque {}; |
| 4226 | data: *Tag.TypeFunction, | 4223 | data: *Tag.TypeFunction, |
| 4227 | @"trailing.comptime_bits.len": *@"data.flags.has_comptime_bits", | ||
| 4228 | @"trailing.noalias_bits.len": *@"data.flags.has_noalias_bits", | ||
| 4229 | @"trailing.cc_bits.len": *@"data.flags.cc.extraLen()", | ||
| 4230 | @"trailing.param_types.len": *@"data.params_len", | 4224 | @"trailing.param_types.len": *@"data.params_len", |
| 4231 | trailing: struct { comptime_bits: []u32, noalias_bits: []u32, cc_bits: []u32, param_types: []Index }, | 4225 | trailing: struct { param_types: []Index }, |
| 4232 | }, | 4226 | }, |
| 4233 | type_tuple: struct { | 4227 | type_tuple: struct { |
| 4234 | const @"data.fields_len" = opaque {}; | 4228 | const @"data.fields_len" = opaque {}; |
| 4235 | data: *TypeTuple, | 4229 | data: *TypeTuple, |
| 4236 | @"trailing.types.len": *@"data.fields_len", | 4230 | @"trailing.types.len": *@"data.fields_len", |
| 4237 | @"trailing.values.len": *@"data.fields_len", | 4231 | @"trailing.values.len": *@"data.fields_len", |
| 4238 | trailing: struct { | 4232 | trailing: struct { types: []Index, values: []Index }, |
| 4239 | types: []Index, | ||
| 4240 | values: []Index, | ||
| 4241 | }, | ||
| 4242 | }, | 4233 | }, |
| 4243 | 4234 | ||
| 4244 | type_struct: struct { data: *Tag.TypeStruct }, | 4235 | type_struct: struct { data: *Tag.TypeStruct }, |
| ... | @@ -4350,7 +4341,7 @@ pub const Index = enum(u32) { | ... | @@ -4350,7 +4341,7 @@ pub const Index = enum(u32) { |
| 4350 | const encoding = @field(Tag.encodings, tag_name); | 4341 | const encoding = @field(Tag.encodings, tag_name); |
| 4351 | if (@hasField(@TypeOf(encoding), "trailing")) { | 4342 | if (@hasField(@TypeOf(encoding), "trailing")) { |
| 4352 | const trailing_info = @typeInfo(encoding.trailing).@"struct"; | 4343 | const trailing_info = @typeInfo(encoding.trailing).@"struct"; |
| 4353 | for (trailing_info.field_names, trailing_info.field_types) |field_name, field_type| { | 4344 | for (trailing_info.field_names, trailing_info.field_types) |trailing_field_name, trailing_field_type| { |
| 4354 | struct { | 4345 | struct { |
| 4355 | fn checkConfig(name: []const u8) void { | 4346 | fn checkConfig(name: []const u8) void { |
| 4356 | if (!@hasField(@TypeOf(encoding.config), name)) @compileError("missing field: " ++ @typeName(Tag) ++ ".encodings." ++ tag_name ++ ".config.@\"" ++ name ++ "\""); | 4347 | if (!@hasField(@TypeOf(encoding.config), name)) @compileError("missing field: " ++ @typeName(Tag) ++ ".encodings." ++ tag_name ++ ".config.@\"" ++ name ++ "\""); |
| ... | @@ -4359,22 +4350,30 @@ pub const Index = enum(u32) { | ... | @@ -4359,22 +4350,30 @@ pub const Index = enum(u32) { |
| 4359 | } | 4350 | } |
| 4360 | fn checkField(name: []const u8, Type: type) void { | 4351 | fn checkField(name: []const u8, Type: type) void { |
| 4361 | switch (@typeInfo(Type)) { | 4352 | switch (@typeInfo(Type)) { |
| 4362 | .int => {}, | 4353 | .int, .@"enum" => return, |
| 4363 | .@"enum" => {}, | 4354 | .@"struct" => |info| switch (info.layout) { |
| 4364 | .@"struct" => |info| assert(info.layout == .@"packed"), | 4355 | .auto => unreachable, |
| 4356 | .@"extern" => { | ||
| 4357 | for (info.field_names, info.field_types) |field_name, field_type| checkField(name ++ "." ++ field_name, field_type); | ||
| 4358 | return; | ||
| 4359 | }, | ||
| 4360 | .@"packed" => return, | ||
| 4361 | }, | ||
| 4365 | .optional => |info| { | 4362 | .optional => |info| { |
| 4366 | checkConfig(name ++ ".?"); | 4363 | checkConfig(name ++ ".?"); |
| 4367 | checkField(name ++ ".?", info.child); | 4364 | checkField(name ++ ".?", info.child); |
| 4365 | return; | ||
| 4368 | }, | 4366 | }, |
| 4369 | .pointer => |info| { | 4367 | .pointer => |info| if (info.size == .slice) { |
| 4370 | assert(info.size == .slice); | ||
| 4371 | checkConfig(name ++ ".len"); | 4368 | checkConfig(name ++ ".len"); |
| 4372 | checkField(name ++ "[0]", info.child); | 4369 | checkField(name ++ "[0]", info.child); |
| 4370 | return; | ||
| 4373 | }, | 4371 | }, |
| 4374 | else => @compileError("unsupported type: " ++ @typeName(Tag) ++ ".encodings." ++ tag_name ++ "." ++ name ++ ": " ++ @typeName(Type)), | 4372 | else => {}, |
| 4375 | } | 4373 | } |
| 4374 | @compileError("unsupported type: " ++ @typeName(Tag) ++ ".encodings." ++ tag_name ++ "." ++ name ++ ": " ++ @typeName(Type)); | ||
| 4376 | } | 4375 | } |
| 4377 | }.checkField("trailing." ++ field_name, field_type); | 4376 | }.checkField("trailing." ++ trailing_field_name, trailing_field_type); |
| 4378 | } | 4377 | } |
| 4379 | } | 4378 | } |
| 4380 | }, | 4379 | }, |
| ... | @@ -5186,17 +5185,18 @@ pub const Tag = enum(u8) { | ... | @@ -5186,17 +5185,18 @@ pub const Tag = enum(u8) { |
| 5186 | .trailing = struct { | 5185 | .trailing = struct { |
| 5187 | param_comptime_bits: ?[]u32, | 5186 | param_comptime_bits: ?[]u32, |
| 5188 | param_noalias_bits: ?[]u32, | 5187 | param_noalias_bits: ?[]u32, |
| 5189 | param_cc_bits: ?[]u32, | 5188 | spirv_kernel_options: ?extern struct { x: u32, y: u32, z: u32 }, |
| 5190 | param_type: []Index, | 5189 | spirv_mesh_options: ?extern struct { max_primitives: u32, max_vertices: u32 }, |
| 5190 | param_types: []Index, | ||
| 5191 | }, | 5191 | }, |
| 5192 | .config = .{ | 5192 | .config = .{ |
| 5193 | .@"trailing.param_comptime_bits.?" = .@"payload.flags.has_comptime_bits", | 5193 | .@"trailing.param_comptime_bits.?" = .@"payload.flags.has_comptime_bits", |
| 5194 | .@"trailing.param_comptime_bits.?.len" = .@"(payload.params_len + 31) / 32", | 5194 | .@"trailing.param_comptime_bits.?.len" = .@"(payload.params_len + 31) / 32", |
| 5195 | .@"trailing.param_noalias_bits.?" = .@"payload.flags.has_noalias_bits", | 5195 | .@"trailing.param_noalias_bits.?" = .@"payload.flags.has_noalias_bits", |
| 5196 | .@"trailing.param_noalias_bits.?.len" = .@"(payload.params_len + 31) / 32", | 5196 | .@"trailing.param_noalias_bits.?.len" = .@"(payload.params_len + 31) / 32", |
| 5197 | .@"trailing.param_cc_bits.?" = .@"payload.flags.cc.extraLen() != 0", | 5197 | .@"trailing.spirv_kernel_options.?" = .@"payload.flags.cc.tag == .spirv_kernel or payload.flags.cc.tag == .spirv_task", |
| 5198 | .@"trailing.param_cc_bits.?.len" = .@"payload.flags.cc.extraLen()", | 5198 | .@"trailing.spirv_mesh_options.?" = .@"payload.flags.cc.tag == .spirv_mesh", |
| 5199 | .@"trailing.param_type.len" = .@"payload.params_len", | 5199 | .@"trailing.param_types.len" = .@"payload.params_len", |
| 5200 | }, | 5200 | }, |
| 5201 | }, | 5201 | }, |
| 5202 | 5202 | ||
| ... | @@ -5225,7 +5225,7 @@ pub const Tag = enum(u8) { | ... | @@ -5225,7 +5225,7 @@ pub const Tag = enum(u8) { |
| 5225 | .@"trailing.field_defaults.?" = .@"payload.flags.any_field_defaults", | 5225 | .@"trailing.field_defaults.?" = .@"payload.flags.any_field_defaults", |
| 5226 | .@"trailing.field_defaults.?.len" = .@"payload.fields_len", | 5226 | .@"trailing.field_defaults.?.len" = .@"payload.fields_len", |
| 5227 | .@"trailing.field_aligns.?" = .@"payload.flags.any_field_aligns", | 5227 | .@"trailing.field_aligns.?" = .@"payload.flags.any_field_aligns", |
| 5228 | .@"trailing.field_aligns.?.len" = .@"payload.fields_len", | 5228 | .@"trailing.field_aligns.?.len" = .@"(payload.fields_len + 3) / 4", |
| 5229 | .@"trailing.field_is_comptime_bits.?" = .@"payload.flags.any_comptime_fields", | 5229 | .@"trailing.field_is_comptime_bits.?" = .@"payload.flags.any_comptime_fields", |
| 5230 | .@"trailing.field_is_comptime_bits.?.len" = .@"(payload.fields_len + 31) / 32", | 5230 | .@"trailing.field_is_comptime_bits.?.len" = .@"(payload.fields_len + 31) / 32", |
| 5231 | .@"trailing.field_runtime_order.?" = .@"payload.flags.layout == .auto", | 5231 | .@"trailing.field_runtime_order.?" = .@"payload.flags.layout == .auto", |
| ... | @@ -5254,7 +5254,7 @@ pub const Tag = enum(u8) { | ... | @@ -5254,7 +5254,7 @@ pub const Tag = enum(u8) { |
| 5254 | .@"trailing.captures.?.len" = .@"trailing.captures_len.?", | 5254 | .@"trailing.captures.?.len" = .@"trailing.captures_len.?", |
| 5255 | .@"trailing.field_types.len" = .@"payload.fields_len", | 5255 | .@"trailing.field_types.len" = .@"payload.fields_len", |
| 5256 | .@"trailing.field_aligns.?" = .@"payloads.flags.any_field_aligns", | 5256 | .@"trailing.field_aligns.?" = .@"payloads.flags.any_field_aligns", |
| 5257 | .@"trailing.field_aligns.?.len" = .@"payload.fields_len", | 5257 | .@"trailing.field_aligns.?.len" = .@"(payload.fields_len + 3) / 4", |
| 5258 | }, | 5258 | }, |
| 5259 | }, | 5259 | }, |
| 5260 | .type_union_packed_auto = union_packed_encoding, | 5260 | .type_union_packed_auto = union_packed_encoding, |
| ... | @@ -11428,7 +11428,7 @@ pub fn getOrPutTrailingString( | ... | @@ -11428,7 +11428,7 @@ pub fn getOrPutTrailingString( |
| 11428 | .tid = tid, | 11428 | .tid = tid, |
| 11429 | .index = strings.mutate.len - 1, | 11429 | .index = strings.mutate.len - 1, |
| 11430 | }).wrap(ip)))); | 11430 | }).wrap(ip)))); |
| 11431 | const has_embedded_null = std.mem.indexOfScalar(u8, key, 0) != null; | 11431 | const has_embedded_null = std.mem.findScalar(u8, key, 0) != null; |
| 11432 | switch (embedded_nulls) { | 11432 | switch (embedded_nulls) { |
| 11433 | .no_embedded_nulls => assert(!has_embedded_null), | 11433 | .no_embedded_nulls => assert(!has_embedded_null), |
| 11434 | .maybe_embedded_nulls => if (has_embedded_null) { | 11434 | .maybe_embedded_nulls => if (has_embedded_null) { |
src/Module.zig+9-26| ... | @@ -26,7 +26,7 @@ fully_qualified_name: []const u8, | ... | @@ -26,7 +26,7 @@ fully_qualified_name: []const u8, |
| 26 | deps: Deps = .{}, | 26 | deps: Deps = .{}, |
| 27 | 27 | ||
| 28 | resolved_target: ResolvedTarget, | 28 | resolved_target: ResolvedTarget, |
| 29 | optimize_mode: std.lang.OptimizeMode, | 29 | optimize_mode: std.lang.Optimize, |
| 30 | code_model: std.lang.CodeModel, | 30 | code_model: std.lang.CodeModel, |
| 31 | single_threaded: bool, | 31 | single_threaded: bool, |
| 32 | error_tracing: bool, | 32 | error_tracing: bool, |
| ... | @@ -42,8 +42,6 @@ sanitize_thread: bool, | ... | @@ -42,8 +42,6 @@ sanitize_thread: bool, |
| 42 | fuzz: bool, | 42 | fuzz: bool, |
| 43 | unwind_tables: std.lang.UnwindTables, | 43 | unwind_tables: std.lang.UnwindTables, |
| 44 | cc_argv: []const []const u8, | 44 | cc_argv: []const []const u8, |
| 45 | /// (SPIR-V) whether to generate a structured control flow graph or not | ||
| 46 | structured_cfg: bool, | ||
| 47 | no_builtin: bool, | 45 | no_builtin: bool, |
| 48 | 46 | ||
| 49 | pub const Deps = std.array_hash_map.String(*Module); | 47 | pub const Deps = std.array_hash_map.String(*Module); |
| ... | @@ -67,7 +65,7 @@ pub const CreateOptions = struct { | ... | @@ -67,7 +65,7 @@ pub const CreateOptions = struct { |
| 67 | pub const Inherited = struct { | 65 | pub const Inherited = struct { |
| 68 | /// If this is null then `parent` must be non-null. | 66 | /// If this is null then `parent` must be non-null. |
| 69 | resolved_target: ?ResolvedTarget = null, | 67 | resolved_target: ?ResolvedTarget = null, |
| 70 | optimize_mode: ?std.lang.OptimizeMode = null, | 68 | optimize_mode: ?std.lang.Optimize = null, |
| 71 | code_model: ?std.lang.CodeModel = null, | 69 | code_model: ?std.lang.CodeModel = null, |
| 72 | single_threaded: ?bool = null, | 70 | single_threaded: ?bool = null, |
| 73 | error_tracing: ?bool = null, | 71 | error_tracing: ?bool = null, |
| ... | @@ -85,7 +83,6 @@ pub const CreateOptions = struct { | ... | @@ -85,7 +83,6 @@ pub const CreateOptions = struct { |
| 85 | sanitize_c: ?std.zig.SanitizeC = null, | 83 | sanitize_c: ?std.zig.SanitizeC = null, |
| 86 | sanitize_thread: ?bool = null, | 84 | sanitize_thread: ?bool = null, |
| 87 | fuzz: ?bool = null, | 85 | fuzz: ?bool = null, |
| 88 | structured_cfg: ?bool = null, | ||
| 89 | no_builtin: ?bool = null, | 86 | no_builtin: ?bool = null, |
| 90 | }; | 87 | }; |
| 91 | }; | 88 | }; |
| ... | @@ -144,7 +141,7 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Module { | ... | @@ -144,7 +141,7 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Module { |
| 144 | if (options.inherited.valgrind) |x| break :b x; | 141 | if (options.inherited.valgrind) |x| break :b x; |
| 145 | if (options.parent) |p| break :b p.valgrind; | 142 | if (options.parent) |p| break :b p.valgrind; |
| 146 | if (strip) break :b false; | 143 | if (strip) break :b false; |
| 147 | break :b optimize_mode == .Debug; | 144 | break :b optimize_mode == .debug; |
| 148 | }; | 145 | }; |
| 149 | 146 | ||
| 150 | const single_threaded = b: { | 147 | const single_threaded = b: { |
| ... | @@ -212,7 +209,7 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Module { | ... | @@ -212,7 +209,7 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Module { |
| 212 | const omit_frame_pointer = b: { | 209 | const omit_frame_pointer = b: { |
| 213 | if (options.inherited.omit_frame_pointer) |x| break :b x; | 210 | if (options.inherited.omit_frame_pointer) |x| break :b x; |
| 214 | if (options.parent) |p| break :b p.omit_frame_pointer; | 211 | if (options.parent) |p| break :b p.omit_frame_pointer; |
| 215 | if (optimize_mode == .ReleaseSmall) { | 212 | if (optimize_mode == .small) { |
| 216 | // On x86, in most cases, keeping the frame pointer usually results in smaller binary size. | 213 | // On x86, in most cases, keeping the frame pointer usually results in smaller binary size. |
| 217 | // This has to do with how instructions for memory access via the stack base pointer register (when keeping the frame pointer) | 214 | // This has to do with how instructions for memory access via the stack base pointer register (when keeping the frame pointer) |
| 218 | // are smaller than instructions for memory access via the stack pointer register (when omitting the frame pointer). | 215 | // are smaller than instructions for memory access via the stack pointer register (when omitting the frame pointer). |
| ... | @@ -251,21 +248,21 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Module { | ... | @@ -251,21 +248,21 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Module { |
| 251 | }; | 248 | }; |
| 252 | 249 | ||
| 253 | const is_safe_mode = switch (optimize_mode) { | 250 | const is_safe_mode = switch (optimize_mode) { |
| 254 | .Debug, .ReleaseSafe => true, | 251 | .debug, .safe => true, |
| 255 | .ReleaseFast, .ReleaseSmall => false, | 252 | .fast, .small => false, |
| 256 | }; | 253 | }; |
| 257 | 254 | ||
| 258 | const sanitize_c: std.zig.SanitizeC = b: { | 255 | const sanitize_c: std.zig.SanitizeC = b: { |
| 259 | if (options.inherited.sanitize_c) |x| break :b x; | 256 | if (options.inherited.sanitize_c) |x| break :b x; |
| 260 | if (options.parent) |p| break :b p.sanitize_c; | 257 | if (options.parent) |p| break :b p.sanitize_c; |
| 261 | break :b switch (optimize_mode) { | 258 | break :b switch (optimize_mode) { |
| 262 | .Debug => .full, | 259 | .debug => .full, |
| 263 | // It's recommended to use the minimal runtime in production | 260 | // It's recommended to use the minimal runtime in production |
| 264 | // environments due to the security implications of the full runtime. | 261 | // environments due to the security implications of the full runtime. |
| 265 | // The minimal runtime doesn't provide much benefit over simply | 262 | // The minimal runtime doesn't provide much benefit over simply |
| 266 | // trapping, however, so we do that instead. | 263 | // trapping, however, so we do that instead. |
| 267 | .ReleaseSafe => .trap, | 264 | .safe => .trap, |
| 268 | .ReleaseFast, .ReleaseSmall => .off, | 265 | .fast, .small => .off, |
| 269 | }; | 266 | }; |
| 270 | }; | 267 | }; |
| 271 | 268 | ||
| ... | @@ -320,17 +317,6 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Module { | ... | @@ -320,17 +317,6 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Module { |
| 320 | break :sp target_util.default_stack_protector_buffer_size; | 317 | break :sp target_util.default_stack_protector_buffer_size; |
| 321 | }; | 318 | }; |
| 322 | 319 | ||
| 323 | const structured_cfg = b: { | ||
| 324 | if (options.inherited.structured_cfg) |x| break :b x; | ||
| 325 | if (options.parent) |p| break :b p.structured_cfg; | ||
| 326 | // We always want a structured control flow in shaders. This option is | ||
| 327 | // only relevant for OpenCL kernels. | ||
| 328 | break :b switch (target.os.tag) { | ||
| 329 | .opencl => false, | ||
| 330 | else => true, | ||
| 331 | }; | ||
| 332 | }; | ||
| 333 | |||
| 334 | const no_builtin = b: { | 320 | const no_builtin = b: { |
| 335 | if (options.inherited.no_builtin) |x| break :b x; | 321 | if (options.inherited.no_builtin) |x| break :b x; |
| 336 | if (options.parent) |p| break :b p.no_builtin; | 322 | if (options.parent) |p| break :b p.no_builtin; |
| ... | @@ -411,7 +397,6 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Module { | ... | @@ -411,7 +397,6 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Module { |
| 411 | .fuzz = fuzz, | 397 | .fuzz = fuzz, |
| 412 | .unwind_tables = unwind_tables, | 398 | .unwind_tables = unwind_tables, |
| 413 | .cc_argv = options.cc_argv, | 399 | .cc_argv = options.cc_argv, |
| 414 | .structured_cfg = structured_cfg, | ||
| 415 | .no_builtin = no_builtin, | 400 | .no_builtin = no_builtin, |
| 416 | }; | 401 | }; |
| 417 | return mod; | 402 | return mod; |
| ... | @@ -450,7 +435,6 @@ pub fn createLimited(gpa: Allocator, options: LimitedOptions) Allocator.Error!*M | ... | @@ -450,7 +435,6 @@ pub fn createLimited(gpa: Allocator, options: LimitedOptions) Allocator.Error!*M |
| 450 | .fuzz = undefined, | 435 | .fuzz = undefined, |
| 451 | .unwind_tables = undefined, | 436 | .unwind_tables = undefined, |
| 452 | .cc_argv = undefined, | 437 | .cc_argv = undefined, |
| 453 | .structured_cfg = undefined, | ||
| 454 | .no_builtin = undefined, | 438 | .no_builtin = undefined, |
| 455 | }; | 439 | }; |
| 456 | return mod; | 440 | return mod; |
| ... | @@ -489,7 +473,6 @@ pub fn createBuiltin(arena: Allocator, opts: Builtin, dirs: std.zig.Directories) | ... | @@ -489,7 +473,6 @@ pub fn createBuiltin(arena: Allocator, opts: Builtin, dirs: std.zig.Directories) |
| 489 | .stack_protector = 0, | 473 | .stack_protector = 0, |
| 490 | .red_zone = false, | 474 | .red_zone = false, |
| 491 | .sanitize_c = .off, | 475 | .sanitize_c = .off, |
| 492 | .structured_cfg = false, | ||
| 493 | .no_builtin = false, | 476 | .no_builtin = false, |
| 494 | }; | 477 | }; |
| 495 | return new; | 478 | return new; |
src/RangeSet.zig+18-23| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | const RangeSet = @This(); | 1 | const RangeSet = @This(); |
| 2 | 2 | ||
| 3 | ranges: std.MultiArrayList(Range), | 3 | list: std.MultiArrayList(Range), |
| 4 | 4 | ||
| 5 | pub const Range = struct { | 5 | pub const Range = struct { |
| 6 | first: Value, | 6 | first: Value, |
| ... | @@ -8,41 +8,36 @@ pub const Range = struct { | ... | @@ -8,41 +8,36 @@ pub const Range = struct { |
| 8 | src: LazySrcLoc, | 8 | src: LazySrcLoc, |
| 9 | }; | 9 | }; |
| 10 | 10 | ||
| 11 | pub const empty: RangeSet = .{ .ranges = .empty }; | 11 | pub const empty: RangeSet = .{ .list = .empty }; |
| 12 | 12 | ||
| 13 | pub fn deinit(self: *RangeSet, allocator: Allocator) void { | 13 | pub fn deinit(self: *RangeSet, allocator: Allocator) void { |
| 14 | self.ranges.deinit(allocator); | 14 | self.list.deinit(allocator); |
| 15 | self.* = undefined; | 15 | self.* = undefined; |
| 16 | } | 16 | } |
| 17 | 17 | ||
| 18 | pub fn ensureUnusedCapacity(self: *RangeSet, allocator: Allocator, additional_count: usize) Allocator.Error!void { | 18 | pub fn ensureUnusedCapacity(set: *RangeSet, allocator: Allocator, additional_count: usize) Allocator.Error!void { |
| 19 | return self.ranges.ensureUnusedCapacity(allocator, additional_count); | 19 | return set.list.ensureUnusedCapacity(allocator, additional_count); |
| 20 | } | 20 | } |
| 21 | 21 | ||
| 22 | pub fn addAssumeCapacity(set: *RangeSet, new: Range, ty: Type, zcu: *Zcu) ?LazySrcLoc { | 22 | pub fn addAssumeCapacity(set: *RangeSet, new: Range, ty: Type, zcu: *Zcu) ?Range { |
| 23 | assert(new.first.typeOf(zcu).eql(ty)); | 23 | assert(new.first.typeOf(zcu).eql(ty)); |
| 24 | assert(new.last.typeOf(zcu).eql(ty)); | 24 | assert(new.last.typeOf(zcu).eql(ty)); |
| 25 | assert(new.first.compareScalar(.lte, new.last, ty, zcu)); | 25 | assert(new.first.compareScalar(.lte, new.last, ty, zcu)); |
| 26 | 26 | ||
| 27 | const idx = std.sort.lowerBound(Value, set.ranges.items(.last), @as(SearchCtx, .{ | 27 | const idx = std.sort.lowerBound(Value, set.list.items(.last), @as(SearchCtx, .{ |
| 28 | .val = new.first, | 28 | .val = new.first, |
| 29 | .zcu = zcu, | 29 | .zcu = zcu, |
| 30 | }), compare); | 30 | }), compare); |
| 31 | 31 | ||
| 32 | if (idx != set.ranges.len and // `new.first` is *not* greater than all `old.last` | 32 | if (idx != set.list.len and // `new.first` is *not* greater than all `old.last` |
| 33 | new.last.compareScalar(.gte, set.ranges.items(.first)[idx], ty, zcu)) | 33 | new.last.compareScalar(.gte, set.list.items(.first)[idx], ty, zcu)) |
| 34 | { | 34 | { |
| 35 | return set.ranges.items(.src)[idx]; // `new` overlaps with existing range. | 35 | return set.list.get(idx); // `new` overlaps with existing range. |
| 36 | } | 36 | } |
| 37 | set.ranges.insertAssumeCapacity(idx, new); | 37 | set.list.insertAssumeCapacity(idx, new); |
| 38 | return null; | 38 | return null; |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | pub fn add(set: *RangeSet, allocator: Allocator, new: Range, ty: Type, zcu: *Zcu) Allocator.Error!?LazySrcLoc { | ||
| 42 | try set.ensureUnusedCapacity(allocator, 1); | ||
| 43 | return set.addAssumeCapacity(new, ty, zcu); | ||
| 44 | } | ||
| 45 | |||
| 46 | pub fn spans( | 41 | pub fn spans( |
| 47 | set: *RangeSet, | 42 | set: *RangeSet, |
| 48 | allocator: Allocator, | 43 | allocator: Allocator, |
| ... | @@ -53,13 +48,13 @@ pub fn spans( | ... | @@ -53,13 +48,13 @@ pub fn spans( |
| 53 | ) Allocator.Error!bool { | 48 | ) Allocator.Error!bool { |
| 54 | assert(first.typeOf(zcu).eql(ty)); | 49 | assert(first.typeOf(zcu).eql(ty)); |
| 55 | assert(last.typeOf(zcu).eql(ty)); | 50 | assert(last.typeOf(zcu).eql(ty)); |
| 56 | if (set.ranges.len == 0) return false; | 51 | if (set.list.len == 0) return false; |
| 57 | 52 | ||
| 58 | assert(std.sort.isSorted(Value, set.ranges.items(.first), @as(SortCtx, .{ .ty = ty, .zcu = zcu }), lessThan)); | 53 | assert(std.sort.isSorted(Value, set.list.items(.first), @as(SortCtx, .{ .ty = ty, .zcu = zcu }), lessThan)); |
| 59 | assert(std.sort.isSorted(Value, set.ranges.items(.last), @as(SortCtx, .{ .ty = ty, .zcu = zcu }), lessThan)); | 54 | assert(std.sort.isSorted(Value, set.list.items(.last), @as(SortCtx, .{ .ty = ty, .zcu = zcu }), lessThan)); |
| 60 | 55 | ||
| 61 | if (!set.ranges.items(.first)[0].eql(first, ty, zcu) or | 56 | if (!set.list.items(.first)[0].eql(first, ty, zcu) or |
| 62 | !set.ranges.items(.last)[set.ranges.len - 1].eql(last, ty, zcu)) | 57 | !set.list.items(.last)[set.list.len - 1].eql(last, ty, zcu)) |
| 63 | { | 58 | { |
| 64 | return false; | 59 | return false; |
| 65 | } | 60 | } |
| ... | @@ -75,8 +70,8 @@ pub fn spans( | ... | @@ -75,8 +70,8 @@ pub fn spans( |
| 75 | 70 | ||
| 76 | // look for gaps | 71 | // look for gaps |
| 77 | for ( | 72 | for ( |
| 78 | set.ranges.items(.first)[1..], | 73 | set.list.items(.first)[1..], |
| 79 | set.ranges.items(.last)[0 .. set.ranges.len - 1], | 74 | set.list.items(.last)[0 .. set.list.len - 1], |
| 80 | ) |cur_first, prev_last| { | 75 | ) |cur_first, prev_last| { |
| 81 | // prev_last + 1 == cur_first | 76 | // prev_last + 1 == cur_first |
| 82 | counter.copy(prev_last.toBigInt(&space, zcu)); | 77 | counter.copy(prev_last.toBigInt(&space, zcu)); |
src/Sema.zig+551-262| ... | @@ -532,20 +532,20 @@ pub const Block = struct { | ... | @@ -532,20 +532,20 @@ pub const Block = struct { |
| 532 | 532 | ||
| 533 | fn wantSafeTypes(block: *const Block) bool { | 533 | fn wantSafeTypes(block: *const Block) bool { |
| 534 | return block.want_safety orelse switch (block.ownerModule().optimize_mode) { | 534 | return block.want_safety orelse switch (block.ownerModule().optimize_mode) { |
| 535 | .Debug => true, | 535 | .debug => true, |
| 536 | .ReleaseSafe => true, | 536 | .safe => true, |
| 537 | .ReleaseFast => false, | 537 | .fast => false, |
| 538 | .ReleaseSmall => false, | 538 | .small => false, |
| 539 | }; | 539 | }; |
| 540 | } | 540 | } |
| 541 | 541 | ||
| 542 | fn wantSafety(block: *const Block) bool { | 542 | fn wantSafety(block: *const Block) bool { |
| 543 | if (block.isComptime()) return false; // runtime safety checks are pointless in comptime blocks | 543 | if (block.isComptime()) return false; // runtime safety checks are pointless in comptime blocks |
| 544 | return block.want_safety orelse switch (block.ownerModule().optimize_mode) { | 544 | return block.want_safety orelse switch (block.ownerModule().optimize_mode) { |
| 545 | .Debug => true, | 545 | .debug => true, |
| 546 | .ReleaseSafe => true, | 546 | .safe => true, |
| 547 | .ReleaseFast => false, | 547 | .fast => false, |
| 548 | .ReleaseSmall => false, | 548 | .small => false, |
| 549 | }; | 549 | }; |
| 550 | } | 550 | } |
| 551 | 551 | ||
| ... | @@ -1472,7 +1472,7 @@ fn analyzeBodyInner( | ... | @@ -1472,7 +1472,7 @@ fn analyzeBodyInner( |
| 1472 | i += 1; | 1472 | i += 1; |
| 1473 | continue; | 1473 | continue; |
| 1474 | }, | 1474 | }, |
| 1475 | .astgen_error => return error.AnalysisFail, | 1475 | .astgen_error => return sema.failTransitive(.astgen_error), |
| 1476 | .float_op_result_ty => try sema.zirFloatOpResultType(block, extended), | 1476 | .float_op_result_ty => try sema.zirFloatOpResultType(block, extended), |
| 1477 | }; | 1477 | }; |
| 1478 | }, | 1478 | }, |
| ... | @@ -2247,7 +2247,7 @@ fn resolveValue(sema: *Sema, inst: Air.Inst.Ref) ?Value { | ... | @@ -2247,7 +2247,7 @@ fn resolveValue(sema: *Sema, inst: Air.Inst.Ref) ?Value { |
| 2247 | .inferred_alloc_comptime => unreachable, // assertion failure | 2247 | .inferred_alloc_comptime => unreachable, // assertion failure |
| 2248 | else => {}, | 2248 | else => {}, |
| 2249 | } | 2249 | } |
| 2250 | // LLVM fails to eliminate this `classify` call in ReleaseFast, which hurts performance, so | 2250 | // LLVM fails to eliminate this `classify` call in -Ofast, which hurts performance, so |
| 2251 | // we must explicitly check for `std.debug.runtime_safety`. | 2251 | // we must explicitly check for `std.debug.runtime_safety`. |
| 2252 | if (std.debug.runtime_safety) switch (sema.typeOf(inst).classify(zcu)) { | 2252 | if (std.debug.runtime_safety) switch (sema.typeOf(inst).classify(zcu)) { |
| 2253 | .no_possible_value => unreachable, // values of this type do not exist | 2253 | .no_possible_value => unreachable, // values of this type do not exist |
| ... | @@ -2352,6 +2352,10 @@ pub fn failWithUseOfUndef(sema: *Sema, block: *Block, src: LazySrcLoc, vector_in | ... | @@ -2352,6 +2352,10 @@ pub fn failWithUseOfUndef(sema: *Sema, block: *Block, src: LazySrcLoc, vector_in |
| 2352 | }); | 2352 | }); |
| 2353 | } | 2353 | } |
| 2354 | 2354 | ||
| 2355 | pub fn failWithUndefSliceLen(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError { | ||
| 2356 | return sema.fail(block, src, "use of slice with undefined length here causes illegal behavior", .{}); | ||
| 2357 | } | ||
| 2358 | |||
| 2355 | pub fn failWithDivideByZero(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError { | 2359 | pub fn failWithDivideByZero(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError { |
| 2356 | return sema.fail(block, src, "division by zero here causes illegal behavior", .{}); | 2360 | return sema.fail(block, src, "division by zero here causes illegal behavior", .{}); |
| 2357 | } | 2361 | } |
| ... | @@ -2697,13 +2701,15 @@ fn failWithTypeMismatch(sema: *Sema, block: *Block, src: LazySrcLoc, expected: T | ... | @@ -2697,13 +2701,15 @@ fn failWithTypeMismatch(sema: *Sema, block: *Block, src: LazySrcLoc, expected: T |
| 2697 | }); | 2701 | }); |
| 2698 | } | 2702 | } |
| 2699 | 2703 | ||
| 2700 | pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Zcu.ErrorMsg) error{ AnalysisFail, OutOfMemory } { | 2704 | pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Zcu.ErrorMsg) SemaError { |
| 2701 | @branchHint(.cold); | 2705 | @branchHint(.cold); |
| 2702 | const zcu = sema.pt.zcu; | 2706 | const zcu = sema.pt.zcu; |
| 2703 | const comp = zcu.comp; | 2707 | const comp = zcu.comp; |
| 2704 | const gpa = comp.gpa; | 2708 | const gpa = comp.gpa; |
| 2705 | const io = comp.io; | 2709 | const io = comp.io; |
| 2706 | 2710 | ||
| 2711 | assert(sema.err == null); | ||
| 2712 | |||
| 2707 | if (build_options.enable_debug_extensions and comp.debug_compile_errors) { | 2713 | if (build_options.enable_debug_extensions and comp.debug_compile_errors) { |
| 2708 | var wip_errors: std.zig.ErrorBundle.Wip = undefined; | 2714 | var wip_errors: std.zig.ErrorBundle.Wip = undefined; |
| 2709 | wip_errors.init(gpa) catch @panic("out of memory"); | 2715 | wip_errors.init(gpa) catch @panic("out of memory"); |
| ... | @@ -2729,17 +2735,11 @@ pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Zcu.ErrorMsg | ... | @@ -2729,17 +2735,11 @@ pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Zcu.ErrorMsg |
| 2729 | 2735 | ||
| 2730 | err_msg.reference_trace_root = sema.owner.toOptional(); | 2736 | err_msg.reference_trace_root = sema.owner.toOptional(); |
| 2731 | 2737 | ||
| 2732 | const gop = try zcu.failed_analysis.getOrPut(gpa, sema.owner); | 2738 | try zcu.failed_analysis.putNoClobber(gpa, sema.owner, err_msg); |
| 2733 | if (gop.found_existing) { | 2739 | assert(!zcu.transitive_failed_analysis.contains(sema.owner)); |
| 2734 | // If there are multiple errors for the same Decl, prefer the first one added. | ||
| 2735 | sema.err = null; | ||
| 2736 | err_msg.destroy(gpa); | ||
| 2737 | } else { | ||
| 2738 | sema.err = err_msg; | ||
| 2739 | gop.value_ptr.* = err_msg; | ||
| 2740 | } | ||
| 2741 | 2740 | ||
| 2742 | return error.AnalysisFail; | 2741 | sema.err = err_msg; |
| 2742 | return error.AlreadyReported; | ||
| 2743 | } | 2743 | } |
| 2744 | 2744 | ||
| 2745 | /// Given an ErrorMsg, modify its message and source location to the given values, turning the | 2745 | /// Given an ErrorMsg, modify its message and source location to the given values, turning the |
| ... | @@ -3117,9 +3117,14 @@ fn zirRefDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -3117,9 +3117,14 @@ fn zirRefDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 3117 | try sema.validateDeref(block, src, operand, operand_ty); | 3117 | try sema.validateDeref(block, src, operand, operand_ty); |
| 3118 | 3118 | ||
| 3119 | const ptr_info = operand_ty.ptrInfo(zcu); | 3119 | const ptr_info = operand_ty.ptrInfo(zcu); |
| 3120 | return switch (ptr_info.flags.size) { | 3120 | return single_ptr: switch (ptr_info.flags.size) { |
| 3121 | .many, .slice => unreachable, // cannot be dereferenced | 3121 | .many => unreachable, // cannot be dereferenced directly |
| 3122 | .c => single_ptr: { | 3122 | .slice => { |
| 3123 | const slice_val = sema.resolveValue(operand).?; | ||
| 3124 | const slice = zcu.intern_pool.indexToKey(slice_val.toIntern()).slice; | ||
| 3125 | break :single_ptr .fromValue(try pt.sliceToArrayPtr(slice)); | ||
| 3126 | }, | ||
| 3127 | .c => { | ||
| 3123 | const single_ptr_ty = try pt.ptrType(p: { | 3128 | const single_ptr_ty = try pt.ptrType(p: { |
| 3124 | var p = ptr_info; | 3129 | var p = ptr_info; |
| 3125 | p.flags.size = .one; | 3130 | p.flags.size = .one; |
| ... | @@ -3153,18 +3158,26 @@ fn validateDeref( | ... | @@ -3153,18 +3158,26 @@ fn validateDeref( |
| 3153 | ) CompileError!void { | 3158 | ) CompileError!void { |
| 3154 | const pt = sema.pt; | 3159 | const pt = sema.pt; |
| 3155 | const zcu = pt.zcu; | 3160 | const zcu = pt.zcu; |
| 3161 | const ip = &zcu.intern_pool; | ||
| 3156 | if (ty.zigTypeTag(zcu) != .pointer) { | 3162 | if (ty.zigTypeTag(zcu) != .pointer) { |
| 3157 | return sema.fail(block, src, "cannot dereference non-pointer type '{f}'", .{ty.fmt(pt)}); | 3163 | return sema.fail(block, src, "cannot dereference non-pointer type '{f}'", .{ty.fmt(pt)}); |
| 3158 | } else switch (ty.ptrSize(zcu)) { | 3164 | } |
| 3159 | .one, .c => {}, | 3165 | const size = ty.ptrSize(zcu); |
| 3166 | switch (size) { | ||
| 3160 | .many => return sema.fail(block, src, "index syntax required for unknown-length pointer type '{f}'", .{ty.fmt(pt)}), | 3167 | .many => return sema.fail(block, src, "index syntax required for unknown-length pointer type '{f}'", .{ty.fmt(pt)}), |
| 3161 | .slice => return sema.fail(block, src, "index syntax required for slice type '{f}'", .{ty.fmt(pt)}), | 3168 | .one, .c, .slice => {}, |
| 3162 | } | 3169 | } |
| 3163 | if (sema.resolveValue(ref)) |val| { | 3170 | if (sema.resolveValue(ref)) |val| { |
| 3164 | // Error for deref of undef pointer, unless the pointee is OPV in which case it's legal. | 3171 | // Error for deref of undef pointer, unless the pointee is OPV in which case it's legal. |
| 3165 | if (val.isUndef(zcu) and ty.childType(zcu).classify(zcu) != .one_possible_value) { | 3172 | if (val.isUndef(zcu) and ty.childType(zcu).classify(zcu) != .one_possible_value) { |
| 3166 | return sema.fail(block, src, "cannot dereference undefined value", .{}); | 3173 | return sema.fail(block, src, "cannot dereference undefined value", .{}); |
| 3167 | } | 3174 | } |
| 3175 | // We need a defined slice length for the array type the slice should be dereferenced to. | ||
| 3176 | if (size == .slice and ip.indexToKey(val.toIntern()).slice.len == .undef_usize) { | ||
| 3177 | return sema.fail(block, src, "cannot dereference slice with undefined length", .{}); | ||
| 3178 | } | ||
| 3179 | } else if (size == .slice) { | ||
| 3180 | return sema.fail(block, src, "index syntax required to access runtime-known slice", .{}); | ||
| 3168 | } | 3181 | } |
| 3169 | } | 3182 | } |
| 3170 | 3183 | ||
| ... | @@ -3186,10 +3199,12 @@ fn ensureResultUsed( | ... | @@ -3186,10 +3199,12 @@ fn ensureResultUsed( |
| 3186 | const zcu = pt.zcu; | 3199 | const zcu = pt.zcu; |
| 3187 | switch (ty.zigTypeTag(zcu)) { | 3200 | switch (ty.zigTypeTag(zcu)) { |
| 3188 | .void, .noreturn => return, | 3201 | .void, .noreturn => return, |
| 3189 | .error_set => return sema.fail(block, src, "error set is ignored", .{}), | 3202 | .error_set => { |
| 3203 | return sema.fail(block, src, "error set of type '{f}' is ignored", .{ty.fmt(pt)}); | ||
| 3204 | }, | ||
| 3190 | .error_union => { | 3205 | .error_union => { |
| 3191 | const msg = msg: { | 3206 | const msg = msg: { |
| 3192 | const msg = try sema.errMsg(src, "error union is ignored", .{}); | 3207 | const msg = try sema.errMsg(src, "error union of type '{f}' is ignored", .{ty.fmt(pt)}); |
| 3193 | errdefer msg.destroy(sema.gpa); | 3208 | errdefer msg.destroy(sema.gpa); |
| 3194 | try sema.errNote(src, msg, "consider using 'try', 'catch', or 'if'", .{}); | 3209 | try sema.errNote(src, msg, "consider using 'try', 'catch', or 'if'", .{}); |
| 3195 | break :msg msg; | 3210 | break :msg msg; |
| ... | @@ -4745,11 +4760,14 @@ fn failWithBadMemberAccess( | ... | @@ -4745,11 +4760,14 @@ fn failWithBadMemberAccess( |
| 4745 | .@"enum" => "enum", | 4760 | .@"enum" => "enum", |
| 4746 | else => unreachable, | 4761 | else => unreachable, |
| 4747 | }; | 4762 | }; |
| 4748 | if (agg_ty.typeDeclInst(zcu)) |inst| if ((inst.resolve(ip) orelse return error.AnalysisFail) == .main_struct_inst) { | 4763 | if (agg_ty.typeDeclInst(zcu)) |inst| { |
| 4749 | return sema.fail(block, field_src, "root source file struct '{f}' has no member named '{f}'", .{ | 4764 | const inst_index = inst.resolve(ip) orelse return sema.failTransitive(.{ .lost_tracking = inst }); |
| 4750 | agg_ty.fmt(pt), field_name.fmt(ip), | 4765 | if (inst_index == .main_struct_inst) { |
| 4751 | }); | 4766 | return sema.fail(block, field_src, "root source file struct '{f}' has no member named '{f}'", .{ |
| 4752 | }; | 4767 | agg_ty.fmt(pt), field_name.fmt(ip), |
| 4768 | }); | ||
| 4769 | } | ||
| 4770 | } | ||
| 4753 | 4771 | ||
| 4754 | return sema.fail(block, field_src, "{s} '{f}' has no member named '{f}'", .{ | 4772 | return sema.fail(block, field_src, "{s} '{f}' has no member named '{f}'", .{ |
| 4755 | kw_name, agg_ty.fmt(pt), field_name.fmt(ip), | 4773 | kw_name, agg_ty.fmt(pt), field_name.fmt(ip), |
| ... | @@ -5997,7 +6015,14 @@ fn lookupInNamespace( | ... | @@ -5997,7 +6015,14 @@ fn lookupInNamespace( |
| 5997 | const pt = sema.pt; | 6015 | const pt = sema.pt; |
| 5998 | const zcu = pt.zcu; | 6016 | const zcu = pt.zcu; |
| 5999 | 6017 | ||
| 6000 | try pt.ensureNamespaceUpToDate(namespace_index); | 6018 | pt.ensureNamespaceUpToDate(namespace_index) catch |err| switch (err) { |
| 6019 | error.LostZirContainerDecl => { | ||
| 6020 | const namespace = zcu.namespacePtr(namespace_index); | ||
| 6021 | const ns_ty: Type = .fromInterned(namespace.owner_type); | ||
| 6022 | return sema.failTransitive(.{ .lost_tracking = ns_ty.typeDeclInstAllowGeneratedTag(zcu).? }); | ||
| 6023 | }, | ||
| 6024 | else => |e| return e, | ||
| 6025 | }; | ||
| 6001 | 6026 | ||
| 6002 | const namespace = zcu.namespacePtr(namespace_index); | 6027 | const namespace = zcu.namespacePtr(namespace_index); |
| 6003 | 6028 | ||
| ... | @@ -6062,7 +6087,7 @@ pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref | ... | @@ -6062,7 +6087,7 @@ pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref |
| 6062 | const stack_trace_ty = try sema.getStdLangType(block.nodeOffset(.zero), .StackTrace); | 6087 | const stack_trace_ty = try sema.getStdLangType(block.nodeOffset(.zero), .StackTrace); |
| 6063 | const field_name = try zcu.intern_pool.getOrPutString(gpa, io, pt.tid, "index", .no_embedded_nulls); | 6088 | const field_name = try zcu.intern_pool.getOrPutString(gpa, io, pt.tid, "index", .no_embedded_nulls); |
| 6064 | const field_index = sema.structFieldIndex(block, stack_trace_ty, field_name, LazySrcLoc.unneeded) catch |err| switch (err) { | 6089 | const field_index = sema.structFieldIndex(block, stack_trace_ty, field_name, LazySrcLoc.unneeded) catch |err| switch (err) { |
| 6065 | error.AnalysisFail => @panic("std.lang.StackTrace is corrupt"), | 6090 | error.AlreadyReported => @panic("std.lang.StackTrace is corrupt"), |
| 6066 | error.ComptimeReturn, error.ComptimeBreak => unreachable, | 6091 | error.ComptimeReturn, error.ComptimeBreak => unreachable, |
| 6067 | error.OutOfMemory, error.Canceled => |e| return e, | 6092 | error.OutOfMemory, error.Canceled => |e| return e, |
| 6068 | }; | 6093 | }; |
| ... | @@ -6724,7 +6749,9 @@ fn analyzeCall( | ... | @@ -6724,7 +6749,9 @@ fn analyzeCall( |
| 6724 | const fn_nav: InternPool.Nav, const fn_zir: Zir, const fn_tracked_inst: InternPool.TrackedInst.Index, const fn_zir_inst: Zir.Inst.Index, const fn_zir_info: Zir.FnInfo = if (func_val) |f| b: { | 6749 | const fn_nav: InternPool.Nav, const fn_zir: Zir, const fn_tracked_inst: InternPool.TrackedInst.Index, const fn_zir_inst: Zir.Inst.Index, const fn_zir_info: Zir.FnInfo = if (func_val) |f| b: { |
| 6725 | const info = ip.indexToKey(f.toIntern()).func; | 6750 | const info = ip.indexToKey(f.toIntern()).func; |
| 6726 | const nav = ip.getNav(info.owner_nav); | 6751 | const nav = ip.getNav(info.owner_nav); |
| 6727 | const resolved_func_inst = info.zir_body_inst.resolveFull(ip) orelse return error.AnalysisFail; | 6752 | const resolved_func_inst = info.zir_body_inst.resolveFull(ip) orelse { |
| 6753 | return sema.failTransitive(.{ .lost_tracking = info.zir_body_inst }); | ||
| 6754 | }; | ||
| 6728 | const file = zcu.fileByIndex(resolved_func_inst.file); | 6755 | const file = zcu.fileByIndex(resolved_func_inst.file); |
| 6729 | const zir_info = file.zir.?.getFnInfo(resolved_func_inst.inst); | 6756 | const zir_info = file.zir.?.getFnInfo(resolved_func_inst.inst); |
| 6730 | break :b .{ nav, file.zir.?, info.zir_body_inst, resolved_func_inst.inst, zir_info }; | 6757 | break :b .{ nav, file.zir.?, info.zir_body_inst, resolved_func_inst.inst, zir_info }; |
| ... | @@ -8355,7 +8382,10 @@ fn zirFunc( | ... | @@ -8355,7 +8382,10 @@ fn zirFunc( |
| 8355 | const cc: std.lang.CallingConvention = if (has_body) cc: { | 8382 | const cc: std.lang.CallingConvention = if (has_body) cc: { |
| 8356 | const func_decl_nav = sema.owner.unwrap().nav_val; | 8383 | const func_decl_nav = sema.owner.unwrap().nav_val; |
| 8357 | const fn_is_exported = exported: { | 8384 | const fn_is_exported = exported: { |
| 8358 | const decl_inst = ip.getNav(func_decl_nav).analysis.?.zir_index.resolve(ip) orelse return error.AnalysisFail; | 8385 | const decl_ti = ip.getNav(func_decl_nav).analysis.?.zir_index; |
| 8386 | const decl_inst = decl_ti.resolve(ip) orelse { | ||
| 8387 | return sema.failTransitive(.{ .lost_tracking = decl_ti }); | ||
| 8388 | }; | ||
| 8359 | const zir_decl = sema.code.getDeclaration(decl_inst); | 8389 | const zir_decl = sema.code.getDeclaration(decl_inst); |
| 8360 | break :exported zir_decl.linkage == .@"export"; | 8390 | break :exported zir_decl.linkage == .@"export"; |
| 8361 | }; | 8391 | }; |
| ... | @@ -8501,6 +8531,7 @@ const calling_conventions_supporting_var_args = [_]std.lang.CallingConvention.Ta | ... | @@ -8501,6 +8531,7 @@ const calling_conventions_supporting_var_args = [_]std.lang.CallingConvention.Ta |
| 8501 | .x86_64_win, | 8531 | .x86_64_win, |
| 8502 | .x86_sysv, | 8532 | .x86_sysv, |
| 8503 | .x86_win, | 8533 | .x86_win, |
| 8534 | .x86_mingw, | ||
| 8504 | .aarch64_aapcs, | 8535 | .aarch64_aapcs, |
| 8505 | .aarch64_aapcs_darwin, | 8536 | .aarch64_aapcs_darwin, |
| 8506 | .aarch64_aapcs_win, | 8537 | .aarch64_aapcs_win, |
| ... | @@ -10760,7 +10791,7 @@ fn finishSwitchBr( | ... | @@ -10760,7 +10791,7 @@ fn finishSwitchBr( |
| 10760 | .@"enum" => if (else_is_named_only or | 10791 | .@"enum" => if (else_is_named_only or |
| 10761 | !item_ty.isNonexhaustiveEnum(zcu) or tagged_union_originally) | 10792 | !item_ty.isNonexhaustiveEnum(zcu) or tagged_union_originally) |
| 10762 | { | 10793 | { |
| 10763 | try branch_hints.ensureUnusedCapacity(gpa, @intCast(validated_switch.seen_enum_fields.len)); | 10794 | try branch_hints.ensureUnusedCapacity(gpa, @intCast(validated_switch.seen.enum_fields.len)); |
| 10764 | break :check_enumerable .{ undefined, undefined }; | 10795 | break :check_enumerable .{ undefined, undefined }; |
| 10765 | }, | 10796 | }, |
| 10766 | .error_set => if (!operand_ty.isAnyError(zcu)) { | 10797 | .error_set => if (!operand_ty.isAnyError(zcu)) { |
| ... | @@ -10881,13 +10912,13 @@ fn finishSwitchBr( | ... | @@ -10881,13 +10912,13 @@ fn finishSwitchBr( |
| 10881 | try branch_hints.append(gpa, prong_hint); | 10912 | try branch_hints.append(gpa, prong_hint); |
| 10882 | 10913 | ||
| 10883 | try cases_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.SwitchBr.Case).@"struct".field_names.len + | 10914 | try cases_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.SwitchBr.Case).@"struct".field_names.len + |
| 10884 | (validated_switch.seen_enum_fields.len + 1 - zir_switch.totalItemsLen()) + // +1 because totalItemsLen includes the _ | 10915 | (validated_switch.seen.enum_fields.len + 1 - zir_switch.totalItemsLen()) + // +1 because totalItemsLen includes the _ |
| 10885 | case_block.instructions.items.len); | 10916 | case_block.instructions.items.len); |
| 10886 | const extra_case = cases_extra.addManyAsArrayAssumeCapacity( | 10917 | const extra_case = cases_extra.addManyAsArrayAssumeCapacity( |
| 10887 | @typeInfo(Air.SwitchBr.Case).@"struct".field_names.len, | 10918 | @typeInfo(Air.SwitchBr.Case).@"struct".field_names.len, |
| 10888 | ); | 10919 | ); |
| 10889 | var items_len: u32 = 0; | 10920 | var items_len: u32 = 0; |
| 10890 | for (validated_switch.seen_enum_fields, 0..) |seen_field, field_i| { | 10921 | for (validated_switch.seen.enum_fields, 0..) |seen_field, field_i| { |
| 10891 | if (seen_field != null) continue; | 10922 | if (seen_field != null) continue; |
| 10892 | const item_val = try pt.enumValueFieldIndex(item_ty, @intCast(field_i)); | 10923 | const item_val = try pt.enumValueFieldIndex(item_ty, @intCast(field_i)); |
| 10893 | const item_ref: Air.Inst.Ref = .fromValue(item_val); | 10924 | const item_ref: Air.Inst.Ref = .fromValue(item_val); |
| ... | @@ -10920,7 +10951,7 @@ fn finishSwitchBr( | ... | @@ -10920,7 +10951,7 @@ fn finishSwitchBr( |
| 10920 | } | 10951 | } |
| 10921 | if (tagged_union_originally) { | 10952 | if (tagged_union_originally) { |
| 10922 | const union_obj = zcu.typeToUnion(operand_ty).?; | 10953 | const union_obj = zcu.typeToUnion(operand_ty).?; |
| 10923 | for (validated_switch.seen_enum_fields, 0..) |seen_field, field_i| { | 10954 | for (validated_switch.seen.enum_fields, 0..) |seen_field, field_i| { |
| 10924 | if (seen_field != null) continue; | 10955 | if (seen_field != null) continue; |
| 10925 | const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[field_i]); | 10956 | const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[field_i]); |
| 10926 | if (!field_ty.isNoReturn(zcu)) break :analyze_body true; | 10957 | if (!field_ty.isNoReturn(zcu)) break :analyze_body true; |
| ... | @@ -11004,17 +11035,21 @@ fn finishSwitchBr( | ... | @@ -11004,17 +11035,21 @@ fn finishSwitchBr( |
| 11004 | } | 11035 | } |
| 11005 | 11036 | ||
| 11006 | const ValidatedSwitchBlock = struct { | 11037 | const ValidatedSwitchBlock = struct { |
| 11007 | seen_enum_fields: []const ?LazySrcLoc, | 11038 | seen: Seen, |
| 11008 | seen_errors: std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, LazySrcLoc), | ||
| 11009 | seen_ranges: std.MultiArrayList(RangeSet.Range).Slice, | ||
| 11010 | true_src: ?LazySrcLoc, | ||
| 11011 | false_src: ?LazySrcLoc, | ||
| 11012 | void_src: ?LazySrcLoc, | ||
| 11013 | |||
| 11014 | case_vals: []const Air.Inst.Ref, | 11039 | case_vals: []const Air.Inst.Ref, |
| 11015 | else_case: Zir.UnwrappedSwitchBlock.Case.Else, | 11040 | else_case: Zir.UnwrappedSwitchBlock.Case.Else, |
| 11016 | else_err_ty: ?Type, | 11041 | else_err_ty: ?Type, |
| 11017 | 11042 | ||
| 11043 | const Seen = struct { | ||
| 11044 | enum_fields: []?LazySrcLoc, | ||
| 11045 | errors: std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, LazySrcLoc), | ||
| 11046 | sparse_values: std.AutoHashMapUnmanaged(InternPool.Index, LazySrcLoc), | ||
| 11047 | ranges: RangeSet, | ||
| 11048 | true_src: ?LazySrcLoc, | ||
| 11049 | false_src: ?LazySrcLoc, | ||
| 11050 | void_src: ?LazySrcLoc, | ||
| 11051 | }; | ||
| 11052 | |||
| 11018 | fn iterateUnhandledItems( | 11053 | fn iterateUnhandledItems( |
| 11019 | validated_switch: *const ValidatedSwitchBlock, | 11054 | validated_switch: *const ValidatedSwitchBlock, |
| 11020 | /// May be `undefined` if `item_ty` isn't an `error_set`. | 11055 | /// May be `undefined` if `item_ty` isn't an `error_set`. |
| ... | @@ -11023,28 +11058,26 @@ const ValidatedSwitchBlock = struct { | ... | @@ -11023,28 +11058,26 @@ const ValidatedSwitchBlock = struct { |
| 11023 | min_int: Value, | 11058 | min_int: Value, |
| 11024 | ) UnhandledIterator { | 11059 | ) UnhandledIterator { |
| 11025 | return .{ | 11060 | return .{ |
| 11061 | .error_names = error_names, | ||
| 11062 | .seen = &validated_switch.seen, | ||
| 11063 | |||
| 11026 | .next_idx = 0, | 11064 | .next_idx = 0, |
| 11027 | .next_val = min_int, | 11065 | .next_val = min_int, |
| 11028 | .error_names = error_names, | 11066 | .handled_true = validated_switch.seen.true_src != null, |
| 11029 | .seen_enum_fields = validated_switch.seen_enum_fields, | 11067 | .handled_false = validated_switch.seen.false_src != null, |
| 11030 | .seen_errors = &validated_switch.seen_errors, | 11068 | .handled_void = validated_switch.seen.void_src != null, |
| 11031 | .seen_ranges = validated_switch.seen_ranges, | ||
| 11032 | .seen_true = validated_switch.true_src != null, | ||
| 11033 | .seen_false = validated_switch.false_src != null, | ||
| 11034 | .seen_void = validated_switch.void_src != null, | ||
| 11035 | }; | 11069 | }; |
| 11036 | } | 11070 | } |
| 11037 | 11071 | ||
| 11038 | const UnhandledIterator = struct { | 11072 | const UnhandledIterator = struct { |
| 11073 | error_names: InternPool.NullTerminatedString.Slice, | ||
| 11074 | seen: *const Seen, | ||
| 11075 | |||
| 11039 | next_idx: u32, | 11076 | next_idx: u32, |
| 11040 | next_val: ?Value, | 11077 | next_val: ?Value, |
| 11041 | error_names: InternPool.NullTerminatedString.Slice, | 11078 | handled_true: bool, |
| 11042 | seen_enum_fields: []const ?LazySrcLoc, | 11079 | handled_false: bool, |
| 11043 | seen_errors: *const std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, LazySrcLoc), | 11080 | handled_void: bool, |
| 11044 | seen_ranges: std.MultiArrayList(RangeSet.Range).Slice, | ||
| 11045 | seen_true: bool, | ||
| 11046 | seen_false: bool, | ||
| 11047 | seen_void: bool, | ||
| 11048 | 11081 | ||
| 11049 | fn next(it: *UnhandledIterator, sema: *Sema, item_ty: Type) CompileError!?Value { | 11082 | fn next(it: *UnhandledIterator, sema: *Sema, item_ty: Type) CompileError!?Value { |
| 11050 | const pt = sema.pt; | 11083 | const pt = sema.pt; |
| ... | @@ -11052,7 +11085,7 @@ const ValidatedSwitchBlock = struct { | ... | @@ -11052,7 +11085,7 @@ const ValidatedSwitchBlock = struct { |
| 11052 | const ip = &zcu.intern_pool; | 11085 | const ip = &zcu.intern_pool; |
| 11053 | switch (item_ty.zigTypeTag(zcu)) { | 11086 | switch (item_ty.zigTypeTag(zcu)) { |
| 11054 | .@"enum" => { | 11087 | .@"enum" => { |
| 11055 | for (it.seen_enum_fields[it.next_idx..], it.next_idx..) |seen_field, field_i| { | 11088 | for (it.seen.enum_fields[it.next_idx..], it.next_idx..) |seen_field, field_i| { |
| 11056 | if (seen_field != null) continue; | 11089 | if (seen_field != null) continue; |
| 11057 | it.next_idx = @intCast(field_i + 1); | 11090 | it.next_idx = @intCast(field_i + 1); |
| 11058 | return try pt.enumValueFieldIndex(item_ty, @intCast(field_i)); | 11091 | return try pt.enumValueFieldIndex(item_ty, @intCast(field_i)); |
| ... | @@ -11061,7 +11094,7 @@ const ValidatedSwitchBlock = struct { | ... | @@ -11061,7 +11094,7 @@ const ValidatedSwitchBlock = struct { |
| 11061 | }, | 11094 | }, |
| 11062 | .error_set => { | 11095 | .error_set => { |
| 11063 | for (it.error_names.get(ip)[it.next_idx..], it.next_idx..) |err_name, name_i| { | 11096 | for (it.error_names.get(ip)[it.next_idx..], it.next_idx..) |err_name, name_i| { |
| 11064 | if (it.seen_errors.contains(err_name)) continue; | 11097 | if (it.seen.errors.contains(err_name)) continue; |
| 11065 | it.next_idx = @intCast(name_i + 1); | 11098 | it.next_idx = @intCast(name_i + 1); |
| 11066 | return .fromInterned(try pt.intern(.{ .err = .{ | 11099 | return .fromInterned(try pt.intern(.{ .err = .{ |
| 11067 | .ty = item_ty.toIntern(), | 11100 | .ty = item_ty.toIntern(), |
| ... | @@ -11077,14 +11110,14 @@ const ValidatedSwitchBlock = struct { | ... | @@ -11077,14 +11110,14 @@ const ValidatedSwitchBlock = struct { |
| 11077 | .@"union", .@"struct" => item_ty.backingIntType(zcu), | 11110 | .@"union", .@"struct" => item_ty.backingIntType(zcu), |
| 11078 | else => unreachable, | 11111 | else => unreachable, |
| 11079 | }; | 11112 | }; |
| 11080 | while (it.next_idx < it.seen_ranges.len and | 11113 | while (it.next_idx < it.seen.ranges.list.len and |
| 11081 | cur_val.eql(it.seen_ranges.items(.first)[it.next_idx], int_ty, zcu)) | 11114 | cur_val.eql(it.seen.ranges.list.items(.first)[it.next_idx], int_ty, zcu)) |
| 11082 | { | 11115 | { |
| 11083 | defer it.next_idx += 1; | 11116 | defer it.next_idx += 1; |
| 11084 | const incr = try arith.incrementDefinedInt( | 11117 | const incr = try arith.incrementDefinedInt( |
| 11085 | sema, | 11118 | sema, |
| 11086 | int_ty, | 11119 | int_ty, |
| 11087 | it.seen_ranges.items(.last)[it.next_idx], | 11120 | it.seen.ranges.list.items(.last)[it.next_idx], |
| 11088 | ); | 11121 | ); |
| 11089 | if (incr.overflow) { | 11122 | if (incr.overflow) { |
| 11090 | it.next_val = null; | 11123 | it.next_val = null; |
| ... | @@ -11101,19 +11134,19 @@ const ValidatedSwitchBlock = struct { | ... | @@ -11101,19 +11134,19 @@ const ValidatedSwitchBlock = struct { |
| 11101 | }; | 11134 | }; |
| 11102 | }, | 11135 | }, |
| 11103 | .bool => { | 11136 | .bool => { |
| 11104 | if (!it.seen_true) { | 11137 | if (!it.handled_true) { |
| 11105 | it.seen_true = true; | 11138 | it.handled_true = true; |
| 11106 | return .true; | 11139 | return .true; |
| 11107 | } | 11140 | } |
| 11108 | if (!it.seen_false) { | 11141 | if (!it.handled_false) { |
| 11109 | it.seen_false = true; | 11142 | it.handled_false = true; |
| 11110 | return .false; | 11143 | return .false; |
| 11111 | } | 11144 | } |
| 11112 | return null; | 11145 | return null; |
| 11113 | }, | 11146 | }, |
| 11114 | .void => { | 11147 | .void => { |
| 11115 | if (!it.seen_void) { | 11148 | if (!it.handled_void) { |
| 11116 | it.seen_void = true; | 11149 | it.handled_void = true; |
| 11117 | return .void; | 11150 | return .void; |
| 11118 | } | 11151 | } |
| 11119 | return null; | 11152 | return null; |
| ... | @@ -11186,14 +11219,8 @@ fn validateSwitchBlock( | ... | @@ -11186,14 +11219,8 @@ fn validateSwitchBlock( |
| 11186 | operand_ty.assertHasLayout(zcu); | 11219 | operand_ty.assertHasLayout(zcu); |
| 11187 | const union_obj = ip.loadUnionType(operand_ty.toIntern()); | 11220 | const union_obj = ip.loadUnionType(operand_ty.toIntern()); |
| 11188 | switch (union_obj.tag_usage) { | 11221 | switch (union_obj.tag_usage) { |
| 11189 | .tagged => { | 11222 | .tagged => break :item_ty .fromInterned(union_obj.enum_tag_type), |
| 11190 | break :item_ty .fromInterned(union_obj.enum_tag_type); | 11223 | .none => if (union_obj.layout == .@"packed") break :item_ty operand_ty, |
| 11191 | }, | ||
| 11192 | .none => { | ||
| 11193 | if (union_obj.layout == .@"packed") { | ||
| 11194 | break :item_ty operand_ty; | ||
| 11195 | } | ||
| 11196 | }, | ||
| 11197 | .safety => {}, | 11224 | .safety => {}, |
| 11198 | } | 11225 | } |
| 11199 | return sema.failWithOwnedErrorMsg(block, msg: { | 11226 | return sema.failWithOwnedErrorMsg(block, msg: { |
| ... | @@ -11208,27 +11235,47 @@ fn validateSwitchBlock( | ... | @@ -11208,27 +11235,47 @@ fn validateSwitchBlock( |
| 11208 | 11235 | ||
| 11209 | .@"struct" => { | 11236 | .@"struct" => { |
| 11210 | operand_ty.assertHasLayout(zcu); | 11237 | operand_ty.assertHasLayout(zcu); |
| 11211 | const layout = operand_ty.containerLayout(zcu); | 11238 | if (operand_ty.containerLayout(zcu) == .@"packed") break :item_ty operand_ty; |
| 11212 | if (layout == .@"packed") { | ||
| 11213 | break :item_ty operand_ty; | ||
| 11214 | } | ||
| 11215 | return sema.failWithOwnedErrorMsg(block, msg: { | 11239 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 11216 | const msg = try sema.errMsg(operand_src, "switch on struct with {t} layout", .{layout}); | 11240 | const msg = try sema.errMsg(operand_src, "switch on non-packed struct", .{}); |
| 11217 | errdefer msg.destroy(sema.gpa); | 11241 | errdefer msg.destroy(sema.gpa); |
| 11218 | if (operand_ty.srcLocOrNull(zcu)) |struct_src| { | 11242 | try sema.addDeclaredHereNote(msg, operand_ty); |
| 11219 | try sema.errNote(struct_src, msg, "consider 'packed struct' here", .{}); | ||
| 11220 | } | ||
| 11221 | break :msg msg; | 11243 | break :msg msg; |
| 11222 | }); | 11244 | }); |
| 11223 | }, | 11245 | }, |
| 11224 | 11246 | ||
| 11225 | .pointer => { | 11247 | .pointer => if (!operand_ty.isSlice(zcu)) break :item_ty operand_ty, |
| 11226 | if (!operand_ty.isSlice(zcu)) { | ||
| 11227 | break :item_ty operand_ty; | ||
| 11228 | } | ||
| 11229 | }, | ||
| 11230 | 11248 | ||
| 11231 | else => {}, | 11249 | .optional => return sema.failWithOwnedErrorMsg(block, msg: { |
| 11250 | const msg = try sema.errMsg(operand_src, "switch on optional type '{f}'", .{ | ||
| 11251 | operand_ty.fmt(pt), | ||
| 11252 | }); | ||
| 11253 | errdefer msg.destroy(gpa); | ||
| 11254 | try sema.errNote(operand_src, msg, "consider using '.?', 'orelse', or 'if'", .{}); | ||
| 11255 | break :msg msg; | ||
| 11256 | }), | ||
| 11257 | |||
| 11258 | .error_union => return sema.failWithOwnedErrorMsg(block, msg: { | ||
| 11259 | const msg = try sema.errMsg(operand_src, "switch on error union type '{f}'", .{ | ||
| 11260 | operand_ty.fmt(pt), | ||
| 11261 | }); | ||
| 11262 | errdefer msg.destroy(gpa); | ||
| 11263 | try sema.errNote(operand_src, msg, "consider using 'try', 'catch', or 'if'", .{}); | ||
| 11264 | break :msg msg; | ||
| 11265 | }), | ||
| 11266 | |||
| 11267 | .noreturn, | ||
| 11268 | .float, | ||
| 11269 | .comptime_float, | ||
| 11270 | .array, | ||
| 11271 | .vector, | ||
| 11272 | .undefined, | ||
| 11273 | .null, | ||
| 11274 | .@"opaque", | ||
| 11275 | .frame, | ||
| 11276 | .@"anyframe", | ||
| 11277 | .spirv, | ||
| 11278 | => {}, | ||
| 11232 | } | 11279 | } |
| 11233 | return sema.fail(block, operand_src, "switch on type '{f}'", .{operand_ty.fmt(pt)}); | 11280 | return sema.fail(block, operand_src, "switch on type '{f}'", .{operand_ty.fmt(pt)}); |
| 11234 | }; | 11281 | }; |
| ... | @@ -11253,13 +11300,15 @@ fn validateSwitchBlock( | ... | @@ -11253,13 +11300,15 @@ fn validateSwitchBlock( |
| 11253 | var case_vals: std.ArrayList(Air.Inst.Ref) = try .initCapacity(arena, zir_switch.item_infos.len); | 11300 | var case_vals: std.ArrayList(Air.Inst.Ref) = try .initCapacity(arena, zir_switch.item_infos.len); |
| 11254 | 11301 | ||
| 11255 | // Duplicate checking variables later also used for `inline else`. | 11302 | // Duplicate checking variables later also used for `inline else`. |
| 11256 | var seen_enum_fields: []?LazySrcLoc = &.{}; | 11303 | var seen: ValidatedSwitchBlock.Seen = .{ |
| 11257 | var seen_errors: std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, LazySrcLoc) = .empty; | 11304 | .enum_fields = &.{}, |
| 11258 | var seen_sparse_values: std.AutoHashMapUnmanaged(InternPool.Index, LazySrcLoc) = .empty; | 11305 | .errors = .empty, |
| 11259 | var range_set: RangeSet = .empty; | 11306 | .sparse_values = .empty, |
| 11260 | var true_src: ?LazySrcLoc = null; | 11307 | .ranges = .empty, |
| 11261 | var false_src: ?LazySrcLoc = null; | 11308 | .true_src = null, |
| 11262 | var void_src: ?LazySrcLoc = null; | 11309 | .false_src = null, |
| 11310 | .void_src = null, | ||
| 11311 | }; | ||
| 11263 | 11312 | ||
| 11264 | var else_err_ty: ?Type = null; | 11313 | var else_err_ty: ?Type = null; |
| 11265 | 11314 | ||
| ... | @@ -11267,20 +11316,20 @@ fn validateSwitchBlock( | ... | @@ -11267,20 +11316,20 @@ fn validateSwitchBlock( |
| 11267 | 11316 | ||
| 11268 | switch (item_ty.zigTypeTag(zcu)) { | 11317 | switch (item_ty.zigTypeTag(zcu)) { |
| 11269 | .@"enum" => { | 11318 | .@"enum" => { |
| 11270 | seen_enum_fields = try arena.alloc(?LazySrcLoc, item_ty.enumFieldCount(zcu)); | 11319 | seen.enum_fields = try arena.alloc(?LazySrcLoc, item_ty.enumFieldCount(zcu)); |
| 11271 | @memset(seen_enum_fields, null); | 11320 | @memset(seen.enum_fields, null); |
| 11272 | // `range_set` is used for non-exhaustive enum values that do not | 11321 | // `seen.ranges` is used for non-exhaustive enum values that do not |
| 11273 | // correspond to any tags. Since this is rare, we only allocate on | 11322 | // correspond to any tags. Since this is rare, we only allocate on |
| 11274 | // demand in `validateSwitchItem`. | 11323 | // demand in `validateSwitchItem`. |
| 11275 | }, | 11324 | }, |
| 11276 | .error_set => { | 11325 | .error_set => { |
| 11277 | try seen_errors.ensureUnusedCapacity(arena, zir_switch.totalItemsLen()); | 11326 | try seen.errors.ensureUnusedCapacity(arena, zir_switch.totalItemsLen()); |
| 11278 | }, | 11327 | }, |
| 11279 | .int, .comptime_int, .@"union", .@"struct" => { | 11328 | .int, .comptime_int, .@"union", .@"struct" => { |
| 11280 | try range_set.ensureUnusedCapacity(arena, zir_switch.totalItemsLen()); | 11329 | try seen.ranges.ensureUnusedCapacity(arena, zir_switch.totalItemsLen()); |
| 11281 | }, | 11330 | }, |
| 11282 | .enum_literal, .@"fn", .pointer, .type => { | 11331 | .enum_literal, .@"fn", .pointer, .type => { |
| 11283 | try seen_sparse_values.ensureUnusedCapacity(arena, zir_switch.totalItemsLen()); | 11332 | try seen.sparse_values.ensureUnusedCapacity(arena, zir_switch.totalItemsLen()); |
| 11284 | }, | 11333 | }, |
| 11285 | .bool, .void => {}, | 11334 | .bool, .void => {}, |
| 11286 | 11335 | ||
| ... | @@ -11323,7 +11372,7 @@ fn validateSwitchBlock( | ... | @@ -11323,7 +11372,7 @@ fn validateSwitchBlock( |
| 11323 | case_vals.appendAssumeCapacity(.none); | 11372 | case_vals.appendAssumeCapacity(.none); |
| 11324 | } else { | 11373 | } else { |
| 11325 | const item, extra_index = try sema.resolveSwitchItem(block, item_src, item_ty, item_info, extra_index, switch_inst, prong_info.is_comptime_unreach); | 11374 | const item, extra_index = try sema.resolveSwitchItem(block, item_src, item_ty, item_info, extra_index, switch_inst, prong_info.is_comptime_unreach); |
| 11326 | try sema.validateSwitchItemOrRange(block, item_src, item.val, null, item_ty, seen_enum_fields, &seen_errors, &seen_sparse_values, &range_set, &true_src, &false_src, &void_src); | 11375 | try sema.validateSwitchItemOrRange(block, item_src, item.val, null, item_ty, &seen); |
| 11327 | case_vals.appendAssumeCapacity(item.ref); | 11376 | case_vals.appendAssumeCapacity(item.ref); |
| 11328 | } | 11377 | } |
| 11329 | } | 11378 | } |
| ... | @@ -11338,7 +11387,7 @@ fn validateSwitchBlock( | ... | @@ -11338,7 +11387,7 @@ fn validateSwitchBlock( |
| 11338 | const last_src = block.src(.{ .switch_case_item_range_last = range_offset }); | 11387 | const last_src = block.src(.{ .switch_case_item_range_last = range_offset }); |
| 11339 | const first_item, extra_index = try sema.resolveSwitchItem(block, first_src, item_ty, range_info[0], extra_index, switch_inst, prong_info.is_comptime_unreach); | 11388 | const first_item, extra_index = try sema.resolveSwitchItem(block, first_src, item_ty, range_info[0], extra_index, switch_inst, prong_info.is_comptime_unreach); |
| 11340 | const last_item, extra_index = try sema.resolveSwitchItem(block, last_src, item_ty, range_info[1], extra_index, switch_inst, prong_info.is_comptime_unreach); | 11389 | const last_item, extra_index = try sema.resolveSwitchItem(block, last_src, item_ty, range_info[1], extra_index, switch_inst, prong_info.is_comptime_unreach); |
| 11341 | try sema.validateSwitchItemOrRange(block, range_src, first_item.val, last_item.val, item_ty, seen_enum_fields, &seen_errors, &seen_sparse_values, &range_set, &true_src, &false_src, &void_src); | 11390 | try sema.validateSwitchItemOrRange(block, range_src, first_item.val, last_item.val, item_ty, &seen); |
| 11342 | case_vals.appendSliceAssumeCapacity(&.{ first_item.ref, last_item.ref }); | 11391 | case_vals.appendSliceAssumeCapacity(&.{ first_item.ref, last_item.ref }); |
| 11343 | } | 11392 | } |
| 11344 | } | 11393 | } |
| ... | @@ -11369,13 +11418,13 @@ fn validateSwitchBlock( | ... | @@ -11369,13 +11418,13 @@ fn validateSwitchBlock( |
| 11369 | // Validate for missing special prongs. | 11418 | // Validate for missing special prongs. |
| 11370 | switch (item_ty.zigTypeTag(zcu)) { | 11419 | switch (item_ty.zigTypeTag(zcu)) { |
| 11371 | .@"enum" => { | 11420 | .@"enum" => { |
| 11372 | const all_tags_handled = for (seen_enum_fields) |seen_src| { | 11421 | const all_tags_handled = for (seen.enum_fields) |seen_src| { |
| 11373 | if (seen_src == null) break false; | 11422 | if (seen_src == null) break false; |
| 11374 | } else true; | 11423 | } else true; |
| 11375 | 11424 | ||
| 11376 | if (has_else) { | 11425 | if (has_else) { |
| 11377 | if (all_tags_handled) { | 11426 | if (all_tags_handled) { |
| 11378 | if (item_ty.isNonexhaustiveEnum(zcu)) { | 11427 | if (operand_ty.isNonexhaustiveEnum(zcu)) { |
| 11379 | if (has_under) return sema.fail( | 11428 | if (has_under) return sema.fail( |
| 11380 | block, | 11429 | block, |
| 11381 | else_prong_src, | 11430 | else_prong_src, |
| ... | @@ -11397,7 +11446,7 @@ fn validateSwitchBlock( | ... | @@ -11397,7 +11446,7 @@ fn validateSwitchBlock( |
| 11397 | .{}, | 11446 | .{}, |
| 11398 | ); | 11447 | ); |
| 11399 | errdefer msg.destroy(sema.gpa); | 11448 | errdefer msg.destroy(sema.gpa); |
| 11400 | for (seen_enum_fields, 0..) |seen_src, i| { | 11449 | for (seen.enum_fields, 0..) |seen_src, i| { |
| 11401 | if (seen_src != null) continue; | 11450 | if (seen_src != null) continue; |
| 11402 | 11451 | ||
| 11403 | const field_name = item_ty.enumFieldName(i, zcu); | 11452 | const field_name = item_ty.enumFieldName(i, zcu); |
| ... | @@ -11449,7 +11498,7 @@ fn validateSwitchBlock( | ... | @@ -11449,7 +11498,7 @@ fn validateSwitchBlock( |
| 11449 | 11498 | ||
| 11450 | var seen_errors_from_set: u32 = 0; | 11499 | var seen_errors_from_set: u32 = 0; |
| 11451 | for (error_names.get(ip)) |error_name| { | 11500 | for (error_names.get(ip)) |error_name| { |
| 11452 | if (seen_errors.contains(error_name)) { | 11501 | if (seen.errors.contains(error_name)) { |
| 11453 | seen_errors_from_set += 1; | 11502 | seen_errors_from_set += 1; |
| 11454 | } else if (!has_else) { | 11503 | } else if (!has_else) { |
| 11455 | const msg = maybe_msg orelse blk: { | 11504 | const msg = maybe_msg orelse blk: { |
| ... | @@ -11491,7 +11540,7 @@ fn validateSwitchBlock( | ... | @@ -11491,7 +11540,7 @@ fn validateSwitchBlock( |
| 11491 | var names: InferredErrorSet.NameMap = .{}; | 11540 | var names: InferredErrorSet.NameMap = .{}; |
| 11492 | try names.ensureUnusedCapacity(sema.arena, error_names.len); | 11541 | try names.ensureUnusedCapacity(sema.arena, error_names.len); |
| 11493 | for (error_names.get(ip)) |error_name| { | 11542 | for (error_names.get(ip)) |error_name| { |
| 11494 | if (seen_errors.contains(error_name)) continue; | 11543 | if (seen.errors.contains(error_name)) continue; |
| 11495 | names.putAssumeCapacityNoClobber(error_name, {}); | 11544 | names.putAssumeCapacityNoClobber(error_name, {}); |
| 11496 | } | 11545 | } |
| 11497 | // No need to keep the hash map metadata correct; here we | 11546 | // No need to keep the hash map metadata correct; here we |
| ... | @@ -11509,7 +11558,7 @@ fn validateSwitchBlock( | ... | @@ -11509,7 +11558,7 @@ fn validateSwitchBlock( |
| 11509 | }; | 11558 | }; |
| 11510 | const min_int = try int_ty.minInt(pt, int_ty); | 11559 | const min_int = try int_ty.minInt(pt, int_ty); |
| 11511 | const max_int = try int_ty.maxInt(pt, int_ty); | 11560 | const max_int = try int_ty.maxInt(pt, int_ty); |
| 11512 | if (try range_set.spans(arena, min_int, max_int, int_ty, zcu)) { | 11561 | if (try seen.ranges.spans(arena, min_int, max_int, int_ty, zcu)) { |
| 11513 | if (has_else) { | 11562 | if (has_else) { |
| 11514 | return sema.fail( | 11563 | return sema.fail( |
| 11515 | block, | 11564 | block, |
| ... | @@ -11542,8 +11591,8 @@ fn validateSwitchBlock( | ... | @@ -11542,8 +11591,8 @@ fn validateSwitchBlock( |
| 11542 | }, | 11591 | }, |
| 11543 | .bool, .void => |type_tag| { | 11592 | .bool, .void => |type_tag| { |
| 11544 | const all_values_handled = switch (type_tag) { | 11593 | const all_values_handled = switch (type_tag) { |
| 11545 | .bool => true_src != null and false_src != null, | 11594 | .bool => seen.true_src != null and seen.false_src != null, |
| 11546 | .void => void_src != null, | 11595 | .void => seen.void_src != null, |
| 11547 | else => unreachable, | 11596 | else => unreachable, |
| 11548 | }; | 11597 | }; |
| 11549 | if (has_else) { | 11598 | if (has_else) { |
| ... | @@ -11570,13 +11619,7 @@ fn validateSwitchBlock( | ... | @@ -11570,13 +11619,7 @@ fn validateSwitchBlock( |
| 11570 | } | 11619 | } |
| 11571 | 11620 | ||
| 11572 | return .{ | 11621 | return .{ |
| 11573 | .seen_enum_fields = seen_enum_fields, | 11622 | .seen = seen, |
| 11574 | .seen_errors = seen_errors, | ||
| 11575 | .seen_ranges = range_set.ranges.slice(), | ||
| 11576 | .true_src = true_src, | ||
| 11577 | .false_src = false_src, | ||
| 11578 | .void_src = void_src, | ||
| 11579 | |||
| 11580 | .case_vals = case_vals.items, | 11623 | .case_vals = case_vals.items, |
| 11581 | .else_case = else_case, | 11624 | .else_case = else_case, |
| 11582 | .else_err_ty = else_err_ty, | 11625 | .else_err_ty = else_err_ty, |
| ... | @@ -11754,7 +11797,7 @@ fn resolveSwitchBlock( | ... | @@ -11754,7 +11797,7 @@ fn resolveSwitchBlock( |
| 11754 | .{ else_case.index, else_case.body, else_case.capture, else_case.has_tag_capture, else_case.is_inline }; | 11797 | .{ else_case.index, else_case.body, else_case.capture, else_case.has_tag_capture, else_case.is_inline }; |
| 11755 | if (err_set) try sema.maybeErrorUnwrapComptime(child_block, body, cond_ref); | 11798 | if (err_set) try sema.maybeErrorUnwrapComptime(child_block, body, cond_ref); |
| 11756 | if (tagged_union_originally) { | 11799 | if (tagged_union_originally) { |
| 11757 | for (validated_switch.seen_enum_fields, 0..) |maybe_seen, field_i| { | 11800 | for (validated_switch.seen.enum_fields, 0..) |maybe_seen, field_i| { |
| 11758 | if (maybe_seen != null) continue; | 11801 | if (maybe_seen != null) continue; |
| 11759 | if (!operand_ty.unionFieldTypeByIndex(field_i, zcu).isNoReturn(zcu)) break; | 11802 | if (!operand_ty.unionFieldTypeByIndex(field_i, zcu).isNoReturn(zcu)) break; |
| 11760 | } else { | 11803 | } else { |
| ... | @@ -12276,10 +12319,11 @@ fn analyzeSwitchPayloadCaptureTaggedUnion( | ... | @@ -12276,10 +12319,11 @@ fn analyzeSwitchPayloadCaptureTaggedUnion( |
| 12276 | dummy_captures, | 12319 | dummy_captures, |
| 12277 | .{ .override = item_srcs }, | 12320 | .{ .override = item_srcs }, |
| 12278 | ) catch |err| switch (err) { | 12321 | ) catch |err| switch (err) { |
| 12279 | error.AnalysisFail => { | 12322 | error.AlreadyReported => |e| { |
| 12280 | const msg = sema.err orelse return error.AnalysisFail; | 12323 | if (sema.err) |msg| { |
| 12281 | try sema.reparentOwnedErrorMsg(capture_src, msg, "capture group with incompatible types", .{}); | 12324 | try sema.reparentOwnedErrorMsg(capture_src, msg, "capture group with incompatible types", .{}); |
| 12282 | return error.AnalysisFail; | 12325 | } |
| 12326 | return e; | ||
| 12283 | }, | 12327 | }, |
| 12284 | else => |e| return e, | 12328 | else => |e| return e, |
| 12285 | }; | 12329 | }; |
| ... | @@ -12315,11 +12359,12 @@ fn analyzeSwitchPayloadCaptureTaggedUnion( | ... | @@ -12315,11 +12359,12 @@ fn analyzeSwitchPayloadCaptureTaggedUnion( |
| 12315 | dummy_captures, | 12359 | dummy_captures, |
| 12316 | .{ .override = item_srcs }, | 12360 | .{ .override = item_srcs }, |
| 12317 | ) catch |err| switch (err) { | 12361 | ) catch |err| switch (err) { |
| 12318 | error.AnalysisFail => { | 12362 | error.AlreadyReported => |e| { |
| 12319 | const msg = sema.err orelse return error.AnalysisFail; | 12363 | if (sema.err) |msg| { |
| 12320 | try sema.errNote(capture_src, msg, "this coercion is only possible when capturing by value", .{}); | 12364 | try sema.errNote(capture_src, msg, "this coercion is only possible when capturing by value", .{}); |
| 12321 | try sema.reparentOwnedErrorMsg(capture_src, msg, "capture group with incompatible types", .{}); | 12365 | try sema.reparentOwnedErrorMsg(capture_src, msg, "capture group with incompatible types", .{}); |
| 12322 | return error.AnalysisFail; | 12366 | } |
| 12367 | return e; | ||
| 12323 | }, | 12368 | }, |
| 12324 | else => |e| return e, | 12369 | else => |e| return e, |
| 12325 | }; | 12370 | }; |
| ... | @@ -12559,13 +12604,7 @@ fn validateSwitchItemOrRange( | ... | @@ -12559,13 +12604,7 @@ fn validateSwitchItemOrRange( |
| 12559 | item_val: Value, | 12604 | item_val: Value, |
| 12560 | opt_last_val: ?Value, | 12605 | opt_last_val: ?Value, |
| 12561 | item_ty: Type, | 12606 | item_ty: Type, |
| 12562 | seen_enum_fields: []?LazySrcLoc, | 12607 | seen: *ValidatedSwitchBlock.Seen, |
| 12563 | seen_errors: *std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, LazySrcLoc), | ||
| 12564 | seen_sparse_values: *std.AutoHashMapUnmanaged(InternPool.Index, LazySrcLoc), | ||
| 12565 | range_set: *RangeSet, | ||
| 12566 | true_src: *?LazySrcLoc, | ||
| 12567 | false_src: *?LazySrcLoc, | ||
| 12568 | void_src: *?LazySrcLoc, | ||
| 12569 | ) CompileError!void { | 12608 | ) CompileError!void { |
| 12570 | const pt = sema.pt; | 12609 | const pt = sema.pt; |
| 12571 | const zcu = pt.zcu; | 12610 | const zcu = pt.zcu; |
| ... | @@ -12574,88 +12613,117 @@ fn validateSwitchItemOrRange( | ... | @@ -12574,88 +12613,117 @@ fn validateSwitchItemOrRange( |
| 12574 | .@"enum" => { | 12613 | .@"enum" => { |
| 12575 | const int = ip.indexToKey(item_val.toIntern()).enum_tag.int; | 12614 | const int = ip.indexToKey(item_val.toIntern()).enum_tag.int; |
| 12576 | if (ip.loadEnumType(item_ty.toIntern()).tagValueIndex(ip, int)) |field_index| { | 12615 | if (ip.loadEnumType(item_ty.toIntern()).tagValueIndex(ip, int)) |field_index| { |
| 12577 | const maybe_prev_src = seen_enum_fields[field_index]; | 12616 | const maybe_prev_src = seen.enum_fields[field_index]; |
| 12578 | seen_enum_fields[field_index] = item_src; | 12617 | seen.enum_fields[field_index] = item_src; |
| 12579 | break :maybe_prev_src maybe_prev_src; | 12618 | break :maybe_prev_src maybe_prev_src; |
| 12580 | } else { | 12619 | } else { |
| 12581 | break :maybe_prev_src try range_set.add(sema.arena, .{ | 12620 | try seen.ranges.ensureUnusedCapacity(sema.arena, 1); |
| 12621 | break :maybe_prev_src if (seen.ranges.addAssumeCapacity(.{ | ||
| 12582 | .first = .fromInterned(int), | 12622 | .first = .fromInterned(int), |
| 12583 | .last = .fromInterned(int), | 12623 | .last = .fromInterned(int), |
| 12584 | .src = item_src, | 12624 | .src = item_src, |
| 12585 | }, .fromInterned(ip.typeOf(int)), zcu); | 12625 | }, .fromInterned(ip.typeOf(int)), zcu)) |prev| prev.src else null; |
| 12586 | } | 12626 | } |
| 12587 | }, | 12627 | }, |
| 12588 | .error_set => { | 12628 | .error_set => { |
| 12589 | const error_name = ip.indexToKey(item_val.toIntern()).err.name; | 12629 | const error_name = ip.indexToKey(item_val.toIntern()).err.name; |
| 12590 | break :maybe_prev_src if (seen_errors.fetchPutAssumeCapacity(error_name, item_src)) |prev| | 12630 | break :maybe_prev_src if (seen.errors.fetchPutAssumeCapacity(error_name, item_src)) |prev| |
| 12591 | prev.value | 12631 | prev.value |
| 12592 | else | 12632 | else |
| 12593 | null; | 12633 | null; |
| 12594 | }, | 12634 | }, |
| 12595 | .int, .comptime_int => { | 12635 | .int, .comptime_int => { |
| 12596 | if (opt_last_val) |last_val| { | 12636 | const first_val = item_val; |
| 12597 | const first_val = item_val; | 12637 | const last_val: Value = last_val: { |
| 12638 | const last_val = opt_last_val orelse break :last_val item_val; | ||
| 12598 | if (try first_val.compareAll(.gt, last_val, item_ty, pt)) { | 12639 | if (try first_val.compareAll(.gt, last_val, item_ty, pt)) { |
| 12599 | return sema.fail(block, item_src, "range start value is greater than the end value", .{}); | 12640 | return sema.fail(block, item_src, "range start value is greater than the end value", .{}); |
| 12600 | } | 12641 | } |
| 12601 | break :maybe_prev_src range_set.addAssumeCapacity(.{ | 12642 | break :last_val last_val; |
| 12602 | .first = first_val, | 12643 | }; |
| 12603 | .last = last_val, | 12644 | if (seen.ranges.addAssumeCapacity(.{ |
| 12604 | .src = item_src, | 12645 | .first = first_val, |
| 12605 | }, item_ty, zcu); | 12646 | .last = last_val, |
| 12606 | } else { | 12647 | .src = item_src, |
| 12607 | break :maybe_prev_src range_set.addAssumeCapacity(.{ | 12648 | }, item_ty, zcu)) |prev_range| { |
| 12608 | .first = item_val, | 12649 | const overlap_start = first_val.numberMax(prev_range.first, zcu); |
| 12609 | .last = item_val, | 12650 | const overlap_end = last_val.numberMin(prev_range.last, zcu); |
| 12610 | .src = item_src, | 12651 | if (overlap_start.eql(overlap_end, item_ty, zcu)) { |
| 12611 | }, item_ty, zcu); | 12652 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 12653 | const msg = try sema.errMsg(item_src, "duplicate switch value '{f}'", .{ | ||
| 12654 | overlap_start.fmtValueSema(pt, sema), | ||
| 12655 | }); | ||
| 12656 | errdefer msg.destroy(sema.gpa); | ||
| 12657 | if (prev_range.first.eql(prev_range.last, item_ty, zcu)) { | ||
| 12658 | try sema.errNote(prev_range.src, msg, "previous value here", .{}); | ||
| 12659 | } else { | ||
| 12660 | try sema.errNote(prev_range.src, msg, "previous value inside range here", .{}); | ||
| 12661 | } | ||
| 12662 | break :msg msg; | ||
| 12663 | }); | ||
| 12664 | } | ||
| 12665 | assert(!prev_range.first.eql(prev_range.last, item_ty, zcu)); | ||
| 12666 | return sema.failWithOwnedErrorMsg(block, msg: { | ||
| 12667 | const msg = try sema.errMsg(item_src, "duplicate switch ranges", .{}); | ||
| 12668 | errdefer msg.destroy(sema.gpa); | ||
| 12669 | if (first_val.eql(prev_range.first, item_ty, zcu) and | ||
| 12670 | last_val.eql(prev_range.last, item_ty, zcu)) | ||
| 12671 | { | ||
| 12672 | try sema.errNote(prev_range.src, msg, "previous range here", .{}); | ||
| 12673 | } else { | ||
| 12674 | try sema.errNote(prev_range.src, msg, "overlaps with previous range here", .{}); | ||
| 12675 | try sema.errNote(prev_range.src, msg, "ranges overlap from '{f}' to '{f}'", .{ | ||
| 12676 | overlap_start.fmtValueSema(pt, sema), overlap_end.fmtValueSema(pt, sema), | ||
| 12677 | }); | ||
| 12678 | } | ||
| 12679 | break :msg msg; | ||
| 12680 | }); | ||
| 12612 | } | 12681 | } |
| 12682 | break :maybe_prev_src null; | ||
| 12613 | }, | 12683 | }, |
| 12614 | .@"union", .@"struct" => { | 12684 | .@"union", .@"struct" => { |
| 12615 | const backing_int_val = ip.indexToKey(item_val.toIntern()).bitpack.backing_int_val; | 12685 | const backing_int_val = ip.indexToKey(item_val.toIntern()).bitpack.backing_int_val; |
| 12616 | break :maybe_prev_src range_set.addAssumeCapacity(.{ | 12686 | break :maybe_prev_src if (seen.ranges.addAssumeCapacity(.{ |
| 12617 | .first = .fromInterned(backing_int_val), | 12687 | .first = .fromInterned(backing_int_val), |
| 12618 | .last = .fromInterned(backing_int_val), | 12688 | .last = .fromInterned(backing_int_val), |
| 12619 | .src = item_src, | 12689 | .src = item_src, |
| 12620 | }, item_ty.backingIntType(zcu), zcu); | 12690 | }, item_ty.backingIntType(zcu), zcu)) |prev| prev.src else null; |
| 12621 | }, | 12691 | }, |
| 12622 | .enum_literal, .@"fn", .pointer, .type => { | 12692 | .enum_literal, .@"fn", .pointer, .type => { |
| 12623 | break :maybe_prev_src if (seen_sparse_values.fetchPutAssumeCapacity(item_val.toIntern(), item_src)) |prev| | 12693 | break :maybe_prev_src if (seen.sparse_values.fetchPutAssumeCapacity(item_val.toIntern(), item_src)) |prev| |
| 12624 | prev.value | 12694 | prev.value |
| 12625 | else | 12695 | else |
| 12626 | null; | 12696 | null; |
| 12627 | }, | 12697 | }, |
| 12628 | .bool => { | 12698 | .bool => { |
| 12629 | if (item_val.toBool()) { | 12699 | if (item_val.toBool()) { |
| 12630 | if (true_src.*) |prev_src| break :maybe_prev_src prev_src; | 12700 | if (seen.true_src) |prev_src| break :maybe_prev_src prev_src; |
| 12631 | true_src.* = item_src; | 12701 | seen.true_src = item_src; |
| 12632 | } else { | 12702 | } else { |
| 12633 | if (false_src.*) |prev_src| break :maybe_prev_src prev_src; | 12703 | if (seen.false_src) |prev_src| break :maybe_prev_src prev_src; |
| 12634 | false_src.* = item_src; | 12704 | seen.false_src = item_src; |
| 12635 | } | 12705 | } |
| 12636 | break :maybe_prev_src null; | 12706 | break :maybe_prev_src null; |
| 12637 | }, | 12707 | }, |
| 12638 | .void => { | 12708 | .void => { |
| 12639 | if (void_src.*) |prev_src| break :maybe_prev_src prev_src; | 12709 | if (seen.void_src) |prev_src| break :maybe_prev_src prev_src; |
| 12640 | void_src.* = item_src; | 12710 | seen.void_src = item_src; |
| 12641 | break :maybe_prev_src null; | 12711 | break :maybe_prev_src null; |
| 12642 | }, | 12712 | }, |
| 12643 | else => unreachable, // should have already checked for invalid types | 12713 | else => unreachable, // should have already checked for invalid types |
| 12644 | }; | 12714 | }; |
| 12645 | if (maybe_prev_src) |prev_src| { | 12715 | if (maybe_prev_src) |prev_src| { |
| 12646 | return sema.failWithOwnedErrorMsg(block, msg: { | 12716 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 12647 | const msg = try sema.errMsg( | 12717 | const msg = try sema.errMsg(item_src, "duplicate switch value '{f}'", .{ |
| 12648 | item_src, | 12718 | item_val.fmtValueSema(pt, sema), |
| 12649 | "duplicate switch value", | 12719 | }); |
| 12650 | .{}, | ||
| 12651 | ); | ||
| 12652 | errdefer msg.destroy(sema.gpa); | 12720 | errdefer msg.destroy(sema.gpa); |
| 12653 | try sema.errNote( | 12721 | try sema.errNote(prev_src, msg, "previous value here", .{}); |
| 12654 | prev_src, | 12722 | if (item_ty.zigTypeTag(zcu) == .type) { |
| 12655 | msg, | 12723 | try sema.addDeclaredHereNote(msg, item_val.toType()); |
| 12656 | "previous value here", | 12724 | } else { |
| 12657 | .{}, | 12725 | try sema.addDeclaredHereNote(msg, item_ty); |
| 12658 | ); | 12726 | } |
| 12659 | break :msg msg; | 12727 | break :msg msg; |
| 12660 | }); | 12728 | }); |
| 12661 | } | 12729 | } |
| ... | @@ -17171,7 +17239,14 @@ fn typeInfoNamespaceDecls( | ... | @@ -17171,7 +17239,14 @@ fn typeInfoNamespaceDecls( |
| 17171 | const ip = &zcu.intern_pool; | 17239 | const ip = &zcu.intern_pool; |
| 17172 | 17240 | ||
| 17173 | const namespace_index = opt_namespace_index.unwrap() orelse return; | 17241 | const namespace_index = opt_namespace_index.unwrap() orelse return; |
| 17174 | try pt.ensureNamespaceUpToDate(namespace_index); | 17242 | pt.ensureNamespaceUpToDate(namespace_index) catch |err| switch (err) { |
| 17243 | error.LostZirContainerDecl => { | ||
| 17244 | const namespace = zcu.namespacePtr(namespace_index); | ||
| 17245 | const ns_ty: Type = .fromInterned(namespace.owner_type); | ||
| 17246 | return sema.failTransitive(.{ .lost_tracking = ns_ty.typeDeclInstAllowGeneratedTag(zcu).? }); | ||
| 17247 | }, | ||
| 17248 | else => |e| return e, | ||
| 17249 | }; | ||
| 17175 | const namespace = zcu.namespacePtr(namespace_index); | 17250 | const namespace = zcu.namespacePtr(namespace_index); |
| 17176 | 17251 | ||
| 17177 | const gop = try seen_namespaces.getOrPut(namespace); | 17252 | const gop = try seen_namespaces.getOrPut(namespace); |
| ... | @@ -17897,11 +17972,12 @@ fn zirUnreachable(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -17897,11 +17972,12 @@ fn zirUnreachable(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 17897 | } | 17972 | } |
| 17898 | // TODO Add compile error for @optimizeFor occurring too late in a scope. | 17973 | // TODO Add compile error for @optimizeFor occurring too late in a scope. |
| 17899 | sema.analyzeUnreachable(block, src, true) catch |err| switch (err) { | 17974 | sema.analyzeUnreachable(block, src, true) catch |err| switch (err) { |
| 17900 | error.AnalysisFail => { | 17975 | error.AlreadyReported => |e| { |
| 17901 | const msg = sema.err orelse return err; | 17976 | if (sema.err) |msg| { |
| 17902 | if (!mem.eql(u8, msg.msg, "runtime safety check not allowed in naked function")) return err; | 17977 | if (!mem.eql(u8, msg.msg, "runtime safety check not allowed in naked function")) return err; |
| 17903 | try sema.errNote(src, msg, "the end of a naked function is implicitly unreachable", .{}); | 17978 | try sema.errNote(src, msg, "the end of a naked function is implicitly unreachable", .{}); |
| 17904 | return err; | 17979 | } |
| 17980 | return e; | ||
| 17905 | }, | 17981 | }, |
| 17906 | else => |e| return e, | 17982 | else => |e| return e, |
| 17907 | }; | 17983 | }; |
| ... | @@ -18317,11 +18393,16 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -18317,11 +18393,16 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 18317 | 18393 | ||
| 18318 | const elem_ty = blk: { | 18394 | const elem_ty = blk: { |
| 18319 | const air_inst = sema.resolveInst(extra.data.elem_type); | 18395 | const air_inst = sema.resolveInst(extra.data.elem_type); |
| 18320 | const ty = sema.analyzeAsType(block, elem_ty_src, .type, air_inst) catch |err| { | 18396 | const ty = sema.analyzeAsType(block, elem_ty_src, .type, air_inst) catch |err| switch (err) { |
| 18321 | if (err == error.AnalysisFail and sema.err != null and sema.typeOf(air_inst).isSinglePointer(zcu)) { | 18397 | error.AlreadyReported => |e| { |
| 18322 | try sema.errNote(elem_ty_src, sema.err.?, "use '.*' to dereference pointer", .{}); | 18398 | if (sema.err) |msg| { |
| 18323 | } | 18399 | if (sema.typeOf(air_inst).isSinglePointer(zcu)) { |
| 18324 | return err; | 18400 | try sema.errNote(elem_ty_src, msg, "use '.*' to dereference pointer", .{}); |
| 18401 | } | ||
| 18402 | } | ||
| 18403 | return e; | ||
| 18404 | }, | ||
| 18405 | else => |e| return e, | ||
| 18325 | }; | 18406 | }; |
| 18326 | assert(!ty.isGenericPoison()); | 18407 | assert(!ty.isGenericPoison()); |
| 18327 | break :blk ty; | 18408 | break :blk ty; |
| ... | @@ -21103,7 +21184,10 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro | ... | @@ -21103,7 +21184,10 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 21103 | const dest_scalar_ty = dest_ty.scalarType(zcu); | 21184 | const dest_scalar_ty = dest_ty.scalarType(zcu); |
| 21104 | const operand_scalar_ty = operand_ty.scalarType(zcu); | 21185 | const operand_scalar_ty = operand_ty.scalarType(zcu); |
| 21105 | 21186 | ||
| 21106 | _ = try sema.checkIntType(block, src, dest_scalar_ty); | 21187 | switch (dest_scalar_ty.zigTypeTag(zcu)) { |
| 21188 | .comptime_int, .int => {}, | ||
| 21189 | else => return sema.fail(block, src, "expected integer result type, found '{f}'", .{dest_scalar_ty.fmt(pt)}), | ||
| 21190 | } | ||
| 21107 | try sema.checkFloatType(block, operand_src, operand_scalar_ty); | 21191 | try sema.checkFloatType(block, operand_src, operand_scalar_ty); |
| 21108 | 21192 | ||
| 21109 | if (sema.resolveValue(operand)) |operand_val| { | 21193 | if (sema.resolveValue(operand)) |operand_val| { |
| ... | @@ -21279,7 +21363,10 @@ fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro | ... | @@ -21279,7 +21363,10 @@ fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 21279 | const dest_scalar_ty = dest_ty.scalarType(zcu); | 21363 | const dest_scalar_ty = dest_ty.scalarType(zcu); |
| 21280 | const operand_scalar_ty = operand_ty.scalarType(zcu); | 21364 | const operand_scalar_ty = operand_ty.scalarType(zcu); |
| 21281 | 21365 | ||
| 21282 | try sema.checkFloatType(block, src, dest_scalar_ty); | 21366 | switch (dest_scalar_ty.zigTypeTag(zcu)) { |
| 21367 | .comptime_float, .float => {}, | ||
| 21368 | else => return sema.fail(block, src, "expected float result type, found '{f}'", .{dest_scalar_ty.fmt(pt)}), | ||
| 21369 | } | ||
| 21283 | _ = try sema.checkIntType(block, operand_src, operand_scalar_ty); | 21370 | _ = try sema.checkIntType(block, operand_src, operand_scalar_ty); |
| 21284 | 21371 | ||
| 21285 | if (sema.resolveValue(operand)) |operand_val| { | 21372 | if (sema.resolveValue(operand)) |operand_val| { |
| ... | @@ -21594,16 +21681,16 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData | ... | @@ -21594,16 +21681,16 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData |
| 21594 | const is_zero = try block.addBinOp(.cmp_eq, err_int_inst, zero_err); | 21681 | const is_zero = try block.addBinOp(.cmp_eq, err_int_inst, zero_err); |
| 21595 | if (result == .disjoint) { | 21682 | if (result == .disjoint) { |
| 21596 | // Error must be zero. | 21683 | // Error must be zero. |
| 21597 | try sema.addSafetyCheck(block, src, is_zero, .invalid_error_code); | 21684 | try sema.addSafetyCheckCall(block, src, is_zero, .@"panic.unexpectedErrorCode", &.{err_code_inst}); |
| 21598 | } else { | 21685 | } else { |
| 21599 | // Error must be in destination set or zero. | 21686 | // Error must be in destination set or zero. |
| 21600 | const has_value = try block.addTyOp(.error_set_has_value, dest_err_ty, err_int_inst); | 21687 | const has_value = try block.addTyOp(.error_set_has_value, dest_err_ty, err_int_inst); |
| 21601 | const ok = try block.addBinOp(.bit_or, has_value, is_zero); | 21688 | const ok = try block.addBinOp(.bit_or, has_value, is_zero); |
| 21602 | try sema.addSafetyCheck(block, src, ok, .invalid_error_code); | 21689 | try sema.addSafetyCheckCall(block, src, ok, .@"panic.unexpectedErrorCode", &.{err_code_inst}); |
| 21603 | } | 21690 | } |
| 21604 | } else { | 21691 | } else { |
| 21605 | const ok = try block.addTyOp(.error_set_has_value, dest_err_ty, err_int_inst); | 21692 | const ok = try block.addTyOp(.error_set_has_value, dest_err_ty, err_int_inst); |
| 21606 | try sema.addSafetyCheck(block, src, ok, .invalid_error_code); | 21693 | try sema.addSafetyCheckCall(block, src, ok, .@"panic.unexpectedErrorCode", &.{err_code_inst}); |
| 21607 | } | 21694 | } |
| 21608 | } | 21695 | } |
| 21609 | 21696 | ||
| ... | @@ -23460,7 +23547,9 @@ fn analyzeShuffle( | ... | @@ -23460,7 +23547,9 @@ fn analyzeShuffle( |
| 23460 | // `InternPool.Index` values using the known operands. | 23547 | // `InternPool.Index` values using the known operands. |
| 23461 | for (mask_shuffle_two, mask_ip_index) |in, *out| { | 23548 | for (mask_shuffle_two, mask_ip_index) |in, *out| { |
| 23462 | const val: Value = switch (in.unwrap()) { | 23549 | const val: Value = switch (in.unwrap()) { |
| 23463 | .undef => try pt.undefValue(elem_ty), | 23550 | // Special case zero bit types: there is no undefined value for OPV elements. |
| 23551 | // Only affects the case where `!a_rt and !b_rt` since `a_coerced` and `b_coerced`'s types are also OPV for OPV elements. | ||
| 23552 | .undef => try elem_ty.onePossibleValue(pt) orelse try pt.undefValue(elem_ty), | ||
| 23464 | .a_elem => |idx| try maybe_a_val.?.elemValue(pt, idx), | 23553 | .a_elem => |idx| try maybe_a_val.?.elemValue(pt, idx), |
| 23465 | .b_elem => |idx| try maybe_b_val.?.elemValue(pt, idx), | 23554 | .b_elem => |idx| try maybe_b_val.?.elemValue(pt, idx), |
| 23466 | }; | 23555 | }; |
| ... | @@ -23509,6 +23598,9 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C | ... | @@ -23509,6 +23598,9 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C |
| 23509 | const a = try sema.coerce(block, vec_ty, sema.resolveInst(extra.a), a_src); | 23598 | const a = try sema.coerce(block, vec_ty, sema.resolveInst(extra.a), a_src); |
| 23510 | const b = try sema.coerce(block, vec_ty, sema.resolveInst(extra.b), b_src); | 23599 | const b = try sema.coerce(block, vec_ty, sema.resolveInst(extra.b), b_src); |
| 23511 | 23600 | ||
| 23601 | // special case zero bit types | ||
| 23602 | if (try vec_ty.onePossibleValue(pt)) |opv| return .fromValue(opv); | ||
| 23603 | |||
| 23512 | const maybe_pred = sema.resolveValue(pred); | 23604 | const maybe_pred = sema.resolveValue(pred); |
| 23513 | const maybe_a = sema.resolveValue(a); | 23605 | const maybe_a = sema.resolveValue(a); |
| 23514 | const maybe_b = sema.resolveValue(b); | 23606 | const maybe_b = sema.resolveValue(b); |
| ... | @@ -24873,7 +24965,10 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -24873,7 +24965,10 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 24873 | } else cc: { | 24965 | } else cc: { |
| 24874 | if (has_body) { | 24966 | if (has_body) { |
| 24875 | const func_decl_nav = sema.owner.unwrap().nav_val; | 24967 | const func_decl_nav = sema.owner.unwrap().nav_val; |
| 24876 | const func_decl_inst = ip.getNav(func_decl_nav).analysis.?.zir_index.resolve(&zcu.intern_pool) orelse return error.AnalysisFail; | 24968 | const func_decl_ti = ip.getNav(func_decl_nav).analysis.?.zir_index; |
| 24969 | const func_decl_inst = func_decl_ti.resolve(&zcu.intern_pool) orelse { | ||
| 24970 | return sema.failTransitive(.{ .lost_tracking = func_decl_ti }); | ||
| 24971 | }; | ||
| 24877 | const zir_decl = sema.code.getDeclaration(func_decl_inst); | 24972 | const zir_decl = sema.code.getDeclaration(func_decl_inst); |
| 24878 | if (zir_decl.linkage == .@"export") { | 24973 | if (zir_decl.linkage == .@"export") { |
| 24879 | break :cc target.cCallingConvention() orelse { | 24974 | break :cc target.cCallingConvention() orelse { |
| ... | @@ -25458,10 +25553,10 @@ fn zirRoundOpType(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDa | ... | @@ -25458,10 +25553,10 @@ fn zirRoundOpType(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDa |
| 25458 | return .generic_poison_type; | 25553 | return .generic_poison_type; |
| 25459 | }; | 25554 | }; |
| 25460 | 25555 | ||
| 25461 | const float_ty = dest_ty.optEuBaseType(zcu); | 25556 | const dest_base_ty = dest_ty.optEuBaseType(zcu); |
| 25462 | switch (float_ty.scalarType(zcu).zigTypeTag(zcu)) { | 25557 | switch (dest_base_ty.scalarType(zcu).zigTypeTag(zcu)) { |
| 25463 | .float, .comptime_float => return .fromType(float_ty), | 25558 | .float, .comptime_float => return .fromType(dest_base_ty), |
| 25464 | else => return .comptime_float_type, | 25559 | else => return .generic_poison_type, |
| 25465 | } | 25560 | } |
| 25466 | } | 25561 | } |
| 25467 | 25562 | ||
| ... | @@ -25640,7 +25735,6 @@ pub fn explainWhyTypeIsNotExtern( | ... | @@ -25640,7 +25735,6 @@ pub fn explainWhyTypeIsNotExtern( |
| 25640 | 25735 | ||
| 25641 | .@"opaque", | 25736 | .@"opaque", |
| 25642 | .bool, | 25737 | .bool, |
| 25643 | .float, | ||
| 25644 | .@"anyframe", | 25738 | .@"anyframe", |
| 25645 | => unreachable, // these *are* allowed | 25739 | => unreachable, // these *are* allowed |
| 25646 | 25740 | ||
| ... | @@ -25649,6 +25743,7 @@ pub fn explainWhyTypeIsNotExtern( | ... | @@ -25649,6 +25743,7 @@ pub fn explainWhyTypeIsNotExtern( |
| 25649 | try sema.errNote(src_loc, msg, "SPIR-V runtime arrays must be the last field of an extern struct", .{}); | 25743 | try sema.errNote(src_loc, msg, "SPIR-V runtime arrays must be the last field of an extern struct", .{}); |
| 25650 | }, | 25744 | }, |
| 25651 | 25745 | ||
| 25746 | .float => try sema.errNote(src_loc, msg, "'{f}' is not extern compatible on this target", .{ty.fmt(pt)}), | ||
| 25652 | .pointer => if (ty.isSlice(zcu)) { | 25747 | .pointer => if (ty.isSlice(zcu)) { |
| 25653 | try sema.errNote(src_loc, msg, "slices have no guaranteed in-memory representation", .{}); | 25748 | try sema.errNote(src_loc, msg, "slices have no guaranteed in-memory representation", .{}); |
| 25654 | } else { | 25749 | } else { |
| ... | @@ -28174,9 +28269,94 @@ fn coerceExtra( | ... | @@ -28174,9 +28269,94 @@ fn coerceExtra( |
| 28174 | }, | 28269 | }, |
| 28175 | else => {}, | 28270 | else => {}, |
| 28176 | }, | 28271 | }, |
| 28177 | .one => {}, | 28272 | // []T to *[n]T |
| 28273 | .one => slice_to_array_ptr: { | ||
| 28274 | if (!inst_ty.isSlice(zcu)) break :slice_to_array_ptr; | ||
| 28275 | if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :slice_to_array_ptr; | ||
| 28276 | const array_ty: Type = .fromInterned(dest_info.child); | ||
| 28277 | if (array_ty.zigTypeTag(zcu) != .array) break :slice_to_array_ptr; | ||
| 28278 | const inst_val = maybe_inst_val orelse { | ||
| 28279 | if (!opts.report_err) return error.NotCoercible; | ||
| 28280 | return sema.fail( | ||
| 28281 | block, | ||
| 28282 | inst_src, | ||
| 28283 | "coercion from slice to array pointer type '{f}' requires length to be known at compile-time", | ||
| 28284 | .{dest_ty.fmt(pt)}, | ||
| 28285 | ); | ||
| 28286 | }; | ||
| 28287 | |||
| 28288 | const slice: InternPool.Key.Slice = slice: { | ||
| 28289 | switch (ip.indexToKey(inst_val.toIntern())) { | ||
| 28290 | .undef => {}, | ||
| 28291 | .slice => |slice| if (slice.len != .undef_usize) break :slice slice, | ||
| 28292 | else => unreachable, | ||
| 28293 | } | ||
| 28294 | if (!opts.report_err) return error.NotCoercible; | ||
| 28295 | return sema.failWithOwnedErrorMsg(block, msg: { | ||
| 28296 | const msg = try sema.errMsg(inst_src, "slice with undefined length cannot cast into array pointer type '{f}'", .{ | ||
| 28297 | dest_ty.fmt(pt), | ||
| 28298 | }); | ||
| 28299 | errdefer msg.destroy(gpa); | ||
| 28300 | try sema.errNote(inst_src, msg, "length of slice must be defined and match length of array type", .{}); | ||
| 28301 | break :msg msg; | ||
| 28302 | }); | ||
| 28303 | }; | ||
| 28304 | const slice_len = Value.fromInterned(slice.len).toUnsignedInt(zcu); | ||
| 28305 | if (array_ty.arrayLen(zcu) != slice_len) { | ||
| 28306 | if (!opts.report_err) return error.NotCoercible; | ||
| 28307 | return sema.failWithOwnedErrorMsg(block, msg: { | ||
| 28308 | const msg = try sema.errMsg(inst_src, "slice of length {d} cannot cast into array pointer type '{f}'", .{ | ||
| 28309 | slice_len, dest_ty.fmt(pt), | ||
| 28310 | }); | ||
| 28311 | errdefer msg.destroy(gpa); | ||
| 28312 | try sema.errNote(inst_src, msg, "length of slice must match length of array type", .{}); | ||
| 28313 | break :msg msg; | ||
| 28314 | }); | ||
| 28315 | } | ||
| 28316 | |||
| 28317 | const inst_elem_ty = inst_ty.childType(zcu); | ||
| 28318 | const dest_elem_ty = array_ty.childType(zcu); | ||
| 28319 | const dest_is_mut = !dest_info.flags.is_const; | ||
| 28320 | switch (try sema.coerceInMemoryAllowed(block, dest_elem_ty, inst_elem_ty, dest_is_mut, target, dest_ty_src, inst_src, null)) { | ||
| 28321 | .ok => {}, | ||
| 28322 | else => |elem_res| { | ||
| 28323 | in_memory_result = .{ .ptr_child = .{ | ||
| 28324 | .child = try elem_res.dupe(sema.arena), | ||
| 28325 | .actual = inst_elem_ty, | ||
| 28326 | .wanted = dest_elem_ty, | ||
| 28327 | } }; | ||
| 28328 | break :slice_to_array_ptr; | ||
| 28329 | }, | ||
| 28330 | } | ||
| 28331 | |||
| 28332 | if (array_ty.sentinel(zcu)) |array_sentinel| { | ||
| 28333 | if (inst_ty.sentinel(zcu)) |slice_sentinel| { | ||
| 28334 | if (array_sentinel.toIntern() != | ||
| 28335 | (try pt.getCoerced(slice_sentinel, dest_elem_ty)).toIntern()) | ||
| 28336 | { | ||
| 28337 | in_memory_result = .{ .ptr_sentinel = .{ | ||
| 28338 | .actual = slice_sentinel, | ||
| 28339 | .wanted = array_sentinel, | ||
| 28340 | .ty = dest_elem_ty, | ||
| 28341 | } }; | ||
| 28342 | break :slice_to_array_ptr; | ||
| 28343 | } | ||
| 28344 | } else { | ||
| 28345 | in_memory_result = .{ .ptr_sentinel = .{ | ||
| 28346 | .actual = .@"unreachable", | ||
| 28347 | .wanted = array_sentinel, | ||
| 28348 | .ty = dest_elem_ty, | ||
| 28349 | } }; | ||
| 28350 | break :slice_to_array_ptr; | ||
| 28351 | } | ||
| 28352 | } | ||
| 28353 | |||
| 28354 | const array_ptr = try pt.sliceToArrayPtr(slice); | ||
| 28355 | return sema.coerceCompatiblePtrs(block, dest_ty, .fromValue(array_ptr), inst_src); | ||
| 28356 | }, | ||
| 28178 | .slice => to_slice: { | 28357 | .slice => to_slice: { |
| 28179 | if (inst_ty.zigTypeTag(zcu) == .array) { | 28358 | if (inst_ty.zigTypeTag(zcu) == .array) { |
| 28359 | if (!opts.report_err) return error.NotCoercible; | ||
| 28180 | return sema.fail( | 28360 | return sema.fail( |
| 28181 | block, | 28361 | block, |
| 28182 | inst_src, | 28362 | inst_src, |
| ... | @@ -28204,6 +28384,7 @@ fn coerceExtra( | ... | @@ -28204,6 +28384,7 @@ fn coerceExtra( |
| 28204 | 28384 | ||
| 28205 | // pointer to tuple to slice | 28385 | // pointer to tuple to slice |
| 28206 | if (!dest_info.flags.is_const) { | 28386 | if (!dest_info.flags.is_const) { |
| 28387 | if (!opts.report_err) return error.NotCoercible; | ||
| 28207 | const err_msg = err_msg: { | 28388 | const err_msg = err_msg: { |
| 28208 | const err_msg = try sema.errMsg(inst_src, "cannot cast pointer to tuple to '{f}'", .{dest_ty.fmt(pt)}); | 28389 | const err_msg = try sema.errMsg(inst_src, "cannot cast pointer to tuple to '{f}'", .{dest_ty.fmt(pt)}); |
| 28209 | errdefer err_msg.destroy(sema.gpa); | 28390 | errdefer err_msg.destroy(sema.gpa); |
| ... | @@ -28299,6 +28480,7 @@ fn coerceExtra( | ... | @@ -28299,6 +28480,7 @@ fn coerceExtra( |
| 28299 | if (maybe_inst_val) |val| { | 28480 | if (maybe_inst_val) |val| { |
| 28300 | const result_val = try val.floatCast(dest_ty, pt); | 28481 | const result_val = try val.floatCast(dest_ty, pt); |
| 28301 | if (!val.eql(try result_val.floatCast(inst_ty, pt), inst_ty, zcu)) { | 28482 | if (!val.eql(try result_val.floatCast(inst_ty, pt), inst_ty, zcu)) { |
| 28483 | if (!opts.report_err) return error.NotCoercible; | ||
| 28302 | return sema.fail( | 28484 | return sema.fail( |
| 28303 | block, | 28485 | block, |
| 28304 | inst_src, | 28486 | inst_src, |
| ... | @@ -28356,12 +28538,15 @@ fn coerceExtra( | ... | @@ -28356,12 +28538,15 @@ fn coerceExtra( |
| 28356 | break :fits result_big_int.toConst().eql(operand_big_int); | 28538 | break :fits result_big_int.toConst().eql(operand_big_int); |
| 28357 | }, | 28539 | }, |
| 28358 | }; | 28540 | }; |
| 28359 | if (!fits) return sema.fail( | 28541 | if (!fits) { |
| 28360 | block, | 28542 | if (!opts.report_err) return error.NotCoercible; |
| 28361 | inst_src, | 28543 | return sema.fail( |
| 28362 | "type '{f}' cannot represent integer value '{f}'", | 28544 | block, |
| 28363 | .{ dest_ty.fmt(pt), val.fmtValue(pt) }, | 28545 | inst_src, |
| 28364 | ); | 28546 | "type '{f}' cannot represent integer value '{f}'", |
| 28547 | .{ dest_ty.fmt(pt), val.fmtValue(pt) }, | ||
| 28548 | ); | ||
| 28549 | } | ||
| 28365 | return .fromValue(result_val); | 28550 | return .fromValue(result_val); |
| 28366 | }, | 28551 | }, |
| 28367 | else => {}, | 28552 | else => {}, |
| ... | @@ -28372,6 +28557,7 @@ fn coerceExtra( | ... | @@ -28372,6 +28557,7 @@ fn coerceExtra( |
| 28372 | const val = sema.resolveValue(inst).?; | 28557 | const val = sema.resolveValue(inst).?; |
| 28373 | const string = zcu.intern_pool.indexToKey(val.toIntern()).enum_literal; | 28558 | const string = zcu.intern_pool.indexToKey(val.toIntern()).enum_literal; |
| 28374 | const field_index = dest_ty.enumFieldIndex(string, zcu) orelse { | 28559 | const field_index = dest_ty.enumFieldIndex(string, zcu) orelse { |
| 28560 | if (!opts.report_err) return error.NotCoercible; | ||
| 28375 | return sema.fail(block, inst_src, "no field named '{f}' in enum '{f}'", .{ | 28561 | return sema.fail(block, inst_src, "no field named '{f}' in enum '{f}'", .{ |
| 28376 | string.fmt(&zcu.intern_pool), dest_ty.fmt(pt), | 28562 | string.fmt(&zcu.intern_pool), dest_ty.fmt(pt), |
| 28377 | }); | 28563 | }); |
| ... | @@ -29622,7 +29808,7 @@ fn coerceVarArgParam( | ... | @@ -29622,7 +29808,7 @@ fn coerceVarArgParam( |
| 29622 | .array => return sema.fail(block, inst_src, "arrays must be passed by reference to variadic function", .{}), | 29808 | .array => return sema.fail(block, inst_src, "arrays must be passed by reference to variadic function", .{}), |
| 29623 | .float => float: { | 29809 | .float => float: { |
| 29624 | const target = zcu.getTarget(); | 29810 | const target = zcu.getTarget(); |
| 29625 | const double_bits = target.cTypeBitSize(.double); | 29811 | const double_bits = target.cTypeBitSize(.double) orelse break :float inst; |
| 29626 | const inst_bits = uncasted_ty.floatBits(target); | 29812 | const inst_bits = uncasted_ty.floatBits(target); |
| 29627 | if (inst_bits >= double_bits) break :float inst; | 29813 | if (inst_bits >= double_bits) break :float inst; |
| 29628 | switch (double_bits) { | 29814 | switch (double_bits) { |
| ... | @@ -29638,21 +29824,21 @@ fn coerceVarArgParam( | ... | @@ -29638,21 +29824,21 @@ fn coerceVarArgParam( |
| 29638 | if (uncasted_info.bits <= target.cTypeBitSize(switch (uncasted_info.signedness) { | 29824 | if (uncasted_info.bits <= target.cTypeBitSize(switch (uncasted_info.signedness) { |
| 29639 | .signed => .int, | 29825 | .signed => .int, |
| 29640 | .unsigned => .uint, | 29826 | .unsigned => .uint, |
| 29641 | })) break :int try sema.coerce(block, switch (uncasted_info.signedness) { | 29827 | }) orelse break :int inst) break :int try sema.coerce(block, switch (uncasted_info.signedness) { |
| 29642 | .signed => .c_int, | 29828 | .signed => .c_int, |
| 29643 | .unsigned => .c_uint, | 29829 | .unsigned => .c_uint, |
| 29644 | }, inst, inst_src); | 29830 | }, inst, inst_src); |
| 29645 | if (uncasted_info.bits <= target.cTypeBitSize(switch (uncasted_info.signedness) { | 29831 | if (uncasted_info.bits <= target.cTypeBitSize(switch (uncasted_info.signedness) { |
| 29646 | .signed => .long, | 29832 | .signed => .long, |
| 29647 | .unsigned => .ulong, | 29833 | .unsigned => .ulong, |
| 29648 | })) break :int try sema.coerce(block, switch (uncasted_info.signedness) { | 29834 | }).?) break :int try sema.coerce(block, switch (uncasted_info.signedness) { |
| 29649 | .signed => .c_long, | 29835 | .signed => .c_long, |
| 29650 | .unsigned => .c_ulong, | 29836 | .unsigned => .c_ulong, |
| 29651 | }, inst, inst_src); | 29837 | }, inst, inst_src); |
| 29652 | if (uncasted_info.bits <= target.cTypeBitSize(switch (uncasted_info.signedness) { | 29838 | if (uncasted_info.bits <= target.cTypeBitSize(switch (uncasted_info.signedness) { |
| 29653 | .signed => .longlong, | 29839 | .signed => .longlong, |
| 29654 | .unsigned => .ulonglong, | 29840 | .unsigned => .ulonglong, |
| 29655 | })) break :int try sema.coerce(block, switch (uncasted_info.signedness) { | 29841 | }).?) break :int try sema.coerce(block, switch (uncasted_info.signedness) { |
| 29656 | .signed => .c_longlong, | 29842 | .signed => .c_longlong, |
| 29657 | .unsigned => .c_ulonglong, | 29843 | .unsigned => .c_ulonglong, |
| 29658 | }, inst, inst_src); | 29844 | }, inst, inst_src); |
| ... | @@ -30048,6 +30234,19 @@ fn checkPtrAttributes(sema: *Sema, dest_ty: Type, inst_ty: Type, in_memory_resul | ... | @@ -30048,6 +30234,19 @@ fn checkPtrAttributes(sema: *Sema, dest_ty: Type, inst_ty: Type, in_memory_resul |
| 30048 | } }; | 30234 | } }; |
| 30049 | return false; | 30235 | return false; |
| 30050 | } | 30236 | } |
| 30237 | |||
| 30238 | if (inst_info.packed_offset.host_size != dest_info.packed_offset.host_size or | ||
| 30239 | inst_info.packed_offset.bit_offset != dest_info.packed_offset.bit_offset) | ||
| 30240 | { | ||
| 30241 | in_memory_result.* = .{ .ptr_bit_range = .{ | ||
| 30242 | .actual_host = inst_info.packed_offset.host_size, | ||
| 30243 | .wanted_host = dest_info.packed_offset.host_size, | ||
| 30244 | .actual_offset = inst_info.packed_offset.bit_offset, | ||
| 30245 | .wanted_offset = dest_info.packed_offset.bit_offset, | ||
| 30246 | } }; | ||
| 30247 | return false; | ||
| 30248 | } | ||
| 30249 | |||
| 30051 | if (inst_info.flags.alignment == .none and dest_info.flags.alignment == .none) return true; | 30250 | if (inst_info.flags.alignment == .none and dest_info.flags.alignment == .none) return true; |
| 30052 | if (len0) return true; | 30251 | if (len0) return true; |
| 30053 | 30252 | ||
| ... | @@ -30068,19 +30267,6 @@ fn checkPtrAttributes(sema: *Sema, dest_ty: Type, inst_ty: Type, in_memory_resul | ... | @@ -30068,19 +30267,6 @@ fn checkPtrAttributes(sema: *Sema, dest_ty: Type, inst_ty: Type, in_memory_resul |
| 30068 | } }; | 30267 | } }; |
| 30069 | return false; | 30268 | return false; |
| 30070 | } | 30269 | } |
| 30071 | |||
| 30072 | if (inst_info.packed_offset.host_size != dest_info.packed_offset.host_size or | ||
| 30073 | inst_info.packed_offset.bit_offset != dest_info.packed_offset.bit_offset) | ||
| 30074 | { | ||
| 30075 | in_memory_result.* = .{ .ptr_bit_range = .{ | ||
| 30076 | .actual_host = inst_info.packed_offset.host_size, | ||
| 30077 | .wanted_host = dest_info.packed_offset.host_size, | ||
| 30078 | .actual_offset = inst_info.packed_offset.bit_offset, | ||
| 30079 | .wanted_offset = dest_info.packed_offset.bit_offset, | ||
| 30080 | } }; | ||
| 30081 | return false; | ||
| 30082 | } | ||
| 30083 | |||
| 30084 | return true; | 30270 | return true; |
| 30085 | } | 30271 | } |
| 30086 | 30272 | ||
| ... | @@ -30606,7 +30792,10 @@ fn ensureMemoizedStateResolved(sema: *Sema, src: LazySrcLoc, stage: InternPool.M | ... | @@ -30606,7 +30792,10 @@ fn ensureMemoizedStateResolved(sema: *Sema, src: LazySrcLoc, stage: InternPool.M |
| 30606 | if (pt.zcu.analysis_in_progress.contains(unit)) { | 30792 | if (pt.zcu.analysis_in_progress.contains(unit)) { |
| 30607 | return sema.failWithDependencyLoop(unit, &reason); | 30793 | return sema.failWithDependencyLoop(unit, &reason); |
| 30608 | } | 30794 | } |
| 30609 | try pt.ensureMemoizedStateUpToDate(stage, &reason); | 30795 | pt.ensureMemoizedStateUpToDate(stage, &reason) catch |err| switch (err) { |
| 30796 | error.AnalysisFail => return sema.failTransitive(.{ .failed_unit = unit }), | ||
| 30797 | else => |e| return e, | ||
| 30798 | }; | ||
| 30610 | } | 30799 | } |
| 30611 | 30800 | ||
| 30612 | pub fn ensureNavResolved(sema: *Sema, block: *Block, src: LazySrcLoc, nav_index: InternPool.Nav.Index, kind: enum { type, fully }) CompileError!void { | 30801 | pub fn ensureNavResolved(sema: *Sema, block: *Block, src: LazySrcLoc, nav_index: InternPool.Nav.Index, kind: enum { type, fully }) CompileError!void { |
| ... | @@ -30642,9 +30831,15 @@ pub fn ensureNavResolved(sema: *Sema, block: *Block, src: LazySrcLoc, nav_index: | ... | @@ -30642,9 +30831,15 @@ pub fn ensureNavResolved(sema: *Sema, block: *Block, src: LazySrcLoc, nav_index: |
| 30642 | switch (kind) { | 30831 | switch (kind) { |
| 30643 | .type => { | 30832 | .type => { |
| 30644 | try zcu.ensureNavValAnalysisQueued(nav_index); | 30833 | try zcu.ensureNavValAnalysisQueued(nav_index); |
| 30645 | return pt.ensureNavTypeUpToDate(nav_index, &reason); | 30834 | return pt.ensureNavTypeUpToDate(nav_index, &reason) catch |err| switch (err) { |
| 30835 | error.AnalysisFail => return sema.failTransitive(.{ .failed_unit = anal_unit }), | ||
| 30836 | else => |e| return e, | ||
| 30837 | }; | ||
| 30838 | }, | ||
| 30839 | .fully => return pt.ensureNavValUpToDate(nav_index, &reason) catch |err| switch (err) { | ||
| 30840 | error.AnalysisFail => return sema.failTransitive(.{ .failed_unit = anal_unit }), | ||
| 30841 | else => |e| return e, | ||
| 30646 | }, | 30842 | }, |
| 30647 | .fully => return pt.ensureNavValUpToDate(nav_index, &reason), | ||
| 30648 | } | 30843 | } |
| 30649 | } | 30844 | } |
| 30650 | 30845 | ||
| ... | @@ -30856,7 +31051,18 @@ fn analyzeLoad( | ... | @@ -30856,7 +31051,18 @@ fn analyzeLoad( |
| 30856 | const comptime_only = switch (elem_ty.classify(zcu)) { | 31051 | const comptime_only = switch (elem_ty.classify(zcu)) { |
| 30857 | .no_possible_value => switch (elem_ty.zigTypeTag(zcu)) { | 31052 | .no_possible_value => switch (elem_ty.zigTypeTag(zcu)) { |
| 30858 | .@"opaque" => return sema.fail(block, src, "cannot load opaque type '{f}'", .{elem_ty.fmt(pt)}), | 31053 | .@"opaque" => return sema.fail(block, src, "cannot load opaque type '{f}'", .{elem_ty.fmt(pt)}), |
| 30859 | else => return sema.fail(block, src, "cannot load uninstantiable type '{f}'", .{elem_ty.fmt(pt)}), | 31054 | else => { |
| 31055 | // Loading an uninstantiable type always invokes Illegal Behavior. | ||
| 31056 | if (block.isComptime()) { | ||
| 31057 | return sema.fail(block, src, "cannot load uninstantiable type '{f}'", .{elem_ty.fmt(pt)}); | ||
| 31058 | } else if (block.wantSafety()) { | ||
| 31059 | try sema.safetyPanic(block, src, .load_uninstantiable_type); | ||
| 31060 | return .unreachable_value; | ||
| 31061 | } else { | ||
| 31062 | _ = try block.addNoOp(.unreach); | ||
| 31063 | return .unreachable_value; | ||
| 31064 | } | ||
| 31065 | }, | ||
| 30860 | }, | 31066 | }, |
| 30861 | .one_possible_value => return .fromValue((try elem_ty.onePossibleValue(pt)).?), | 31067 | .one_possible_value => return .fromValue((try elem_ty.onePossibleValue(pt)).?), |
| 30862 | .runtime => false, | 31068 | .runtime => false, |
| ... | @@ -30864,8 +31070,11 @@ fn analyzeLoad( | ... | @@ -30864,8 +31070,11 @@ fn analyzeLoad( |
| 30864 | }; | 31070 | }; |
| 30865 | 31071 | ||
| 30866 | if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| { | 31072 | if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| { |
| 30867 | if (try sema.pointerDeref(block, src, ptr_val, ptr_ty)) |elem_val| { | 31073 | if (switch (ptr_ty.ptrSize(zcu)) { |
| 30868 | return Air.internedToRef(elem_val.toIntern()); | 31074 | .slice => try sema.maybeDerefSliceAsArray(block, src, ptr_val), |
| 31075 | else => try sema.pointerDeref(block, src, ptr_val, ptr_ty), | ||
| 31076 | }) |elem_val| { | ||
| 31077 | return .fromValue(elem_val); | ||
| 30869 | } | 31078 | } |
| 30870 | } | 31079 | } |
| 30871 | 31080 | ||
| ... | @@ -33707,7 +33916,10 @@ fn ensureFuncIesResolved( | ... | @@ -33707,7 +33916,10 @@ fn ensureFuncIesResolved( |
| 33707 | return sema.failWithDependencyLoop(.wrap(.{ .func = func_index }), &reason); | 33916 | return sema.failWithDependencyLoop(.wrap(.{ .func = func_index }), &reason); |
| 33708 | } | 33917 | } |
| 33709 | 33918 | ||
| 33710 | try pt.ensureFuncBodyUpToDate(func_index, &reason); | 33919 | pt.ensureFuncBodyUpToDate(func_index, &reason) catch |err| switch (err) { |
| 33920 | error.AnalysisFail => return sema.failTransitive(.{ .failed_unit = .wrap(.{ .func = func_index }) }), | ||
| 33921 | else => |e| return e, | ||
| 33922 | }; | ||
| 33711 | } | 33923 | } |
| 33712 | 33924 | ||
| 33713 | pub fn resolveInferredErrorSetPtr( | 33925 | pub fn resolveInferredErrorSetPtr( |
| ... | @@ -33821,7 +34033,7 @@ pub fn getTmpAir(sema: Sema) Air { | ... | @@ -33821,7 +34033,7 @@ pub fn getTmpAir(sema: Sema) Air { |
| 33821 | } | 34033 | } |
| 33822 | 34034 | ||
| 33823 | pub fn addExtra(sema: *Sema, extra: anytype) Allocator.Error!u32 { | 34035 | pub fn addExtra(sema: *Sema, extra: anytype) Allocator.Error!u32 { |
| 33824 | const field_count = std.meta.fieldNames(@TypeOf(extra)).len; | 34036 | const field_count = @typeInfo(@TypeOf(extra)).@"struct".field_names.len; |
| 33825 | try sema.air_extra.ensureUnusedCapacity(sema.gpa, field_count); | 34037 | try sema.air_extra.ensureUnusedCapacity(sema.gpa, field_count); |
| 33826 | return sema.addExtraAssumeCapacity(extra); | 34038 | return sema.addExtraAssumeCapacity(extra); |
| 33827 | } | 34039 | } |
| ... | @@ -34536,7 +34748,6 @@ fn maybeDerefSliceAsArray( | ... | @@ -34536,7 +34748,6 @@ fn maybeDerefSliceAsArray( |
| 34536 | ) CompileError!?Value { | 34748 | ) CompileError!?Value { |
| 34537 | const pt = sema.pt; | 34749 | const pt = sema.pt; |
| 34538 | const zcu = pt.zcu; | 34750 | const zcu = pt.zcu; |
| 34539 | const ip = &zcu.intern_pool; | ||
| 34540 | const slice_ty = slice_val.typeOf(zcu); | 34751 | const slice_ty = slice_val.typeOf(zcu); |
| 34541 | assert(slice_ty.zigTypeTag(zcu) == .pointer); | 34752 | assert(slice_ty.zigTypeTag(zcu) == .pointer); |
| 34542 | switch (slice_ty.ptrInfo(zcu).flags.size) { | 34753 | switch (slice_ty.ptrInfo(zcu).flags.size) { |
| ... | @@ -34544,26 +34755,14 @@ fn maybeDerefSliceAsArray( | ... | @@ -34544,26 +34755,14 @@ fn maybeDerefSliceAsArray( |
| 34544 | .one => return sema.pointerDeref(block, src, slice_val, slice_ty), | 34755 | .one => return sema.pointerDeref(block, src, slice_val, slice_ty), |
| 34545 | .many, .c => unreachable, | 34756 | .many, .c => unreachable, |
| 34546 | } | 34757 | } |
| 34547 | const slice = switch (ip.indexToKey(slice_val.toIntern())) { | 34758 | const slice = switch (zcu.intern_pool.indexToKey(slice_val.toIntern())) { |
| 34548 | .undef => return sema.failWithUseOfUndef(block, src, null), | 34759 | .undef => return sema.failWithUseOfUndef(block, src, null), |
| 34549 | .slice => |slice| slice, | 34760 | .slice => |slice| slice, |
| 34550 | else => unreachable, | 34761 | else => unreachable, |
| 34551 | }; | 34762 | }; |
| 34552 | const elem_ty = Type.fromInterned(slice.ty).childType(zcu); | 34763 | if (slice.len == .undef_usize) return sema.failWithUndefSliceLen(block, src); |
| 34553 | const len = Value.fromInterned(slice.len).toUnsignedInt(zcu); | 34764 | const casted_ptr = try pt.sliceToArrayPtr(slice); |
| 34554 | const array_ty = try pt.arrayType(.{ | 34765 | return sema.pointerDeref(block, src, casted_ptr, casted_ptr.typeOf(zcu)); |
| 34555 | .child = elem_ty.toIntern(), | ||
| 34556 | .len = len, | ||
| 34557 | }); | ||
| 34558 | const ptr_ty = try pt.ptrType(p: { | ||
| 34559 | var p = Type.fromInterned(slice.ty).ptrInfo(zcu); | ||
| 34560 | p.flags.size = .one; | ||
| 34561 | p.child = array_ty.toIntern(); | ||
| 34562 | p.sentinel = .none; | ||
| 34563 | break :p p; | ||
| 34564 | }); | ||
| 34565 | const casted_ptr = try pt.getCoerced(Value.fromInterned(slice.ptr), ptr_ty); | ||
| 34566 | return sema.pointerDeref(block, src, casted_ptr, ptr_ty); | ||
| 34567 | } | 34766 | } |
| 34568 | 34767 | ||
| 34569 | fn analyzeUnreachable(sema: *Sema, block: *Block, src: LazySrcLoc, safety_check: bool) !void { | 34768 | fn analyzeUnreachable(sema: *Sema, block: *Block, src: LazySrcLoc, safety_check: bool) !void { |
| ... | @@ -34668,7 +34867,7 @@ pub fn resolveNavPtrModifiers( | ... | @@ -34668,7 +34867,7 @@ pub fn resolveNavPtrModifiers( |
| 34668 | const linksection_body = zir_decl.linksection_body orelse break :ls .none; | 34867 | const linksection_body = zir_decl.linksection_body orelse break :ls .none; |
| 34669 | const linksection_ref = try sema.resolveInlineBody(block, linksection_body, decl_inst); | 34868 | const linksection_ref = try sema.resolveInlineBody(block, linksection_body, decl_inst); |
| 34670 | const bytes = try sema.toConstString(block, section_src, linksection_ref, .{ .simple = .@"linksection" }); | 34869 | const bytes = try sema.toConstString(block, section_src, linksection_ref, .{ .simple = .@"linksection" }); |
| 34671 | if (std.mem.indexOfScalar(u8, bytes, 0) != null) { | 34870 | if (std.mem.findScalar(u8, bytes, 0) != null) { |
| 34672 | return sema.fail(block, section_src, "linksection cannot contain null bytes", .{}); | 34871 | return sema.fail(block, section_src, "linksection cannot contain null bytes", .{}); |
| 34673 | } else if (bytes.len == 0) { | 34872 | } else if (bytes.len == 0) { |
| 34674 | return sema.fail(block, section_src, "linksection cannot be empty", .{}); | 34873 | return sema.fail(block, section_src, "linksection cannot be empty", .{}); |
| ... | @@ -34843,7 +35042,9 @@ fn getExpectedBuiltinFnType(sema: *Sema, decl: Zcu.StdLangDecl) CompileError!Typ | ... | @@ -34843,7 +35042,9 @@ fn getExpectedBuiltinFnType(sema: *Sema, decl: Zcu.StdLangDecl) CompileError!Typ |
| 34843 | }), | 35042 | }), |
| 34844 | 35043 | ||
| 34845 | // `fn (anyerror) noreturn` | 35044 | // `fn (anyerror) noreturn` |
| 34846 | .@"panic.unwrapError" => try pt.funcType(.{ | 35045 | .@"panic.unwrapError", |
| 35046 | .@"panic.unexpectedErrorCode", | ||
| 35047 | => try pt.funcType(.{ | ||
| 34847 | .param_types = &.{.anyerror_type}, | 35048 | .param_types = &.{.anyerror_type}, |
| 34848 | .return_type = .noreturn_type, | 35049 | .return_type = .noreturn_type, |
| 34849 | }), | 35050 | }), |
| ... | @@ -34882,12 +35083,60 @@ fn getExpectedBuiltinFnType(sema: *Sema, decl: Zcu.StdLangDecl) CompileError!Typ | ... | @@ -34882,12 +35083,60 @@ fn getExpectedBuiltinFnType(sema: *Sema, decl: Zcu.StdLangDecl) CompileError!Typ |
| 34882 | .@"panic.copyLenMismatch", | 35083 | .@"panic.copyLenMismatch", |
| 34883 | .@"panic.memcpyAlias", | 35084 | .@"panic.memcpyAlias", |
| 34884 | .@"panic.noreturnReturned", | 35085 | .@"panic.noreturnReturned", |
| 35086 | .@"panic.loadUninstantiableType", | ||
| 34885 | => try pt.funcType(.{ | 35087 | => try pt.funcType(.{ |
| 34886 | .param_types = &.{}, | 35088 | .param_types = &.{}, |
| 34887 | .return_type = .noreturn_type, | 35089 | .return_type = .noreturn_type, |
| 34888 | }), | 35090 | }), |
| 34889 | 35091 | ||
| 34890 | else => unreachable, | 35092 | .StackTrace, |
| 35093 | .CallingConvention, | ||
| 35094 | .SourceLocation, | ||
| 35095 | .Signedness, | ||
| 35096 | .AddressSpace, | ||
| 35097 | .VaList, | ||
| 35098 | .CallModifier, | ||
| 35099 | .AtomicOrder, | ||
| 35100 | .AtomicRmwOp, | ||
| 35101 | .ReduceOp, | ||
| 35102 | .FloatMode, | ||
| 35103 | .PrefetchOptions, | ||
| 35104 | .ExportOptions, | ||
| 35105 | .ExternOptions, | ||
| 35106 | .BranchHint, | ||
| 35107 | .assembly, | ||
| 35108 | .@"assembly.Clobbers", | ||
| 35109 | .Type, | ||
| 35110 | .@"Type.Fn", | ||
| 35111 | .@"Type.Fn.ParamAttributes", | ||
| 35112 | .@"Type.Fn.Attributes", | ||
| 35113 | .@"Type.Int", | ||
| 35114 | .@"Type.Float", | ||
| 35115 | .@"Type.Pointer", | ||
| 35116 | .@"Type.Pointer.Size", | ||
| 35117 | .@"Type.Pointer.Attributes", | ||
| 35118 | .@"Type.Array", | ||
| 35119 | .@"Type.Vector", | ||
| 35120 | .@"Type.Optional", | ||
| 35121 | .@"Type.ErrorUnion", | ||
| 35122 | .@"Type.ErrorSet", | ||
| 35123 | .@"Type.Enum", | ||
| 35124 | .@"Type.Enum.Mode", | ||
| 35125 | .@"Type.Union", | ||
| 35126 | .@"Type.Union.FieldAttributes", | ||
| 35127 | .@"Type.Struct", | ||
| 35128 | .@"Type.Struct.FieldAttributes", | ||
| 35129 | .@"Type.ContainerLayout", | ||
| 35130 | .@"Type.Opaque", | ||
| 35131 | .@"Type.Spirv", | ||
| 35132 | .@"Type.Spirv.Image", | ||
| 35133 | .@"Type.Spirv.Image.Usage", | ||
| 35134 | .@"Type.Spirv.Image.Format", | ||
| 35135 | .@"Type.Spirv.Image.Dimensionality", | ||
| 35136 | .@"Type.Spirv.Image.Depth", | ||
| 35137 | .@"Type.Spirv.Image.Access", | ||
| 35138 | .panic, | ||
| 35139 | => unreachable, // not a function (`decl.kind() != .func`) | ||
| 34891 | }; | 35140 | }; |
| 34892 | } | 35141 | } |
| 34893 | 35142 | ||
| ... | @@ -34926,7 +35175,9 @@ pub fn setTypeName( | ... | @@ -34926,7 +35175,9 @@ pub fn setTypeName( |
| 34926 | }, | 35175 | }, |
| 34927 | .parent => wip.setName(ip, block.type_name_ctx, sema.owner.unwrap().nav_val.toOptional()), | 35176 | .parent => wip.setName(ip, block.type_name_ctx, sema.owner.unwrap().nav_val.toOptional()), |
| 34928 | .func => { | 35177 | .func => { |
| 34929 | const fn_info = sema.code.getFnInfo(ip.funcZirBodyInst(sema.func_index).resolve(ip) orelse return error.AnalysisFail); | 35178 | const fn_info = sema.code.getFnInfo(ip.funcZirBodyInst(sema.func_index).resolve(ip) orelse { |
| 35179 | return sema.failTransitive(.{ .lost_tracking = ip.funcZirBodyInst(sema.func_index) }); | ||
| 35180 | }); | ||
| 34930 | const zir_tags = sema.code.instructions.items(.tag); | 35181 | const zir_tags = sema.code.instructions.items(.tag); |
| 34931 | 35182 | ||
| 34932 | var aw: std.Io.Writer.Allocating = .init(gpa); | 35183 | var aw: std.Io.Writer.Allocating = .init(gpa); |
| ... | @@ -35042,7 +35293,10 @@ fn zirStructDecl( | ... | @@ -35042,7 +35293,10 @@ fn zirStructDecl( |
| 35042 | }; | 35293 | }; |
| 35043 | 35294 | ||
| 35044 | try sema.addTypeReferenceEntry(src, ty); | 35295 | try sema.addTypeReferenceEntry(src, ty); |
| 35045 | try pt.ensureNamespaceUpToDate(ty.getNamespaceIndex(zcu)); | 35296 | pt.ensureNamespaceUpToDate(ty.getNamespaceIndex(zcu)) catch |err| switch (err) { |
| 35297 | error.LostZirContainerDecl => unreachable, // we literally just tracked it | ||
| 35298 | else => |e| return e, | ||
| 35299 | }; | ||
| 35046 | 35300 | ||
| 35047 | return .fromType(ty); | 35301 | return .fromType(ty); |
| 35048 | } | 35302 | } |
| ... | @@ -35115,7 +35369,10 @@ fn zirUnionDecl( | ... | @@ -35115,7 +35369,10 @@ fn zirUnionDecl( |
| 35115 | }; | 35369 | }; |
| 35116 | 35370 | ||
| 35117 | try sema.addTypeReferenceEntry(src, ty); | 35371 | try sema.addTypeReferenceEntry(src, ty); |
| 35118 | try pt.ensureNamespaceUpToDate(ty.getNamespaceIndex(zcu)); | 35372 | pt.ensureNamespaceUpToDate(ty.getNamespaceIndex(zcu)) catch |err| switch (err) { |
| 35373 | error.LostZirContainerDecl => unreachable, // we literally just tracked it | ||
| 35374 | else => |e| return e, | ||
| 35375 | }; | ||
| 35119 | 35376 | ||
| 35120 | return .fromType(ty); | 35377 | return .fromType(ty); |
| 35121 | } | 35378 | } |
| ... | @@ -35167,7 +35424,10 @@ fn zirEnumDecl( | ... | @@ -35167,7 +35424,10 @@ fn zirEnumDecl( |
| 35167 | }; | 35424 | }; |
| 35168 | 35425 | ||
| 35169 | try sema.addTypeReferenceEntry(src, ty); | 35426 | try sema.addTypeReferenceEntry(src, ty); |
| 35170 | try pt.ensureNamespaceUpToDate(ty.getNamespaceIndex(zcu)); | 35427 | pt.ensureNamespaceUpToDate(ty.getNamespaceIndex(zcu)) catch |err| switch (err) { |
| 35428 | error.LostZirContainerDecl => unreachable, // we literally just tracked it | ||
| 35429 | else => |e| return e, | ||
| 35430 | }; | ||
| 35171 | 35431 | ||
| 35172 | return .fromType(ty); | 35432 | return .fromType(ty); |
| 35173 | } | 35433 | } |
| ... | @@ -35216,7 +35476,10 @@ fn zirOpaqueDecl( | ... | @@ -35216,7 +35476,10 @@ fn zirOpaqueDecl( |
| 35216 | }; | 35476 | }; |
| 35217 | 35477 | ||
| 35218 | try sema.addTypeReferenceEntry(src, ty); | 35478 | try sema.addTypeReferenceEntry(src, ty); |
| 35219 | try pt.ensureNamespaceUpToDate(ty.getNamespaceIndex(zcu)); | 35479 | pt.ensureNamespaceUpToDate(ty.getNamespaceIndex(zcu)) catch |err| switch (err) { |
| 35480 | error.LostZirContainerDecl => unreachable, // we literally just tracked it | ||
| 35481 | else => |e| return e, | ||
| 35482 | }; | ||
| 35220 | 35483 | ||
| 35221 | return .fromType(ty); | 35484 | return .fromType(ty); |
| 35222 | } | 35485 | } |
| ... | @@ -35257,5 +35520,31 @@ pub fn failWithDependencyLoop( | ... | @@ -35257,5 +35520,31 @@ pub fn failWithDependencyLoop( |
| 35257 | } | 35520 | } |
| 35258 | 35521 | ||
| 35259 | // A dependency loop error will be reported. Mark us all as transitive failures. | 35522 | // A dependency loop error will be reported. Mark us all as transitive failures. |
| 35260 | return error.AnalysisFail; | 35523 | return sema.failTransitive(.dependency_loop); |
| 35524 | } | ||
| 35525 | |||
| 35526 | /// Marks the owner of `sema` as having failed semantic failed *without* an error message, and | ||
| 35527 | /// returns failure. This function is suitable to call when any one of the following is true: | ||
| 35528 | /// | ||
| 35529 | /// * `sema.owner` is guaranteed to be unreferenced on this update, for instance because it uses a | ||
| 35530 | /// dead `InternPool.TrackedInst`. | ||
| 35531 | /// | ||
| 35532 | /// * There is guaranteed to be a compile error if this unit is referenced. In practice, this means | ||
| 35533 | /// that either there is an error elsewhere in the pipeline (e.g. AstGen), or we depend on another | ||
| 35534 | /// `AnalUnit` which has itself failed. | ||
| 35535 | pub fn failTransitive(sema: *Sema, reason: Zcu.TransitiveFailureReason) SemaError { | ||
| 35536 | assert(sema.err == null); | ||
| 35537 | const zcu = sema.pt.zcu; | ||
| 35538 | const unit = sema.owner; | ||
| 35539 | |||
| 35540 | log.debug("transitive failure analyzing '{f}' ({t})", .{ zcu.fmtAnalUnit(unit), reason }); | ||
| 35541 | |||
| 35542 | assert(!zcu.failed_analysis.contains(unit)); | ||
| 35543 | try zcu.transitive_failed_analysis.putNoClobber( | ||
| 35544 | zcu.comp.gpa, | ||
| 35545 | unit, | ||
| 35546 | if (build_options.enable_debug_extensions) reason, | ||
| 35547 | ); | ||
| 35548 | |||
| 35549 | return error.AlreadyReported; | ||
| 35261 | } | 35550 | } |
src/Sema/LowerZon.zig+2-2| ... | @@ -320,7 +320,7 @@ fn failUnsupportedResultType( | ... | @@ -320,7 +320,7 @@ fn failUnsupportedResultType( |
| 320 | self: *LowerZon, | 320 | self: *LowerZon, |
| 321 | ty: Type, | 321 | ty: Type, |
| 322 | opt_note: ?[]const u8, | 322 | opt_note: ?[]const u8, |
| 323 | ) error{ AnalysisFail, OutOfMemory } { | 323 | ) Zcu.SemaError { |
| 324 | @branchHint(.cold); | 324 | @branchHint(.cold); |
| 325 | const sema = self.sema; | 325 | const sema = self.sema; |
| 326 | const gpa = sema.gpa; | 326 | const gpa = sema.gpa; |
| ... | @@ -338,7 +338,7 @@ fn fail( | ... | @@ -338,7 +338,7 @@ fn fail( |
| 338 | node: Zoir.Node.Index, | 338 | node: Zoir.Node.Index, |
| 339 | comptime format: []const u8, | 339 | comptime format: []const u8, |
| 340 | args: anytype, | 340 | args: anytype, |
| 341 | ) error{ AnalysisFail, OutOfMemory } { | 341 | ) Zcu.SemaError { |
| 342 | @branchHint(.cold); | 342 | @branchHint(.cold); |
| 343 | const err_msg = try Zcu.ErrorMsg.create(self.sema.pt.zcu.gpa, self.nodeSrc(node), format, args); | 343 | const err_msg = try Zcu.ErrorMsg.create(self.sema.pt.zcu.gpa, self.nodeSrc(node), format, args); |
| 344 | try self.sema.pt.zcu.errNote(self.import_loc, err_msg, "imported here", .{}); | 344 | try self.sema.pt.zcu.errNote(self.import_loc, err_msg, "imported here", .{}); |
src/Sema/type_resolution.zig+22-8| ... | @@ -116,7 +116,10 @@ fn ensureLayoutResolvedInner(sema: *Sema, ty: Type, orig_ty: Type, reason: *cons | ... | @@ -116,7 +116,10 @@ fn ensureLayoutResolvedInner(sema: *Sema, ty: Type, orig_ty: Type, reason: *cons |
| 116 | if (zcu.analysis_in_progress.contains(.wrap(.{ .type_layout = ty.toIntern() }))) { | 116 | if (zcu.analysis_in_progress.contains(.wrap(.{ .type_layout = ty.toIntern() }))) { |
| 117 | return sema.failWithDependencyLoop(.wrap(.{ .type_layout = ty.toIntern() }), reason); | 117 | return sema.failWithDependencyLoop(.wrap(.{ .type_layout = ty.toIntern() }), reason); |
| 118 | } | 118 | } |
| 119 | try pt.ensureTypeLayoutUpToDate(ty, reason); | 119 | pt.ensureTypeLayoutUpToDate(ty, reason) catch |err| switch (err) { |
| 120 | error.AnalysisFail => return sema.failTransitive(.{ .failed_unit = .wrap(.{ .type_layout = ty.toIntern() }) }), | ||
| 121 | else => |e| return e, | ||
| 122 | }; | ||
| 120 | }, | 123 | }, |
| 121 | 124 | ||
| 122 | // values, not types | 125 | // values, not types |
| ... | @@ -166,7 +169,10 @@ pub fn ensureStructDefaultsResolved(sema: *Sema, ty: Type, src: LazySrcLoc) Sema | ... | @@ -166,7 +169,10 @@ pub fn ensureStructDefaultsResolved(sema: *Sema, ty: Type, src: LazySrcLoc) Sema |
| 166 | return sema.failWithDependencyLoop(.wrap(.{ .struct_defaults = ty.toIntern() }), &reason); | 169 | return sema.failWithDependencyLoop(.wrap(.{ .struct_defaults = ty.toIntern() }), &reason); |
| 167 | } | 170 | } |
| 168 | 171 | ||
| 169 | try pt.ensureStructDefaultsUpToDate(ty, &reason); | 172 | pt.ensureStructDefaultsUpToDate(ty, &reason) catch |err| switch (err) { |
| 173 | error.AnalysisFail => return sema.failTransitive(.{ .failed_unit = .wrap(.{ .struct_defaults = ty.toIntern() }) }), | ||
| 174 | else => |e| return e, | ||
| 175 | }; | ||
| 170 | } | 176 | } |
| 171 | 177 | ||
| 172 | /// Asserts that `struct_ty` is a non-packed non-tuple struct, and that `sema.owner` is that type. | 178 | /// Asserts that `struct_ty` is a non-packed non-tuple struct, and that `sema.owner` is that type. |
| ... | @@ -188,7 +194,9 @@ pub fn resolveStructLayout(sema: *Sema, struct_ty: Type) CompileError!void { | ... | @@ -188,7 +194,9 @@ pub fn resolveStructLayout(sema: *Sema, struct_ty: Type) CompileError!void { |
| 188 | 194 | ||
| 189 | const struct_obj = ip.loadStructType(struct_ty.toIntern()); | 195 | const struct_obj = ip.loadStructType(struct_ty.toIntern()); |
| 190 | assert(struct_obj.want_layout); | 196 | assert(struct_obj.want_layout); |
| 191 | const zir_index = struct_obj.zir_index.resolve(ip) orelse return error.AnalysisFail; | 197 | const zir_index = struct_obj.zir_index.resolve(ip) orelse { |
| 198 | return sema.failTransitive(.{ .lost_tracking = struct_obj.zir_index }); | ||
| 199 | }; | ||
| 192 | 200 | ||
| 193 | var block: Block = .{ | 201 | var block: Block = .{ |
| 194 | .parent = null, | 202 | .parent = null, |
| ... | @@ -364,7 +372,7 @@ pub fn resolveStructLayout(sema: *Sema, struct_ty: Type) CompileError!void { | ... | @@ -364,7 +372,7 @@ pub fn resolveStructLayout(sema: *Sema, struct_ty: Type) CompileError!void { |
| 364 | const a = struct_obj.field_aligns.get(ip)[field_idx]; | 372 | const a = struct_obj.field_aligns.get(ip)[field_idx]; |
| 365 | if (a != .none) break :a a; | 373 | if (a != .none) break :a a; |
| 366 | } | 374 | } |
| 367 | break :a field_ty.defaultStructFieldAlignment(struct_obj.layout, zcu); | 375 | break :a field_ty.abiAlignment(zcu); |
| 368 | }; | 376 | }; |
| 369 | align_out.* = field_align; | 377 | align_out.* = field_align; |
| 370 | if (struct_obj.field_is_comptime_bits.get(ip, field_idx)) { | 378 | if (struct_obj.field_is_comptime_bits.get(ip, field_idx)) { |
| ... | @@ -606,7 +614,7 @@ pub fn resolveStructDefaults(sema: *Sema, struct_ty: Type) CompileError!void { | ... | @@ -606,7 +614,7 @@ pub fn resolveStructDefaults(sema: *Sema, struct_ty: Type) CompileError!void { |
| 606 | struct_ty.assertHasLayout(zcu); | 614 | struct_ty.assertHasLayout(zcu); |
| 607 | const layout_unit: InternPool.AnalUnit = .wrap(.{ .type_layout = struct_ty.toIntern() }); | 615 | const layout_unit: InternPool.AnalUnit = .wrap(.{ .type_layout = struct_ty.toIntern() }); |
| 608 | if (zcu.failed_analysis.contains(layout_unit) or zcu.transitive_failed_analysis.contains(layout_unit)) { | 616 | if (zcu.failed_analysis.contains(layout_unit) or zcu.transitive_failed_analysis.contains(layout_unit)) { |
| 609 | return error.AnalysisFail; | 617 | return sema.failTransitive(.{ .failed_unit = layout_unit }); |
| 610 | } | 618 | } |
| 611 | 619 | ||
| 612 | const struct_obj = ip.loadStructType(struct_ty.toIntern()); | 620 | const struct_obj = ip.loadStructType(struct_ty.toIntern()); |
| ... | @@ -656,7 +664,9 @@ fn resolveStructDefaultsInner( | ... | @@ -656,7 +664,9 @@ fn resolveStructDefaultsInner( |
| 656 | assert(struct_obj.field_defaults.len > 0); | 664 | assert(struct_obj.field_defaults.len > 0); |
| 657 | 665 | ||
| 658 | // We'll need to map the struct decl instruction to provide result types | 666 | // We'll need to map the struct decl instruction to provide result types |
| 659 | const zir_index = struct_obj.zir_index.resolve(ip) orelse return error.AnalysisFail; | 667 | const zir_index = struct_obj.zir_index.resolve(ip) orelse { |
| 668 | return sema.failTransitive(.{ .lost_tracking = struct_obj.zir_index }); | ||
| 669 | }; | ||
| 660 | try sema.inst_map.ensureSpaceForInstructions(gpa, &.{zir_index}); | 670 | try sema.inst_map.ensureSpaceForInstructions(gpa, &.{zir_index}); |
| 661 | 671 | ||
| 662 | const field_types = struct_obj.field_types.get(ip); | 672 | const field_types = struct_obj.field_types.get(ip); |
| ... | @@ -713,7 +723,9 @@ pub fn resolveUnionLayout(sema: *Sema, union_ty: Type) CompileError!void { | ... | @@ -713,7 +723,9 @@ pub fn resolveUnionLayout(sema: *Sema, union_ty: Type) CompileError!void { |
| 713 | 723 | ||
| 714 | const union_obj = ip.loadUnionType(union_ty.toIntern()); | 724 | const union_obj = ip.loadUnionType(union_ty.toIntern()); |
| 715 | assert(union_obj.want_layout); | 725 | assert(union_obj.want_layout); |
| 716 | const zir_index = union_obj.zir_index.resolve(ip) orelse return error.AnalysisFail; | 726 | const zir_index = union_obj.zir_index.resolve(ip) orelse { |
| 727 | return sema.failTransitive(.{ .lost_tracking = union_obj.zir_index }); | ||
| 728 | }; | ||
| 717 | 729 | ||
| 718 | var block: Block = .{ | 730 | var block: Block = .{ |
| 719 | .parent = null, | 731 | .parent = null, |
| ... | @@ -1212,7 +1224,9 @@ pub fn resolveEnumLayout(sema: *Sema, enum_ty: Type) CompileError!void { | ... | @@ -1212,7 +1224,9 @@ pub fn resolveEnumLayout(sema: *Sema, enum_ty: Type) CompileError!void { |
| 1212 | }; | 1224 | }; |
| 1213 | 1225 | ||
| 1214 | const tracked_inst = enum_obj.zir_index.unwrap() orelse maybe_parent_union_obj.?.zir_index; | 1226 | const tracked_inst = enum_obj.zir_index.unwrap() orelse maybe_parent_union_obj.?.zir_index; |
| 1215 | const zir_index = tracked_inst.resolve(ip) orelse return error.AnalysisFail; | 1227 | const zir_index = tracked_inst.resolve(ip) orelse { |
| 1228 | return sema.failTransitive(.{ .lost_tracking = tracked_inst }); | ||
| 1229 | }; | ||
| 1216 | 1230 | ||
| 1217 | var block: Block = .{ | 1231 | var block: Block = .{ |
| 1218 | .parent = null, | 1232 | .parent = null, |
src/Type.zig+107-86| ... | @@ -957,12 +957,27 @@ pub fn abiAlignment(ty: Type, zcu: *const Zcu) Alignment { | ... | @@ -957,12 +957,27 @@ pub fn abiAlignment(ty: Type, zcu: *const Zcu) Alignment { |
| 957 | if (vector_type.len == 0) return .@"1"; | 957 | if (vector_type.len == 0) return .@"1"; |
| 958 | switch (zcu.comp.getZigBackend()) { | 958 | switch (zcu.comp.getZigBackend()) { |
| 959 | else => { | 959 | else => { |
| 960 | const elem_bits: u32 = @intCast(Type.fromInterned(vector_type.child).bitSize(zcu)); | 960 | const elem_ty: Type = .fromInterned(vector_type.child); |
| 961 | switch (if (elem_ty.isRuntimeFloat()) | ||
| 962 | std.zig.target.compilerRtFloatAbi(target, elem_ty.floatBits(target)) | ||
| 963 | else | ||
| 964 | .hard) { | ||
| 965 | .hard => {}, | ||
| 966 | .soft => return elem_ty.abiAlignment(zcu), | ||
| 967 | } | ||
| 968 | const elem_bits: u32 = @intCast(elem_ty.bitSize(zcu)); | ||
| 961 | if (elem_bits == 0) return .@"1"; | 969 | if (elem_bits == 0) return .@"1"; |
| 962 | const bytes = ((elem_bits * vector_type.len) + 7) / 8; | 970 | const bytes = ((elem_bits * vector_type.len) + 7) / 8; |
| 963 | return .fromByteUnits(std.math.ceilPowerOfTwoAssert(u32, bytes)); | 971 | const arch = target.cpu.arch; |
| 972 | return .fromByteUnits(std.math.ceilPowerOfTwoAssert( | ||
| 973 | u32, | ||
| 974 | if (arch.isArm() or arch.isAARCH64() or arch == .s390x) | ||
| 975 | @min(bytes, target.stackAlignment()) | ||
| 976 | else | ||
| 977 | bytes, | ||
| 978 | )); | ||
| 964 | }, | 979 | }, |
| 965 | .stage2_c, .stage2_wasm => return Type.fromInterned(vector_type.child).defaultStructFieldAlignment(.auto, zcu), | 980 | .stage2_c, .stage2_wasm => return Type.fromInterned(vector_type.child).abiAlignment(zcu), |
| 966 | .stage2_x86_64 => { | 981 | .stage2_x86_64 => { |
| 967 | if (vector_type.child == .bool_type) { | 982 | if (vector_type.child == .bool_type) { |
| 968 | if (vector_type.len > 256 and target.cpu.has(.x86, .avx512f)) return .@"64"; | 983 | if (vector_type.len > 256 and target.cpu.has(.x86, .avx512f)) return .@"64"; |
| ... | @@ -1018,19 +1033,33 @@ pub fn abiAlignment(ty: Type, zcu: *const Zcu) Alignment { | ... | @@ -1018,19 +1033,33 @@ pub fn abiAlignment(ty: Type, zcu: *const Zcu) Alignment { |
| 1018 | .c_ulonglong => cTypeAlign(target, .ulonglong), | 1033 | .c_ulonglong => cTypeAlign(target, .ulonglong), |
| 1019 | .c_longdouble => cTypeAlign(target, .longdouble), | 1034 | .c_longdouble => cTypeAlign(target, .longdouble), |
| 1020 | 1035 | ||
| 1021 | .f16 => .@"2", | 1036 | .f16 => .fromByteUnits(std.zig.target.intAlignment(target, 16)), // repr: u16 |
| 1022 | .f32 => if (target.os.tag == .opengl) .@"4" else cTypeAlign(target, .float), | 1037 | .f32 => if (target.cTypeBitSize(.float) == 32) |
| 1023 | .f64 => if (target.os.tag == .opengl) .@"8" else switch (target.cTypeBitSize(.double)) { | 1038 | cTypeAlign(target, .float) // abi: c_float, |
| 1024 | 64 => cTypeAlign(target, .double), | 1039 | else |
| 1025 | else => .@"8", | 1040 | .fromByteUnits(std.zig.target.intAlignment(target, 32)), // repr: u32, |
| 1026 | }, | 1041 | .f64 => if (target.cTypeBitSize(.double) == 64) |
| 1027 | .f80 => switch (target.cTypeBitSize(.longdouble)) { | 1042 | cTypeAlign(target, .double) // abi: c_double, |
| 1028 | 80 => cTypeAlign(target, .longdouble), | 1043 | else |
| 1029 | else => Type.u80.abiAlignment(zcu), | 1044 | .fromByteUnits(std.zig.target.intAlignment(target, 64)), // repr: u64, |
| 1030 | }, | 1045 | .f80 => if (target.cTypeBitSize(.longdouble) == 80) |
| 1031 | .f128 => switch (target.cTypeBitSize(.longdouble)) { | 1046 | cTypeAlign(target, .longdouble) // abi: c_longdouble, |
| 1032 | 128 => cTypeAlign(target, .longdouble), | 1047 | else |
| 1033 | else => .@"16", | 1048 | .fromByteUnits(switch (std.zig.target.compilerRtFloatAbi(target, 80)) { |
| 1049 | .hard => std.zig.target.intAlignment(target, 80), // repr: u80, | ||
| 1050 | .soft => @max( | ||
| 1051 | std.zig.target.intAlignment(target, 64), // mantissa: u64, | ||
| 1052 | std.zig.target.intAlignment(target, 16), // exponent: u16, | ||
| 1053 | ), | ||
| 1054 | }), | ||
| 1055 | .f128 => if (target.cTypeBitSize(.longdouble) == 128) | ||
| 1056 | cTypeAlign(target, .longdouble) // abi: c_longdouble, | ||
| 1057 | else switch (std.zig.target.compilerRtFloatAbi(target, 128)) { | ||
| 1058 | .hard => if (target.cpu.arch.isX86()) | ||
| 1059 | .@"16" // abi: c___float128, | ||
| 1060 | else | ||
| 1061 | .fromByteUnits(std.zig.target.intAlignment(target, 128)), // repr: u128, | ||
| 1062 | .soft => .fromByteUnits(std.zig.target.intAlignment(target, 64)), // lo: u64, hi: u64, | ||
| 1034 | }, | 1063 | }, |
| 1035 | 1064 | ||
| 1036 | .generic_poison => unreachable, | 1065 | .generic_poison => unreachable, |
| ... | @@ -1111,7 +1140,13 @@ pub fn abiSize(ty: Type, zcu: *const Zcu) u64 { | ... | @@ -1111,7 +1140,13 @@ pub fn abiSize(ty: Type, zcu: *const Zcu) u64 { |
| 1111 | .vector_type => |vec| { | 1140 | .vector_type => |vec| { |
| 1112 | const elem_ty: Type = .fromInterned(vec.child); | 1141 | const elem_ty: Type = .fromInterned(vec.child); |
| 1113 | const bytes = switch (zcu.comp.getZigBackend()) { | 1142 | const bytes = switch (zcu.comp.getZigBackend()) { |
| 1114 | else => @divCeil(vec.len * elem_ty.bitSize(zcu), 8), | 1143 | else => switch (if (elem_ty.isRuntimeFloat()) |
| 1144 | std.zig.target.compilerRtFloatAbi(target, elem_ty.floatBits(target)) | ||
| 1145 | else | ||
| 1146 | .hard) { | ||
| 1147 | .hard => @divCeil(vec.len * elem_ty.bitSize(zcu), 8), | ||
| 1148 | .soft => vec.len * elem_ty.abiSize(zcu), | ||
| 1149 | }, | ||
| 1115 | .stage2_c, .stage2_wasm => vec.len * elem_ty.abiSize(zcu), | 1150 | .stage2_c, .stage2_wasm => vec.len * elem_ty.abiSize(zcu), |
| 1116 | .stage2_x86_64 => switch (elem_ty.toIntern()) { | 1151 | .stage2_x86_64 => switch (elem_ty.toIntern()) { |
| 1117 | .bool_type => @divCeil(vec.len, 8), | 1152 | .bool_type => @divCeil(vec.len, 8), |
| ... | @@ -1167,25 +1202,44 @@ pub fn abiSize(ty: Type, zcu: *const Zcu) u64 { | ... | @@ -1167,25 +1202,44 @@ pub fn abiSize(ty: Type, zcu: *const Zcu) u64 { |
| 1167 | .anyerror, .adhoc_inferred_error_set => errorAbiSize(zcu), | 1202 | .anyerror, .adhoc_inferred_error_set => errorAbiSize(zcu), |
| 1168 | .usize, .isize => ptrAbiSize(target), | 1203 | .usize, .isize => ptrAbiSize(target), |
| 1169 | 1204 | ||
| 1170 | .c_char => target.cTypeByteSize(.char), | 1205 | .c_char => target.cTypeByteSize(.char).?, |
| 1171 | .c_short => target.cTypeByteSize(.short), | 1206 | .c_short => target.cTypeByteSize(.short).?, |
| 1172 | .c_ushort => target.cTypeByteSize(.ushort), | 1207 | .c_ushort => target.cTypeByteSize(.ushort).?, |
| 1173 | .c_int => target.cTypeByteSize(.int), | 1208 | .c_int => target.cTypeByteSize(.int).?, |
| 1174 | .c_uint => target.cTypeByteSize(.uint), | 1209 | .c_uint => target.cTypeByteSize(.uint).?, |
| 1175 | .c_long => target.cTypeByteSize(.long), | 1210 | .c_long => target.cTypeByteSize(.long).?, |
| 1176 | .c_ulong => target.cTypeByteSize(.ulong), | 1211 | .c_ulong => target.cTypeByteSize(.ulong).?, |
| 1177 | .c_longlong => target.cTypeByteSize(.longlong), | 1212 | .c_longlong => target.cTypeByteSize(.longlong).?, |
| 1178 | .c_ulonglong => target.cTypeByteSize(.ulonglong), | 1213 | .c_ulonglong => target.cTypeByteSize(.ulonglong).?, |
| 1179 | .c_longdouble => target.cTypeByteSize(.longdouble), | 1214 | .c_longdouble => target.cTypeByteSize(.longdouble).?, |
| 1180 | 1215 | ||
| 1181 | .f16 => 2, | 1216 | .f16 => std.zig.target.intByteSize(target, 16), // repr: u16 |
| 1182 | .f32 => 4, | 1217 | .f32 => if (target.cTypeBitSize(.float) == 32) |
| 1183 | .f64 => 8, | 1218 | target.cTypeByteSize(.float).? // abi: c_float, |
| 1184 | .f80 => switch (target.cTypeBitSize(.longdouble)) { | 1219 | else |
| 1185 | 80 => target.cTypeByteSize(.longdouble), | 1220 | std.zig.target.intByteSize(target, 32), // repr: u32, |
| 1186 | else => Type.u80.abiSize(zcu), | 1221 | .f64 => if (target.cTypeBitSize(.double) == 64) |
| 1222 | target.cTypeByteSize(.double).? // abi: c_double, | ||
| 1223 | else | ||
| 1224 | std.zig.target.intByteSize(target, 64), // repr: u64, | ||
| 1225 | .f80 => if (target.cTypeBitSize(.longdouble) == 80) | ||
| 1226 | target.cTypeByteSize(.longdouble).? // abi: c_longdouble, | ||
| 1227 | else switch (std.zig.target.compilerRtFloatAbi(target, 80)) { | ||
| 1228 | .hard => std.zig.target.intByteSize(target, 80), // repr: u80, | ||
| 1229 | .soft => ty.abiAlignment(zcu).forward( | ||
| 1230 | std.zig.target.intByteSize(target, 64) + // mantissa: u64, | ||
| 1231 | std.zig.target.intByteSize(target, 16), // exponent: u16 | ||
| 1232 | ), | ||
| 1233 | }, | ||
| 1234 | .f128 => if (target.cTypeBitSize(.longdouble) == 128) | ||
| 1235 | target.cTypeByteSize(.longdouble).? // abi: c_longdouble, | ||
| 1236 | else switch (std.zig.target.compilerRtFloatAbi(target, 128)) { | ||
| 1237 | .hard => if (target.cpu.arch.isX86()) | ||
| 1238 | 16 // abi: c___float128, | ||
| 1239 | else | ||
| 1240 | std.zig.target.intByteSize(target, 128), // repr: u128, | ||
| 1241 | .soft => std.zig.target.intByteSize(target, 64) * 2, // lo: u64, hi: u64, | ||
| 1187 | }, | 1242 | }, |
| 1188 | .f128 => 16, | ||
| 1189 | 1243 | ||
| 1190 | .anyopaque => unreachable, | 1244 | .anyopaque => unreachable, |
| 1191 | .generic_poison => unreachable, | 1245 | .generic_poison => unreachable, |
| ... | @@ -1733,7 +1787,7 @@ pub fn isInt(self: Type, zcu: *const Zcu) bool { | ... | @@ -1733,7 +1787,7 @@ pub fn isInt(self: Type, zcu: *const Zcu) bool { |
| 1733 | /// Returns true if and only if the type is a fixed-width, signed integer. | 1787 | /// Returns true if and only if the type is a fixed-width, signed integer. |
| 1734 | pub fn isSignedInt(ty: Type, zcu: *const Zcu) bool { | 1788 | pub fn isSignedInt(ty: Type, zcu: *const Zcu) bool { |
| 1735 | return switch (ty.toIntern()) { | 1789 | return switch (ty.toIntern()) { |
| 1736 | .c_char_type => zcu.getTarget().cCharSignedness() == .signed, | 1790 | .c_char_type => zcu.getTarget().cCharSignedness().? == .signed, |
| 1737 | .isize_type, .c_short_type, .c_int_type, .c_long_type, .c_longlong_type => true, | 1791 | .isize_type, .c_short_type, .c_int_type, .c_long_type, .c_longlong_type => true, |
| 1738 | else => switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | 1792 | else => switch (zcu.intern_pool.indexToKey(ty.toIntern())) { |
| 1739 | .int_type => |int_type| int_type.signedness == .signed, | 1793 | .int_type => |int_type| int_type.signedness == .signed, |
| ... | @@ -1745,7 +1799,7 @@ pub fn isSignedInt(ty: Type, zcu: *const Zcu) bool { | ... | @@ -1745,7 +1799,7 @@ pub fn isSignedInt(ty: Type, zcu: *const Zcu) bool { |
| 1745 | /// Returns true if and only if the type is a fixed-width, unsigned integer. | 1799 | /// Returns true if and only if the type is a fixed-width, unsigned integer. |
| 1746 | pub fn isUnsignedInt(ty: Type, zcu: *const Zcu) bool { | 1800 | pub fn isUnsignedInt(ty: Type, zcu: *const Zcu) bool { |
| 1747 | return switch (ty.toIntern()) { | 1801 | return switch (ty.toIntern()) { |
| 1748 | .c_char_type => zcu.getTarget().cCharSignedness() == .unsigned, | 1802 | .c_char_type => zcu.getTarget().cCharSignedness().? == .unsigned, |
| 1749 | .usize_type, .c_ushort_type, .c_uint_type, .c_ulong_type, .c_ulonglong_type => true, | 1803 | .usize_type, .c_ushort_type, .c_uint_type, .c_ulong_type, .c_ulonglong_type => true, |
| 1750 | else => switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | 1804 | else => switch (zcu.intern_pool.indexToKey(ty.toIntern())) { |
| 1751 | .int_type => |int_type| int_type.signedness == .unsigned, | 1805 | .int_type => |int_type| int_type.signedness == .unsigned, |
| ... | @@ -1776,15 +1830,15 @@ pub fn intInfo(starting_ty: Type, zcu: *const Zcu) InternPool.Key.IntType { | ... | @@ -1776,15 +1830,15 @@ pub fn intInfo(starting_ty: Type, zcu: *const Zcu) InternPool.Key.IntType { |
| 1776 | }, | 1830 | }, |
| 1777 | .usize_type => return .{ .signedness = .unsigned, .bits = target.ptrBitWidth() }, | 1831 | .usize_type => return .{ .signedness = .unsigned, .bits = target.ptrBitWidth() }, |
| 1778 | .isize_type => return .{ .signedness = .signed, .bits = target.ptrBitWidth() }, | 1832 | .isize_type => return .{ .signedness = .signed, .bits = target.ptrBitWidth() }, |
| 1779 | .c_char_type => return .{ .signedness = zcu.getTarget().cCharSignedness(), .bits = target.cTypeBitSize(.char) }, | 1833 | .c_char_type => return .{ .signedness = target.cCharSignedness().?, .bits = target.cTypeBitSize(.char).? }, |
| 1780 | .c_short_type => return .{ .signedness = .signed, .bits = target.cTypeBitSize(.short) }, | 1834 | .c_short_type => return .{ .signedness = .signed, .bits = target.cTypeBitSize(.short).? }, |
| 1781 | .c_ushort_type => return .{ .signedness = .unsigned, .bits = target.cTypeBitSize(.ushort) }, | 1835 | .c_ushort_type => return .{ .signedness = .unsigned, .bits = target.cTypeBitSize(.ushort).? }, |
| 1782 | .c_int_type => return .{ .signedness = .signed, .bits = target.cTypeBitSize(.int) }, | 1836 | .c_int_type => return .{ .signedness = .signed, .bits = target.cTypeBitSize(.int).? }, |
| 1783 | .c_uint_type => return .{ .signedness = .unsigned, .bits = target.cTypeBitSize(.uint) }, | 1837 | .c_uint_type => return .{ .signedness = .unsigned, .bits = target.cTypeBitSize(.uint).? }, |
| 1784 | .c_long_type => return .{ .signedness = .signed, .bits = target.cTypeBitSize(.long) }, | 1838 | .c_long_type => return .{ .signedness = .signed, .bits = target.cTypeBitSize(.long).? }, |
| 1785 | .c_ulong_type => return .{ .signedness = .unsigned, .bits = target.cTypeBitSize(.ulong) }, | 1839 | .c_ulong_type => return .{ .signedness = .unsigned, .bits = target.cTypeBitSize(.ulong).? }, |
| 1786 | .c_longlong_type => return .{ .signedness = .signed, .bits = target.cTypeBitSize(.longlong) }, | 1840 | .c_longlong_type => return .{ .signedness = .signed, .bits = target.cTypeBitSize(.longlong).? }, |
| 1787 | .c_ulonglong_type => return .{ .signedness = .unsigned, .bits = target.cTypeBitSize(.ulonglong) }, | 1841 | .c_ulonglong_type => return .{ .signedness = .unsigned, .bits = target.cTypeBitSize(.ulonglong).? }, |
| 1788 | else => switch (ip.indexToKey(ty.toIntern())) { | 1842 | else => switch (ip.indexToKey(ty.toIntern())) { |
| 1789 | .int_type => |int_type| return int_type, | 1843 | .int_type => |int_type| return int_type, |
| 1790 | .struct_type => { | 1844 | .struct_type => { |
| ... | @@ -1882,7 +1936,7 @@ pub fn floatBits(ty: Type, target: *const Target) u16 { | ... | @@ -1882,7 +1936,7 @@ pub fn floatBits(ty: Type, target: *const Target) u16 { |
| 1882 | .f64_type => 64, | 1936 | .f64_type => 64, |
| 1883 | .f80_type => 80, | 1937 | .f80_type => 80, |
| 1884 | .f128_type, .comptime_float_type => 128, | 1938 | .f128_type, .comptime_float_type => 128, |
| 1885 | .c_longdouble_type => target.cTypeBitSize(.longdouble), | 1939 | .c_longdouble_type => target.cTypeBitSize(.longdouble).?, |
| 1886 | 1940 | ||
| 1887 | else => unreachable, | 1941 | else => unreachable, |
| 1888 | }; | 1942 | }; |
| ... | @@ -2147,13 +2201,6 @@ pub fn isVector(ty: Type, zcu: *const Zcu) bool { | ... | @@ -2147,13 +2201,6 @@ pub fn isVector(ty: Type, zcu: *const Zcu) bool { |
| 2147 | return ty.zigTypeTag(zcu) == .vector; | 2201 | return ty.zigTypeTag(zcu) == .vector; |
| 2148 | } | 2202 | } |
| 2149 | 2203 | ||
| 2150 | /// Returns 0 if not a vector, otherwise returns @bitSizeOf(Element) * vector_len. | ||
| 2151 | pub fn totalVectorBits(ty: Type, zcu: *Zcu) u64 { | ||
| 2152 | if (!ty.isVector(zcu)) return 0; | ||
| 2153 | const v = zcu.intern_pool.indexToKey(ty.toIntern()).vector_type; | ||
| 2154 | return v.len * Type.fromInterned(v.child).bitSize(zcu); | ||
| 2155 | } | ||
| 2156 | |||
| 2157 | pub fn isArrayOrVector(ty: Type, zcu: *const Zcu) bool { | 2204 | pub fn isArrayOrVector(ty: Type, zcu: *const Zcu) bool { |
| 2158 | return switch (ty.zigTypeTag(zcu)) { | 2205 | return switch (ty.zigTypeTag(zcu)) { |
| 2159 | .array, .vector => true, | 2206 | .array, .vector => true, |
| ... | @@ -2416,34 +2463,6 @@ pub fn explicitFieldAlignment(ty: Type, index: usize, zcu: *const Zcu) Alignment | ... | @@ -2416,34 +2463,6 @@ pub fn explicitFieldAlignment(ty: Type, index: usize, zcu: *const Zcu) Alignment |
| 2416 | }; | 2463 | }; |
| 2417 | } | 2464 | } |
| 2418 | 2465 | ||
| 2419 | /// Returns the alignment a struct field of type `field_ty` will be given if no alignment is | ||
| 2420 | /// explicitly specified. However, in an `extern struct`, a higher alignment may be available due | ||
| 2421 | /// to the struct's full layout (i.e. a field might coincidentally be more aligned). | ||
| 2422 | /// | ||
| 2423 | /// Asserts that the layout of `field_ty` is resolved. Asserts that `layout` is not `.@"packed"`. | ||
| 2424 | pub fn defaultStructFieldAlignment( | ||
| 2425 | field_ty: Type, | ||
| 2426 | layout: std.lang.Type.ContainerLayout, | ||
| 2427 | zcu: *const Zcu, | ||
| 2428 | ) Alignment { | ||
| 2429 | const overalign_big_int = switch (layout) { | ||
| 2430 | .@"packed" => unreachable, | ||
| 2431 | .auto => zcu.getTarget().ofmt == .c, | ||
| 2432 | .@"extern" => true, | ||
| 2433 | }; | ||
| 2434 | const abi_align = field_ty.abiAlignment(zcu); | ||
| 2435 | assert(abi_align != .none); | ||
| 2436 | // We check for anything over 64 here, because the C backend will lower e.g. u64 to a 128-bit | ||
| 2437 | // integer, which has 16-byte alignment. | ||
| 2438 | if (overalign_big_int and | ||
| 2439 | ((field_ty.isAbiInt(zcu) and field_ty.intInfo(zcu).bits > 64) or | ||
| 2440 | (field_ty.toIntern() == .f80_type and zcu.getTarget().cTypeBitSize(.longdouble) != 80))) | ||
| 2441 | { | ||
| 2442 | return abi_align.maxStrict(if (zcu.getTarget().cpu.arch == .s390x) .@"8" else .@"16"); | ||
| 2443 | } | ||
| 2444 | return abi_align; | ||
| 2445 | } | ||
| 2446 | |||
| 2447 | pub fn structFieldDefaultValue(ty: Type, index: usize, zcu: *const Zcu) ?Value { | 2466 | pub fn structFieldDefaultValue(ty: Type, index: usize, zcu: *const Zcu) ?Value { |
| 2448 | const ip = &zcu.intern_pool; | 2467 | const ip = &zcu.intern_pool; |
| 2449 | switch (ip.indexToKey(ty.toIntern())) { | 2468 | switch (ip.indexToKey(ty.toIntern())) { |
| ... | @@ -2961,8 +2980,7 @@ pub fn fieldPtrType(ptr_ty: Type, field_index: u32, pt: Zcu.PerThread) Allocator | ... | @@ -2961,8 +2980,7 @@ pub fn fieldPtrType(ptr_ty: Type, field_index: u32, pt: Zcu.PerThread) Allocator |
| 2961 | } | 2980 | } |
| 2962 | const actual_field_align = switch (field_align) { | 2981 | const actual_field_align = switch (field_align) { |
| 2963 | .none => switch (ip.indexToKey(aggregate_ty.toIntern())) { | 2982 | .none => switch (ip.indexToKey(aggregate_ty.toIntern())) { |
| 2964 | .tuple_type, .union_type => field_ty.abiAlignment(zcu), | 2983 | .struct_type, .tuple_type, .union_type => field_ty.abiAlignment(zcu), |
| 2965 | .struct_type => field_ty.defaultStructFieldAlignment(.auto, zcu), | ||
| 2966 | .ptr_type => Type.usize.abiAlignment(zcu), | 2984 | .ptr_type => Type.usize.abiAlignment(zcu), |
| 2967 | else => unreachable, | 2985 | else => unreachable, |
| 2968 | }, | 2986 | }, |
| ... | @@ -3122,7 +3140,6 @@ pub fn validateExtern(ty: Type, position: ExternPosition, zcu: *const Zcu) bool | ... | @@ -3122,7 +3140,6 @@ pub fn validateExtern(ty: Type, position: ExternPosition, zcu: *const Zcu) bool |
| 3122 | 3140 | ||
| 3123 | .@"opaque", | 3141 | .@"opaque", |
| 3124 | .bool, | 3142 | .bool, |
| 3125 | .float, | ||
| 3126 | .@"anyframe", | 3143 | .@"anyframe", |
| 3127 | => true, | 3144 | => true, |
| 3128 | 3145 | ||
| ... | @@ -3144,6 +3161,10 @@ pub fn validateExtern(ty: Type, position: ExternPosition, zcu: *const Zcu) bool | ... | @@ -3144,6 +3161,10 @@ pub fn validateExtern(ty: Type, position: ExternPosition, zcu: *const Zcu) bool |
| 3144 | 24, 48 => zcu.getTarget().cpu.arch == .ez80, | 3161 | 24, 48 => zcu.getTarget().cpu.arch == .ez80, |
| 3145 | else => false, | 3162 | else => false, |
| 3146 | }, | 3163 | }, |
| 3164 | .float => switch (ty.floatBits(zcu.getTarget())) { | ||
| 3165 | else => true, | ||
| 3166 | 80 => zcu.getTarget().cTypeBitSize(.longdouble) == 80, | ||
| 3167 | }, | ||
| 3147 | .@"fn" => { | 3168 | .@"fn" => { |
| 3148 | if (position != .other) return false; | 3169 | if (position != .other) return false; |
| 3149 | return validateExternCallconv(ty.fnCallingConvention(zcu)); | 3170 | return validateExternCallconv(ty.fnCallingConvention(zcu)); |
| ... | @@ -3600,5 +3621,5 @@ pub fn smallestUnsignedBits(max: u64) u16 { | ... | @@ -3600,5 +3621,5 @@ pub fn smallestUnsignedBits(max: u64) u16 { |
| 3600 | pub const packed_struct_layout_version = 2; | 3621 | pub const packed_struct_layout_version = 2; |
| 3601 | 3622 | ||
| 3602 | fn cTypeAlign(target: *const Target, c_type: Target.CType) Alignment { | 3623 | fn cTypeAlign(target: *const Target, c_type: Target.CType) Alignment { |
| 3603 | return Alignment.fromByteUnits(target.cTypeAlignment(c_type)); | 3624 | return .fromByteUnits(target.cTypeAlignment(c_type).?); |
| 3604 | } | 3625 | } |
src/Value.zig+2-7| ... | @@ -611,12 +611,7 @@ pub fn toFloat(val: Value, comptime T: type, zcu: *const Zcu) T { | ... | @@ -611,12 +611,7 @@ pub fn toFloat(val: Value, comptime T: type, zcu: *const Zcu) T { |
| 611 | return switch (zcu.intern_pool.indexToKey(val.toIntern())) { | 611 | return switch (zcu.intern_pool.indexToKey(val.toIntern())) { |
| 612 | .int => |int| switch (int.storage) { | 612 | .int => |int| switch (int.storage) { |
| 613 | .big_int => |big_int| big_int.toFloat(T, .nearest_even)[0], | 613 | .big_int => |big_int| big_int.toFloat(T, .nearest_even)[0], |
| 614 | inline .u64, .i64 => |x| { | 614 | inline .u64, .i64 => |x| @floatFromInt(x), |
| 615 | if (T == f80) { | ||
| 616 | @panic("TODO we can't lower this properly on non-x86 llvm backend yet"); | ||
| 617 | } | ||
| 618 | return @floatFromInt(x); | ||
| 619 | }, | ||
| 620 | }, | 615 | }, |
| 621 | .float => |float| switch (float.storage) { | 616 | .float => |float| switch (float.storage) { |
| 622 | inline else => |x| @floatCast(x), | 617 | inline else => |x| @floatCast(x), |
| ... | @@ -959,7 +954,7 @@ pub fn anyScalarIsZero(val: Value, zcu: *Zcu) bool { | ... | @@ -959,7 +954,7 @@ pub fn anyScalarIsZero(val: Value, zcu: *Zcu) bool { |
| 959 | .bytes => |str| { | 954 | .bytes => |str| { |
| 960 | const len = Type.fromInterned(agg.ty).vectorLen(zcu); | 955 | const len = Type.fromInterned(agg.ty).vectorLen(zcu); |
| 961 | const slice = str.toSlice(len, &zcu.intern_pool); | 956 | const slice = str.toSlice(len, &zcu.intern_pool); |
| 962 | return std.mem.indexOfScalar(u8, slice, 0) != null; | 957 | return std.mem.findScalar(u8, slice, 0) != null; |
| 963 | }, | 958 | }, |
| 964 | .elems => |elems| { | 959 | .elems => |elems| { |
| 965 | for (elems) |elem| { | 960 | for (elems) |elem| { |
src/Zcu.zig+41-29| ... | @@ -182,7 +182,10 @@ analysis_in_progress: std.array_hash_map.Auto(AnalUnit, ?*const DependencyReason | ... | @@ -182,7 +182,10 @@ analysis_in_progress: std.array_hash_map.Auto(AnalUnit, ?*const DependencyReason |
| 182 | /// The ErrorMsg memory is owned by the `AnalUnit`, using Module's general purpose allocator. | 182 | /// The ErrorMsg memory is owned by the `AnalUnit`, using Module's general purpose allocator. |
| 183 | failed_analysis: std.array_hash_map.Auto(AnalUnit, *ErrorMsg) = .empty, | 183 | failed_analysis: std.array_hash_map.Auto(AnalUnit, *ErrorMsg) = .empty, |
| 184 | /// This `AnalUnit` failed semantic analysis because it required analysis of another `AnalUnit` which itself failed. | 184 | /// This `AnalUnit` failed semantic analysis because it required analysis of another `AnalUnit` which itself failed. |
| 185 | transitive_failed_analysis: std.array_hash_map.Auto(AnalUnit, void) = .empty, | 185 | transitive_failed_analysis: std.array_hash_map.Auto( |
| 186 | AnalUnit, | ||
| 187 | if (build_options.enable_debug_extensions) TransitiveFailureReason else void, | ||
| 188 | ) = .empty, | ||
| 186 | /// This `Nav` succeeded analysis, but failed codegen. | 189 | /// This `Nav` succeeded analysis, but failed codegen. |
| 187 | /// This may be a simple "value" `Nav`, or it may be a function. | 190 | /// This may be a simple "value" `Nav`, or it may be a function. |
| 188 | /// The ErrorMsg memory is owned by the `AnalUnit`, using Module's general purpose allocator. | 191 | /// The ErrorMsg memory is owned by the `AnalUnit`, using Module's general purpose allocator. |
| ... | @@ -351,6 +354,18 @@ pub const DependencyReason = struct { | ... | @@ -351,6 +354,18 @@ pub const DependencyReason = struct { |
| 351 | type_layout_reason: Sema.type_resolution.LayoutResolveReason, | 354 | type_layout_reason: Sema.type_resolution.LayoutResolveReason, |
| 352 | }; | 355 | }; |
| 353 | 356 | ||
| 357 | /// These are not required for anything, but when the compiler is built with debug extensions, we | ||
| 358 | /// store these in `Zcu.transitive_failed_analysis` and surface them in the incremental debug server | ||
| 359 | /// (see `src/IncrementalDebugServer.zig`) because they are a useful debugging aid for bugs in | ||
| 360 | /// incremental compilation. | ||
| 361 | pub const TransitiveFailureReason = union(enum) { | ||
| 362 | astgen_error, | ||
| 363 | dependency_loop, | ||
| 364 | lost_tracking: InternPool.TrackedInst.Index, | ||
| 365 | failed_unit: AnalUnit, | ||
| 366 | func_nav_val_changed: InternPool.Index, | ||
| 367 | }; | ||
| 368 | |||
| 354 | pub const IncrementalDebugState = struct { | 369 | pub const IncrementalDebugState = struct { |
| 355 | /// All container types in the ZCU, even dead ones. | 370 | /// All container types in the ZCU, even dead ones. |
| 356 | /// Value is the generation the type was created on. | 371 | /// Value is the generation the type was created on. |
| ... | @@ -488,6 +503,7 @@ pub const StdLangDecl = enum { | ... | @@ -488,6 +503,7 @@ pub const StdLangDecl = enum { |
| 488 | @"panic.castToNull", | 503 | @"panic.castToNull", |
| 489 | @"panic.incorrectAlignment", | 504 | @"panic.incorrectAlignment", |
| 490 | @"panic.invalidErrorCode", | 505 | @"panic.invalidErrorCode", |
| 506 | @"panic.unexpectedErrorCode", | ||
| 491 | @"panic.integerOutOfBounds", | 507 | @"panic.integerOutOfBounds", |
| 492 | @"panic.integerOverflow", | 508 | @"panic.integerOverflow", |
| 493 | @"panic.shlOverflow", | 509 | @"panic.shlOverflow", |
| ... | @@ -502,6 +518,7 @@ pub const StdLangDecl = enum { | ... | @@ -502,6 +518,7 @@ pub const StdLangDecl = enum { |
| 502 | @"panic.copyLenMismatch", | 518 | @"panic.copyLenMismatch", |
| 503 | @"panic.memcpyAlias", | 519 | @"panic.memcpyAlias", |
| 504 | @"panic.noreturnReturned", | 520 | @"panic.noreturnReturned", |
| 521 | @"panic.loadUninstantiableType", | ||
| 505 | 522 | ||
| 506 | VaList, | 523 | VaList, |
| 507 | 524 | ||
| ... | @@ -577,6 +594,7 @@ pub const StdLangDecl = enum { | ... | @@ -577,6 +594,7 @@ pub const StdLangDecl = enum { |
| 577 | .@"panic.castToNull", | 594 | .@"panic.castToNull", |
| 578 | .@"panic.incorrectAlignment", | 595 | .@"panic.incorrectAlignment", |
| 579 | .@"panic.invalidErrorCode", | 596 | .@"panic.invalidErrorCode", |
| 597 | .@"panic.unexpectedErrorCode", | ||
| 580 | .@"panic.integerOutOfBounds", | 598 | .@"panic.integerOutOfBounds", |
| 581 | .@"panic.integerOverflow", | 599 | .@"panic.integerOverflow", |
| 582 | .@"panic.shlOverflow", | 600 | .@"panic.shlOverflow", |
| ... | @@ -591,6 +609,7 @@ pub const StdLangDecl = enum { | ... | @@ -591,6 +609,7 @@ pub const StdLangDecl = enum { |
| 591 | .@"panic.copyLenMismatch", | 609 | .@"panic.copyLenMismatch", |
| 592 | .@"panic.memcpyAlias", | 610 | .@"panic.memcpyAlias", |
| 593 | .@"panic.noreturnReturned", | 611 | .@"panic.noreturnReturned", |
| 612 | .@"panic.loadUninstantiableType", | ||
| 594 | => .func, | 613 | => .func, |
| 595 | }; | 614 | }; |
| 596 | } | 615 | } |
| ... | @@ -633,7 +652,7 @@ pub const StdLangDecl = enum { | ... | @@ -633,7 +652,7 @@ pub const StdLangDecl = enum { |
| 633 | return switch (decl) { | 652 | return switch (decl) { |
| 634 | inline else => |tag| { | 653 | inline else => |tag| { |
| 635 | const name = @tagName(tag); | 654 | const name = @tagName(tag); |
| 636 | const split = (comptime std.mem.lastIndexOfScalar(u8, name, '.')) orelse return .{ .direct = name }; | 655 | const split = (comptime std.mem.findScalarLast(u8, name, '.')) orelse return .{ .direct = name }; |
| 637 | const parent = @field(StdLangDecl, name[0..split]); | 656 | const parent = @field(StdLangDecl, name[0..split]); |
| 638 | comptime assert(@backingInt(parent) < @backingInt(tag)); // dependencies ordered correctly | 657 | comptime assert(@backingInt(parent) < @backingInt(tag)); // dependencies ordered correctly |
| 639 | return .{ .nested = .{ parent, name[split + 1 ..] } }; | 658 | return .{ .nested = .{ parent, name[split + 1 ..] } }; |
| ... | @@ -664,6 +683,7 @@ pub const SimplePanicId = enum { | ... | @@ -664,6 +683,7 @@ pub const SimplePanicId = enum { |
| 664 | copy_len_mismatch, | 683 | copy_len_mismatch, |
| 665 | memcpy_alias, | 684 | memcpy_alias, |
| 666 | noreturn_returned, | 685 | noreturn_returned, |
| 686 | load_uninstantiable_type, | ||
| 667 | 687 | ||
| 668 | pub fn toStdLangDecl(id: SimplePanicId) StdLangDecl { | 688 | pub fn toStdLangDecl(id: SimplePanicId) StdLangDecl { |
| 669 | return switch (id) { | 689 | return switch (id) { |
| ... | @@ -687,6 +707,7 @@ pub const SimplePanicId = enum { | ... | @@ -687,6 +707,7 @@ pub const SimplePanicId = enum { |
| 687 | .copy_len_mismatch => .@"panic.copyLenMismatch", | 707 | .copy_len_mismatch => .@"panic.copyLenMismatch", |
| 688 | .memcpy_alias => .@"panic.memcpyAlias", | 708 | .memcpy_alias => .@"panic.memcpyAlias", |
| 689 | .noreturn_returned => .@"panic.noreturnReturned", | 709 | .noreturn_returned => .@"panic.noreturnReturned", |
| 710 | .load_uninstantiable_type => .@"panic.loadUninstantiableType", | ||
| 690 | // zig fmt: on | 711 | // zig fmt: on |
| 691 | }; | 712 | }; |
| 692 | } | 713 | } |
| ... | @@ -2808,13 +2829,13 @@ pub const LazySrcLoc = struct { | ... | @@ -2808,13 +2829,13 @@ pub const LazySrcLoc = struct { |
| 2808 | } | 2829 | } |
| 2809 | }; | 2830 | }; |
| 2810 | 2831 | ||
| 2811 | pub const SemaError = error{ OutOfMemory, Canceled, AnalysisFail }; | 2832 | pub const SemaError = error{ OutOfMemory, Canceled, AlreadyReported }; |
| 2812 | pub const CompileError = error{ | 2833 | pub const CompileError = error{ |
| 2813 | OutOfMemory, | 2834 | OutOfMemory, |
| 2814 | /// The compilation update is no longer desired. | 2835 | /// The compilation update is no longer desired. |
| 2815 | Canceled, | 2836 | Canceled, |
| 2816 | /// When this is returned, the compile error for the failure has already been recorded. | 2837 | /// When this is returned, the compile error for the failure has already been recorded. |
| 2817 | AnalysisFail, | 2838 | AlreadyReported, |
| 2818 | /// In a comptime scope, a return instruction was encountered. This error is only seen when | 2839 | /// In a comptime scope, a return instruction was encountered. This error is only seen when |
| 2819 | /// doing a comptime function call. | 2840 | /// doing a comptime function call. |
| 2820 | ComptimeReturn, | 2841 | ComptimeReturn, |
| ... | @@ -2825,6 +2846,11 @@ pub const CompileError = error{ | ... | @@ -2825,6 +2846,11 @@ pub const CompileError = error{ |
| 2825 | 2846 | ||
| 2826 | pub fn init(zcu: *Zcu, gpa: Allocator, io: Io, thread_count: usize) !void { | 2847 | pub fn init(zcu: *Zcu, gpa: Allocator, io: Io, thread_count: usize) !void { |
| 2827 | try zcu.intern_pool.init(gpa, io, thread_count); | 2848 | try zcu.intern_pool.init(gpa, io, thread_count); |
| 2849 | } | ||
| 2850 | |||
| 2851 | /// It is valid to not call this function before `deinit` in error paths. | ||
| 2852 | /// Requires the fields on `zcu.comp` to already be initialized. | ||
| 2853 | pub fn initAfterCompilation(zcu: *Zcu) void { | ||
| 2828 | zcu.initTracyPlots(); | 2854 | zcu.initTracyPlots(); |
| 2829 | } | 2855 | } |
| 2830 | 2856 | ||
| ... | @@ -4273,7 +4299,7 @@ fn resolveReferencesInner(zcu: *Zcu) Allocator.Error!std.array_hash_map.Auto(Ana | ... | @@ -4273,7 +4299,7 @@ fn resolveReferencesInner(zcu: *Zcu) Allocator.Error!std.array_hash_map.Auto(Ana |
| 4273 | const fqn_slice = nav.fqn.toSlice(ip); | 4299 | const fqn_slice = nav.fqn.toSlice(ip); |
| 4274 | if (comp.test_filters.len > 0) { | 4300 | if (comp.test_filters.len > 0) { |
| 4275 | for (comp.test_filters) |test_filter| { | 4301 | for (comp.test_filters) |test_filter| { |
| 4276 | if (std.mem.indexOf(u8, fqn_slice, test_filter) != null) break; | 4302 | if (std.mem.find(u8, fqn_slice, test_filter) != null) break; |
| 4277 | } else break :a false; | 4303 | } else break :a false; |
| 4278 | } | 4304 | } |
| 4279 | break :a true; | 4305 | break :a true; |
| ... | @@ -4597,6 +4623,7 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.lang.CallingConvention) union(enum) | ... | @@ -4597,6 +4623,7 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.lang.CallingConvention) union(enum) |
| 4597 | .x86_64_regcall_v3_sysv, | 4623 | .x86_64_regcall_v3_sysv, |
| 4598 | .x86_64_regcall_v4_win, | 4624 | .x86_64_regcall_v4_win, |
| 4599 | .x86_64_interrupt, | 4625 | .x86_64_interrupt, |
| 4626 | .x86_64_preserve_none, | ||
| 4600 | .x86_fastcall, | 4627 | .x86_fastcall, |
| 4601 | .x86_thiscall, | 4628 | .x86_thiscall, |
| 4602 | .x86_vectorcall, | 4629 | .x86_vectorcall, |
| ... | @@ -4605,6 +4632,7 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.lang.CallingConvention) union(enum) | ... | @@ -4605,6 +4632,7 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.lang.CallingConvention) union(enum) |
| 4605 | .x86_interrupt, | 4632 | .x86_interrupt, |
| 4606 | .aarch64_vfabi, | 4633 | .aarch64_vfabi, |
| 4607 | .aarch64_vfabi_sve, | 4634 | .aarch64_vfabi_sve, |
| 4635 | .aarch64_preserve_none, | ||
| 4608 | .arm_aapcs, | 4636 | .arm_aapcs, |
| 4609 | .csky_interrupt, | 4637 | .csky_interrupt, |
| 4610 | .riscv64_lp64_v, | 4638 | .riscv64_lp64_v, |
| ... | @@ -4612,43 +4640,26 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.lang.CallingConvention) union(enum) | ... | @@ -4612,43 +4640,26 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.lang.CallingConvention) union(enum) |
| 4612 | .m68k_rtd, | 4640 | .m68k_rtd, |
| 4613 | .m68k_interrupt, | 4641 | .m68k_interrupt, |
| 4614 | .msp430_interrupt, | 4642 | .msp430_interrupt, |
| 4615 | => |opts| opts.incoming_stack_alignment == null, | ||
| 4616 | |||
| 4617 | .arm_aapcs_vfp, | 4643 | .arm_aapcs_vfp, |
| 4618 | => |opts| opts.incoming_stack_alignment == null, | ||
| 4619 | |||
| 4620 | .arc_interrupt, | 4644 | .arc_interrupt, |
| 4621 | => |opts| opts.incoming_stack_alignment == null, | ||
| 4622 | |||
| 4623 | .arm_interrupt, | 4645 | .arm_interrupt, |
| 4624 | => |opts| opts.incoming_stack_alignment == null, | ||
| 4625 | |||
| 4626 | .microblaze_interrupt, | 4646 | .microblaze_interrupt, |
| 4627 | => |opts| opts.incoming_stack_alignment == null, | ||
| 4628 | |||
| 4629 | .mips_interrupt, | 4647 | .mips_interrupt, |
| 4630 | .mips64_interrupt, | 4648 | .mips64_interrupt, |
| 4631 | => |opts| opts.incoming_stack_alignment == null, | ||
| 4632 | |||
| 4633 | .riscv32_interrupt, | 4649 | .riscv32_interrupt, |
| 4634 | .riscv64_interrupt, | 4650 | .riscv64_interrupt, |
| 4635 | => |opts| opts.incoming_stack_alignment == null, | ||
| 4636 | |||
| 4637 | .sh_interrupt, | 4651 | .sh_interrupt, |
| 4638 | => |opts| opts.incoming_stack_alignment == null, | 4652 | .avr_interrupt, |
| 4653 | .avr_signal, | ||
| 4654 | .ez80_tiflags, | ||
| 4655 | .naked, | ||
| 4656 | => true, // incoming stack alignment supported | ||
| 4639 | 4657 | ||
| 4640 | .x86_sysv, | 4658 | .x86_sysv, |
| 4641 | .x86_win, | 4659 | .x86_win, |
| 4660 | .x86_mingw, | ||
| 4642 | .x86_stdcall, | 4661 | .x86_stdcall, |
| 4643 | => |opts| opts.incoming_stack_alignment == null and opts.register_params == 0, | 4662 | => |opts| opts.register_params == 0, // incoming stack alignment supported |
| 4644 | |||
| 4645 | .avr_interrupt, | ||
| 4646 | .avr_signal, | ||
| 4647 | => true, | ||
| 4648 | |||
| 4649 | .ez80_tiflags => true, | ||
| 4650 | |||
| 4651 | .naked => true, | ||
| 4652 | 4663 | ||
| 4653 | else => false, | 4664 | else => false, |
| 4654 | }; | 4665 | }; |
| ... | @@ -4673,6 +4684,7 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.lang.CallingConvention) union(enum) | ... | @@ -4673,6 +4684,7 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.lang.CallingConvention) union(enum) |
| 4673 | .stage2_x86 => switch (cc) { | 4684 | .stage2_x86 => switch (cc) { |
| 4674 | .x86_sysv, | 4685 | .x86_sysv, |
| 4675 | .x86_win, | 4686 | .x86_win, |
| 4687 | .x86_mingw, | ||
| 4676 | => |opts| opts.incoming_stack_alignment == null and opts.register_params == 0, | 4688 | => |opts| opts.incoming_stack_alignment == null and opts.register_params == 0, |
| 4677 | .naked => true, | 4689 | .naked => true, |
| 4678 | else => false, | 4690 | else => false, |
src/Zcu/PerThread.zig+96-93| ... | @@ -320,7 +320,7 @@ pub fn update( | ... | @@ -320,7 +320,7 @@ pub fn update( |
| 320 | // Zig compilation pipeline. It selects some `AnalUnit` which we know needs to be analyzed, | 320 | // Zig compilation pipeline. It selects some `AnalUnit` which we know needs to be analyzed, |
| 321 | // and analyzes it, which may in turn discover more `AnalUnit`s which we need to analyze. | 321 | // and analyzes it, which may in turn discover more `AnalUnit`s which we need to analyze. |
| 322 | while (try zcu.findOutdatedToAnalyze()) |unit| { | 322 | while (try zcu.findOutdatedToAnalyze()) |unit| { |
| 323 | const maybe_err: Zcu.SemaError!void = switch (unit.unwrap()) { | 323 | const maybe_err: UpdateUnitError!void = switch (unit.unwrap()) { |
| 324 | .@"comptime" => |cu| pt.ensureComptimeUnitUpToDate(cu), | 324 | .@"comptime" => |cu| pt.ensureComptimeUnitUpToDate(cu), |
| 325 | .nav_ty => |nav| pt.ensureNavTypeUpToDate(nav, null), | 325 | .nav_ty => |nav| pt.ensureNavTypeUpToDate(nav, null), |
| 326 | .nav_val => |nav| pt.ensureNavValUpToDate(nav, null), | 326 | .nav_val => |nav| pt.ensureNavValUpToDate(nav, null), |
| ... | @@ -332,7 +332,7 @@ pub fn update( | ... | @@ -332,7 +332,7 @@ pub fn update( |
| 332 | error.Canceled, | 332 | error.Canceled, |
| 333 | => |e| return e, | 333 | => |e| return e, |
| 334 | 334 | ||
| 335 | error.AnalysisFail => {}, // already reported | 335 | error.AnalysisFail => {}, |
| 336 | }; | 336 | }; |
| 337 | break :res pt.ensureStructDefaultsUpToDate(.fromInterned(ty), null); | 337 | break :res pt.ensureStructDefaultsUpToDate(.fromInterned(ty), null); |
| 338 | }, | 338 | }, |
| ... | @@ -344,7 +344,7 @@ pub fn update( | ... | @@ -344,7 +344,7 @@ pub fn update( |
| 344 | error.Canceled, | 344 | error.Canceled, |
| 345 | => |e| return e, | 345 | => |e| return e, |
| 346 | 346 | ||
| 347 | error.AnalysisFail => {}, // already reported | 347 | error.AnalysisFail => {}, |
| 348 | }; | 348 | }; |
| 349 | } | 349 | } |
| 350 | } | 350 | } |
| ... | @@ -455,7 +455,7 @@ fn detectEmbedFileUpdate(comp: *Compilation, tid: Zcu.PerThread.Id, ef_index: Zc | ... | @@ -455,7 +455,7 @@ fn detectEmbedFileUpdate(comp: *Compilation, tid: Zcu.PerThread.Id, ef_index: Zc |
| 455 | 455 | ||
| 456 | /// Ensures that `file` has up-to-date ZIR. If not, loads the ZIR cache or runs | 456 | /// Ensures that `file` has up-to-date ZIR. If not, loads the ZIR cache or runs |
| 457 | /// AstGen as needed. Also updates `file.status`. Does not assume that `file.mod` | 457 | /// AstGen as needed. Also updates `file.status`. Does not assume that `file.mod` |
| 458 | /// is populated. Does not return `error.AnalysisFail` on AstGen failures. | 458 | /// is populated. Returns success even if the file has AstGen errors. |
| 459 | pub fn updateFile( | 459 | pub fn updateFile( |
| 460 | pt: Zcu.PerThread, | 460 | pt: Zcu.PerThread, |
| 461 | file_index: Zcu.File.Index, | 461 | file_index: Zcu.File.Index, |
| ... | @@ -876,6 +876,7 @@ fn updateZirRefs(pt: Zcu.PerThread) (Io.Cancelable || Allocator.Error)!void { | ... | @@ -876,6 +876,7 @@ fn updateZirRefs(pt: Zcu.PerThread) (Io.Cancelable || Allocator.Error)!void { |
| 876 | const old_line = old_zir.getDeclaration(old_inst).src_line; | 876 | const old_line = old_zir.getDeclaration(old_inst).src_line; |
| 877 | const new_line = new_zir.getDeclaration(new_inst).src_line; | 877 | const new_line = new_zir.getDeclaration(new_inst).src_line; |
| 878 | if (old_line != new_line) { | 878 | if (old_line != new_line) { |
| 879 | comp.link_prog_node.increaseEstimatedTotalItems(1); | ||
| 879 | try comp.link_queue.enqueueZcu(comp, pt.tid, .{ .debug_update_line_number = tracked_inst_index }); | 880 | try comp.link_queue.enqueueZcu(comp, pt.tid, .{ .debug_update_line_number = tracked_inst_index }); |
| 880 | } | 881 | } |
| 881 | }, | 882 | }, |
| ... | @@ -1035,6 +1036,11 @@ pub fn ensureFilePopulated(pt: Zcu.PerThread, file_index: Zcu.File.Index) (Alloc | ... | @@ -1035,6 +1036,11 @@ pub fn ensureFilePopulated(pt: Zcu.PerThread, file_index: Zcu.File.Index) (Alloc |
| 1035 | zcu.setFileRootType(file_index, wip.finish(ip, new_namespace_index)); | 1036 | zcu.setFileRootType(file_index, wip.finish(ip, new_namespace_index)); |
| 1036 | } | 1037 | } |
| 1037 | 1038 | ||
| 1039 | const UpdateUnitError = Allocator.Error || Io.Cancelable || error{ | ||
| 1040 | /// Semantic analysis of this `AnalUnit` failed. | ||
| 1041 | AnalysisFail, | ||
| 1042 | }; | ||
| 1043 | |||
| 1038 | /// Ensures that all memoized state on `Zcu` is up-to-date, performing re-analysis if necessary. | 1044 | /// Ensures that all memoized state on `Zcu` is up-to-date, performing re-analysis if necessary. |
| 1039 | /// Returns `error.AnalysisFail` if an analysis error is encountered; the caller is free to ignore | 1045 | /// Returns `error.AnalysisFail` if an analysis error is encountered; the caller is free to ignore |
| 1040 | /// this, since the error is already registered, but it must not use the value of memoized fields. | 1046 | /// this, since the error is already registered, but it must not use the value of memoized fields. |
| ... | @@ -1043,7 +1049,7 @@ pub fn ensureMemoizedStateUpToDate( | ... | @@ -1043,7 +1049,7 @@ pub fn ensureMemoizedStateUpToDate( |
| 1043 | stage: InternPool.MemoizedStateStage, | 1049 | stage: InternPool.MemoizedStateStage, |
| 1044 | /// `null` is valid only for the "root" analysis, i.e. called from `Compilation.processOneJob`. | 1050 | /// `null` is valid only for the "root" analysis, i.e. called from `Compilation.processOneJob`. |
| 1045 | reason: ?*const Zcu.DependencyReason, | 1051 | reason: ?*const Zcu.DependencyReason, |
| 1046 | ) Zcu.SemaError!void { | 1052 | ) UpdateUnitError!void { |
| 1047 | const zcu = pt.zcu; | 1053 | const zcu = pt.zcu; |
| 1048 | const gpa = zcu.gpa; | 1054 | const gpa = zcu.gpa; |
| 1049 | 1055 | ||
| ... | @@ -1077,15 +1083,7 @@ pub fn ensureMemoizedStateUpToDate( | ... | @@ -1077,15 +1083,7 @@ pub fn ensureMemoizedStateUpToDate( |
| 1077 | const any_changed: bool, const new_failed: bool = if (pt.analyzeMemoizedState(stage, reason)) |any_changed| | 1083 | const any_changed: bool, const new_failed: bool = if (pt.analyzeMemoizedState(stage, reason)) |any_changed| |
| 1078 | .{ any_changed or prev_failed, false } | 1084 | .{ any_changed or prev_failed, false } |
| 1079 | else |err| switch (err) { | 1085 | else |err| switch (err) { |
| 1080 | error.AnalysisFail => res: { | 1086 | error.AlreadyReported => .{ !prev_failed, true }, |
| 1081 | if (!zcu.failed_analysis.contains(unit)) { | ||
| 1082 | // If this unit caused the error, it would have an entry in `failed_analysis`. | ||
| 1083 | // Since it does not, this must be a transitive failure. | ||
| 1084 | try zcu.transitive_failed_analysis.put(gpa, unit, {}); | ||
| 1085 | log.debug("mark transitive analysis failure for {f}", .{zcu.fmtAnalUnit(unit)}); | ||
| 1086 | } | ||
| 1087 | break :res .{ !prev_failed, true }; | ||
| 1088 | }, | ||
| 1089 | error.OutOfMemory => { | 1087 | error.OutOfMemory => { |
| 1090 | // TODO: same as for `ensureComptimeUnitUpToDate` etc | 1088 | // TODO: same as for `ensureComptimeUnitUpToDate` etc |
| 1091 | return error.OutOfMemory; | 1089 | return error.OutOfMemory; |
| ... | @@ -1153,7 +1151,7 @@ fn analyzeMemoizedState( | ... | @@ -1153,7 +1151,7 @@ fn analyzeMemoizedState( |
| 1153 | /// Ensures that the state of the given `ComptimeUnit` is fully up-to-date, performing re-analysis | 1151 | /// Ensures that the state of the given `ComptimeUnit` is fully up-to-date, performing re-analysis |
| 1154 | /// if necessary. Returns `error.AnalysisFail` if an analysis error is encountered; the caller is | 1152 | /// if necessary. Returns `error.AnalysisFail` if an analysis error is encountered; the caller is |
| 1155 | /// free to ignore this, since the error is already registered. | 1153 | /// free to ignore this, since the error is already registered. |
| 1156 | pub fn ensureComptimeUnitUpToDate(pt: Zcu.PerThread, cu_id: InternPool.ComptimeUnit.Id) Zcu.SemaError!void { | 1154 | pub fn ensureComptimeUnitUpToDate(pt: Zcu.PerThread, cu_id: InternPool.ComptimeUnit.Id) UpdateUnitError!void { |
| 1157 | const zcu = pt.zcu; | 1155 | const zcu = pt.zcu; |
| 1158 | const gpa = zcu.gpa; | 1156 | const gpa = zcu.gpa; |
| 1159 | 1157 | ||
| ... | @@ -1194,15 +1192,7 @@ pub fn ensureComptimeUnitUpToDate(pt: Zcu.PerThread, cu_id: InternPool.ComptimeU | ... | @@ -1194,15 +1192,7 @@ pub fn ensureComptimeUnitUpToDate(pt: Zcu.PerThread, cu_id: InternPool.ComptimeU |
| 1194 | defer unit_tracking.end(zcu); | 1192 | defer unit_tracking.end(zcu); |
| 1195 | 1193 | ||
| 1196 | return pt.analyzeComptimeUnit(cu_id) catch |err| switch (err) { | 1194 | return pt.analyzeComptimeUnit(cu_id) catch |err| switch (err) { |
| 1197 | error.AnalysisFail => { | 1195 | error.AlreadyReported => return error.AnalysisFail, |
| 1198 | if (!zcu.failed_analysis.contains(anal_unit)) { | ||
| 1199 | // If this unit caused the error, it would have an entry in `failed_analysis`. | ||
| 1200 | // Since it does not, this must be a transitive failure. | ||
| 1201 | try zcu.transitive_failed_analysis.put(gpa, anal_unit, {}); | ||
| 1202 | log.debug("mark transitive analysis failure for {f}", .{zcu.fmtAnalUnit(anal_unit)}); | ||
| 1203 | } | ||
| 1204 | return error.AnalysisFail; | ||
| 1205 | }, | ||
| 1206 | error.OutOfMemory => { | 1196 | error.OutOfMemory => { |
| 1207 | // TODO: it's unclear how to gracefully handle this. | 1197 | // TODO: it's unclear how to gracefully handle this. |
| 1208 | // To report the error cleanly, we need to add a message to `failed_analysis` and a | 1198 | // To report the error cleanly, we need to add a message to `failed_analysis` and a |
| ... | @@ -1220,8 +1210,7 @@ pub fn ensureComptimeUnitUpToDate(pt: Zcu.PerThread, cu_id: InternPool.ComptimeU | ... | @@ -1220,8 +1210,7 @@ pub fn ensureComptimeUnitUpToDate(pt: Zcu.PerThread, cu_id: InternPool.ComptimeU |
| 1220 | 1210 | ||
| 1221 | /// Re-analyzes a `ComptimeUnit`. The unit has already been determined to be out-of-date, and old | 1211 | /// Re-analyzes a `ComptimeUnit`. The unit has already been determined to be out-of-date, and old |
| 1222 | /// side effects (exports/references/etc) have been dropped. If semantic analysis fails, this | 1212 | /// side effects (exports/references/etc) have been dropped. If semantic analysis fails, this |
| 1223 | /// function will return `error.AnalysisFail`, and it is the caller's reponsibility to add an entry | 1213 | /// function will return `error.AlreadyReported`. |
| 1224 | /// to `transitive_failed_analysis` if necessary. | ||
| 1225 | fn analyzeComptimeUnit(pt: Zcu.PerThread, cu_id: InternPool.ComptimeUnit.Id) Zcu.CompileError!void { | 1214 | fn analyzeComptimeUnit(pt: Zcu.PerThread, cu_id: InternPool.ComptimeUnit.Id) Zcu.CompileError!void { |
| 1226 | const zcu = pt.zcu; | 1215 | const zcu = pt.zcu; |
| 1227 | const ip = &zcu.intern_pool; | 1216 | const ip = &zcu.intern_pool; |
| ... | @@ -1238,7 +1227,14 @@ fn analyzeComptimeUnit(pt: Zcu.PerThread, cu_id: InternPool.ComptimeUnit.Id) Zcu | ... | @@ -1238,7 +1227,14 @@ fn analyzeComptimeUnit(pt: Zcu.PerThread, cu_id: InternPool.ComptimeUnit.Id) Zcu |
| 1238 | defer tracy_trace.end(); | 1227 | defer tracy_trace.end(); |
| 1239 | tracy_trace.addTextFmt("cu_id={d}", .{cu_id}); | 1228 | tracy_trace.addTextFmt("cu_id={d}", .{cu_id}); |
| 1240 | 1229 | ||
| 1241 | const inst_resolved = comptime_unit.zir_index.resolveFull(ip) orelse return error.AnalysisFail; | 1230 | const inst_resolved = comptime_unit.zir_index.resolveFull(ip) orelse { |
| 1231 | try zcu.transitive_failed_analysis.putNoClobber( | ||
| 1232 | gpa, | ||
| 1233 | anal_unit, | ||
| 1234 | if (build_options.enable_debug_extensions) .{ .lost_tracking = comptime_unit.zir_index }, | ||
| 1235 | ); | ||
| 1236 | return error.AlreadyReported; | ||
| 1237 | }; | ||
| 1242 | const file = zcu.fileByIndex(inst_resolved.file); | 1238 | const file = zcu.fileByIndex(inst_resolved.file); |
| 1243 | const zir = file.zir.?; | 1239 | const zir = file.zir.?; |
| 1244 | 1240 | ||
| ... | @@ -1313,7 +1309,7 @@ pub fn ensureTypeLayoutUpToDate( | ... | @@ -1313,7 +1309,7 @@ pub fn ensureTypeLayoutUpToDate( |
| 1313 | ty: Type, | 1309 | ty: Type, |
| 1314 | /// `null` is valid only for the "root" analysis, i.e. called from `Compilation.processOneJob`. | 1310 | /// `null` is valid only for the "root" analysis, i.e. called from `Compilation.processOneJob`. |
| 1315 | reason: ?*const Zcu.DependencyReason, | 1311 | reason: ?*const Zcu.DependencyReason, |
| 1316 | ) Zcu.SemaError!void { | 1312 | ) UpdateUnitError!void { |
| 1317 | const zcu = pt.zcu; | 1313 | const zcu = pt.zcu; |
| 1318 | const ip = &zcu.intern_pool; | 1314 | const ip = &zcu.intern_pool; |
| 1319 | const comp = zcu.comp; | 1315 | const comp = zcu.comp; |
| ... | @@ -1398,15 +1394,7 @@ pub fn ensureTypeLayoutUpToDate( | ... | @@ -1398,15 +1394,7 @@ pub fn ensureTypeLayoutUpToDate( |
| 1398 | const new_failed: bool = if (result) failed: { | 1394 | const new_failed: bool = if (result) failed: { |
| 1399 | break :failed false; | 1395 | break :failed false; |
| 1400 | } else |err| switch (err) { | 1396 | } else |err| switch (err) { |
| 1401 | error.AnalysisFail => failed: { | 1397 | error.AlreadyReported => true, |
| 1402 | if (!zcu.failed_analysis.contains(anal_unit)) { | ||
| 1403 | // If this unit caused the error, it would have an entry in `failed_analysis`. | ||
| 1404 | // Since it does not, this must be a transitive failure. | ||
| 1405 | try zcu.transitive_failed_analysis.put(gpa, anal_unit, {}); | ||
| 1406 | log.debug("mark transitive analysis failure for {f}", .{zcu.fmtAnalUnit(anal_unit)}); | ||
| 1407 | } | ||
| 1408 | break :failed true; | ||
| 1409 | }, | ||
| 1410 | error.OutOfMemory, | 1398 | error.OutOfMemory, |
| 1411 | error.Canceled, | 1399 | error.Canceled, |
| 1412 | => |e| return e, | 1400 | => |e| return e, |
| ... | @@ -1441,7 +1429,7 @@ pub fn ensureStructDefaultsUpToDate( | ... | @@ -1441,7 +1429,7 @@ pub fn ensureStructDefaultsUpToDate( |
| 1441 | ty: Type, | 1429 | ty: Type, |
| 1442 | /// `null` is valid only for the "root" analysis, i.e. called from `Compilation.processOneJob`. | 1430 | /// `null` is valid only for the "root" analysis, i.e. called from `Compilation.processOneJob`. |
| 1443 | reason: ?*const Zcu.DependencyReason, | 1431 | reason: ?*const Zcu.DependencyReason, |
| 1444 | ) Zcu.SemaError!void { | 1432 | ) UpdateUnitError!void { |
| 1445 | const zcu = pt.zcu; | 1433 | const zcu = pt.zcu; |
| 1446 | const ip = &zcu.intern_pool; | 1434 | const ip = &zcu.intern_pool; |
| 1447 | const comp = zcu.comp; | 1435 | const comp = zcu.comp; |
| ... | @@ -1512,15 +1500,7 @@ pub fn ensureStructDefaultsUpToDate( | ... | @@ -1512,15 +1500,7 @@ pub fn ensureStructDefaultsUpToDate( |
| 1512 | const new_failed: bool = if (Sema.type_resolution.resolveStructDefaults(&sema, ty)) failed: { | 1500 | const new_failed: bool = if (Sema.type_resolution.resolveStructDefaults(&sema, ty)) failed: { |
| 1513 | break :failed false; | 1501 | break :failed false; |
| 1514 | } else |err| switch (err) { | 1502 | } else |err| switch (err) { |
| 1515 | error.AnalysisFail => failed: { | 1503 | error.AlreadyReported => true, |
| 1516 | if (!zcu.failed_analysis.contains(anal_unit)) { | ||
| 1517 | // If this unit caused the error, it would have an entry in `failed_analysis`. | ||
| 1518 | // Since it does not, this must be a transitive failure. | ||
| 1519 | try zcu.transitive_failed_analysis.put(gpa, anal_unit, {}); | ||
| 1520 | log.debug("mark transitive analysis failure for {f}", .{zcu.fmtAnalUnit(anal_unit)}); | ||
| 1521 | } | ||
| 1522 | break :failed true; | ||
| 1523 | }, | ||
| 1524 | error.OutOfMemory, | 1504 | error.OutOfMemory, |
| 1525 | error.Canceled, | 1505 | error.Canceled, |
| 1526 | => |e| return e, | 1506 | => |e| return e, |
| ... | @@ -1546,7 +1526,7 @@ pub fn ensureNavValUpToDate( | ... | @@ -1546,7 +1526,7 @@ pub fn ensureNavValUpToDate( |
| 1546 | nav_id: InternPool.Nav.Index, | 1526 | nav_id: InternPool.Nav.Index, |
| 1547 | /// `null` is valid only for the "root" analysis, i.e. called from `Compilation.processOneJob`. | 1527 | /// `null` is valid only for the "root" analysis, i.e. called from `Compilation.processOneJob`. |
| 1548 | reason: ?*const Zcu.DependencyReason, | 1528 | reason: ?*const Zcu.DependencyReason, |
| 1549 | ) Zcu.SemaError!void { | 1529 | ) UpdateUnitError!void { |
| 1550 | const zcu = pt.zcu; | 1530 | const zcu = pt.zcu; |
| 1551 | const gpa = zcu.gpa; | 1531 | const gpa = zcu.gpa; |
| 1552 | const ip = &zcu.intern_pool; | 1532 | const ip = &zcu.intern_pool; |
| ... | @@ -1593,15 +1573,7 @@ pub fn ensureNavValUpToDate( | ... | @@ -1593,15 +1573,7 @@ pub fn ensureNavValUpToDate( |
| 1593 | false, | 1573 | false, |
| 1594 | }; | 1574 | }; |
| 1595 | } else |err| switch (err) { | 1575 | } else |err| switch (err) { |
| 1596 | error.AnalysisFail => res: { | 1576 | error.AlreadyReported => .{ !prev_failed, true }, |
| 1597 | if (!zcu.failed_analysis.contains(anal_unit)) { | ||
| 1598 | // If this unit caused the error, it would have an entry in `failed_analysis`. | ||
| 1599 | // Since it does not, this must be a transitive failure. | ||
| 1600 | try zcu.transitive_failed_analysis.put(gpa, anal_unit, {}); | ||
| 1601 | log.debug("mark transitive analysis failure for {f}", .{zcu.fmtAnalUnit(anal_unit)}); | ||
| 1602 | } | ||
| 1603 | break :res .{ !prev_failed, true }; | ||
| 1604 | }, | ||
| 1605 | error.OutOfMemory => { | 1577 | error.OutOfMemory => { |
| 1606 | // TODO: it's unclear how to gracefully handle this. | 1578 | // TODO: it's unclear how to gracefully handle this. |
| 1607 | // To report the error cleanly, we need to add a message to `failed_analysis` and a | 1579 | // To report the error cleanly, we need to add a message to `failed_analysis` and a |
| ... | @@ -1654,7 +1626,14 @@ fn analyzeNavVal( | ... | @@ -1654,7 +1626,14 @@ fn analyzeNavVal( |
| 1654 | tracy_trace.addText(old_nav.fqn.toSlice(ip)); | 1626 | tracy_trace.addText(old_nav.fqn.toSlice(ip)); |
| 1655 | tracy_trace.addTextFmt("nav_id={d}", .{nav_id}); | 1627 | tracy_trace.addTextFmt("nav_id={d}", .{nav_id}); |
| 1656 | 1628 | ||
| 1657 | const inst_resolved = old_nav.analysis.?.zir_index.resolveFull(ip) orelse return error.AnalysisFail; | 1629 | const inst_resolved = old_nav.analysis.?.zir_index.resolveFull(ip) orelse { |
| 1630 | try zcu.transitive_failed_analysis.putNoClobber( | ||
| 1631 | gpa, | ||
| 1632 | anal_unit, | ||
| 1633 | if (build_options.enable_debug_extensions) .{ .lost_tracking = old_nav.analysis.?.zir_index }, | ||
| 1634 | ); | ||
| 1635 | return error.AlreadyReported; | ||
| 1636 | }; | ||
| 1658 | const file = zcu.fileByIndex(inst_resolved.file); | 1637 | const file = zcu.fileByIndex(inst_resolved.file); |
| 1659 | const zir = file.zir.?; | 1638 | const zir = file.zir.?; |
| 1660 | const zir_decl = zir.getDeclaration(inst_resolved.inst); | 1639 | const zir_decl = zir.getDeclaration(inst_resolved.inst); |
| ... | @@ -1915,7 +1894,7 @@ pub fn ensureNavTypeUpToDate( | ... | @@ -1915,7 +1894,7 @@ pub fn ensureNavTypeUpToDate( |
| 1915 | nav_id: InternPool.Nav.Index, | 1894 | nav_id: InternPool.Nav.Index, |
| 1916 | /// `null` is valid only for the "root" analysis, i.e. called from `Compilation.processOneJob`. | 1895 | /// `null` is valid only for the "root" analysis, i.e. called from `Compilation.processOneJob`. |
| 1917 | reason: ?*const Zcu.DependencyReason, | 1896 | reason: ?*const Zcu.DependencyReason, |
| 1918 | ) Zcu.SemaError!void { | 1897 | ) UpdateUnitError!void { |
| 1919 | const zcu = pt.zcu; | 1898 | const zcu = pt.zcu; |
| 1920 | const gpa = zcu.gpa; | 1899 | const gpa = zcu.gpa; |
| 1921 | const ip = &zcu.intern_pool; | 1900 | const ip = &zcu.intern_pool; |
| ... | @@ -1962,15 +1941,7 @@ pub fn ensureNavTypeUpToDate( | ... | @@ -1962,15 +1941,7 @@ pub fn ensureNavTypeUpToDate( |
| 1962 | false, | 1941 | false, |
| 1963 | }; | 1942 | }; |
| 1964 | } else |err| switch (err) { | 1943 | } else |err| switch (err) { |
| 1965 | error.AnalysisFail => res: { | 1944 | error.AlreadyReported => .{ !prev_failed, true }, |
| 1966 | if (!zcu.failed_analysis.contains(anal_unit)) { | ||
| 1967 | // If this unit caused the error, it would have an entry in `failed_analysis`. | ||
| 1968 | // Since it does not, this must be a transitive failure. | ||
| 1969 | try zcu.transitive_failed_analysis.put(gpa, anal_unit, {}); | ||
| 1970 | log.debug("mark transitive analysis failure for {f}", .{zcu.fmtAnalUnit(anal_unit)}); | ||
| 1971 | } | ||
| 1972 | break :res .{ !prev_failed, true }; | ||
| 1973 | }, | ||
| 1974 | error.OutOfMemory => { | 1945 | error.OutOfMemory => { |
| 1975 | // TODO: it's unclear how to gracefully handle this. | 1946 | // TODO: it's unclear how to gracefully handle this. |
| 1976 | // To report the error cleanly, we need to add a message to `failed_analysis` and a | 1947 | // To report the error cleanly, we need to add a message to `failed_analysis` and a |
| ... | @@ -2023,7 +1994,14 @@ fn analyzeNavType( | ... | @@ -2023,7 +1994,14 @@ fn analyzeNavType( |
| 2023 | tracy_trace.addText(old_nav.fqn.toSlice(ip)); | 1994 | tracy_trace.addText(old_nav.fqn.toSlice(ip)); |
| 2024 | tracy_trace.addTextFmt("nav_id={d}", .{nav_id}); | 1995 | tracy_trace.addTextFmt("nav_id={d}", .{nav_id}); |
| 2025 | 1996 | ||
| 2026 | const inst_resolved = old_nav.analysis.?.zir_index.resolveFull(ip) orelse return error.AnalysisFail; | 1997 | const inst_resolved = old_nav.analysis.?.zir_index.resolveFull(ip) orelse { |
| 1998 | try zcu.transitive_failed_analysis.putNoClobber( | ||
| 1999 | gpa, | ||
| 2000 | anal_unit, | ||
| 2001 | if (build_options.enable_debug_extensions) .{ .lost_tracking = old_nav.analysis.?.zir_index }, | ||
| 2002 | ); | ||
| 2003 | return error.AlreadyReported; | ||
| 2004 | }; | ||
| 2027 | const file = zcu.fileByIndex(inst_resolved.file); | 2005 | const file = zcu.fileByIndex(inst_resolved.file); |
| 2028 | const zir = file.zir.?; | 2006 | const zir = file.zir.?; |
| 2029 | 2007 | ||
| ... | @@ -2159,7 +2137,7 @@ pub fn ensureFuncBodyUpToDate( | ... | @@ -2159,7 +2137,7 @@ pub fn ensureFuncBodyUpToDate( |
| 2159 | func_index: InternPool.Index, | 2137 | func_index: InternPool.Index, |
| 2160 | /// `null` is valid only for the "root" analysis, i.e. called from `Compilation.processOneJob`. | 2138 | /// `null` is valid only for the "root" analysis, i.e. called from `Compilation.processOneJob`. |
| 2161 | reason: ?*const Zcu.DependencyReason, | 2139 | reason: ?*const Zcu.DependencyReason, |
| 2162 | ) Zcu.SemaError!void { | 2140 | ) UpdateUnitError!void { |
| 2163 | dev.check(.sema); | 2141 | dev.check(.sema); |
| 2164 | 2142 | ||
| 2165 | const zcu = pt.zcu; | 2143 | const zcu = pt.zcu; |
| ... | @@ -2203,18 +2181,10 @@ pub fn ensureFuncBodyUpToDate( | ... | @@ -2203,18 +2181,10 @@ pub fn ensureFuncBodyUpToDate( |
| 2203 | const ies_outdated, const new_failed = if (pt.analyzeFuncBody(func_index, reason)) |result| | 2181 | const ies_outdated, const new_failed = if (pt.analyzeFuncBody(func_index, reason)) |result| |
| 2204 | .{ prev_failed or result.ies_outdated, false } | 2182 | .{ prev_failed or result.ies_outdated, false } |
| 2205 | else |err| switch (err) { | 2183 | else |err| switch (err) { |
| 2206 | error.AnalysisFail => res: { | 2184 | // We consider the IES to be outdated if the function previously succeeded analysis; in this case, |
| 2207 | if (!zcu.failed_analysis.contains(anal_unit)) { | 2185 | // we need to re-analyze dependants to ensure they hit a transitive error here, rather than reporting |
| 2208 | // If this function caused the error, it would have an entry in `failed_analysis`. | 2186 | // a different error later (which may now be invalid). |
| 2209 | // Since it does not, this must be a transitive failure. | 2187 | error.AlreadyReported => .{ !prev_failed, true }, |
| 2210 | try zcu.transitive_failed_analysis.put(gpa, anal_unit, {}); | ||
| 2211 | log.debug("mark transitive analysis failure for {f}", .{zcu.fmtAnalUnit(anal_unit)}); | ||
| 2212 | } | ||
| 2213 | // We consider the IES to be outdated if the function previously succeeded analysis; in this case, | ||
| 2214 | // we need to re-analyze dependants to ensure they hit a transitive error here, rather than reporting | ||
| 2215 | // a different error later (which may now be invalid). | ||
| 2216 | break :res .{ !prev_failed, true }; | ||
| 2217 | }, | ||
| 2218 | error.OutOfMemory => { | 2188 | error.OutOfMemory => { |
| 2219 | // TODO: it's unclear how to gracefully handle this. | 2189 | // TODO: it's unclear how to gracefully handle this. |
| 2220 | // To report the error cleanly, we need to add a message to `failed_analysis` and a | 2190 | // To report the error cleanly, we need to add a message to `failed_analysis` and a |
| ... | @@ -3206,7 +3176,7 @@ const ScanDeclIter = struct { | ... | @@ -3206,7 +3176,7 @@ const ScanDeclIter = struct { |
| 3206 | if (is_named and comp.test_filters.len > 0) { | 3176 | if (is_named and comp.test_filters.len > 0) { |
| 3207 | const fqn_slice = fqn.toSlice(ip); | 3177 | const fqn_slice = fqn.toSlice(ip); |
| 3208 | for (comp.test_filters) |test_filter| { | 3178 | for (comp.test_filters) |test_filter| { |
| 3209 | if (std.mem.indexOf(u8, fqn_slice, test_filter) != null) break; | 3179 | if (std.mem.find(u8, fqn_slice, test_filter) != null) break; |
| 3210 | } else break :a false; | 3180 | } else break :a false; |
| 3211 | } | 3181 | } |
| 3212 | try zcu.test_functions.put(gpa, nav, {}); | 3182 | try zcu.test_functions.put(gpa, nav, {}); |
| ... | @@ -3292,9 +3262,7 @@ fn analyzeFuncBodyInner( | ... | @@ -3292,9 +3262,7 @@ fn analyzeFuncBodyInner( |
| 3292 | defer sema.deinit(); | 3262 | defer sema.deinit(); |
| 3293 | 3263 | ||
| 3294 | // Every runtime function has a dependency on the source of the Decl it originates from. | 3264 | // Every runtime function has a dependency on the source of the Decl it originates from. |
| 3295 | // It also depends on the value of its owner Decl. | ||
| 3296 | try sema.declareDependency(.{ .src_hash = decl_analysis.zir_index }); | 3265 | try sema.declareDependency(.{ .src_hash = decl_analysis.zir_index }); |
| 3297 | try sema.declareDependency(.{ .nav_val = func.owner_nav }); | ||
| 3298 | 3266 | ||
| 3299 | // Make sure that the declaration `Nav` still refers to this function (or its generic owner). | 3267 | // Make sure that the declaration `Nav` still refers to this function (or its generic owner). |
| 3300 | // This will not be the case if the incremental update has changed a function type or turned a | 3268 | // This will not be the case if the incremental update has changed a function type or turned a |
| ... | @@ -3305,15 +3273,23 @@ fn analyzeFuncBodyInner( | ... | @@ -3305,15 +3273,23 @@ fn analyzeFuncBodyInner( |
| 3305 | // If we *are* still owned by the right NAV, this analysis updates `zir_body_inst` if necessary. | 3273 | // If we *are* still owned by the right NAV, this analysis updates `zir_body_inst` if necessary. |
| 3306 | 3274 | ||
| 3307 | if (func.generic_owner == .none) { | 3275 | if (func.generic_owner == .none) { |
| 3308 | try pt.ensureNavValUpToDate(func.owner_nav, reason); | 3276 | try sema.declareDependency(.{ .nav_val = func.owner_nav }); |
| 3277 | pt.ensureNavValUpToDate(func.owner_nav, reason) catch |err| switch (err) { | ||
| 3278 | error.AnalysisFail => return sema.failTransitive(.{ .failed_unit = .wrap(.{ .nav_val = func.owner_nav }) }), | ||
| 3279 | else => |e| return e, | ||
| 3280 | }; | ||
| 3309 | if (ip.getNav(func.owner_nav).resolved.?.value != func_index) { | 3281 | if (ip.getNav(func.owner_nav).resolved.?.value != func_index) { |
| 3310 | return error.AnalysisFail; | 3282 | return sema.failTransitive(.{ .func_nav_val_changed = func_index }); |
| 3311 | } | 3283 | } |
| 3312 | } else { | 3284 | } else { |
| 3313 | const go_nav = zcu.funcInfo(func.generic_owner).owner_nav; | 3285 | const go_nav = zcu.funcInfo(func.generic_owner).owner_nav; |
| 3314 | try pt.ensureNavValUpToDate(go_nav, reason); | 3286 | try sema.declareDependency(.{ .nav_val = go_nav }); |
| 3287 | pt.ensureNavValUpToDate(go_nav, reason) catch |err| switch (err) { | ||
| 3288 | error.AnalysisFail => return sema.failTransitive(.{ .failed_unit = .wrap(.{ .nav_val = go_nav }) }), | ||
| 3289 | else => |e| return e, | ||
| 3290 | }; | ||
| 3315 | if (ip.getNav(go_nav).resolved.?.value != func.generic_owner) { | 3291 | if (ip.getNav(go_nav).resolved.?.value != func.generic_owner) { |
| 3316 | return error.AnalysisFail; | 3292 | return sema.failTransitive(.{ .func_nav_val_changed = func.generic_owner }); |
| 3317 | } | 3293 | } |
| 3318 | } | 3294 | } |
| 3319 | 3295 | ||
| ... | @@ -3343,7 +3319,9 @@ fn analyzeFuncBodyInner( | ... | @@ -3343,7 +3319,9 @@ fn analyzeFuncBodyInner( |
| 3343 | }; | 3319 | }; |
| 3344 | defer inner_block.instructions.deinit(gpa); | 3320 | defer inner_block.instructions.deinit(gpa); |
| 3345 | 3321 | ||
| 3346 | const fn_info = sema.code.getFnInfo(func.zirBodyInstUnordered(ip).resolve(ip) orelse return error.AnalysisFail); | 3322 | const fn_info = sema.code.getFnInfo(func.zirBodyInstUnordered(ip).resolve(ip) orelse { |
| 3323 | return sema.failTransitive(.{ .lost_tracking = func.zirBodyInstUnordered(ip) }); | ||
| 3324 | }); | ||
| 3347 | 3325 | ||
| 3348 | // Here we are performing "runtime semantic analysis" for a function body, which means | 3326 | // Here we are performing "runtime semantic analysis" for a function body, which means |
| 3349 | // we must map the parameter ZIR instructions to `arg` AIR instructions. | 3327 | // we must map the parameter ZIR instructions to `arg` AIR instructions. |
| ... | @@ -3520,6 +3498,25 @@ pub fn getErrorValueFromSlice(pt: Zcu.PerThread, name: []const u8) Allocator.Err | ... | @@ -3520,6 +3498,25 @@ pub fn getErrorValueFromSlice(pt: Zcu.PerThread, name: []const u8) Allocator.Err |
| 3520 | return pt.getErrorValue(try pt.zcu.intern_pool.getOrPutString(gpa, io, name)); | 3498 | return pt.getErrorValue(try pt.zcu.intern_pool.getOrPutString(gpa, io, name)); |
| 3521 | } | 3499 | } |
| 3522 | 3500 | ||
| 3501 | /// Asserts that `slice.len` is *not* undef. | ||
| 3502 | pub fn sliceToArrayPtr(pt: Zcu.PerThread, slice: InternPool.Key.Slice) Allocator.Error!Value { | ||
| 3503 | const zcu = pt.zcu; | ||
| 3504 | const slice_info = Type.fromInterned(slice.ty).ptrInfo(zcu); | ||
| 3505 | const array_ty = try pt.arrayType(.{ | ||
| 3506 | .len = Value.fromInterned(slice.len).toUnsignedInt(zcu), | ||
| 3507 | .child = slice_info.child, | ||
| 3508 | .sentinel = slice_info.sentinel, | ||
| 3509 | }); | ||
| 3510 | const ptr_ty = try pt.ptrType(ptr_info: { | ||
| 3511 | var ptr_info = slice_info; | ||
| 3512 | ptr_info.flags.size = .one; | ||
| 3513 | ptr_info.child = array_ty.toIntern(); | ||
| 3514 | ptr_info.sentinel = .none; | ||
| 3515 | break :ptr_info ptr_info; | ||
| 3516 | }); | ||
| 3517 | return pt.getCoerced(.fromInterned(slice.ptr), ptr_ty); | ||
| 3518 | } | ||
| 3519 | |||
| 3523 | /// Removes any entry from `Zcu.failed_files` associated with `file`. Acquires `Compilation.mutex` as needed. | 3520 | /// Removes any entry from `Zcu.failed_files` associated with `file`. Acquires `Compilation.mutex` as needed. |
| 3524 | /// `file.zir` must be unchanged from the last update, as it is used to determine if there is such an entry. | 3521 | /// `file.zir` must be unchanged from the last update, as it is used to determine if there is such an entry. |
| 3525 | fn lockAndClearFileCompileError(pt: Zcu.PerThread, file_index: Zcu.File.Index, file: *Zcu.File) void { | 3522 | fn lockAndClearFileCompileError(pt: Zcu.PerThread, file_index: Zcu.File.Index, file: *Zcu.File) void { |
| ... | @@ -4377,12 +4374,18 @@ pub fn getExtern(pt: Zcu.PerThread, key: InternPool.Key.Extern) (Io.Cancelable | | ... | @@ -4377,12 +4374,18 @@ pub fn getExtern(pt: Zcu.PerThread, key: InternPool.Key.Extern) (Io.Cancelable | |
| 4377 | return result.index; | 4374 | return result.index; |
| 4378 | } | 4375 | } |
| 4379 | 4376 | ||
| 4377 | const UpdateNamespaceError = Allocator.Error || Io.Cancelable || error{ | ||
| 4378 | /// This namespace refers to a ZIR container declaration which no longer exists, so any code | ||
| 4379 | /// referencing it is guaranteed to be unreferenced on this update. | ||
| 4380 | LostZirContainerDecl, | ||
| 4381 | }; | ||
| 4382 | |||
| 4380 | /// Given a namespace, re-scan its declarations from the type definition if they have not | 4383 | /// Given a namespace, re-scan its declarations from the type definition if they have not |
| 4381 | /// yet been re-scanned on this update. | 4384 | /// yet been re-scanned on this update. |
| 4382 | /// If the type declaration instruction has been lost, returns `error.AnalysisFail`. | 4385 | /// If the type declaration instruction has been lost, returns `error.LostZirContainerDecl`. |
| 4383 | /// This will effectively short-circuit the caller, which will be semantic analysis of a | 4386 | /// This will effectively short-circuit the caller, which will be semantic analysis of a |
| 4384 | /// guaranteed-unreferenced `AnalUnit`, to trigger a transitive analysis error. | 4387 | /// guaranteed-unreferenced `AnalUnit`, to trigger a transitive analysis error. |
| 4385 | pub fn ensureNamespaceUpToDate(pt: Zcu.PerThread, namespace_index: Zcu.Namespace.Index) Zcu.SemaError!void { | 4388 | pub fn ensureNamespaceUpToDate(pt: Zcu.PerThread, namespace_index: Zcu.Namespace.Index) UpdateNamespaceError!void { |
| 4386 | const zcu = pt.zcu; | 4389 | const zcu = pt.zcu; |
| 4387 | const ip = &zcu.intern_pool; | 4390 | const ip = &zcu.intern_pool; |
| 4388 | const namespace = zcu.namespacePtr(namespace_index); | 4391 | const namespace = zcu.namespacePtr(namespace_index); |
| ... | @@ -4409,7 +4412,7 @@ pub fn ensureNamespaceUpToDate(pt: Zcu.PerThread, namespace_index: Zcu.Namespace | ... | @@ -4409,7 +4412,7 @@ pub fn ensureNamespaceUpToDate(pt: Zcu.PerThread, namespace_index: Zcu.Namespace |
| 4409 | 4412 | ||
| 4410 | // Namespace outdated -- re-scan the type if necessary. | 4413 | // Namespace outdated -- re-scan the type if necessary. |
| 4411 | 4414 | ||
| 4412 | const inst_info = key.zir_index.resolveFull(ip) orelse return error.AnalysisFail; | 4415 | const inst_info = key.zir_index.resolveFull(ip) orelse return error.LostZirContainerDecl; |
| 4413 | const file = zcu.fileByIndex(inst_info.file); | 4416 | const file = zcu.fileByIndex(inst_info.file); |
| 4414 | const zir = &file.zir.?; | 4417 | const zir = &file.zir.?; |
| 4415 | 4418 |
src/codegen.zig+196-30| ... | @@ -767,11 +767,9 @@ fn lowerNavRef( | ... | @@ -767,11 +767,9 @@ fn lowerNavRef( |
| 767 | offset: u64, | 767 | offset: u64, |
| 768 | ) (Error || std.Io.Writer.Error)!void { | 768 | ) (Error || std.Io.Writer.Error)!void { |
| 769 | const zcu = pt.zcu; | 769 | const zcu = pt.zcu; |
| 770 | const gpa = zcu.gpa; | ||
| 771 | const ip = &zcu.intern_pool; | 770 | const ip = &zcu.intern_pool; |
| 772 | const target = &zcu.navFileScope(nav_index).mod.?.resolved_target.result; | 771 | const target = &zcu.navFileScope(nav_index).mod.?.resolved_target.result; |
| 773 | const ptr_width_bytes = @divExact(target.ptrBitWidth(), 8); | 772 | const ptr_width_bytes = @divExact(target.ptrBitWidth(), 8); |
| 774 | const is_obj = lf.comp.config.output_mode == .Obj; | ||
| 775 | const nav_ty = Type.fromInterned(ip.getNav(nav_index).resolved.?.type); | 773 | const nav_ty = Type.fromInterned(ip.getNav(nav_index).resolved.?.type); |
| 776 | 774 | ||
| 777 | if (!nav_ty.isRuntimeFnOrHasRuntimeBits(zcu) and ip.getNav(nav_index).getExtern(ip) == null) { | 775 | if (!nav_ty.isRuntimeFnOrHasRuntimeBits(zcu) and ip.getNav(nav_index).getExtern(ip) == null) { |
| ... | @@ -786,34 +784,7 @@ fn lowerNavRef( | ... | @@ -786,34 +784,7 @@ fn lowerNavRef( |
| 786 | dev.check(link.File.Tag.wasm.devFeature()); | 784 | dev.check(link.File.Tag.wasm.devFeature()); |
| 787 | const wasm = lf.cast(.wasm).?; | 785 | const wasm = lf.cast(.wasm).?; |
| 788 | assert(reloc_parent == .none); | 786 | assert(reloc_parent == .none); |
| 789 | if (nav_ty.zigTypeTag(zcu) == .@"fn") { | 787 | try wasm.addNavReloc(w.end, nav_index, nav_ty, @intCast(offset)); |
| 790 | const gop = try wasm.zcu_indirect_function_set.getOrPut(gpa, nav_index); | ||
| 791 | if (!gop.found_existing) gop.value_ptr.* = {}; | ||
| 792 | if (is_obj) { | ||
| 793 | @panic("TODO add out_reloc for this"); | ||
| 794 | } else { | ||
| 795 | try wasm.func_table_fixups.append(gpa, .{ | ||
| 796 | .table_index = @fromBackingInt(@intCast(gop.index)), | ||
| 797 | .offset = @intCast(w.end), | ||
| 798 | }); | ||
| 799 | } | ||
| 800 | } else { | ||
| 801 | if (is_obj) { | ||
| 802 | try wasm.out_relocs.append(gpa, .{ | ||
| 803 | .offset = @intCast(w.end), | ||
| 804 | .pointee = .{ .symbol_index = try wasm.navSymbolIndex(nav_index) }, | ||
| 805 | .tag = if (ptr_width_bytes == 4) .memory_addr_i32 else .memory_addr_i64, | ||
| 806 | .addend = @intCast(offset), | ||
| 807 | }); | ||
| 808 | } else { | ||
| 809 | try wasm.nav_fixups.ensureUnusedCapacity(gpa, 1); | ||
| 810 | wasm.nav_fixups.appendAssumeCapacity(.{ | ||
| 811 | .navs_exe_index = try wasm.refNavExe(nav_index), | ||
| 812 | .offset = @intCast(w.end), | ||
| 813 | .addend = @intCast(offset), | ||
| 814 | }); | ||
| 815 | } | ||
| 816 | } | ||
| 817 | try w.splatByteAll(0, ptr_width_bytes); | 788 | try w.splatByteAll(0, ptr_width_bytes); |
| 818 | return; | 789 | return; |
| 819 | }, | 790 | }, |
| ... | @@ -1124,6 +1095,201 @@ pub fn fieldOffset(ptr_agg_ty: Type, ptr_field_ty: Type, field_index: u32, zcu: | ... | @@ -1124,6 +1095,201 @@ pub fn fieldOffset(ptr_agg_ty: Type, ptr_field_ty: Type, field_index: u32, zcu: |
| 1124 | }; | 1095 | }; |
| 1125 | } | 1096 | } |
| 1126 | 1097 | ||
| 1098 | pub const FlattenedItem = struct { offset: u64, type: ?Type }; | ||
| 1099 | pub fn flattenType(items_buf: []FlattenedItem, ty: Type, zcu: *Zcu, opts: struct { | ||
| 1100 | offset: u64 = 0, | ||
| 1101 | allow_arrays: bool = true, | ||
| 1102 | fn increaseOffset(opts: @This(), offset: u64) @This() { | ||
| 1103 | return .{ | ||
| 1104 | .offset = opts.offset + offset, | ||
| 1105 | .allow_arrays = opts.allow_arrays, | ||
| 1106 | }; | ||
| 1107 | } | ||
| 1108 | }) ?[]FlattenedItem { | ||
| 1109 | const ip = &zcu.intern_pool; | ||
| 1110 | switch (ip.indexToKey(ty.toIntern())) { | ||
| 1111 | .int_type => |int_type| { | ||
| 1112 | if (int_type.bits == 0) return items_buf[0..0]; | ||
| 1113 | if (items_buf.len < 1) return null; | ||
| 1114 | const items = items_buf[0..1]; | ||
| 1115 | items.* = .{.{ .offset = opts.offset, .type = ty }}; | ||
| 1116 | return items; | ||
| 1117 | }, | ||
| 1118 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { | ||
| 1119 | .one, .many, .c => { | ||
| 1120 | if (items_buf.len < 1) return null; | ||
| 1121 | const items = items_buf[0..1]; | ||
| 1122 | items.* = .{.{ .offset = opts.offset, .type = ty }}; | ||
| 1123 | return items; | ||
| 1124 | }, | ||
| 1125 | .slice => { | ||
| 1126 | if (items_buf.len < 2) return null; | ||
| 1127 | const items = items_buf[0..2]; | ||
| 1128 | const ptr_field_ty = ty.slicePtrFieldType(zcu); | ||
| 1129 | items.* = .{ | ||
| 1130 | .{ .offset = opts.offset, .type = ptr_field_ty }, | ||
| 1131 | .{ .offset = opts.offset + ptr_field_ty.abiSize(zcu), .type = .usize }, | ||
| 1132 | }; | ||
| 1133 | return items; | ||
| 1134 | }, | ||
| 1135 | }, | ||
| 1136 | .array_type => |array_type| { | ||
| 1137 | const len = array_type.lenIncludingSentinel(); | ||
| 1138 | if (len == 0) return items_buf[0..0]; | ||
| 1139 | const elem_ty: Type = .fromInterned(array_type.child); | ||
| 1140 | const elem_items = flattenType(items_buf, elem_ty, zcu, opts) orelse return null; | ||
| 1141 | if (elem_items.len == 0) return items_buf[0..0]; | ||
| 1142 | if (!opts.allow_arrays) return null; | ||
| 1143 | const items_len, const items_overflow = @mulWithOverflow(elem_items.len, len); | ||
| 1144 | if (items_overflow != 0 or items_buf.len < items_len) return null; | ||
| 1145 | var items_index = elem_items.len; | ||
| 1146 | const elem_size = elem_ty.abiSize(zcu); | ||
| 1147 | var elem_offset: u64 = elem_size; | ||
| 1148 | while (items_index != items_len) : ({ | ||
| 1149 | items_index += elem_items.len; | ||
| 1150 | elem_offset += elem_size; | ||
| 1151 | }) for (items_buf[items_index..][0..elem_items.len], elem_items) |*item, elem_item| { | ||
| 1152 | item.* = .{ .offset = elem_offset + elem_item.offset, .type = elem_item.type }; | ||
| 1153 | }; | ||
| 1154 | return items_buf[0..@intCast(items_len)]; | ||
| 1155 | }, | ||
| 1156 | .vector_type => |vector_type| { | ||
| 1157 | if (vector_type.len == 0) return items_buf[0..0]; | ||
| 1158 | if (items_buf.len < 1) return null; | ||
| 1159 | const items = items_buf[0..1]; | ||
| 1160 | items.* = .{.{ .offset = opts.offset, .type = ty }}; | ||
| 1161 | return items; | ||
| 1162 | }, | ||
| 1163 | .opt_type, .error_union_type => return null, | ||
| 1164 | .simple_type => |simple_type| switch (simple_type) { | ||
| 1165 | .f16, | ||
| 1166 | .f32, | ||
| 1167 | .f64, | ||
| 1168 | .f80, | ||
| 1169 | .f128, | ||
| 1170 | .usize, | ||
| 1171 | .isize, | ||
| 1172 | .c_char, | ||
| 1173 | .c_short, | ||
| 1174 | .c_ushort, | ||
| 1175 | .c_int, | ||
| 1176 | .c_uint, | ||
| 1177 | .c_long, | ||
| 1178 | .c_ulong, | ||
| 1179 | .c_longlong, | ||
| 1180 | .c_ulonglong, | ||
| 1181 | .c_longdouble, | ||
| 1182 | .bool, | ||
| 1183 | .anyerror, | ||
| 1184 | => { | ||
| 1185 | if (items_buf.len < 1) return null; | ||
| 1186 | const items = items_buf[0..1]; | ||
| 1187 | items.* = .{.{ .offset = opts.offset, .type = ty }}; | ||
| 1188 | return items; | ||
| 1189 | }, | ||
| 1190 | .anyopaque, .noreturn => return null, | ||
| 1191 | .void, | ||
| 1192 | .type, | ||
| 1193 | .comptime_int, | ||
| 1194 | .comptime_float, | ||
| 1195 | .null, | ||
| 1196 | .undefined, | ||
| 1197 | .enum_literal, | ||
| 1198 | => return items_buf[0..0], | ||
| 1199 | .adhoc_inferred_error_set, .generic_poison => unreachable, | ||
| 1200 | }, | ||
| 1201 | .struct_type => { | ||
| 1202 | const loaded_struct = ip.loadStructType(ty.toIntern()); | ||
| 1203 | switch (loaded_struct.layout) { | ||
| 1204 | .auto, .@"extern" => {}, | ||
| 1205 | .@"packed" => return flattenType(items_buf, .fromInterned( | ||
| 1206 | loaded_struct.packed_backing_int_type, | ||
| 1207 | ), zcu, opts), | ||
| 1208 | } | ||
| 1209 | var items_len: usize = 0; | ||
| 1210 | var offset: u64 = 0; | ||
| 1211 | var field_it = loaded_struct.iterateRuntimeOrder(ip); | ||
| 1212 | while (field_it.next()) |field_index| { | ||
| 1213 | const field_ty: Type = .fromInterned(loaded_struct.field_types.get(ip)[field_index]); | ||
| 1214 | const field_offset = loaded_struct.field_offsets.get(ip)[field_index]; | ||
| 1215 | if (field_offset - offset > 0 and | ||
| 1216 | (items_len == 0 or items_buf[items_len - 1].type != null)) | ||
| 1217 | { | ||
| 1218 | if (items_len == items_buf.len) return null; | ||
| 1219 | items_buf[items_len] = .{ .offset = offset, .type = null }; | ||
| 1220 | items_len += 1; | ||
| 1221 | } | ||
| 1222 | items_len += (flattenType(items_buf[items_len..], field_ty, zcu, opts.increaseOffset( | ||
| 1223 | field_offset, | ||
| 1224 | )) orelse return null).len; | ||
| 1225 | offset = field_offset + field_ty.abiSize(zcu); | ||
| 1226 | } | ||
| 1227 | if (ty.abiSize(zcu) - offset > 0 and | ||
| 1228 | (items_len == 0 or items_buf[items_len - 1].type != null)) | ||
| 1229 | { | ||
| 1230 | if (items_len == items_buf.len) return null; | ||
| 1231 | items_buf[items_len] = .{ .offset = offset, .type = null }; | ||
| 1232 | items_len += 1; | ||
| 1233 | } | ||
| 1234 | return items_buf[0..items_len]; | ||
| 1235 | }, | ||
| 1236 | .tuple_type => |tuple_type| { | ||
| 1237 | if (items_buf.len < tuple_type.types.len) return null; | ||
| 1238 | var items_len: usize = 0; | ||
| 1239 | var offset: u64 = 0; | ||
| 1240 | for (tuple_type.types.get(ip)) |field_ty_ip| { | ||
| 1241 | const field_ty: Type = .fromInterned(field_ty_ip); | ||
| 1242 | offset = field_ty.abiAlignment(zcu).forward(offset); | ||
| 1243 | items_len += (flattenType(items_buf[items_len..], field_ty, zcu, opts.increaseOffset( | ||
| 1244 | offset, | ||
| 1245 | )) orelse return null).len; | ||
| 1246 | offset += field_ty.abiSize(zcu); | ||
| 1247 | } | ||
| 1248 | return items_buf[0..items_len]; | ||
| 1249 | }, | ||
| 1250 | .union_type => { | ||
| 1251 | const loaded_union = ip.loadUnionType(ty.toIntern()); | ||
| 1252 | return switch (loaded_union.layout) { | ||
| 1253 | .auto, .@"extern" => return null, | ||
| 1254 | .@"packed" => return flattenType(items_buf, .fromInterned( | ||
| 1255 | loaded_union.packed_backing_int_type, | ||
| 1256 | ), zcu, opts), | ||
| 1257 | }; | ||
| 1258 | }, | ||
| 1259 | .opaque_type, .spirv_type, .func_type => return null, | ||
| 1260 | .enum_type => return flattenType(items_buf, .fromInterned( | ||
| 1261 | ip.loadEnumType(ty.toIntern()).int_tag_type, | ||
| 1262 | ), zcu, opts), | ||
| 1263 | .error_set_type, .inferred_error_set_type => { | ||
| 1264 | if (items_buf.len < 1) return null; | ||
| 1265 | const items = items_buf[0..1]; | ||
| 1266 | items.* = .{.{ .offset = opts.offset, .type = ty }}; | ||
| 1267 | return items; | ||
| 1268 | }, | ||
| 1269 | .anyframe_type, | ||
| 1270 | // values, not types | ||
| 1271 | .undef, | ||
| 1272 | .simple_value, | ||
| 1273 | .@"extern", | ||
| 1274 | .func, | ||
| 1275 | .int, | ||
| 1276 | .err, | ||
| 1277 | .error_union, | ||
| 1278 | .enum_literal, | ||
| 1279 | .enum_tag, | ||
| 1280 | .float, | ||
| 1281 | .ptr, | ||
| 1282 | .slice, | ||
| 1283 | .opt, | ||
| 1284 | .aggregate, | ||
| 1285 | .un, | ||
| 1286 | .bitpack, | ||
| 1287 | // memoization, not types | ||
| 1288 | .memoized_call, | ||
| 1289 | => unreachable, | ||
| 1290 | } | ||
| 1291 | } | ||
| 1292 | |||
| 1127 | test { | 1293 | test { |
| 1128 | _ = aarch64; | 1294 | _ = aarch64; |
| 1129 | } | 1295 | } |
src/codegen/aarch64/Assemble.zig+1-1| ... | @@ -163,7 +163,7 @@ const matchers = matchers: { | ... | @@ -163,7 +163,7 @@ const matchers = matchers: { |
| 163 | arg.* = zonCast(param_type.?, instruction.encode[encode_index], symbols); | 163 | arg.* = zonCast(param_type.?, instruction.encode[encode_index], symbols); |
| 164 | return @call(.auto, encode, args); | 164 | return @call(.auto, encode, args); |
| 165 | } else if (pattern_token[0] == '<') { | 165 | } else if (pattern_token[0] == '<') { |
| 166 | const symbol_name = comptime pattern_token[1 .. std.mem.indexOfScalarPos(u8, pattern_token, 1, '|') orelse | 166 | const symbol_name = comptime pattern_token[1 .. std.mem.findScalarPos(u8, pattern_token, 1, '|') orelse |
| 167 | pattern_token.len - 1]; | 167 | pattern_token.len - 1]; |
| 168 | const symbol = @field(Symbol, symbol_name); | 168 | const symbol = @field(Symbol, symbol_name); |
| 169 | const symbol_ptr = &@field(symbols, symbol_name); | 169 | const symbol_ptr = &@field(symbols, symbol_name); |
src/codegen/aarch64/Mir.zig+2-2| ... | @@ -70,8 +70,8 @@ pub fn emit( | ... | @@ -70,8 +70,8 @@ pub fn emit( |
| 70 | 70 | ||
| 71 | const func_align = switch (nav.resolved.?.@"align") { | 71 | const func_align = switch (nav.resolved.?.@"align") { |
| 72 | .none => switch (mod.optimize_mode) { | 72 | .none => switch (mod.optimize_mode) { |
| 73 | .Debug, .ReleaseSafe, .ReleaseFast => target_util.defaultFunctionAlignment(target), | 73 | .debug, .safe, .fast => target_util.defaultFunctionAlignment(target), |
| 74 | .ReleaseSmall => target_util.minFunctionAlignment(target), | 74 | .small => target_util.minFunctionAlignment(target), |
| 75 | }, | 75 | }, |
| 76 | else => |a| a.maxStrict(target_util.minFunctionAlignment(target)), | 76 | else => |a| a.maxStrict(target_util.minFunctionAlignment(target)), |
| 77 | }; | 77 | }; |
src/codegen/aarch64/Select.zig+23-27| ... | @@ -2099,7 +2099,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, | ... | @@ -2099,7 +2099,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, |
| 2099 | 32 => "truncf", | 2099 | 32 => "truncf", |
| 2100 | 64 => "trunc", | 2100 | 64 => "trunc", |
| 2101 | 80 => "__truncx", | 2101 | 80 => "__truncx", |
| 2102 | 128 => "truncq", | 2102 | 128 => "truncf128", |
| 2103 | }, | 2103 | }, |
| 2104 | .reloc = .{ .label = @intCast(isel.instructions.items.len) }, | 2104 | .reloc = .{ .label = @intCast(isel.instructions.items.len) }, |
| 2105 | }); | 2105 | }); |
| ... | @@ -2113,7 +2113,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, | ... | @@ -2113,7 +2113,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, |
| 2113 | 32 => "floorf", | 2113 | 32 => "floorf", |
| 2114 | 64 => "floor", | 2114 | 64 => "floor", |
| 2115 | 80 => "__floorx", | 2115 | 80 => "__floorx", |
| 2116 | 128 => "floorq", | 2116 | 128 => "floorf128", |
| 2117 | }, | 2117 | }, |
| 2118 | .reloc = .{ .label = @intCast(isel.instructions.items.len) }, | 2118 | .reloc = .{ .label = @intCast(isel.instructions.items.len) }, |
| 2119 | }); | 2119 | }); |
| ... | @@ -2431,7 +2431,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, | ... | @@ -2431,7 +2431,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, |
| 2431 | 32 => "fmodf", | 2431 | 32 => "fmodf", |
| 2432 | 64 => "fmod", | 2432 | 64 => "fmod", |
| 2433 | 80 => "__fmodx", | 2433 | 80 => "__fmodx", |
| 2434 | 128 => "fmodq", | 2434 | 128 => "fmodf128", |
| 2435 | }, | 2435 | }, |
| 2436 | .reloc = .{ .label = @intCast(isel.instructions.items.len) }, | 2436 | .reloc = .{ .label = @intCast(isel.instructions.items.len) }, |
| 2437 | }); | 2437 | }); |
| ... | @@ -2599,7 +2599,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, | ... | @@ -2599,7 +2599,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, |
| 2599 | 32 => "fmaxf", | 2599 | 32 => "fmaxf", |
| 2600 | 64 => "fmax", | 2600 | 64 => "fmax", |
| 2601 | 80 => "__fmaxx", | 2601 | 80 => "__fmaxx", |
| 2602 | 128 => "fmaxq", | 2602 | 128 => "fmaxf128", |
| 2603 | }, | 2603 | }, |
| 2604 | .min => switch (bits) { | 2604 | .min => switch (bits) { |
| 2605 | else => unreachable, | 2605 | else => unreachable, |
| ... | @@ -2607,7 +2607,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, | ... | @@ -2607,7 +2607,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, |
| 2607 | 32 => "fminf", | 2607 | 32 => "fminf", |
| 2608 | 64 => "fmin", | 2608 | 64 => "fmin", |
| 2609 | 80 => "__fminx", | 2609 | 80 => "__fminx", |
| 2610 | 128 => "fminq", | 2610 | 128 => "fminf128", |
| 2611 | }, | 2611 | }, |
| 2612 | }, | 2612 | }, |
| 2613 | .reloc = .{ .label = @intCast(isel.instructions.items.len) }, | 2613 | .reloc = .{ .label = @intCast(isel.instructions.items.len) }, |
| ... | @@ -2856,7 +2856,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, | ... | @@ -2856,7 +2856,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, |
| 2856 | const remaining_source = std.mem.span(as.source); | 2856 | const remaining_source = std.mem.span(as.source); |
| 2857 | return isel.fail("unable to assemble: '{s}'", .{std.mem.trim( | 2857 | return isel.fail("unable to assemble: '{s}'", .{std.mem.trim( |
| 2858 | u8, | 2858 | u8, |
| 2859 | as.source[0 .. std.mem.indexOfScalar(u8, remaining_source, '\n') orelse remaining_source.len], | 2859 | as.source[0 .. std.mem.findScalar(u8, remaining_source, '\n') orelse remaining_source.len], |
| 2860 | &std.ascii.whitespace, | 2860 | &std.ascii.whitespace, |
| 2861 | )}); | 2861 | )}); |
| 2862 | }, | 2862 | }, |
| ... | @@ -4055,7 +4055,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, | ... | @@ -4055,7 +4055,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, |
| 4055 | 32 => "sqrtf", | 4055 | 32 => "sqrtf", |
| 4056 | 64 => "sqrt", | 4056 | 64 => "sqrt", |
| 4057 | 80 => "__sqrtx", | 4057 | 80 => "__sqrtx", |
| 4058 | 128 => "sqrtq", | 4058 | 128 => "sqrtf128", |
| 4059 | }, | 4059 | }, |
| 4060 | .floor => switch (bits) { | 4060 | .floor => switch (bits) { |
| 4061 | else => unreachable, | 4061 | else => unreachable, |
| ... | @@ -4063,7 +4063,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, | ... | @@ -4063,7 +4063,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, |
| 4063 | 32 => "floorf", | 4063 | 32 => "floorf", |
| 4064 | 64 => "floor", | 4064 | 64 => "floor", |
| 4065 | 80 => "__floorx", | 4065 | 80 => "__floorx", |
| 4066 | 128 => "floorq", | 4066 | 128 => "floorf128", |
| 4067 | }, | 4067 | }, |
| 4068 | .ceil => switch (bits) { | 4068 | .ceil => switch (bits) { |
| 4069 | else => unreachable, | 4069 | else => unreachable, |
| ... | @@ -4071,7 +4071,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, | ... | @@ -4071,7 +4071,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, |
| 4071 | 32 => "ceilf", | 4071 | 32 => "ceilf", |
| 4072 | 64 => "ceil", | 4072 | 64 => "ceil", |
| 4073 | 80 => "__ceilx", | 4073 | 80 => "__ceilx", |
| 4074 | 128 => "ceilq", | 4074 | 128 => "ceilf128", |
| 4075 | }, | 4075 | }, |
| 4076 | .round => switch (bits) { | 4076 | .round => switch (bits) { |
| 4077 | else => unreachable, | 4077 | else => unreachable, |
| ... | @@ -4079,7 +4079,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, | ... | @@ -4079,7 +4079,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, |
| 4079 | 32 => "roundf", | 4079 | 32 => "roundf", |
| 4080 | 64 => "round", | 4080 | 64 => "round", |
| 4081 | 80 => "__roundx", | 4081 | 80 => "__roundx", |
| 4082 | 128 => "roundq", | 4082 | 128 => "roundf128", |
| 4083 | }, | 4083 | }, |
| 4084 | .trunc_float => switch (bits) { | 4084 | .trunc_float => switch (bits) { |
| 4085 | else => unreachable, | 4085 | else => unreachable, |
| ... | @@ -4087,7 +4087,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, | ... | @@ -4087,7 +4087,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, |
| 4087 | 32 => "truncf", | 4087 | 32 => "truncf", |
| 4088 | 64 => "trunc", | 4088 | 64 => "trunc", |
| 4089 | 80 => "__truncx", | 4089 | 80 => "__truncx", |
| 4090 | 128 => "truncq", | 4090 | 128 => "truncf128", |
| 4091 | }, | 4091 | }, |
| 4092 | }, | 4092 | }, |
| 4093 | .reloc = .{ .label = @intCast(isel.instructions.items.len) }, | 4093 | .reloc = .{ .label = @intCast(isel.instructions.items.len) }, |
| ... | @@ -4147,7 +4147,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, | ... | @@ -4147,7 +4147,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, |
| 4147 | 32 => "sinf", | 4147 | 32 => "sinf", |
| 4148 | 64 => "sin", | 4148 | 64 => "sin", |
| 4149 | 80 => "__sinx", | 4149 | 80 => "__sinx", |
| 4150 | 128 => "sinq", | 4150 | 128 => "sinf128", |
| 4151 | }, | 4151 | }, |
| 4152 | .cos => switch (bits) { | 4152 | .cos => switch (bits) { |
| 4153 | else => unreachable, | 4153 | else => unreachable, |
| ... | @@ -4155,7 +4155,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, | ... | @@ -4155,7 +4155,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, |
| 4155 | 32 => "cosf", | 4155 | 32 => "cosf", |
| 4156 | 64 => "cos", | 4156 | 64 => "cos", |
| 4157 | 80 => "__cosx", | 4157 | 80 => "__cosx", |
| 4158 | 128 => "cosq", | 4158 | 128 => "cosf128", |
| 4159 | }, | 4159 | }, |
| 4160 | .tan => switch (bits) { | 4160 | .tan => switch (bits) { |
| 4161 | else => unreachable, | 4161 | else => unreachable, |
| ... | @@ -4163,7 +4163,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, | ... | @@ -4163,7 +4163,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, |
| 4163 | 32 => "tanf", | 4163 | 32 => "tanf", |
| 4164 | 64 => "tan", | 4164 | 64 => "tan", |
| 4165 | 80 => "__tanx", | 4165 | 80 => "__tanx", |
| 4166 | 128 => "tanq", | 4166 | 128 => "tanf128", |
| 4167 | }, | 4167 | }, |
| 4168 | .exp => switch (bits) { | 4168 | .exp => switch (bits) { |
| 4169 | else => unreachable, | 4169 | else => unreachable, |
| ... | @@ -4171,7 +4171,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, | ... | @@ -4171,7 +4171,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, |
| 4171 | 32 => "expf", | 4171 | 32 => "expf", |
| 4172 | 64 => "exp", | 4172 | 64 => "exp", |
| 4173 | 80 => "__expx", | 4173 | 80 => "__expx", |
| 4174 | 128 => "expq", | 4174 | 128 => "expf128", |
| 4175 | }, | 4175 | }, |
| 4176 | .exp2 => switch (bits) { | 4176 | .exp2 => switch (bits) { |
| 4177 | else => unreachable, | 4177 | else => unreachable, |
| ... | @@ -4179,7 +4179,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, | ... | @@ -4179,7 +4179,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, |
| 4179 | 32 => "exp2f", | 4179 | 32 => "exp2f", |
| 4180 | 64 => "exp2", | 4180 | 64 => "exp2", |
| 4181 | 80 => "__exp2x", | 4181 | 80 => "__exp2x", |
| 4182 | 128 => "exp2q", | 4182 | 128 => "exp2f128", |
| 4183 | }, | 4183 | }, |
| 4184 | .log => switch (bits) { | 4184 | .log => switch (bits) { |
| 4185 | else => unreachable, | 4185 | else => unreachable, |
| ... | @@ -4187,7 +4187,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, | ... | @@ -4187,7 +4187,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, |
| 4187 | 32 => "logf", | 4187 | 32 => "logf", |
| 4188 | 64 => "log", | 4188 | 64 => "log", |
| 4189 | 80 => "__logx", | 4189 | 80 => "__logx", |
| 4190 | 128 => "logq", | 4190 | 128 => "logf128", |
| 4191 | }, | 4191 | }, |
| 4192 | .log2 => switch (bits) { | 4192 | .log2 => switch (bits) { |
| 4193 | else => unreachable, | 4193 | else => unreachable, |
| ... | @@ -4195,7 +4195,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, | ... | @@ -4195,7 +4195,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, |
| 4195 | 32 => "log2f", | 4195 | 32 => "log2f", |
| 4196 | 64 => "log2", | 4196 | 64 => "log2", |
| 4197 | 80 => "__log2x", | 4197 | 80 => "__log2x", |
| 4198 | 128 => "log2q", | 4198 | 128 => "log2f128", |
| 4199 | }, | 4199 | }, |
| 4200 | .log10 => switch (bits) { | 4200 | .log10 => switch (bits) { |
| 4201 | else => unreachable, | 4201 | else => unreachable, |
| ... | @@ -4203,7 +4203,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, | ... | @@ -4203,7 +4203,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, |
| 4203 | 32 => "log10f", | 4203 | 32 => "log10f", |
| 4204 | 64 => "log10", | 4204 | 64 => "log10", |
| 4205 | 80 => "__log10x", | 4205 | 80 => "__log10x", |
| 4206 | 128 => "log10q", | 4206 | 128 => "log10f128", |
| 4207 | }, | 4207 | }, |
| 4208 | }, | 4208 | }, |
| 4209 | .reloc = .{ .label = @intCast(isel.instructions.items.len) }, | 4209 | .reloc = .{ .label = @intCast(isel.instructions.items.len) }, |
| ... | @@ -7118,7 +7118,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, | ... | @@ -7118,7 +7118,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, |
| 7118 | 32 => "fmaf", | 7118 | 32 => "fmaf", |
| 7119 | 64 => "fma", | 7119 | 64 => "fma", |
| 7120 | 80 => "__fmax", | 7120 | 80 => "__fmax", |
| 7121 | 128 => "fmaq", | 7121 | 128 => "fmaf128", |
| 7122 | }, | 7122 | }, |
| 7123 | .reloc = .{ .label = @intCast(isel.instructions.items.len) }, | 7123 | .reloc = .{ .label = @intCast(isel.instructions.items.len) }, |
| 7124 | }); | 7124 | }); |
| ... | @@ -12176,9 +12176,7 @@ pub const CallAbiIterator = struct { | ... | @@ -12176,9 +12176,7 @@ pub const CallAbiIterator = struct { |
| 12176 | const loaded_struct = ip.loadStructType(ty.toIntern()); | 12176 | const loaded_struct = ip.loadStructType(ty.toIntern()); |
| 12177 | switch (loaded_struct.layout) { | 12177 | switch (loaded_struct.layout) { |
| 12178 | .auto, .@"extern" => {}, | 12178 | .auto, .@"extern" => {}, |
| 12179 | .@"packed" => continue :type_key .{ | 12179 | .@"packed" => continue :type_key ip.indexToKey(loaded_struct.packed_backing_int_type), |
| 12180 | .int_type = ip.indexToKey(loaded_struct.packed_backing_int_type).int_type, | ||
| 12181 | }, | ||
| 12182 | } | 12180 | } |
| 12183 | const size = wip_vi.size(isel); | 12181 | const size = wip_vi.size(isel); |
| 12184 | if (size <= 16 * 4) homogeneous_aggregate: { | 12182 | if (size <= 16 * 4) homogeneous_aggregate: { |
| ... | @@ -12300,9 +12298,7 @@ pub const CallAbiIterator = struct { | ... | @@ -12300,9 +12298,7 @@ pub const CallAbiIterator = struct { |
| 12300 | } | 12298 | } |
| 12301 | }, | 12299 | }, |
| 12302 | .opaque_type, .func_type => continue :type_key .{ .simple_type = .anyopaque }, | 12300 | .opaque_type, .func_type => continue :type_key .{ .simple_type = .anyopaque }, |
| 12303 | .enum_type => continue :type_key .{ | 12301 | .enum_type => continue :type_key ip.indexToKey(ip.loadEnumType(ty.toIntern()).int_tag_type), |
| 12304 | .int_type = ip.indexToKey(ip.loadEnumType(ty.toIntern()).int_tag_type).int_type, | ||
| 12305 | }, | ||
| 12306 | .error_set_type, | 12302 | .error_set_type, |
| 12307 | .inferred_error_set_type, | 12303 | .inferred_error_set_type, |
| 12308 | => continue :type_key .{ .simple_type = .anyerror }, | 12304 | => continue :type_key .{ .simple_type = .anyerror }, |
| ... | @@ -12388,7 +12384,7 @@ pub const CallAbiIterator = struct { | ... | @@ -12388,7 +12384,7 @@ pub const CallAbiIterator = struct { |
| 12388 | .f32 => .single, | 12384 | .f32 => .single, |
| 12389 | .f64 => .double, | 12385 | .f64 => .double, |
| 12390 | .f128 => .quad, | 12386 | .f128 => .quad, |
| 12391 | .c_longdouble => switch (zcu.getTarget().cTypeBitSize(.longdouble)) { | 12387 | .c_longdouble => switch (zcu.getTarget().cTypeBitSize(.longdouble).?) { |
| 12392 | else => unreachable, | 12388 | else => unreachable, |
| 12393 | 64 => .double, | 12389 | 64 => .double, |
| 12394 | 80 => null, | 12390 | 80 => null, |
src/codegen/aarch64/abi.zig+7-2| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | const assert = @import("std").debug.assert; | 1 | const assert = std.debug.assert; |
| 2 | const std = @import("std"); | 2 | const std = @import("std"); |
| 3 | const InternPool = @import("../../InternPool.zig"); | 3 | const InternPool = @import("../../InternPool.zig"); |
| 4 | const Type = @import("../../Type.zig"); | 4 | const Type = @import("../../Type.zig"); |
| ... | @@ -35,7 +35,12 @@ pub fn classifyType(ty: Type, zcu: *Zcu) Class { | ... | @@ -35,7 +35,12 @@ pub fn classifyType(ty: Type, zcu: *Zcu) Class { |
| 35 | if (bit_size > 64) return .double_integer; | 35 | if (bit_size > 64) return .double_integer; |
| 36 | return .integer; | 36 | return .integer; |
| 37 | }, | 37 | }, |
| 38 | .int, .@"enum", .error_set, .float, .bool => return .byval, | 38 | .int, .@"enum", .error_set, .bool => return .byval, |
| 39 | .float => return switch (ty.floatBits(zcu.getTarget())) { | ||
| 40 | else => unreachable, | ||
| 41 | 16, 32, 64, 128 => .byval, | ||
| 42 | 80 => .double_integer, | ||
| 43 | }, | ||
| 39 | .vector => { | 44 | .vector => { |
| 40 | const bit_size = ty.bitSize(zcu); | 45 | const bit_size = ty.bitSize(zcu); |
| 41 | // TODO is this controlled by a cpu feature? | 46 | // TODO is this controlled by a cpu feature? |
src/codegen/arm/abi.zig+9-7| ... | @@ -39,7 +39,7 @@ pub fn classifyType(ty: Type, zcu: *Zcu, ctx: Context) Class { | ... | @@ -39,7 +39,7 @@ pub fn classifyType(ty: Type, zcu: *Zcu, ctx: Context) Class { |
| 39 | const float_count = countFloats(ty, zcu, &maybe_float_bits); | 39 | const float_count = countFloats(ty, zcu, &maybe_float_bits); |
| 40 | if (float_count <= byval_float_count) return .byval; | 40 | if (float_count <= byval_float_count) return .byval; |
| 41 | 41 | ||
| 42 | if (ty.abiAlignment(zcu).compare(.gt, .@"32")) { | 42 | if (ty.abiAlignment(zcu).compare(.gt, .@"4")) { |
| 43 | return Class.arrSize(bit_size, 64); | 43 | return Class.arrSize(bit_size, 64); |
| 44 | } | 44 | } |
| 45 | 45 | ||
| ... | @@ -62,7 +62,7 @@ pub fn classifyType(ty: Type, zcu: *Zcu, ctx: Context) Class { | ... | @@ -62,7 +62,7 @@ pub fn classifyType(ty: Type, zcu: *Zcu, ctx: Context) Class { |
| 62 | const float_count = countFloats(ty, zcu, &maybe_float_bits); | 62 | const float_count = countFloats(ty, zcu, &maybe_float_bits); |
| 63 | if (float_count <= byval_float_count) return .byval; | 63 | if (float_count <= byval_float_count) return .byval; |
| 64 | 64 | ||
| 65 | if (union_obj.alignment.compareStrict(.gt, .@"32")) { | 65 | if (union_obj.alignment.compareStrict(.gt, .@"4")) { |
| 66 | return Class.arrSize(bit_size, 64); | 66 | return Class.arrSize(bit_size, 64); |
| 67 | } | 67 | } |
| 68 | 68 | ||
| ... | @@ -73,14 +73,16 @@ pub fn classifyType(ty: Type, zcu: *Zcu, ctx: Context) Class { | ... | @@ -73,14 +73,16 @@ pub fn classifyType(ty: Type, zcu: *Zcu, ctx: Context) Class { |
| 73 | } | 73 | } |
| 74 | return Class.arrSize(bit_size, 32); | 74 | return Class.arrSize(bit_size, 32); |
| 75 | }, | 75 | }, |
| 76 | .bool, .float => return .byval, | 76 | .bool => return .byval, |
| 77 | .int => { | 77 | .int => { |
| 78 | // TODO this is incorrect for _BitInt(128) but implementing | 78 | if (ctx == .ret and ty.intInfo(zcu).bits > 64) return .memory; |
| 79 | // this correctly makes implementing compiler-rt impossible. | ||
| 80 | // const bit_size = ty.bitSize(zcu); | ||
| 81 | // if (bit_size > 64) return .memory; | ||
| 82 | return .byval; | 79 | return .byval; |
| 83 | }, | 80 | }, |
| 81 | .float => return switch (ty.floatBits(zcu.getTarget())) { | ||
| 82 | else => unreachable, | ||
| 83 | 16, 32, 64 => .byval, | ||
| 84 | 80, 128 => .{ .i64_array = 2 }, | ||
| 85 | }, | ||
| 84 | .@"enum", .error_set => { | 86 | .@"enum", .error_set => { |
| 85 | const bit_size = ty.bitSize(zcu); | 87 | const bit_size = ty.bitSize(zcu); |
| 86 | if (bit_size > 64) return .memory; | 88 | if (bit_size > 64) return .memory; |
src/codegen/c.zig+751-610| ... | @@ -164,7 +164,8 @@ const BlockData = struct { | ... | @@ -164,7 +164,8 @@ const BlockData = struct { |
| 164 | 164 | ||
| 165 | const LocalType = struct { | 165 | const LocalType = struct { |
| 166 | type: Type, | 166 | type: Type, |
| 167 | alignment: Alignment, | 167 | alignment: Alignment = .none, |
| 168 | array_len: u2 = 1, | ||
| 168 | }; | 169 | }; |
| 169 | 170 | ||
| 170 | const LocalIndex = u16; | 171 | const LocalIndex = u16; |
| ... | @@ -184,13 +185,11 @@ const ValueRenderLocation = enum { | ... | @@ -184,13 +185,11 @@ const ValueRenderLocation = enum { |
| 184 | } | 185 | } |
| 185 | }; | 186 | }; |
| 186 | 187 | ||
| 187 | const BuiltinInfo = enum { none, bits }; | 188 | const BuiltinInfo = enum { none, bits, bits_none, big_temp_bits }; |
| 188 | 189 | ||
| 189 | const reserved_idents = std.StaticStringMap(void).initComptime(.{ | 190 | const reserved_idents = std.StaticStringMap(void).initComptime(.{ |
| 190 | // C language | 191 | // C language |
| 191 | .{ "alignas", { | 192 | .{ "alignas", {} }, |
| 192 | @setEvalBranchQuota(4000); | ||
| 193 | } }, | ||
| 194 | .{ "alignof", {} }, | 193 | .{ "alignof", {} }, |
| 195 | .{ "asm", {} }, | 194 | .{ "asm", {} }, |
| 196 | .{ "atomic_bool", {} }, | 195 | .{ "atomic_bool", {} }, |
| ... | @@ -302,7 +301,100 @@ const reserved_idents = std.StaticStringMap(void).initComptime(.{ | ... | @@ -302,7 +301,100 @@ const reserved_idents = std.StaticStringMap(void).initComptime(.{ |
| 302 | // stddef.h | 301 | // stddef.h |
| 303 | .{ "offsetof", {} }, | 302 | .{ "offsetof", {} }, |
| 304 | 303 | ||
| 304 | // math.h (only symbols exported by compiler-rt) | ||
| 305 | .{ "ceil", {} }, | ||
| 306 | .{ "ceilf", {} }, | ||
| 307 | .{ "ceilf128", {} }, | ||
| 308 | .{ "ceill", {} }, | ||
| 309 | .{ "cos", {} }, | ||
| 310 | .{ "cosf", {} }, | ||
| 311 | .{ "cosf128", {} }, | ||
| 312 | .{ "cosl", {} }, | ||
| 313 | .{ "exp", {} }, | ||
| 314 | .{ "exp2", {} }, | ||
| 315 | .{ "exp2f", {} }, | ||
| 316 | .{ "exp2f128", {} }, | ||
| 317 | .{ "exp2l", {} }, | ||
| 318 | .{ "expf", {} }, | ||
| 319 | .{ "expf128", {} }, | ||
| 320 | .{ "expl", {} }, | ||
| 321 | .{ "fabs", {} }, | ||
| 322 | .{ "fabsf", {} }, | ||
| 323 | .{ "fabsf128", {} }, | ||
| 324 | .{ "fabsl", {} }, | ||
| 325 | .{ "floor", {} }, | ||
| 326 | .{ "floorf", {} }, | ||
| 327 | .{ "floorf128", {} }, | ||
| 328 | .{ "floorl", {} }, | ||
| 329 | .{ "fma", {} }, | ||
| 330 | .{ "fmaf", {} }, | ||
| 331 | .{ "fmaf128", {} }, | ||
| 332 | .{ "fmal", {} }, | ||
| 333 | .{ "fmax", {} }, | ||
| 334 | .{ "fmaxf", {} }, | ||
| 335 | .{ "fmaxf128", {} }, | ||
| 336 | .{ "fmaxl", {} }, | ||
| 337 | .{ "fmin", {} }, | ||
| 338 | .{ "fminf", {} }, | ||
| 339 | .{ "fminf128", {} }, | ||
| 340 | .{ "fminl", {} }, | ||
| 341 | .{ "fmod", {} }, | ||
| 342 | .{ "fmodf", {} }, | ||
| 343 | .{ "fmodf128", {} }, | ||
| 344 | .{ "fmodl", {} }, | ||
| 345 | .{ "log", {} }, | ||
| 346 | .{ "log10", {} }, | ||
| 347 | .{ "log10f", {} }, | ||
| 348 | .{ "log10f128", {} }, | ||
| 349 | .{ "log10l", {} }, | ||
| 350 | .{ "log2", {} }, | ||
| 351 | .{ "log2f", {} }, | ||
| 352 | .{ "log2f128", {} }, | ||
| 353 | .{ "log2l", {} }, | ||
| 354 | .{ "logf", {} }, | ||
| 355 | .{ "logf128", {} }, | ||
| 356 | .{ "logl", {} }, | ||
| 357 | .{ "round", {} }, | ||
| 358 | .{ "roundf", {} }, | ||
| 359 | .{ "roundf128", {} }, | ||
| 360 | .{ "roundl", {} }, | ||
| 361 | .{ "sin", {} }, | ||
| 362 | .{ "sincos", {} }, | ||
| 363 | .{ "sincosf", {} }, | ||
| 364 | .{ "sincosf128", {} }, | ||
| 365 | .{ "sincosl", {} }, | ||
| 366 | .{ "sinf", {} }, | ||
| 367 | .{ "sinf128", {} }, | ||
| 368 | .{ "sinl", {} }, | ||
| 369 | .{ "sqrt", {} }, | ||
| 370 | .{ "sqrtf", {} }, | ||
| 371 | .{ "sqrtf128", {} }, | ||
| 372 | .{ "sqrtl", {} }, | ||
| 373 | .{ "tan", {} }, | ||
| 374 | .{ "tanf", {} }, | ||
| 375 | .{ "tanf128", {} }, | ||
| 376 | .{ "tanl", {} }, | ||
| 377 | .{ "trunc", {} }, | ||
| 378 | .{ "truncf", {} }, | ||
| 379 | .{ "truncf128", {} }, | ||
| 380 | .{ "truncl", {} }, | ||
| 381 | |||
| 305 | // windows.h | 382 | // windows.h |
| 383 | .{"DUMMYSTRUCTNAME"}, | ||
| 384 | .{"DUMMYSTRUCTNAME2"}, | ||
| 385 | .{"DUMMYSTRUCTNAME3"}, | ||
| 386 | .{"DUMMYSTRUCTNAME4"}, | ||
| 387 | .{"DUMMYSTRUCTNAME5"}, | ||
| 388 | .{"DUMMYSTRUCTNAME6"}, | ||
| 389 | .{"DUMMYUNIONNAME"}, | ||
| 390 | .{"DUMMYUNIONNAME2"}, | ||
| 391 | .{"DUMMYUNIONNAME3"}, | ||
| 392 | .{"DUMMYUNIONNAME4"}, | ||
| 393 | .{"DUMMYUNIONNAME5"}, | ||
| 394 | .{"DUMMYUNIONNAME6"}, | ||
| 395 | .{"DUMMYUNIONNAME7"}, | ||
| 396 | .{"DUMMYUNIONNAME8"}, | ||
| 397 | .{"DUMMYUNIONNAME9"}, | ||
| 306 | .{ "max", {} }, | 398 | .{ "max", {} }, |
| 307 | .{ "min", {} }, | 399 | .{ "min", {} }, |
| 308 | }); | 400 | }); |
| ... | @@ -316,13 +408,6 @@ fn isReservedIdent(ident: []const u8) bool { | ... | @@ -316,13 +408,6 @@ fn isReservedIdent(ident: []const u8) bool { |
| 316 | } | 408 | } |
| 317 | } | 409 | } |
| 318 | 410 | ||
| 319 | // windows.h | ||
| 320 | if (mem.startsWith(u8, ident, "DUMMYSTRUCTNAME") or | ||
| 321 | mem.startsWith(u8, ident, "DUMMYUNIONNAME")) | ||
| 322 | { | ||
| 323 | return true; | ||
| 324 | } | ||
| 325 | |||
| 326 | // CType | 411 | // CType |
| 327 | if (mem.startsWith(u8, ident, "enum__") or | 412 | if (mem.startsWith(u8, ident, "enum__") or |
| 328 | mem.startsWith(u8, ident, "bitpack__") or | 413 | mem.startsWith(u8, ident, "bitpack__") or |
| ... | @@ -453,8 +538,8 @@ pub const Function = struct { | ... | @@ -453,8 +538,8 @@ pub const Function = struct { |
| 453 | 538 | ||
| 454 | fn wantSafety(f: *Function) bool { | 539 | fn wantSafety(f: *Function) bool { |
| 455 | return switch (f.dg.mod.optimize_mode) { | 540 | return switch (f.dg.mod.optimize_mode) { |
| 456 | .Debug, .ReleaseSafe => true, | 541 | .debug, .safe => true, |
| 457 | .ReleaseFast, .ReleaseSmall => false, | 542 | .fast, .small => false, |
| 458 | }; | 543 | }; |
| 459 | } | 544 | } |
| 460 | 545 | ||
| ... | @@ -469,10 +554,7 @@ pub const Function = struct { | ... | @@ -469,10 +554,7 @@ pub const Function = struct { |
| 469 | } | 554 | } |
| 470 | 555 | ||
| 471 | fn allocLocal(f: *Function, inst: ?Air.Inst.Index, ty: Type) !CValue { | 556 | fn allocLocal(f: *Function, inst: ?Air.Inst.Index, ty: Type) !CValue { |
| 472 | return f.allocAlignedLocal(inst, .{ | 557 | return f.allocAlignedLocal(inst, .{ .type = ty }); |
| 473 | .type = ty, | ||
| 474 | .alignment = .none, | ||
| 475 | }); | ||
| 476 | } | 558 | } |
| 477 | 559 | ||
| 478 | /// Only allocates the local; does not print anything. Will attempt to re-use locals, so should | 560 | /// Only allocates the local; does not print anything. Will attempt to re-use locals, so should |
| ... | @@ -564,10 +646,6 @@ pub const Function = struct { | ... | @@ -564,10 +646,6 @@ pub const Function = struct { |
| 564 | return f.dg.renderType(w, ty); | 646 | return f.dg.renderType(w, ty); |
| 565 | } | 647 | } |
| 566 | 648 | ||
| 567 | fn renderIntCast(f: *Function, w: *Writer, dest_ty: Type, src: CValue, v: Vectorize, src_ty: Type, location: ValueRenderLocation) !void { | ||
| 568 | return f.dg.renderIntCast(w, dest_ty, .{ .c_value = .{ .f = f, .value = src, .v = v } }, src_ty, location); | ||
| 569 | } | ||
| 570 | |||
| 571 | fn fmtIntLiteralDec(f: *Function, val: Value) !std.fmt.Alt(FormatIntLiteralContext, formatIntLiteral) { | 649 | fn fmtIntLiteralDec(f: *Function, val: Value) !std.fmt.Alt(FormatIntLiteralContext, formatIntLiteral) { |
| 572 | return f.dg.fmtIntLiteralDec(val, .other); | 650 | return f.dg.fmtIntLiteralDec(val, .other); |
| 573 | } | 651 | } |
| ... | @@ -672,7 +750,9 @@ pub const DeclGen = struct { | ... | @@ -672,7 +750,9 @@ pub const DeclGen = struct { |
| 672 | // Render an undefined pointer if we have a pointer to a zero-bit or comptime type. | 750 | // Render an undefined pointer if we have a pointer to a zero-bit or comptime type. |
| 673 | const ptr_ty: Type = .fromInterned(uav.orig_ty); | 751 | const ptr_ty: Type = .fromInterned(uav.orig_ty); |
| 674 | if (ptr_ty.isPtrAtRuntime(zcu) and !uav_ty.isRuntimeFnOrHasRuntimeBits(zcu)) { | 752 | if (ptr_ty.isPtrAtRuntime(zcu) and !uav_ty.isRuntimeFnOrHasRuntimeBits(zcu)) { |
| 675 | return dg.renderUndefValue(w, ptr_ty, location); | 753 | try w.writeByte('('); |
| 754 | try dg.renderOpvPointer(w, ptr_ty, location); | ||
| 755 | return w.writeByte(')'); | ||
| 676 | } | 756 | } |
| 677 | 757 | ||
| 678 | switch (ip.indexToKey(uav.val)) { | 758 | switch (ip.indexToKey(uav.val)) { |
| ... | @@ -737,8 +817,10 @@ pub const DeclGen = struct { | ... | @@ -737,8 +817,10 @@ pub const DeclGen = struct { |
| 737 | // Render an undefined pointer if we have a pointer to a zero-bit or comptime type. | 817 | // Render an undefined pointer if we have a pointer to a zero-bit or comptime type. |
| 738 | const nav_ty: Type = .fromInterned(ip.getNav(owner_nav).resolved.?.type); | 818 | const nav_ty: Type = .fromInterned(ip.getNav(owner_nav).resolved.?.type); |
| 739 | const ptr_ty = try pt.navPtrType(owner_nav); | 819 | const ptr_ty = try pt.navPtrType(owner_nav); |
| 740 | if (!nav_ty.isRuntimeFnOrHasRuntimeBits(zcu)) { | 820 | if (nav_ty.zigTypeTag(zcu) != .@"opaque" and !nav_ty.isRuntimeFnOrHasRuntimeBits(zcu)) { |
| 741 | return dg.renderUndefValue(w, ptr_ty, location); | 821 | try w.writeByte('('); |
| 822 | try dg.renderOpvPointer(w, ptr_ty, location); | ||
| 823 | return w.writeByte(')'); | ||
| 742 | } | 824 | } |
| 743 | 825 | ||
| 744 | // We shouldn't cast C function pointers as this is UB (when you call | 826 | // We shouldn't cast C function pointers as this is UB (when you call |
| ... | @@ -758,6 +840,26 @@ pub const DeclGen = struct { | ... | @@ -758,6 +840,26 @@ pub const DeclGen = struct { |
| 758 | if (need_cast) try w.writeByte(')'); | 840 | if (need_cast) try w.writeByte(')'); |
| 759 | } | 841 | } |
| 760 | 842 | ||
| 843 | fn renderOpvPointer( | ||
| 844 | dg: *DeclGen, | ||
| 845 | w: *Writer, | ||
| 846 | ptr_ty: Type, | ||
| 847 | location: ValueRenderLocation, | ||
| 848 | ) Error!void { | ||
| 849 | const zcu = dg.pt.zcu; | ||
| 850 | const target = zcu.getTarget(); | ||
| 851 | try w.writeByte('('); | ||
| 852 | try dg.renderType(w, ptr_ty); | ||
| 853 | return w.print("){f}", .{fmtUnsignedIntLiteralSmall( | ||
| 854 | target, | ||
| 855 | .uintptr_t, | ||
| 856 | ptr_ty.ptrAlignment(zcu).forward(undefPattern(u64) >> @intCast(64 - target.ptrBitWidth())), | ||
| 857 | location == .static_initializer, | ||
| 858 | 16, | ||
| 859 | .lower, | ||
| 860 | )}); | ||
| 861 | } | ||
| 862 | |||
| 761 | fn renderPointer( | 863 | fn renderPointer( |
| 762 | dg: *DeclGen, | 864 | dg: *DeclGen, |
| 763 | w: *Writer, | 865 | w: *Writer, |
| ... | @@ -959,9 +1061,6 @@ pub const DeclGen = struct { | ... | @@ -959,9 +1061,6 @@ pub const DeclGen = struct { |
| 959 | const bits = ty.floatBits(target); | 1061 | const bits = ty.floatBits(target); |
| 960 | const f128_val = val.toFloat(f128, zcu); | 1062 | const f128_val = val.toFloat(f128, zcu); |
| 961 | 1063 | ||
| 962 | // All unsigned ints matching float types are pre-allocated. | ||
| 963 | const repr_ty = pt.intType(.unsigned, bits) catch unreachable; | ||
| 964 | |||
| 965 | assert(bits <= 128); | 1064 | assert(bits <= 128); |
| 966 | var repr_val_limbs: [BigInt.calcTwosCompLimbCount(128)]BigIntLimb = undefined; | 1065 | var repr_val_limbs: [BigInt.calcTwosCompLimbCount(128)]BigIntLimb = undefined; |
| 967 | var repr_val_big = BigInt.Mutable{ | 1066 | var repr_val_big = BigInt.Mutable{ |
| ... | @@ -971,29 +1070,27 @@ pub const DeclGen = struct { | ... | @@ -971,29 +1070,27 @@ pub const DeclGen = struct { |
| 971 | }; | 1070 | }; |
| 972 | 1071 | ||
| 973 | switch (bits) { | 1072 | switch (bits) { |
| 1073 | else => unreachable, | ||
| 974 | 16 => repr_val_big.set(@as(u16, @bitCast(val.toFloat(f16, zcu)))), | 1074 | 16 => repr_val_big.set(@as(u16, @bitCast(val.toFloat(f16, zcu)))), |
| 975 | 32 => repr_val_big.set(@as(u32, @bitCast(val.toFloat(f32, zcu)))), | 1075 | 32 => repr_val_big.set(@as(u32, @bitCast(val.toFloat(f32, zcu)))), |
| 976 | 64 => repr_val_big.set(@as(u64, @bitCast(val.toFloat(f64, zcu)))), | 1076 | 64 => repr_val_big.set(@as(u64, @bitCast(val.toFloat(f64, zcu)))), |
| 977 | 80 => repr_val_big.set(@as(u80, @bitCast(val.toFloat(f80, zcu)))), | 1077 | 80 => repr_val_big.set(@as(u80, @bitCast(val.toFloat(f80, zcu)))), |
| 978 | 128 => repr_val_big.set(@as(u128, @bitCast(f128_val))), | 1078 | 128 => repr_val_big.set(@as(u128, @bitCast(f128_val))), |
| 979 | else => unreachable, | ||
| 980 | } | 1079 | } |
| 981 | 1080 | ||
| 982 | var empty = true; | ||
| 983 | if (std.math.isFinite(f128_val)) { | 1081 | if (std.math.isFinite(f128_val)) { |
| 984 | try w.writeAll("zig_make_"); | 1082 | try w.writeAll("zig_make_"); |
| 985 | try dg.renderTypeForBuiltinFnName(w, ty); | 1083 | try dg.renderTypeForBuiltinFnName(w, ty); |
| 986 | try w.writeByte('('); | 1084 | try w.writeByte('('); |
| 987 | switch (bits) { | 1085 | switch (bits) { |
| 1086 | else => unreachable, | ||
| 988 | 16 => try w.print("{x}", .{val.toFloat(f16, zcu)}), | 1087 | 16 => try w.print("{x}", .{val.toFloat(f16, zcu)}), |
| 989 | 32 => try w.print("{x}", .{val.toFloat(f32, zcu)}), | 1088 | 32 => try w.print("{x}", .{val.toFloat(f32, zcu)}), |
| 990 | 64 => try w.print("{x}", .{val.toFloat(f64, zcu)}), | 1089 | 64 => try w.print("{x}", .{val.toFloat(f64, zcu)}), |
| 991 | 80 => try w.print("{x}", .{val.toFloat(f80, zcu)}), | 1090 | 80 => try w.print("{x}", .{val.toFloat(f80, zcu)}), |
| 992 | 128 => try w.print("{x}", .{f128_val}), | 1091 | 128 => try w.print("{x}", .{f128_val}), |
| 993 | else => unreachable, | ||
| 994 | } | 1092 | } |
| 995 | try w.writeAll(", "); | 1093 | try w.writeAll(", "); |
| 996 | empty = false; | ||
| 997 | } else { | 1094 | } else { |
| 998 | // isSignalNan is equivalent to isNan currently, and MSVC doesn't have nans, so prefer nan | 1095 | // isSignalNan is equivalent to isNan currently, and MSVC doesn't have nans, so prefer nan |
| 999 | const operation = if (std.math.isNan(f128_val)) | 1096 | const operation = if (std.math.isNan(f128_val)) |
| ... | @@ -1028,6 +1125,7 @@ pub const DeclGen = struct { | ... | @@ -1028,6 +1125,7 @@ pub const DeclGen = struct { |
| 1028 | try w.writeAll(operation); | 1125 | try w.writeAll(operation); |
| 1029 | try w.writeAll(", "); | 1126 | try w.writeAll(", "); |
| 1030 | if (std.math.isNan(f128_val)) switch (bits) { | 1127 | if (std.math.isNan(f128_val)) switch (bits) { |
| 1128 | else => unreachable, | ||
| 1031 | // We only actually need to pass the significand, but it will get | 1129 | // We only actually need to pass the significand, but it will get |
| 1032 | // properly masked anyway, so just pass the whole value. | 1130 | // properly masked anyway, so just pass the whole value. |
| 1033 | 16 => try w.print("\"0x{x}\"", .{@as(u16, @bitCast(val.toFloat(f16, zcu)))}), | 1131 | 16 => try w.print("\"0x{x}\"", .{@as(u16, @bitCast(val.toFloat(f16, zcu)))}), |
| ... | @@ -1035,16 +1133,23 @@ pub const DeclGen = struct { | ... | @@ -1035,16 +1133,23 @@ pub const DeclGen = struct { |
| 1035 | 64 => try w.print("\"0x{x}\"", .{@as(u64, @bitCast(val.toFloat(f64, zcu)))}), | 1133 | 64 => try w.print("\"0x{x}\"", .{@as(u64, @bitCast(val.toFloat(f64, zcu)))}), |
| 1036 | 80 => try w.print("\"0x{x}\"", .{@as(u80, @bitCast(val.toFloat(f80, zcu)))}), | 1134 | 80 => try w.print("\"0x{x}\"", .{@as(u80, @bitCast(val.toFloat(f80, zcu)))}), |
| 1037 | 128 => try w.print("\"0x{x}\"", .{@as(u128, @bitCast(f128_val))}), | 1135 | 128 => try w.print("\"0x{x}\"", .{@as(u128, @bitCast(f128_val))}), |
| 1038 | else => unreachable, | ||
| 1039 | }; | 1136 | }; |
| 1040 | try w.writeAll(", "); | 1137 | try w.writeAll(", "); |
| 1041 | empty = false; | ||
| 1042 | } | 1138 | } |
| 1043 | try w.print("{f}", .{try dg.fmtIntLiteralHex( | 1139 | switch (bits) { |
| 1044 | try pt.intValue_big(repr_ty, repr_val_big.toConst()), | 1140 | else => unreachable, |
| 1045 | location, | 1141 | 16, 32, 64 => { |
| 1046 | )}); | 1142 | // All unsigned ints matching float types are pre-allocated. |
| 1047 | if (!empty) try w.writeByte(')'); | 1143 | const repr_ty = pt.intType(.unsigned, bits) catch unreachable; |
| 1144 | try w.print("{f}", .{try dg.fmtIntLiteralHex( | ||
| 1145 | try pt.intValue_big(repr_ty, repr_val_big.toConst()), | ||
| 1146 | location, | ||
| 1147 | )}); | ||
| 1148 | }, | ||
| 1149 | 80 => try F80Repr.write(@bitCast(val.toFloat(f80, zcu)), w, target, location == .static_initializer), | ||
| 1150 | 128 => try F128Repr.write(@bitCast(f128_val), w, target, location == .static_initializer), | ||
| 1151 | } | ||
| 1152 | try w.writeByte(')'); | ||
| 1048 | }, | 1153 | }, |
| 1049 | .slice => |slice| { | 1154 | .slice => |slice| { |
| 1050 | if (!location.isInitializer()) { | 1155 | if (!location.isInitializer()) { |
| ... | @@ -1306,8 +1411,8 @@ pub const DeclGen = struct { | ... | @@ -1306,8 +1411,8 @@ pub const DeclGen = struct { |
| 1306 | }; | 1411 | }; |
| 1307 | 1412 | ||
| 1308 | const safety_on = switch (dg.mod.optimize_mode) { | 1413 | const safety_on = switch (dg.mod.optimize_mode) { |
| 1309 | .Debug, .ReleaseSafe => true, | 1414 | .debug, .safe => true, |
| 1310 | .ReleaseFast, .ReleaseSmall => false, | 1415 | .fast, .small => false, |
| 1311 | }; | 1416 | }; |
| 1312 | 1417 | ||
| 1313 | switch (ty.toIntern()) { | 1418 | switch (ty.toIntern()) { |
| ... | @@ -1319,22 +1424,29 @@ pub const DeclGen = struct { | ... | @@ -1319,22 +1424,29 @@ pub const DeclGen = struct { |
| 1319 | .f128_type, | 1424 | .f128_type, |
| 1320 | => { | 1425 | => { |
| 1321 | const bits = ty.floatBits(target); | 1426 | const bits = ty.floatBits(target); |
| 1322 | // All unsigned ints matching float types are pre-allocated. | ||
| 1323 | const repr_ty = dg.pt.intType(.unsigned, bits) catch unreachable; | ||
| 1324 | 1427 | ||
| 1325 | try w.writeAll("zig_make_"); | 1428 | try w.writeAll("zig_make_"); |
| 1326 | try dg.renderTypeForBuiltinFnName(w, ty); | 1429 | try dg.renderTypeForBuiltinFnName(w, ty); |
| 1327 | try w.writeByte('('); | 1430 | try w.writeByte('('); |
| 1328 | switch (bits) { | 1431 | switch (bits) { |
| 1329 | 16 => try w.print("{x}", .{@as(f16, @bitCast(undefPattern(i16)))}), | ||
| 1330 | 32 => try w.print("{x}", .{@as(f32, @bitCast(undefPattern(i32)))}), | ||
| 1331 | 64 => try w.print("{x}", .{@as(f64, @bitCast(undefPattern(i64)))}), | ||
| 1332 | 80 => try w.print("{x}", .{@as(f80, @bitCast(undefPattern(i80)))}), | ||
| 1333 | 128 => try w.print("{x}", .{@as(f128, @bitCast(undefPattern(i128)))}), | ||
| 1334 | else => unreachable, | 1432 | else => unreachable, |
| 1433 | 16 => try w.print("{x}", .{undefPattern(f16)}), | ||
| 1434 | 32 => try w.print("{x}", .{undefPattern(f32)}), | ||
| 1435 | 64 => try w.print("{x}", .{undefPattern(f64)}), | ||
| 1436 | 80 => try w.print("{x}", .{undefPattern(f80)}), | ||
| 1437 | 128 => try w.print("{x}", .{undefPattern(f128)}), | ||
| 1335 | } | 1438 | } |
| 1336 | try w.writeAll(", "); | 1439 | try w.writeAll(", "); |
| 1337 | try dg.renderUndefValue(w, repr_ty, .other); | 1440 | switch (bits) { |
| 1441 | else => unreachable, | ||
| 1442 | 16, 32, 64 => { | ||
| 1443 | // All unsigned ints matching float types are pre-allocated. | ||
| 1444 | const repr_ty = dg.pt.intType(.unsigned, bits) catch unreachable; | ||
| 1445 | try dg.renderUndefValue(w, repr_ty, .other); | ||
| 1446 | }, | ||
| 1447 | 80 => try undefPattern(F80Repr).write(w, target, location == .static_initializer), | ||
| 1448 | 128 => try undefPattern(F128Repr).write(w, target, location == .static_initializer), | ||
| 1449 | } | ||
| 1338 | return w.writeByte(')'); | 1450 | return w.writeByte(')'); |
| 1339 | }, | 1451 | }, |
| 1340 | .bool_type => try w.writeAll(if (safety_on) "0xaa" else "false"), | 1452 | .bool_type => try w.writeAll(if (safety_on) "0xaa" else "false"), |
| ... | @@ -1638,8 +1750,6 @@ pub const DeclGen = struct { | ... | @@ -1638,8 +1750,6 @@ pub const DeclGen = struct { |
| 1638 | try w.writeAll("zig_no_builtin "); | 1750 | try w.writeAll("zig_no_builtin "); |
| 1639 | } | 1751 | } |
| 1640 | 1752 | ||
| 1641 | if (fn_info.return_type == .noreturn_type) try w.writeAll("zig_noreturn "); | ||
| 1642 | |||
| 1643 | // While incomplete types are usually an acceptable substitute for "void", this is not true | 1753 | // While incomplete types are usually an acceptable substitute for "void", this is not true |
| 1644 | // in function return types, where "void" is the only incomplete type permitted. | 1754 | // in function return types, where "void" is the only incomplete type permitted. |
| 1645 | const actual_return_type: Type = .fromInterned(fn_info.return_type); | 1755 | const actual_return_type: Type = .fromInterned(fn_info.return_type); |
| ... | @@ -1651,8 +1761,9 @@ pub const DeclGen = struct { | ... | @@ -1651,8 +1761,9 @@ pub const DeclGen = struct { |
| 1651 | 1761 | ||
| 1652 | const ret_cty: CType = try .lower(effective_return_type, &dg.ctype_deps, dg.arena, zcu); | 1762 | const ret_cty: CType = try .lower(effective_return_type, &dg.ctype_deps, dg.arena, zcu); |
| 1653 | try w.print("{f}", .{ret_cty.fmtDeclaratorPrefix(zcu)}); | 1763 | try w.print("{f}", .{ret_cty.fmtDeclaratorPrefix(zcu)}); |
| 1654 | if (toCallingConvention(fn_info.cc, zcu)) |call_conv| { | 1764 | switch (CType.CallingConvention.fromLang(fn_info.cc, zcu.getTarget())) { |
| 1655 | try w.print("zig_callconv({s}) ", .{call_conv}); | 1765 | .c => {}, |
| 1766 | else => |cc| try w.print("zig_callconv({t}) ", .{cc}), | ||
| 1656 | } | 1767 | } |
| 1657 | switch (name) { | 1768 | switch (name) { |
| 1658 | .nav => |nav| try renderNavName(w, nav, ip), | 1769 | .nav => |nav| try renderNavName(w, nav, ip), |
| ... | @@ -1726,136 +1837,6 @@ pub const DeclGen = struct { | ... | @@ -1726,136 +1837,6 @@ pub const DeclGen = struct { |
| 1726 | try w.print("{f}", .{cty.fmtTypeName(zcu)}); | 1837 | try w.print("{f}", .{cty.fmtTypeName(zcu)}); |
| 1727 | } | 1838 | } |
| 1728 | 1839 | ||
| 1729 | const IntCastContext = union(enum) { | ||
| 1730 | c_value: struct { | ||
| 1731 | f: *Function, | ||
| 1732 | value: CValue, | ||
| 1733 | v: Vectorize, | ||
| 1734 | }, | ||
| 1735 | value: struct { | ||
| 1736 | value: Value, | ||
| 1737 | }, | ||
| 1738 | |||
| 1739 | pub fn writeValue(self: *const IntCastContext, dg: *DeclGen, w: *Writer, location: ValueRenderLocation) !void { | ||
| 1740 | switch (self.*) { | ||
| 1741 | .c_value => |v| { | ||
| 1742 | try v.f.writeCValue(w, v.value, location); | ||
| 1743 | try v.v.elem(v.f, w); | ||
| 1744 | }, | ||
| 1745 | .value => |v| try dg.renderValue(w, v.value, location), | ||
| 1746 | } | ||
| 1747 | } | ||
| 1748 | }; | ||
| 1749 | fn intCastIsNoop(dg: *DeclGen, dest_ty: Type, src_ty: Type) bool { | ||
| 1750 | const pt = dg.pt; | ||
| 1751 | const zcu = pt.zcu; | ||
| 1752 | const dest_bits = dest_ty.bitSize(zcu); | ||
| 1753 | const dest_int_info = dest_ty.intInfo(pt.zcu); | ||
| 1754 | |||
| 1755 | const src_is_ptr = src_ty.isPtrAtRuntime(pt.zcu); | ||
| 1756 | const src_eff_ty: Type = if (src_is_ptr) switch (dest_int_info.signedness) { | ||
| 1757 | .unsigned => .usize, | ||
| 1758 | .signed => .isize, | ||
| 1759 | } else src_ty; | ||
| 1760 | |||
| 1761 | const src_bits = src_eff_ty.bitSize(zcu); | ||
| 1762 | const src_int_info = if (src_eff_ty.isAbiInt(pt.zcu)) src_eff_ty.intInfo(pt.zcu) else null; | ||
| 1763 | if (dest_bits <= 64 and src_bits <= 64) { | ||
| 1764 | const needs_cast = src_int_info == null or | ||
| 1765 | (toCIntBits(dest_int_info.bits) != toCIntBits(src_int_info.?.bits) or | ||
| 1766 | dest_int_info.signedness != src_int_info.?.signedness); | ||
| 1767 | return !needs_cast and !src_is_ptr; | ||
| 1768 | } else return false; | ||
| 1769 | } | ||
| 1770 | /// Renders a cast to an int type, from either an int or a pointer. | ||
| 1771 | /// | ||
| 1772 | /// Some platforms don't have 128 bit integers, so we need to use | ||
| 1773 | /// the zig_make_ and zig_lo_ macros in those cases. | ||
| 1774 | /// | ||
| 1775 | /// | Dest type bits | Src type | Result | ||
| 1776 | /// |------------------|------------------|---------------------------| | ||
| 1777 | /// | < 64 bit integer | pointer | (zig_<dest_ty>)(zig_<u|i>size)src | ||
| 1778 | /// | < 64 bit integer | < 64 bit integer | (zig_<dest_ty>)src | ||
| 1779 | /// | < 64 bit integer | > 64 bit integer | zig_lo(src) | ||
| 1780 | /// | > 64 bit integer | pointer | zig_make_<dest_ty>(0, (zig_<u|i>size)src) | ||
| 1781 | /// | > 64 bit integer | < 64 bit integer | zig_make_<dest_ty>(0, src) | ||
| 1782 | /// | > 64 bit integer | > 64 bit integer | zig_make_<dest_ty>(zig_hi_<src_ty>(src), zig_lo_<src_ty>(src)) | ||
| 1783 | fn renderIntCast( | ||
| 1784 | dg: *DeclGen, | ||
| 1785 | w: *Writer, | ||
| 1786 | dest_ty: Type, | ||
| 1787 | context: IntCastContext, | ||
| 1788 | src_ty: Type, | ||
| 1789 | location: ValueRenderLocation, | ||
| 1790 | ) !void { | ||
| 1791 | const pt = dg.pt; | ||
| 1792 | const zcu = pt.zcu; | ||
| 1793 | const dest_bits = dest_ty.bitSize(zcu); | ||
| 1794 | const dest_int_info = dest_ty.intInfo(zcu); | ||
| 1795 | |||
| 1796 | const src_is_ptr = src_ty.isPtrAtRuntime(zcu); | ||
| 1797 | const src_eff_ty: Type = if (src_is_ptr) switch (dest_int_info.signedness) { | ||
| 1798 | .unsigned => .usize, | ||
| 1799 | .signed => .isize, | ||
| 1800 | } else src_ty; | ||
| 1801 | |||
| 1802 | const src_bits = src_eff_ty.bitSize(zcu); | ||
| 1803 | const src_int_info = if (src_eff_ty.isAbiInt(zcu)) src_eff_ty.intInfo(zcu) else null; | ||
| 1804 | if (dest_bits <= 64 and src_bits <= 64) { | ||
| 1805 | const needs_cast = src_int_info == null or | ||
| 1806 | (toCIntBits(dest_int_info.bits) != toCIntBits(src_int_info.?.bits) or | ||
| 1807 | dest_int_info.signedness != src_int_info.?.signedness); | ||
| 1808 | |||
| 1809 | if (needs_cast) { | ||
| 1810 | try w.writeByte('('); | ||
| 1811 | try dg.renderType(w, dest_ty); | ||
| 1812 | try w.writeByte(')'); | ||
| 1813 | } | ||
| 1814 | if (src_is_ptr) { | ||
| 1815 | try w.writeByte('('); | ||
| 1816 | try dg.renderType(w, src_eff_ty); | ||
| 1817 | try w.writeByte(')'); | ||
| 1818 | } | ||
| 1819 | try context.writeValue(dg, w, location); | ||
| 1820 | } else if (dest_bits <= 64 and src_bits > 64) { | ||
| 1821 | assert(!src_is_ptr); | ||
| 1822 | if (dest_bits < 64) { | ||
| 1823 | try w.writeByte('('); | ||
| 1824 | try dg.renderType(w, dest_ty); | ||
| 1825 | try w.writeByte(')'); | ||
| 1826 | } | ||
| 1827 | try w.writeAll("zig_lo_"); | ||
| 1828 | try dg.renderTypeForBuiltinFnName(w, src_eff_ty); | ||
| 1829 | try w.writeByte('('); | ||
| 1830 | try context.writeValue(dg, w, .other); | ||
| 1831 | try w.writeByte(')'); | ||
| 1832 | } else if (dest_bits > 64 and src_bits <= 64) { | ||
| 1833 | try w.writeAll("zig_make_"); | ||
| 1834 | try dg.renderTypeForBuiltinFnName(w, dest_ty); | ||
| 1835 | try w.writeAll("(0, "); | ||
| 1836 | if (src_is_ptr) { | ||
| 1837 | try w.writeByte('('); | ||
| 1838 | try dg.renderType(w, src_eff_ty); | ||
| 1839 | try w.writeByte(')'); | ||
| 1840 | } | ||
| 1841 | try context.writeValue(dg, w, .other); | ||
| 1842 | try w.writeByte(')'); | ||
| 1843 | } else { | ||
| 1844 | assert(!src_is_ptr); | ||
| 1845 | try w.writeAll("zig_make_"); | ||
| 1846 | try dg.renderTypeForBuiltinFnName(w, dest_ty); | ||
| 1847 | try w.writeAll("(zig_hi_"); | ||
| 1848 | try dg.renderTypeForBuiltinFnName(w, src_eff_ty); | ||
| 1849 | try w.writeByte('('); | ||
| 1850 | try context.writeValue(dg, w, .other); | ||
| 1851 | try w.writeAll("), zig_lo_"); | ||
| 1852 | try dg.renderTypeForBuiltinFnName(w, src_eff_ty); | ||
| 1853 | try w.writeByte('('); | ||
| 1854 | try context.writeValue(dg, w, .other); | ||
| 1855 | try w.writeAll("))"); | ||
| 1856 | } | ||
| 1857 | } | ||
| 1858 | |||
| 1859 | /// Renders to `w` a C declarator whose type is the C lowering of the given Zig type. | 1840 | /// Renders to `w` a C declarator whose type is the C lowering of the given Zig type. |
| 1860 | fn renderTypeAndName( | 1841 | fn renderTypeAndName( |
| 1861 | dg: *DeclGen, | 1842 | dg: *DeclGen, |
| ... | @@ -2000,6 +1981,7 @@ pub const DeclGen = struct { | ... | @@ -2000,6 +1981,7 @@ pub const DeclGen = struct { |
| 2000 | switch (info) { | 1981 | switch (info) { |
| 2001 | .none => if (!is_big) return, | 1982 | .none => if (!is_big) return, |
| 2002 | .bits => {}, | 1983 | .bits => {}, |
| 1984 | .bits_none, .big_temp_bits => unreachable, | ||
| 2003 | } | 1985 | } |
| 2004 | 1986 | ||
| 2005 | const int_info: std.lang.Type.Int = if (ty.isAbiInt(zcu)) ty.intInfo(zcu) else .{ | 1987 | const int_info: std.lang.Type.Int = if (ty.isAbiInt(zcu)) ty.intInfo(zcu) else .{ |
| ... | @@ -2056,6 +2038,72 @@ const CQualifiers = packed struct { | ... | @@ -2056,6 +2038,72 @@ const CQualifiers = packed struct { |
| 2056 | restrict: bool = false, | 2038 | restrict: bool = false, |
| 2057 | }; | 2039 | }; |
| 2058 | 2040 | ||
| 2041 | pub fn genHeader(zcu: *Zcu, w: *Writer) !void { | ||
| 2042 | const gpa = zcu.comp.gpa; | ||
| 2043 | |||
| 2044 | var arena: std.heap.ArenaAllocator = .init(gpa); | ||
| 2045 | defer arena.deinit(); | ||
| 2046 | var ctype_deps: CType.Dependencies = .empty; | ||
| 2047 | defer ctype_deps.deinit(gpa); | ||
| 2048 | |||
| 2049 | const target = zcu.getTarget(); | ||
| 2050 | switch (target.abi) { | ||
| 2051 | .msvc, .itanium => try w.writeAll("#define ZIG_TARGET_ABI_MSVC\n"), | ||
| 2052 | else => {}, | ||
| 2053 | } | ||
| 2054 | for ([_]u16{ 16, 32, 64, 80, 128 }) |bits| switch (std.zig.target.compilerRtFloatAbi(target, bits)) { | ||
| 2055 | .hard => {}, | ||
| 2056 | .soft => try w.print("#define ZIG_TARGET_SOFT_COMPILER_RT_F{d}_ABI\n", .{bits}), | ||
| 2057 | }; | ||
| 2058 | try w.print( | ||
| 2059 | \\#define ZIG_TARGET_MAX_INT_ALIGNMENT {d} | ||
| 2060 | \\#include "zig.h" | ||
| 2061 | \\ | ||
| 2062 | \\ | ||
| 2063 | , | ||
| 2064 | .{target.cMaxIntAlignment()}, | ||
| 2065 | ); | ||
| 2066 | |||
| 2067 | var basic_ty: Type = .fromInterned(.first_type); | ||
| 2068 | while (true) : ({ | ||
| 2069 | basic_ty = .fromInterned(@fromBackingInt(@intCast(@backingInt(basic_ty.toIntern()) + 1))); | ||
| 2070 | if (basic_ty.toIntern() == InternPool.Index.last_type) break; | ||
| 2071 | }) { | ||
| 2072 | switch (basic_ty.toIntern()) { | ||
| 2073 | else => {}, | ||
| 2074 | .anyframe_type, | ||
| 2075 | .adhoc_inferred_error_set_type, | ||
| 2076 | .generic_poison_type, | ||
| 2077 | => continue, // skip unsupported types | ||
| 2078 | } | ||
| 2079 | const basic_cty: CType = try .lower(basic_ty, &ctype_deps, arena.allocator(), zcu); | ||
| 2080 | switch (basic_cty) { | ||
| 2081 | .void => {}, // no layout to check | ||
| 2082 | .bool, | ||
| 2083 | .int, | ||
| 2084 | .float, | ||
| 2085 | => try CType.render_defs.writeStaticAssertTypeLayout(basic_ty, basic_cty, w, zcu), | ||
| 2086 | .@"fn", | ||
| 2087 | .@"enum", | ||
| 2088 | .bitpack, | ||
| 2089 | .@"struct", | ||
| 2090 | .union_auto, | ||
| 2091 | .union_extern, | ||
| 2092 | .slice, | ||
| 2093 | .opt, | ||
| 2094 | .arr, | ||
| 2095 | .vec, | ||
| 2096 | .errunion, | ||
| 2097 | .aligned, | ||
| 2098 | .bigint, | ||
| 2099 | .pointer, | ||
| 2100 | .array, | ||
| 2101 | .function, | ||
| 2102 | => {}, | ||
| 2103 | } | ||
| 2104 | } | ||
| 2105 | } | ||
| 2106 | |||
| 2059 | pub fn genGlobalAsm(zcu: *Zcu, w: *Writer) !void { | 2107 | pub fn genGlobalAsm(zcu: *Zcu, w: *Writer) !void { |
| 2060 | for (zcu.global_assembly.values()) |asm_source| { | 2108 | for (zcu.global_assembly.values()) |asm_source| { |
| 2061 | try w.print("__asm({f});\n", .{fmtStringLiteral(asm_source, null)}); | 2109 | try w.print("__asm({f});\n", .{fmtStringLiteral(asm_source, null)}); |
| ... | @@ -2070,16 +2118,16 @@ pub fn genErrDecls( | ... | @@ -2070,16 +2118,16 @@ pub fn genErrDecls( |
| 2070 | const ip = &zcu.intern_pool; | 2118 | const ip = &zcu.intern_pool; |
| 2071 | 2119 | ||
| 2072 | const names = ip.global_error_set.getNamesFromMainThread(); | 2120 | const names = ip.global_error_set.getNamesFromMainThread(); |
| 2073 | // Don't generate an invalid empty enum if the global error set is empty! | 2121 | // Don't generate an invalid empty enum/array if the global error set is empty! |
| 2074 | if (names.len > 0) { | 2122 | if (names.len == 0) return; |
| 2075 | try w.writeAll("enum {\n"); | 2123 | |
| 2076 | for (names, 1..) |name_nts, value| { | 2124 | try w.writeAll("enum {\n"); |
| 2077 | try w.writeByte(' '); | 2125 | for (names, 1..) |name_nts, value| { |
| 2078 | try renderErrorName(w, name_nts.toSlice(ip)); | 2126 | try w.writeByte(' '); |
| 2079 | try w.print(" = {d}u,\n", .{value}); | 2127 | try renderErrorName(w, name_nts.toSlice(ip)); |
| 2080 | } | 2128 | try w.print(" = {d}u,\n", .{value}); |
| 2081 | try w.writeAll("};\n"); | ||
| 2082 | } | 2129 | } |
| 2130 | try w.writeAll("};\n"); | ||
| 2083 | 2131 | ||
| 2084 | for (names) |name_nts| { | 2132 | for (names) |name_nts| { |
| 2085 | const name = name_nts.toSlice(ip); | 2133 | const name = name_nts.toSlice(ip); |
| ... | @@ -2093,7 +2141,7 @@ pub fn genErrDecls( | ... | @@ -2093,7 +2141,7 @@ pub fn genErrDecls( |
| 2093 | "static {s} const zig_errorName[{d}] = {{", | 2141 | "static {s} const zig_errorName[{d}] = {{", |
| 2094 | .{ slice_const_u8_sentinel_0_type_name, names.len }, | 2142 | .{ slice_const_u8_sentinel_0_type_name, names.len }, |
| 2095 | ); | 2143 | ); |
| 2096 | if (names.len > 0) try w.writeByte('\n'); | 2144 | try w.writeByte('\n'); |
| 2097 | for (names) |name_nts| { | 2145 | for (names) |name_nts| { |
| 2098 | const name = name_nts.toSlice(ip); | 2146 | const name = name_nts.toSlice(ip); |
| 2099 | try w.print( | 2147 | try w.print( |
| ... | @@ -2114,10 +2162,18 @@ pub fn genTagNameFn( | ... | @@ -2114,10 +2162,18 @@ pub fn genTagNameFn( |
| 2114 | const ip = &zcu.intern_pool; | 2162 | const ip = &zcu.intern_pool; |
| 2115 | const loaded_enum = ip.loadEnumType(enum_ty.toIntern()); | 2163 | const loaded_enum = ip.loadEnumType(enum_ty.toIntern()); |
| 2116 | assert(loaded_enum.field_names.len > 0); | 2164 | assert(loaded_enum.field_names.len > 0); |
| 2117 | if (Type.fromInterned(loaded_enum.int_tag_type).bitSize(zcu) > 64) { | 2165 | switch (CType.classifyInt(enum_ty, zcu)) { |
| 2118 | @panic("TODO CBE: tagName for enum over 64 bits"); | 2166 | .void => unreachable, |
| 2167 | .small => |int| switch (int) { | ||
| 2168 | else => {}, | ||
| 2169 | .zig_u128, .zig_i128 => @panic("TODO CBE: tagName for 128-bit enums"), | ||
| 2170 | }, | ||
| 2171 | .big => @panic("TODO CBE: tagName for bigint enums"), | ||
| 2119 | } | 2172 | } |
| 2120 | 2173 | ||
| 2174 | if (!zcu.comp.config.root_strip) try w.print("/* @tagName({f}) */\n", .{ | ||
| 2175 | loaded_enum.name.fmt(ip), | ||
| 2176 | }); | ||
| 2121 | try w.print("static {s} zig_tagName_{f}__{d}({s} tag) {{\n", .{ | 2177 | try w.print("static {s} zig_tagName_{f}__{d}({s} tag) {{\n", .{ |
| 2122 | slice_const_u8_sentinel_0_type_name, | 2178 | slice_const_u8_sentinel_0_type_name, |
| 2123 | fmtIdentUnsolo(loaded_enum.name.toSlice(ip)), | 2179 | fmtIdentUnsolo(loaded_enum.name.toSlice(ip)), |
| ... | @@ -2164,6 +2220,7 @@ pub fn genLazyCallModifierFn( | ... | @@ -2164,6 +2220,7 @@ pub fn genLazyCallModifierFn( |
| 2164 | 2220 | ||
| 2165 | const fn_val = zcu.navValue(fn_nav); | 2221 | const fn_val = zcu.navValue(fn_nav); |
| 2166 | 2222 | ||
| 2223 | if (fn_val.typeOf(zcu).fnReturnType(zcu).isNoReturn(zcu)) try w.writeAll("zig_noreturn "); | ||
| 2167 | try w.print("static zig_{t} ", .{kind}); | 2224 | try w.print("static zig_{t} ", .{kind}); |
| 2168 | try dg.renderFunctionSignature(w, fn_val, .none, .definition, switch (kind) { | 2225 | try dg.renderFunctionSignature(w, fn_val, .none, .definition, switch (kind) { |
| 2169 | .never_tail => .{ .nav_never_tail = fn_nav }, | 2226 | .never_tail => .{ .nav_never_tail = fn_nav }, |
| ... | @@ -2269,8 +2326,10 @@ pub fn genFunc(f: *Function, fwd_decl_writer: *Writer, header_writer: *Writer) E | ... | @@ -2269,8 +2326,10 @@ pub fn genFunc(f: *Function, fwd_decl_writer: *Writer, header_writer: *Writer) E |
| 2269 | const gpa = f.dg.gpa; | 2326 | const gpa = f.dg.gpa; |
| 2270 | const nav_index = f.dg.owner_nav.unwrap().?; | 2327 | const nav_index = f.dg.owner_nav.unwrap().?; |
| 2271 | const nav_val = zcu.navValue(nav_index); | 2328 | const nav_val = zcu.navValue(nav_index); |
| 2329 | const fn_info = zcu.typeToFunc(nav_val.typeOf(zcu)).?; | ||
| 2272 | const nav = ip.getNav(nav_index); | 2330 | const nav = ip.getNav(nav_index); |
| 2273 | 2331 | ||
| 2332 | if (Type.fromInterned(fn_info.return_type).isNoReturn(zcu)) try fwd_decl_writer.writeAll("zig_noreturn "); | ||
| 2274 | try fwd_decl_writer.writeAll("static "); | 2333 | try fwd_decl_writer.writeAll("static "); |
| 2275 | try f.dg.renderFunctionSignature( | 2334 | try f.dg.renderFunctionSignature( |
| 2276 | fwd_decl_writer, | 2335 | fwd_decl_writer, |
| ... | @@ -2291,11 +2350,41 @@ pub fn genFunc(f: *Function, fwd_decl_writer: *Writer, header_writer: *Writer) E | ... | @@ -2291,11 +2350,41 @@ pub fn genFunc(f: *Function, fwd_decl_writer: *Writer, header_writer: *Writer) E |
| 2291 | .{ .nav = nav_index }, | 2350 | .{ .nav = nav_index }, |
| 2292 | ); | 2351 | ); |
| 2293 | try header_writer.writeAll(" {\n "); | 2352 | try header_writer.writeAll(" {\n "); |
| 2353 | if (!f.dg.mod.strip) try header_writer.print("/* {f} */\n ", .{nav.fqn.fmt(ip)}); | ||
| 2294 | 2354 | ||
| 2295 | f.free_locals_map.clearRetainingCapacity(); | 2355 | f.free_locals_map.clearRetainingCapacity(); |
| 2296 | 2356 | ||
| 2297 | const main_body = f.air.getMainBody(); | 2357 | const main_body = f.air.getMainBody(); |
| 2298 | f.indent(); | 2358 | f.indent(); |
| 2359 | if (switch (fn_info.cc) { | ||
| 2360 | inline else => |pl| switch (@TypeOf(pl)) { | ||
| 2361 | void, | ||
| 2362 | std.lang.CallingConvention.SpirvKernelOptions, | ||
| 2363 | std.lang.CallingConvention.SpirvFragmentOptions, | ||
| 2364 | std.lang.CallingConvention.SpirvMeshOptions, | ||
| 2365 | => null, | ||
| 2366 | std.lang.CallingConvention.ArcInterruptOptions, | ||
| 2367 | std.lang.CallingConvention.ArmInterruptOptions, | ||
| 2368 | std.lang.CallingConvention.RiscvInterruptOptions, | ||
| 2369 | std.lang.CallingConvention.ShInterruptOptions, | ||
| 2370 | std.lang.CallingConvention.MicroblazeInterruptOptions, | ||
| 2371 | std.lang.CallingConvention.MipsInterruptOptions, | ||
| 2372 | std.lang.CallingConvention.CommonOptions, | ||
| 2373 | std.lang.CallingConvention.X86RegparmOptions, | ||
| 2374 | => pl.incoming_stack_alignment, | ||
| 2375 | else => @compileError(@tagName(pl)), | ||
| 2376 | }, | ||
| 2377 | }) |incoming_stack_alignment| realign_stack: { | ||
| 2378 | const normal_stack_align = zcu.getTarget().stackAlignment(); | ||
| 2379 | if (incoming_stack_alignment >= normal_stack_align) break :realign_stack; | ||
| 2380 | try header_writer.print("char zig_align({d}) zig_realign_stack;\n ", .{ | ||
| 2381 | normal_stack_align << 1, | ||
| 2382 | }); | ||
| 2383 | try f.code.writer.writeAll( | ||
| 2384 | \\__asm volatile("" :: [zig_realign_stack] "m" (zig_realign_stack)); | ||
| 2385 | ); | ||
| 2386 | try f.newline(); | ||
| 2387 | } | ||
| 2299 | try genBodyResolveState(f, undefined, &.{}, main_body, true); | 2388 | try genBodyResolveState(f, undefined, &.{}, main_body, true); |
| 2300 | try f.outdent(); | 2389 | try f.outdent(); |
| 2301 | try f.code.writer.writeByte('}'); | 2390 | try f.code.writer.writeByte('}'); |
| ... | @@ -2346,6 +2435,7 @@ pub fn genFunc(f: *Function, fwd_decl_writer: *Writer, header_writer: *Writer) E | ... | @@ -2346,6 +2435,7 @@ pub fn genFunc(f: *Function, fwd_decl_writer: *Writer, header_writer: *Writer) E |
| 2346 | for (list.keys()) |local_index| { | 2435 | for (list.keys()) |local_index| { |
| 2347 | const local = f.locals.items[local_index]; | 2436 | const local = f.locals.items[local_index]; |
| 2348 | try f.dg.renderTypeAndName(header_writer, local.type, .{ .local = local_index }, .{}, local.alignment); | 2437 | try f.dg.renderTypeAndName(header_writer, local.type, .{ .local = local_index }, .{}, local.alignment); |
| 2438 | if (local.array_len != 1) try header_writer.print("[{d}]", .{local.array_len}); | ||
| 2349 | try header_writer.writeAll(";\n "); | 2439 | try header_writer.writeAll(";\n "); |
| 2350 | } | 2440 | } |
| 2351 | } | 2441 | } |
| ... | @@ -2397,10 +2487,12 @@ pub fn genDeclFwd(dg: *DeclGen, w: *Writer) Error!void { | ... | @@ -2397,10 +2487,12 @@ pub fn genDeclFwd(dg: *DeclGen, w: *Writer) Error!void { |
| 2397 | 2487 | ||
| 2398 | .@"extern" => |@"extern"| switch (nav_ty.zigTypeTag(zcu)) { | 2488 | .@"extern" => |@"extern"| switch (nav_ty.zigTypeTag(zcu)) { |
| 2399 | .@"fn" => { | 2489 | .@"fn" => { |
| 2490 | const fn_val: Value = .fromInterned(nav.resolved.?.value); | ||
| 2491 | if (fn_val.typeOf(zcu).fnReturnType(zcu).isNoReturn(zcu)) try w.writeAll("zig_noreturn "); | ||
| 2400 | try w.writeAll("zig_extern "); | 2492 | try w.writeAll("zig_extern "); |
| 2401 | try dg.renderFunctionSignature( | 2493 | try dg.renderFunctionSignature( |
| 2402 | w, | 2494 | w, |
| 2403 | .fromInterned(nav.resolved.?.value), | 2495 | fn_val, |
| 2404 | nav.resolved.?.@"align", | 2496 | nav.resolved.?.@"align", |
| 2405 | .forward_decl, | 2497 | .forward_decl, |
| 2406 | .{ .@"export" = .{ | 2498 | .{ .@"export" = .{ |
| ... | @@ -2461,7 +2553,12 @@ pub fn genDeclValue(dg: *DeclGen, w: *Writer, options: struct { | ... | @@ -2461,7 +2553,12 @@ pub fn genDeclValue(dg: *DeclGen, w: *Writer, options: struct { |
| 2461 | try dg.renderTypeAndName(w, ty, options.name, .{ .@"const" = options.@"const" }, .none); | 2553 | try dg.renderTypeAndName(w, ty, options.name, .{ .@"const" = options.@"const" }, .none); |
| 2462 | try w.writeAll(" = "); | 2554 | try w.writeAll(" = "); |
| 2463 | try dg.renderValue(w, options.init_val, .static_initializer); | 2555 | try dg.renderValue(w, options.init_val, .static_initializer); |
| 2464 | try w.writeAll(";\n"); | 2556 | try w.writeByte(';'); |
| 2557 | if (dg.owner_nav.unwrap()) |nav_index| { | ||
| 2558 | const ip = &zcu.intern_pool; | ||
| 2559 | if (!dg.mod.strip) try w.print(" /* {f} */", .{ip.getNav(nav_index).fqn.fmt(ip)}); | ||
| 2560 | } | ||
| 2561 | try w.writeByte('\n'); | ||
| 2465 | } | 2562 | } |
| 2466 | pub fn genDeclValueFwd(dg: *DeclGen, w: *Writer, options: struct { | 2563 | pub fn genDeclValueFwd(dg: *DeclGen, w: *Writer, options: struct { |
| 2467 | name: CValue, | 2564 | name: CValue, |
| ... | @@ -2496,11 +2593,13 @@ pub fn genExports(dg: *DeclGen, w: *Writer, exported: Zcu.Exported, export_indic | ... | @@ -2496,11 +2593,13 @@ pub fn genExports(dg: *DeclGen, w: *Writer, exported: Zcu.Exported, export_indic |
| 2496 | const exported_val = exported.getValue(zcu); | 2593 | const exported_val = exported.getValue(zcu); |
| 2497 | if (ip.isFunctionType(exported_val.typeOf(zcu).toIntern())) return for (export_indices) |export_index| { | 2594 | if (ip.isFunctionType(exported_val.typeOf(zcu).toIntern())) return for (export_indices) |export_index| { |
| 2498 | const @"export" = export_index.ptr(zcu); | 2595 | const @"export" = export_index.ptr(zcu); |
| 2596 | const fn_val = exported.getValue(zcu); | ||
| 2597 | if (fn_val.typeOf(zcu).fnReturnType(zcu).isNoReturn(zcu)) try w.writeAll("zig_noreturn "); | ||
| 2499 | try w.writeAll("zig_extern "); | 2598 | try w.writeAll("zig_extern "); |
| 2500 | if (@"export".opts.linkage == .weak) try w.writeAll("zig_weak_linkage_fn "); | 2599 | if (@"export".opts.linkage == .weak) try w.writeAll("zig_weak_linkage_fn "); |
| 2501 | try dg.renderFunctionSignature( | 2600 | try dg.renderFunctionSignature( |
| 2502 | w, | 2601 | w, |
| 2503 | exported.getValue(zcu), | 2602 | fn_val, |
| 2504 | exported.getAlign(zcu), | 2603 | exported.getAlign(zcu), |
| 2505 | .forward_decl, | 2604 | .forward_decl, |
| 2506 | .{ .@"export" = .{ | 2605 | .{ .@"export" = .{ |
| ... | @@ -2662,22 +2761,22 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) Error!void { | ... | @@ -2662,22 +2761,22 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) Error!void { |
| 2662 | .mul => try airBinOp(f, inst, "*", "mul", .none), | 2761 | .mul => try airBinOp(f, inst, "*", "mul", .none), |
| 2663 | 2762 | ||
| 2664 | .neg => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].un_op, "neg", .none), | 2763 | .neg => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].un_op, "neg", .none), |
| 2665 | .div_float => try airBinBuiltinCall(f, inst, "div", .none), | 2764 | .div_float => try airBinBuiltinCall(f, inst, "div", .big_temp_bits), |
| 2666 | 2765 | ||
| 2667 | .div_trunc, .div_exact => try airBinOp(f, inst, "/", "div_trunc", .none), | 2766 | .div_trunc, .div_exact => try airBinOp(f, inst, "/", "divTrunc", .big_temp_bits), |
| 2668 | .rem => blk: { | 2767 | .rem => blk: { |
| 2669 | const bin_op = air_datas[@intFromEnum(inst)].bin_op; | 2768 | const bin_op = air_datas[@intFromEnum(inst)].bin_op; |
| 2670 | const lhs_scalar_ty = f.typeOf(bin_op.lhs).scalarType(zcu); | 2769 | const lhs_scalar_ty = f.typeOf(bin_op.lhs).scalarType(zcu); |
| 2671 | // For binary operations @TypeOf(lhs)==@TypeOf(rhs), | 2770 | // For binary operations @TypeOf(lhs)==@TypeOf(rhs), |
| 2672 | // so we only check one. | 2771 | // so we only check one. |
| 2673 | break :blk if (lhs_scalar_ty.isInt(zcu)) | 2772 | break :blk if (lhs_scalar_ty.isInt(zcu)) |
| 2674 | try airBinOp(f, inst, "%", "rem", .none) | 2773 | try airBinOp(f, inst, "%", "rem", .big_temp_bits) |
| 2675 | else | 2774 | else |
| 2676 | try airBinBuiltinCall(f, inst, "fmod", .none); | 2775 | try airBinBuiltinCall(f, inst, "fmod", .none); |
| 2677 | }, | 2776 | }, |
| 2678 | .div_floor => try airBinBuiltinCall(f, inst, "div_floor", .none), | 2777 | .div_floor => try airBinBuiltinCall(f, inst, "divFloor", .big_temp_bits), |
| 2679 | .div_ceil => try airBinBuiltinCall(f, inst, "div_ceil", .none), | 2778 | .div_ceil => try airBinBuiltinCall(f, inst, "divCeil", .big_temp_bits), |
| 2680 | .mod => try airBinBuiltinCall(f, inst, "mod", .none), | 2779 | .mod => try airBinBuiltinCall(f, inst, "mod", .big_temp_bits), |
| 2681 | .abs => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].ty_op.operand, "abs", .none), | 2780 | .abs => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].ty_op.operand, "abs", .none), |
| 2682 | 2781 | ||
| 2683 | .add_wrap => try airBinBuiltinCall(f, inst, "addw", .bits), | 2782 | .add_wrap => try airBinBuiltinCall(f, inst, "addw", .bits), |
| ... | @@ -2687,7 +2786,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) Error!void { | ... | @@ -2687,7 +2786,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) Error!void { |
| 2687 | .add_sat => try airBinBuiltinCall(f, inst, "adds", .bits), | 2786 | .add_sat => try airBinBuiltinCall(f, inst, "adds", .bits), |
| 2688 | .sub_sat => try airBinBuiltinCall(f, inst, "subs", .bits), | 2787 | .sub_sat => try airBinBuiltinCall(f, inst, "subs", .bits), |
| 2689 | .mul_sat => try airBinBuiltinCall(f, inst, "muls", .bits), | 2788 | .mul_sat => try airBinBuiltinCall(f, inst, "muls", .bits), |
| 2690 | .shl_sat => try airBinBuiltinCall(f, inst, "shls", .bits), | 2789 | .shl_sat => try airBinBuiltinCall(f, inst, "shls", .bits_none), |
| 2691 | 2790 | ||
| 2692 | .sqrt => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].un_op, "sqrt", .none), | 2791 | .sqrt => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].un_op, "sqrt", .none), |
| 2693 | .sin => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].un_op, "sin", .none), | 2792 | .sin => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].un_op, "sin", .none), |
| ... | @@ -2764,8 +2863,8 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) Error!void { | ... | @@ -2764,8 +2863,8 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) Error!void { |
| 2764 | .int_from_error => try airNopCast(f, inst), | 2863 | .int_from_error => try airNopCast(f, inst), |
| 2765 | .union_from_enum => try airUnionFromEnum(f, inst), | 2864 | .union_from_enum => try airUnionFromEnum(f, inst), |
| 2766 | .bit_cast => try airBitCast(f, inst), | 2865 | .bit_cast => try airBitCast(f, inst), |
| 2767 | .int_cast => try airIntCast(f, inst), | 2866 | .int_cast => try airIntCast(f, inst, "intCast", .none), |
| 2768 | .trunc => try airTrunc(f, inst), | 2867 | .trunc => try airIntCast(f, inst, "truncate", .bits), |
| 2769 | .load => try airLoad(f, inst), | 2868 | .load => try airLoad(f, inst), |
| 2770 | .store => try airStore(f, inst, false), | 2869 | .store => try airStore(f, inst, false), |
| 2771 | .store_safe => try airStore(f, inst, true), | 2870 | .store_safe => try airStore(f, inst, true), |
| ... | @@ -2783,9 +2882,9 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) Error!void { | ... | @@ -2783,9 +2882,9 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) Error!void { |
| 2783 | .get_union_tag => try airGetUnionTag(f, inst), | 2882 | .get_union_tag => try airGetUnionTag(f, inst), |
| 2784 | .clz => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].ty_op.operand, "clz", .bits), | 2883 | .clz => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].ty_op.operand, "clz", .bits), |
| 2785 | .ctz => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].ty_op.operand, "ctz", .bits), | 2884 | .ctz => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].ty_op.operand, "ctz", .bits), |
| 2786 | .popcount => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].ty_op.operand, "popcount", .bits), | 2885 | .popcount => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].ty_op.operand, "popCount", .bits), |
| 2787 | .byte_swap => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].ty_op.operand, "byte_swap", .bits), | 2886 | .byte_swap => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].ty_op.operand, "byteSwap", .bits), |
| 2788 | .bit_reverse => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].ty_op.operand, "bit_reverse", .bits), | 2887 | .bit_reverse => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].ty_op.operand, "bitReverse", .bits), |
| 2789 | .tag_name => try airTagName(f, inst), | 2888 | .tag_name => try airTagName(f, inst), |
| 2790 | .error_name => try airErrorName(f, inst), | 2889 | .error_name => try airErrorName(f, inst), |
| 2791 | .splat => try airSplat(f, inst), | 2890 | .splat => try airSplat(f, inst), |
| ... | @@ -3124,7 +3223,16 @@ fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3124,7 +3223,16 @@ fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3124 | const zcu = pt.zcu; | 3223 | const zcu = pt.zcu; |
| 3125 | const inst_ty = f.typeOfIndex(inst); | 3224 | const inst_ty = f.typeOfIndex(inst); |
| 3126 | const elem_ty = inst_ty.childType(zcu); | 3225 | const elem_ty = inst_ty.childType(zcu); |
| 3127 | if (!elem_ty.hasRuntimeBits(zcu)) return .{ .undef = inst_ty }; | 3226 | if (!elem_ty.hasRuntimeBits(zcu)) { |
| 3227 | const w = &f.code.writer; | ||
| 3228 | const local = try f.allocLocal(inst, inst_ty); | ||
| 3229 | try f.writeCValue(w, local, .other); | ||
| 3230 | try w.writeAll(" = "); | ||
| 3231 | try f.dg.renderOpvPointer(w, inst_ty, .other); | ||
| 3232 | try w.writeByte(';'); | ||
| 3233 | try f.newline(); | ||
| 3234 | return local; | ||
| 3235 | } | ||
| 3128 | 3236 | ||
| 3129 | const local = try f.allocLocalValue(.{ | 3237 | const local = try f.allocLocalValue(.{ |
| 3130 | .type = elem_ty, | 3238 | .type = elem_ty, |
| ... | @@ -3298,120 +3406,57 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !void { | ... | @@ -3298,120 +3406,57 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !void { |
| 3298 | } | 3406 | } |
| 3299 | } | 3407 | } |
| 3300 | 3408 | ||
| 3301 | fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue { | 3409 | fn airIntCast(f: *Function, inst: Air.Inst.Index, operation: []const u8, info: BuiltinInfo) !CValue { |
| 3302 | const pt = f.dg.pt; | 3410 | const pt = f.dg.pt; |
| 3303 | const zcu = pt.zcu; | 3411 | const zcu = pt.zcu; |
| 3304 | const ty_op = f.air.instructions.items(.data)[@backingInt(inst)].ty_op; | 3412 | const ty_op = f.air.instructions.items(.data)[@backingInt(inst)].ty_op; |
| 3305 | 3413 | ||
| 3306 | const operand = try f.resolveInst(ty_op.operand); | 3414 | const inst_ty = ty_op.ty.toType(); |
| 3307 | try reap(f, inst, &.{ty_op.operand}); | ||
| 3308 | |||
| 3309 | const inst_ty = f.typeOfIndex(inst); | ||
| 3310 | const inst_scalar_ty = inst_ty.scalarType(zcu); | 3415 | const inst_scalar_ty = inst_ty.scalarType(zcu); |
| 3311 | const operand_ty = f.typeOf(ty_op.operand); | 3416 | const operand_ty = f.typeOf(ty_op.operand); |
| 3312 | const scalar_ty = operand_ty.scalarType(zcu); | 3417 | const operand_scalar_ty = operand_ty.scalarType(zcu); |
| 3313 | 3418 | const is_big = lowersToBigInt(operand_ty, zcu); | |
| 3314 | // `intCastIsNoop` doesn't apply to vectors because every vector lowers to a different C struct. | ||
| 3315 | if (inst_ty.zigTypeTag(zcu) != .vector and f.dg.intCastIsNoop(inst_scalar_ty, scalar_ty)) { | ||
| 3316 | return f.moveCValue(inst, inst_ty, operand); | ||
| 3317 | } | ||
| 3318 | |||
| 3319 | const w = &f.code.writer; | ||
| 3320 | const local = try f.allocLocal(inst, inst_ty); | ||
| 3321 | const v = try Vectorize.start(f, inst, w, operand_ty); | ||
| 3322 | try f.writeCValue(w, local, .other); | ||
| 3323 | try v.elem(f, w); | ||
| 3324 | try w.writeAll(" = "); | ||
| 3325 | try f.renderIntCast(w, inst_scalar_ty, operand, v, scalar_ty, .other); | ||
| 3326 | try w.writeByte(';'); | ||
| 3327 | try f.newline(); | ||
| 3328 | try v.end(f, inst, w); | ||
| 3329 | return local; | ||
| 3330 | } | ||
| 3331 | |||
| 3332 | fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue { | ||
| 3333 | const pt = f.dg.pt; | ||
| 3334 | const zcu = pt.zcu; | ||
| 3335 | const ty_op = f.air.instructions.items(.data)[@backingInt(inst)].ty_op; | ||
| 3336 | 3419 | ||
| 3337 | const operand = try f.resolveInst(ty_op.operand); | 3420 | const operand = try f.resolveInst(ty_op.operand); |
| 3338 | try reap(f, inst, &.{ty_op.operand}); | 3421 | if (!is_big) try reap(f, inst, &.{ty_op.operand}); |
| 3339 | 3422 | ||
| 3340 | const inst_ty = f.typeOfIndex(inst); | 3423 | const ref_ret = lowersToBigInt(inst_scalar_ty, zcu); |
| 3341 | const inst_scalar_ty = inst_ty.scalarType(zcu); | 3424 | const ref_arg = lowersToBigInt(operand_scalar_ty, zcu); |
| 3342 | const dest_int_info = inst_scalar_ty.intInfo(zcu); | ||
| 3343 | const dest_bits = dest_int_info.bits; | ||
| 3344 | const dest_c_bits = toCIntBits(dest_bits) orelse | ||
| 3345 | return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{}); | ||
| 3346 | const operand_ty = f.typeOf(ty_op.operand); | ||
| 3347 | const scalar_ty = operand_ty.scalarType(zcu); | ||
| 3348 | const scalar_int_info = scalar_ty.intInfo(zcu); | ||
| 3349 | |||
| 3350 | const need_cast = dest_c_bits < 64; | ||
| 3351 | const need_lo = scalar_int_info.bits > 64 and dest_bits <= 64; | ||
| 3352 | const need_mask = dest_bits < 8 or !std.math.isPowerOfTwo(dest_bits); | ||
| 3353 | if (!need_cast and !need_lo and !need_mask) return f.moveCValue(inst, inst_ty, operand); | ||
| 3354 | 3425 | ||
| 3355 | const w = &f.code.writer; | 3426 | const w = &f.code.writer; |
| 3356 | const local = try f.allocLocal(inst, inst_ty); | 3427 | const local = try f.allocLocal(inst, inst_ty); |
| 3428 | if (is_big) try reap(f, inst, &.{ty_op.operand}); | ||
| 3357 | const v = try Vectorize.start(f, inst, w, operand_ty); | 3429 | const v = try Vectorize.start(f, inst, w, operand_ty); |
| 3358 | try f.writeCValue(w, local, .other); | 3430 | if (!ref_ret) { |
| 3359 | try v.elem(f, w); | 3431 | try f.writeCValue(w, local, .other); |
| 3360 | try w.writeAll(" = "); | 3432 | try v.elem(f, w); |
| 3361 | if (need_cast) { | 3433 | try w.writeAll(" = "); |
| 3362 | try w.writeByte('('); | ||
| 3363 | try f.renderType(w, inst_scalar_ty); | ||
| 3364 | try w.writeByte(')'); | ||
| 3365 | } | ||
| 3366 | if (need_lo) { | ||
| 3367 | try w.writeAll("zig_lo_"); | ||
| 3368 | try f.dg.renderTypeForBuiltinFnName(w, scalar_ty); | ||
| 3369 | try w.writeByte('('); | ||
| 3370 | } | 3434 | } |
| 3371 | if (!need_mask) { | 3435 | try w.writeAll("zig_"); |
| 3372 | try f.writeCValue(w, operand, .other); | 3436 | try f.dg.renderTypeForBuiltinFnName(w, inst_scalar_ty); |
| 3437 | try w.print("_{s}_", .{operation}); | ||
| 3438 | try f.dg.renderTypeForBuiltinFnName(w, operand_scalar_ty); | ||
| 3439 | try w.writeByte('('); | ||
| 3440 | if (ref_ret) { | ||
| 3441 | try w.writeByte('&'); | ||
| 3442 | try f.writeCValue(w, local, .other); | ||
| 3373 | try v.elem(f, w); | 3443 | try v.elem(f, w); |
| 3374 | } else switch (dest_int_info.signedness) { | 3444 | try w.writeAll(", "); |
| 3375 | .unsigned => { | ||
| 3376 | try w.writeAll("zig_and_"); | ||
| 3377 | try f.dg.renderTypeForBuiltinFnName(w, scalar_ty); | ||
| 3378 | try w.writeByte('('); | ||
| 3379 | try f.writeCValue(w, operand, .other); | ||
| 3380 | try v.elem(f, w); | ||
| 3381 | try w.print(", {f})", .{ | ||
| 3382 | try f.fmtIntLiteralHex(try inst_scalar_ty.maxIntScalar(pt, scalar_ty)), | ||
| 3383 | }); | ||
| 3384 | }, | ||
| 3385 | .signed => { | ||
| 3386 | const c_bits = toCIntBits(scalar_int_info.bits) orelse | ||
| 3387 | return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{}); | ||
| 3388 | const shift_val = try pt.intValue(.u8, c_bits - dest_bits); | ||
| 3389 | |||
| 3390 | try w.writeAll("zig_shr_"); | ||
| 3391 | try f.dg.renderTypeForBuiltinFnName(w, scalar_ty); | ||
| 3392 | if (c_bits == 128) { | ||
| 3393 | try w.print("(zig_bitCast_i{d}(", .{c_bits}); | ||
| 3394 | } else { | ||
| 3395 | try w.print("((int{d}_t)", .{c_bits}); | ||
| 3396 | } | ||
| 3397 | try w.print("zig_shl_u{d}(", .{c_bits}); | ||
| 3398 | if (c_bits == 128) { | ||
| 3399 | try w.print("zig_bitCast_u{d}(", .{c_bits}); | ||
| 3400 | } else { | ||
| 3401 | try w.print("(uint{d}_t)", .{c_bits}); | ||
| 3402 | } | ||
| 3403 | try f.writeCValue(w, operand, .other); | ||
| 3404 | try v.elem(f, w); | ||
| 3405 | if (c_bits == 128) try w.writeByte(')'); | ||
| 3406 | try w.print(", {f})", .{try f.fmtIntLiteralDec(shift_val)}); | ||
| 3407 | if (c_bits == 128) try w.writeByte(')'); | ||
| 3408 | try w.print(", {f})", .{try f.fmtIntLiteralDec(shift_val)}); | ||
| 3409 | }, | ||
| 3410 | } | 3445 | } |
| 3411 | if (need_lo) try w.writeByte(')'); | 3446 | if (ref_arg) { |
| 3412 | try w.writeByte(';'); | 3447 | try w.writeByte('&'); |
| 3448 | switch (operand) { | ||
| 3449 | .constant => |val| try f.dg.renderValueAsLvalue(w, val), | ||
| 3450 | else => try f.writeCValue(w, operand, .other), | ||
| 3451 | } | ||
| 3452 | } else try f.writeCValue(w, operand, .other); | ||
| 3453 | try v.elem(f, w); | ||
| 3454 | try f.dg.renderBuiltinInfo(w, inst_scalar_ty, info); | ||
| 3455 | try f.dg.renderBuiltinInfo(w, operand_scalar_ty, .none); | ||
| 3456 | try w.writeAll(");"); | ||
| 3413 | try f.newline(); | 3457 | try f.newline(); |
| 3414 | try v.end(f, inst, w); | 3458 | try v.end(f, inst, w); |
| 3459 | |||
| 3415 | return local; | 3460 | return local; |
| 3416 | } | 3461 | } |
| 3417 | 3462 | ||
| ... | @@ -3525,39 +3570,46 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info: | ... | @@ -3525,39 +3570,46 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info: |
| 3525 | const ty_pl = f.air.instructions.items(.data)[@backingInt(inst)].ty_pl; | 3570 | const ty_pl = f.air.instructions.items(.data)[@backingInt(inst)].ty_pl; |
| 3526 | const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data; | 3571 | const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data; |
| 3527 | 3572 | ||
| 3573 | const lhs_ty = f.typeOf(bin_op.lhs); | ||
| 3574 | const rhs_ty = f.typeOf(bin_op.rhs); | ||
| 3575 | const is_big = lowersToBigInt(lhs_ty, zcu); | ||
| 3576 | |||
| 3528 | const lhs = try f.resolveInst(bin_op.lhs); | 3577 | const lhs = try f.resolveInst(bin_op.lhs); |
| 3529 | const rhs = try f.resolveInst(bin_op.rhs); | 3578 | const rhs = try f.resolveInst(bin_op.rhs); |
| 3530 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); | 3579 | if (!is_big) try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 3531 | 3580 | ||
| 3532 | const inst_ty = f.typeOfIndex(inst); | 3581 | const lhs_scalar_ty = lhs_ty.scalarType(zcu); |
| 3533 | const operand_ty = f.typeOf(bin_op.lhs); | 3582 | const rhs_scalar_ty = rhs_ty.scalarType(zcu); |
| 3534 | const scalar_ty = operand_ty.scalarType(zcu); | ||
| 3535 | 3583 | ||
| 3536 | const ref_arg = lowersToBigInt(scalar_ty, zcu); | 3584 | const ref_lhs = lowersToBigInt(lhs_scalar_ty, zcu); |
| 3585 | const ref_rhs = lowersToBigInt(rhs_scalar_ty, zcu); | ||
| 3537 | 3586 | ||
| 3538 | const w = &f.code.writer; | 3587 | const w = &f.code.writer; |
| 3539 | const local = try f.allocLocal(inst, inst_ty); | 3588 | const local = try f.allocLocal(inst, f.typeOfIndex(inst)); |
| 3540 | const v = try Vectorize.start(f, inst, w, operand_ty); | 3589 | if (is_big) try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 3590 | const v = try Vectorize.start(f, inst, w, lhs_ty); | ||
| 3541 | try f.writeCValueMember(w, local, .{ .field = 1 }); | 3591 | try f.writeCValueMember(w, local, .{ .field = 1 }); |
| 3542 | try v.elem(f, w); | 3592 | try v.elem(f, w); |
| 3543 | try w.writeAll(" = zig_"); | 3593 | try w.writeAll(" = "); |
| 3594 | try w.writeAll("zig_"); | ||
| 3544 | try w.writeAll(operation); | 3595 | try w.writeAll(operation); |
| 3545 | try w.writeAll("o_"); | 3596 | try w.writeAll("o_"); |
| 3546 | try f.dg.renderTypeForBuiltinFnName(w, scalar_ty); | 3597 | try f.dg.renderTypeForBuiltinFnName(w, lhs_scalar_ty); |
| 3547 | try w.writeByte('('); | 3598 | try w.writeByte('('); |
| 3548 | 3599 | ||
| 3549 | // '&dest', possibly preceded by a cast | 3600 | // '&dest', possibly preceded by a cast |
| 3550 | switch (zcu.intern_pool.indexToKey(scalar_ty.toIntern())) { | 3601 | switch (zcu.intern_pool.indexToKey(lhs_scalar_ty.toIntern())) { |
| 3551 | .int_type => {}, // we already have a '[u]intX_t *' | 3602 | .int_type => {}, // we already have a '[u]intX_t *' |
| 3552 | .simple_type => { | 3603 | .simple_type => { |
| 3553 | // '&dest' will be something like a 'uintptr_t *', which might be a different C type to | 3604 | // '&dest' will be something like a 'uintptr_t *', which might be a different C type to |
| 3554 | // the equivalent sized integer (e.g. 'uint64_t *'), so we need a cast. We don't need a | 3605 | // the equivalent sized integer (e.g. 'uint64_t *'), so we need a cast. We don't need a |
| 3555 | // cast on the *operands* because they are passed by value (except for big integers, | 3606 | // cast on the *operands* because they are passed by value (except for big integers, |
| 3556 | // where this issue doesn't exist because no "simple" int type needs bigint repr). | 3607 | // where this issue doesn't exist because no "simple" int type needs bigint repr). |
| 3557 | try w.print("({s}int{d}_t *)", .{ | 3608 | const inst_int_info = lhs_scalar_ty.intInfo(zcu); |
| 3558 | if (scalar_ty.isUnsignedInt(zcu)) "u" else "", | 3609 | try w.print("({s}int{d}_t *)", .{ switch (inst_int_info.signedness) { |
| 3559 | scalar_ty.abiSize(zcu) * 8, | 3610 | .signed => "", |
| 3560 | }); | 3611 | .unsigned => "u", |
| 3612 | }, inst_int_info.bits }); | ||
| 3561 | }, | 3613 | }, |
| 3562 | else => unreachable, | 3614 | else => unreachable, |
| 3563 | } | 3615 | } |
| ... | @@ -3566,14 +3618,24 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info: | ... | @@ -3566,14 +3618,24 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info: |
| 3566 | try v.elem(f, w); | 3618 | try v.elem(f, w); |
| 3567 | 3619 | ||
| 3568 | try w.writeAll(", "); | 3620 | try w.writeAll(", "); |
| 3569 | if (ref_arg) try w.writeByte('&'); | 3621 | if (ref_lhs) { |
| 3570 | try f.writeCValue(w, lhs, .other); | 3622 | try w.writeByte('&'); |
| 3623 | switch (lhs) { | ||
| 3624 | .constant => |lhs_val| try f.dg.renderValueAsLvalue(w, lhs_val), | ||
| 3625 | else => try f.writeCValue(w, lhs, .other), | ||
| 3626 | } | ||
| 3627 | } else try f.writeCValue(w, lhs, .other); | ||
| 3571 | try v.elem(f, w); | 3628 | try v.elem(f, w); |
| 3572 | try w.writeAll(", "); | 3629 | try w.writeAll(", "); |
| 3573 | if (ref_arg) try w.writeByte('&'); | 3630 | if (ref_rhs) { |
| 3574 | try f.writeCValue(w, rhs, .other); | 3631 | try w.writeByte('&'); |
| 3575 | if (f.typeOf(bin_op.rhs).isVector(zcu)) try v.elem(f, w); | 3632 | switch (rhs) { |
| 3576 | try f.dg.renderBuiltinInfo(w, scalar_ty, info); | 3633 | .constant => |rhs_val| try f.dg.renderValueAsLvalue(w, rhs_val), |
| 3634 | else => try f.writeCValue(w, rhs, .other), | ||
| 3635 | } | ||
| 3636 | } else try f.writeCValue(w, rhs, .other); | ||
| 3637 | try v.elem(f, w); | ||
| 3638 | try f.dg.renderBuiltinInfo(w, lhs_scalar_ty, info); | ||
| 3577 | try w.writeAll(");"); | 3639 | try w.writeAll(");"); |
| 3578 | try f.newline(); | 3640 | try f.newline(); |
| 3579 | try v.end(f, inst, w); | 3641 | try v.end(f, inst, w); |
| ... | @@ -3622,8 +3684,18 @@ fn airBinOp( | ... | @@ -3622,8 +3684,18 @@ fn airBinOp( |
| 3622 | const bin_op = f.air.instructions.items(.data)[@backingInt(inst)].bin_op; | 3684 | const bin_op = f.air.instructions.items(.data)[@backingInt(inst)].bin_op; |
| 3623 | const operand_ty = f.typeOf(bin_op.lhs); | 3685 | const operand_ty = f.typeOf(bin_op.lhs); |
| 3624 | const scalar_ty = operand_ty.scalarType(zcu); | 3686 | const scalar_ty = operand_ty.scalarType(zcu); |
| 3625 | if ((scalar_ty.isInt(zcu) and scalar_ty.bitSize(zcu) > 64) or scalar_ty.isRuntimeFloat()) | 3687 | |
| 3626 | return try airBinBuiltinCall(f, inst, operation, info); | 3688 | builtin: { |
| 3689 | if (scalar_ty.isInt(zcu)) switch (CType.classifyInt(scalar_ty, zcu)) { | ||
| 3690 | .void => unreachable, | ||
| 3691 | .small => |int| switch (int) { | ||
| 3692 | else => break :builtin, | ||
| 3693 | .zig_u128, .zig_i128 => {}, | ||
| 3694 | }, | ||
| 3695 | .big => {}, | ||
| 3696 | } else if (!scalar_ty.isRuntimeFloat()) break :builtin; | ||
| 3697 | return airBinBuiltinCall(f, inst, operation, info); | ||
| 3698 | } | ||
| 3627 | 3699 | ||
| 3628 | const lhs = try f.resolveInst(bin_op.lhs); | 3700 | const lhs = try f.resolveInst(bin_op.lhs); |
| 3629 | const rhs = try f.resolveInst(bin_op.rhs); | 3701 | const rhs = try f.resolveInst(bin_op.rhs); |
| ... | @@ -3662,19 +3734,21 @@ fn airCmpOp( | ... | @@ -3662,19 +3734,21 @@ fn airCmpOp( |
| 3662 | const lhs_ty = f.typeOf(data.lhs); | 3734 | const lhs_ty = f.typeOf(data.lhs); |
| 3663 | const scalar_ty = lhs_ty.scalarType(zcu); | 3735 | const scalar_ty = lhs_ty.scalarType(zcu); |
| 3664 | 3736 | ||
| 3665 | if (scalar_ty.isInt(zcu)) { | 3737 | builtin: { |
| 3666 | const scalar_bits = scalar_ty.bitSize(zcu); | 3738 | if (scalar_ty.isInt(zcu)) { |
| 3667 | if (scalar_bits > 64) return airCmpBuiltinCall( | 3739 | switch (CType.classifyInt(scalar_ty, zcu)) { |
| 3668 | f, | 3740 | .void => unreachable, |
| 3669 | inst, | 3741 | .small => |int| switch (int) { |
| 3670 | data, | 3742 | else => break :builtin, |
| 3671 | operator, | 3743 | .zig_u128, .zig_i128 => {}, |
| 3672 | .cmp, | 3744 | }, |
| 3673 | if (scalar_bits > 128) .bits else .none, | 3745 | .big => {}, |
| 3674 | ); | 3746 | } |
| 3747 | return airCmpBuiltinCall(f, inst, data, operator, .cmp, .none); | ||
| 3748 | } | ||
| 3749 | if (scalar_ty.isRuntimeFloat()) | ||
| 3750 | return airCmpBuiltinCall(f, inst, data, operator, .operator, .none); | ||
| 3675 | } | 3751 | } |
| 3676 | if (scalar_ty.isRuntimeFloat()) | ||
| 3677 | return airCmpBuiltinCall(f, inst, data, operator, .operator, .none); | ||
| 3678 | 3752 | ||
| 3679 | const inst_ty = f.typeOfIndex(inst); | 3753 | const inst_ty = f.typeOfIndex(inst); |
| 3680 | const lhs = try f.resolveInst(data.lhs); | 3754 | const lhs = try f.resolveInst(data.lhs); |
| ... | @@ -3716,21 +3790,23 @@ fn airEquality( | ... | @@ -3716,21 +3790,23 @@ fn airEquality( |
| 3716 | const pt = f.dg.pt; | 3790 | const pt = f.dg.pt; |
| 3717 | const zcu = pt.zcu; | 3791 | const zcu = pt.zcu; |
| 3718 | const bin_op = f.air.instructions.items(.data)[@backingInt(inst)].bin_op; | 3792 | const bin_op = f.air.instructions.items(.data)[@backingInt(inst)].bin_op; |
| 3719 | |||
| 3720 | const operand_ty = f.typeOf(bin_op.lhs); | 3793 | const operand_ty = f.typeOf(bin_op.lhs); |
| 3721 | if (operand_ty.isAbiInt(zcu)) { | 3794 | |
| 3722 | const operand_bits = operand_ty.bitSize(zcu); | 3795 | builtin: { |
| 3723 | if (operand_bits > 64) return airCmpBuiltinCall( | 3796 | if (operand_ty.isAbiInt(zcu)) { |
| 3724 | f, | 3797 | switch (CType.classifyInt(operand_ty, zcu)) { |
| 3725 | inst, | 3798 | .void => unreachable, |
| 3726 | bin_op, | 3799 | .small => |int| switch (int) { |
| 3727 | operator, | 3800 | else => break :builtin, |
| 3728 | .cmp, | 3801 | .zig_u128, .zig_i128 => {}, |
| 3729 | if (operand_bits > 128) .bits else .none, | 3802 | }, |
| 3730 | ); | 3803 | .big => {}, |
| 3804 | } | ||
| 3805 | return airCmpBuiltinCall(f, inst, bin_op, operator, .cmp, .none); | ||
| 3806 | } | ||
| 3807 | if (operand_ty.isRuntimeFloat()) | ||
| 3808 | return airCmpBuiltinCall(f, inst, bin_op, operator, .operator, .none); | ||
| 3731 | } | 3809 | } |
| 3732 | if (operand_ty.isRuntimeFloat()) | ||
| 3733 | return airCmpBuiltinCall(f, inst, bin_op, operator, .operator, .none); | ||
| 3734 | 3810 | ||
| 3735 | const lhs = try f.resolveInst(bin_op.lhs); | 3811 | const lhs = try f.resolveInst(bin_op.lhs); |
| 3736 | const rhs = try f.resolveInst(bin_op.rhs); | 3812 | const rhs = try f.resolveInst(bin_op.rhs); |
| ... | @@ -3809,7 +3885,7 @@ fn airCmpLteErrorsLen(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3809,7 +3885,7 @@ fn airCmpLteErrorsLen(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3809 | try f.writeCValue(w, local, .other); | 3885 | try f.writeCValue(w, local, .other); |
| 3810 | try w.writeAll(" = "); | 3886 | try w.writeAll(" = "); |
| 3811 | try f.writeCValue(w, operand, .other); | 3887 | try f.writeCValue(w, operand, .other); |
| 3812 | try w.writeAll(" < sizeof(zig_errorName) / sizeof(*zig_errorName);"); | 3888 | try w.writeAll(" <= sizeof(zig_errorName) / sizeof(*zig_errorName);"); |
| 3813 | try f.newline(); | 3889 | try f.newline(); |
| 3814 | return local; | 3890 | return local; |
| 3815 | } | 3891 | } |
| ... | @@ -3862,8 +3938,17 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []cons | ... | @@ -3862,8 +3938,17 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []cons |
| 3862 | const inst_ty = f.typeOfIndex(inst); | 3938 | const inst_ty = f.typeOfIndex(inst); |
| 3863 | const inst_scalar_ty = inst_ty.scalarType(zcu); | 3939 | const inst_scalar_ty = inst_ty.scalarType(zcu); |
| 3864 | 3940 | ||
| 3865 | if ((inst_scalar_ty.isInt(zcu) and inst_scalar_ty.bitSize(zcu) > 64) or inst_scalar_ty.isRuntimeFloat()) | 3941 | builtin: { |
| 3866 | return try airBinBuiltinCall(f, inst, operation, .none); | 3942 | if (inst_scalar_ty.isInt(zcu)) switch (CType.classifyInt(inst_scalar_ty, zcu)) { |
| 3943 | .void => unreachable, | ||
| 3944 | .small => |int| switch (int) { | ||
| 3945 | else => break :builtin, | ||
| 3946 | .zig_u128, .zig_i128 => {}, | ||
| 3947 | }, | ||
| 3948 | .big => {}, | ||
| 3949 | } else if (!inst_scalar_ty.isRuntimeFloat()) break :builtin; | ||
| 3950 | return airBinBuiltinCall(f, inst, operation, .none); | ||
| 3951 | } | ||
| 3867 | 3952 | ||
| 3868 | const lhs = try f.resolveInst(bin_op.lhs); | 3953 | const lhs = try f.resolveInst(bin_op.lhs); |
| 3869 | const rhs = try f.resolveInst(bin_op.rhs); | 3954 | const rhs = try f.resolveInst(bin_op.rhs); |
| ... | @@ -3979,10 +4064,7 @@ fn airCall( | ... | @@ -3979,10 +4064,7 @@ fn airCall( |
| 3979 | try w.writeAll("(void)"); | 4064 | try w.writeAll("(void)"); |
| 3980 | break :result .none; | 4065 | break :result .none; |
| 3981 | } else { | 4066 | } else { |
| 3982 | const local = try f.allocAlignedLocal(inst, .{ | 4067 | const local = try f.allocAlignedLocal(inst, .{ .type = ret_ty }); |
| 3983 | .type = ret_ty, | ||
| 3984 | .alignment = .none, | ||
| 3985 | }); | ||
| 3986 | try f.writeCValue(w, local, .other); | 4068 | try f.writeCValue(w, local, .other); |
| 3987 | try w.writeAll(" = "); | 4069 | try w.writeAll(" = "); |
| 3988 | break :result local; | 4070 | break :result local; |
| ... | @@ -4058,16 +4140,7 @@ fn airCall( | ... | @@ -4058,16 +4140,7 @@ fn airCall( |
| 4058 | fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue { | 4140 | fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4059 | const dbg_stmt = f.air.instructions.items(.data)[@backingInt(inst)].dbg_stmt; | 4141 | const dbg_stmt = f.air.instructions.items(.data)[@backingInt(inst)].dbg_stmt; |
| 4060 | const w = &f.code.writer; | 4142 | const w = &f.code.writer; |
| 4061 | // TODO re-evaluate whether to emit these or not. If we naively emit | 4143 | try w.print("/* {d}:{d} */", .{ dbg_stmt.line + 1, dbg_stmt.column + 1 }); |
| 4062 | // these directives, the output file will report bogus line numbers because | ||
| 4063 | // every newline after the #line directive adds one to the line. | ||
| 4064 | // We also don't print the filename yet, so the output is strictly unhelpful. | ||
| 4065 | // If we wanted to go this route, we would need to go all the way and not output | ||
| 4066 | // newlines until the next dbg_stmt occurs. | ||
| 4067 | // Perhaps an additional compilation option is in order? | ||
| 4068 | //try w.print("#line {d}", .{dbg_stmt.line + 1}); | ||
| 4069 | //try f.newline(); | ||
| 4070 | try w.print("/* file:{d}:{d} */", .{ dbg_stmt.line + 1, dbg_stmt.column + 1 }); | ||
| 4071 | try f.newline(); | 4144 | try f.newline(); |
| 4072 | return .none; | 4145 | return .none; |
| 4073 | } | 4146 | } |
| ... | @@ -4433,12 +4506,12 @@ fn airBitCast(f: *Function, inst: Air.Inst.Index) Error!CValue { | ... | @@ -4433,12 +4506,12 @@ fn airBitCast(f: *Function, inst: Air.Inst.Index) Error!CValue { |
| 4433 | const operand_scalar_ty = operand_ty.scalarType(zcu); | 4506 | const operand_scalar_ty = operand_ty.scalarType(zcu); |
| 4434 | const dest_scalar_ty = dest_ty.scalarType(zcu); | 4507 | const dest_scalar_ty = dest_ty.scalarType(zcu); |
| 4435 | 4508 | ||
| 4436 | // Some cases are handled with a simple cast: | ||
| 4437 | // * float -> float | ||
| 4438 | // * bool -> int | ||
| 4439 | if ((operand_scalar_ty.isRuntimeFloat() and dest_scalar_ty.isRuntimeFloat()) or | 4509 | if ((operand_scalar_ty.isRuntimeFloat() and dest_scalar_ty.isRuntimeFloat()) or |
| 4440 | (operand_scalar_ty.toIntern() == .bool_type and dest_scalar_ty.isAbiInt(zcu))) | 4510 | (operand_scalar_ty.toIntern() == .bool_type and dest_scalar_ty.isAbiInt(zcu))) |
| 4441 | { | 4511 | { |
| 4512 | // Some cases are handled with a simple cast: | ||
| 4513 | // * float -> float | ||
| 4514 | // * bool -> int | ||
| 4442 | try f.writeCValue(w, dest_local, .other); | 4515 | try f.writeCValue(w, dest_local, .other); |
| 4443 | try v.elem(f, w); | 4516 | try v.elem(f, w); |
| 4444 | try w.writeAll(" = ("); | 4517 | try w.writeAll(" = ("); |
| ... | @@ -4458,85 +4531,44 @@ fn airBitCast(f: *Function, inst: Air.Inst.Index) Error!CValue { | ... | @@ -4458,85 +4531,44 @@ fn airBitCast(f: *Function, inst: Air.Inst.Index) Error!CValue { |
| 4458 | try v.elem(f, w); | 4531 | try v.elem(f, w); |
| 4459 | try w.writeAll(" != 0;"); | 4532 | try w.writeAll(" != 0;"); |
| 4460 | try f.newline(); | 4533 | try f.newline(); |
| 4461 | } else if (dest_scalar_ty.isRuntimeFloat()) { | ||
| 4462 | // For int->float, just do a memcpy. | ||
| 4463 | assert(operand_scalar_ty.isAbiInt(zcu)); | ||
| 4464 | try w.writeAll("memcpy(&"); | ||
| 4465 | try f.writeCValue(w, dest_local, .other); | ||
| 4466 | try v.elem(f, w); | ||
| 4467 | try w.writeAll(", &"); | ||
| 4468 | switch (operand) { | ||
| 4469 | .constant => |val| try f.dg.renderValueAsLvalue(w, val), | ||
| 4470 | else => try f.writeCValue(w, operand, .other), | ||
| 4471 | } | ||
| 4472 | try v.elem(f, w); | ||
| 4473 | try w.print(", {d});", .{@min(operand_scalar_ty.abiSize(zcu), dest_scalar_ty.abiSize(zcu))}); | ||
| 4474 | try f.newline(); | ||
| 4475 | } else { | 4534 | } else { |
| 4476 | // The only remaining possibility is that the result is an integer. We will need to use | ||
| 4477 | // `zig_wrap_*` to correct the "padding" bits after we populate the value bits. | ||
| 4478 | assert(dest_scalar_ty.isAbiInt(zcu)); | ||
| 4479 | assert(operand_scalar_ty.isRuntimeFloat() or operand_scalar_ty.isAbiInt(zcu)); | 4535 | assert(operand_scalar_ty.isRuntimeFloat() or operand_scalar_ty.isAbiInt(zcu)); |
| 4536 | assert(dest_scalar_ty.isRuntimeFloat() or dest_scalar_ty.isAbiInt(zcu)); | ||
| 4480 | 4537 | ||
| 4481 | // memcpy the value... | 4538 | const ref_ret = lowersToBigInt(dest_scalar_ty, zcu); |
| 4482 | try w.writeAll("memcpy(&"); | 4539 | const ref_arg = lowersToBigInt(operand_scalar_ty, zcu); |
| 4483 | try f.writeCValue(w, dest_local, .other); | 4540 | |
| 4484 | try v.elem(f, w); | 4541 | if (!ref_ret) { |
| 4485 | try w.writeAll(", &"); | 4542 | try f.writeCValue(w, dest_local, .other); |
| 4486 | switch (operand) { | 4543 | try v.elem(f, w); |
| 4487 | .constant => |val| try f.dg.renderValueAsLvalue(w, val), | 4544 | try w.writeAll(" = "); |
| 4488 | else => try f.writeCValue(w, operand, .other), | ||
| 4489 | } | 4545 | } |
| 4546 | try w.writeAll("zig_"); | ||
| 4547 | try f.dg.renderTypeForBuiltinFnName(w, dest_scalar_ty); | ||
| 4548 | try w.writeAll("_bitCast_"); | ||
| 4549 | try f.dg.renderTypeForBuiltinFnName(w, operand_scalar_ty); | ||
| 4550 | try w.writeByte('('); | ||
| 4551 | if (ref_ret) { | ||
| 4552 | try w.writeByte('&'); | ||
| 4553 | try f.writeCValue(w, dest_local, .other); | ||
| 4554 | try v.elem(f, w); | ||
| 4555 | try w.writeAll(", "); | ||
| 4556 | } | ||
| 4557 | if (ref_arg) { | ||
| 4558 | try w.writeByte('&'); | ||
| 4559 | switch (operand) { | ||
| 4560 | .constant => |val| try f.dg.renderValueAsLvalue(w, val), | ||
| 4561 | else => try f.writeCValue(w, operand, .other), | ||
| 4562 | } | ||
| 4563 | } else try f.writeCValue(w, operand, .other); | ||
| 4490 | try v.elem(f, w); | 4564 | try v.elem(f, w); |
| 4491 | try w.print(", {d});", .{@min(operand_scalar_ty.abiSize(zcu), dest_scalar_ty.abiSize(zcu))}); | 4565 | try f.dg.renderBuiltinInfo( |
| 4566 | w, | ||
| 4567 | dest_scalar_ty, | ||
| 4568 | if (operand_scalar_ty.isRuntimeFloat() or dest_scalar_ty.isRuntimeFloat()) .none else .bits, | ||
| 4569 | ); | ||
| 4570 | try w.writeAll(");"); | ||
| 4492 | try f.newline(); | 4571 | try f.newline(); |
| 4493 | |||
| 4494 | // ...and ensure padding bits have the correct value. | ||
| 4495 | switch (CType.classifyInt(dest_scalar_ty, zcu)) { | ||
| 4496 | .void => unreachable, // opv | ||
| 4497 | .small => { | ||
| 4498 | try f.writeCValue(w, dest_local, .other); | ||
| 4499 | try v.elem(f, w); | ||
| 4500 | try w.writeAll(" = zig_wrap_"); | ||
| 4501 | try f.dg.renderTypeForBuiltinFnName(w, dest_scalar_ty); | ||
| 4502 | try w.writeByte('('); | ||
| 4503 | try f.writeCValue(w, dest_local, .other); | ||
| 4504 | try v.elem(f, w); | ||
| 4505 | try f.dg.renderBuiltinInfo(w, dest_scalar_ty, .bits); | ||
| 4506 | try w.writeAll(");"); | ||
| 4507 | try f.newline(); | ||
| 4508 | }, | ||
| 4509 | .big => |big| { | ||
| 4510 | const dest_info = dest_scalar_ty.intInfo(zcu); | ||
| 4511 | const padding_index: u16 = switch (f.dg.mod.resolved_target.result.cpu.arch.endian()) { | ||
| 4512 | .little => big.limbs_len - 1, | ||
| 4513 | .big => 0, | ||
| 4514 | }; | ||
| 4515 | const wrap_bits = ((dest_info.bits - 1) % big.limb_size.bits()) + 1; | ||
| 4516 | if (big.limb_size != .@"128" or dest_info.signedness == .unsigned) { | ||
| 4517 | try f.writeCValue(w, dest_local, .other); | ||
| 4518 | try v.elem(f, w); | ||
| 4519 | try w.print(".limbs[{d}] = zig_wrap_{c}{d}(", .{ | ||
| 4520 | padding_index, | ||
| 4521 | signAbbrev(dest_info.signedness), | ||
| 4522 | big.limb_size.bits(), | ||
| 4523 | }); | ||
| 4524 | try f.writeCValue(w, dest_local, .other); | ||
| 4525 | try v.elem(f, w); | ||
| 4526 | try w.print(".limbs[{d}], {d});", .{ padding_index, wrap_bits }); | ||
| 4527 | } else { | ||
| 4528 | try f.writeCValue(w, dest_local, .other); | ||
| 4529 | try v.elem(f, w); | ||
| 4530 | try w.print(".limbs[{d}] = zig_bitCast_u128(zig_wrap_i128(zig_bitCast_i128(", .{ | ||
| 4531 | padding_index, | ||
| 4532 | }); | ||
| 4533 | try f.writeCValue(w, dest_local, .other); | ||
| 4534 | try v.elem(f, w); | ||
| 4535 | try w.print(".limbs[{d}]), {d}));", .{ padding_index, wrap_bits }); | ||
| 4536 | try f.newline(); | ||
| 4537 | } | ||
| 4538 | }, | ||
| 4539 | } | ||
| 4540 | } | 4572 | } |
| 4541 | 4573 | ||
| 4542 | try v.end(f, inst, w); | 4574 | try v.end(f, inst, w); |
| ... | @@ -4906,11 +4938,9 @@ fn lowerSwitchCmp( | ... | @@ -4906,11 +4938,9 @@ fn lowerSwitchCmp( |
| 4906 | 4938 | ||
| 4907 | fn asmInputNeedsLocal(f: *Function, constraint: []const u8, value: CValue) bool { | 4939 | fn asmInputNeedsLocal(f: *Function, constraint: []const u8, value: CValue) bool { |
| 4908 | const dg = f.dg; | 4940 | const dg = f.dg; |
| 4909 | const target = &dg.mod.resolved_target.result; | ||
| 4910 | return switch (constraint[0]) { | 4941 | return switch (constraint[0]) { |
| 4911 | '{' => true, | 4942 | '{' => true, |
| 4912 | 'i', 'r' => false, | 4943 | 'r', 'i', 'n', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P' => false, |
| 4913 | 'I' => !target.cpu.arch.isArm(), | ||
| 4914 | else => switch (value) { | 4944 | else => switch (value) { |
| 4915 | .constant => |val| switch (dg.pt.zcu.intern_pool.indexToKey(val.toIntern())) { | 4945 | .constant => |val| switch (dg.pt.zcu.intern_pool.indexToKey(val.toIntern())) { |
| 4916 | .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) { | 4946 | .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) { |
| ... | @@ -4937,10 +4967,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4937,10 +4967,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4937 | const w = &f.code.writer; | 4967 | const w = &f.code.writer; |
| 4938 | const inst_ty = f.typeOfIndex(inst); | 4968 | const inst_ty = f.typeOfIndex(inst); |
| 4939 | const inst_local = if (inst_ty.hasRuntimeBits(zcu)) local: { | 4969 | const inst_local = if (inst_ty.hasRuntimeBits(zcu)) local: { |
| 4940 | const inst_local = try f.allocLocalValue(.{ | 4970 | const inst_local = try f.allocLocalValue(.{ .type = inst_ty }); |
| 4941 | .type = inst_ty, | ||
| 4942 | .alignment = .none, | ||
| 4943 | }); | ||
| 4944 | if (f.wantSafety()) { | 4971 | if (f.wantSafety()) { |
| 4945 | try f.writeCValue(w, inst_local, .other); | 4972 | try f.writeCValue(w, inst_local, .other); |
| 4946 | try w.writeAll(" = "); | 4973 | try w.writeAll(" = "); |
| ... | @@ -4967,10 +4994,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4967,10 +4994,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4967 | if (is_reg) { | 4994 | if (is_reg) { |
| 4968 | const output_ty = if (output.operand == .none) inst_ty else f.typeOf(output.operand).childType(zcu); | 4995 | const output_ty = if (output.operand == .none) inst_ty else f.typeOf(output.operand).childType(zcu); |
| 4969 | try w.writeAll("register "); | 4996 | try w.writeAll("register "); |
| 4970 | const output_local = try f.allocLocalValue(.{ | 4997 | const output_local = try f.allocLocalValue(.{ .type = output_ty }); |
| 4971 | .type = output_ty, | ||
| 4972 | .alignment = .none, | ||
| 4973 | }); | ||
| 4974 | try f.allocs.put(gpa, output_local.new_local, false); | 4998 | try f.allocs.put(gpa, output_local.new_local, false); |
| 4975 | try f.dg.renderTypeAndName(w, output_ty, output_local, .{}, .none); | 4999 | try f.dg.renderTypeAndName(w, output_ty, output_local, .{}, .none); |
| 4976 | try w.writeAll(" __asm(\""); | 5000 | try w.writeAll(" __asm(\""); |
| ... | @@ -4989,7 +5013,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4989,7 +5013,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4989 | while (it.next()) |input| { | 5013 | while (it.next()) |input| { |
| 4990 | const constraint = input.constraint; | 5014 | const constraint = input.constraint; |
| 4991 | 5015 | ||
| 4992 | if (constraint.len < 1 or mem.indexOfScalar(u8, "=+&%", constraint[0]) != null or | 5016 | if (constraint.len < 1 or mem.findScalar(u8, "=+&%", constraint[0]) != null or |
| 4993 | (constraint[0] == '{' and constraint[constraint.len - 1] != '}')) | 5017 | (constraint[0] == '{' and constraint[constraint.len - 1] != '}')) |
| 4994 | { | 5018 | { |
| 4995 | return f.fail("CBE: constraint not supported: '{s}'", .{constraint}); | 5019 | return f.fail("CBE: constraint not supported: '{s}'", .{constraint}); |
| ... | @@ -5000,10 +5024,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5000,10 +5024,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5000 | if (asmInputNeedsLocal(f, constraint, input_val)) { | 5024 | if (asmInputNeedsLocal(f, constraint, input_val)) { |
| 5001 | const input_ty = f.typeOf(input.operand); | 5025 | const input_ty = f.typeOf(input.operand); |
| 5002 | if (is_reg) try w.writeAll("register "); | 5026 | if (is_reg) try w.writeAll("register "); |
| 5003 | const input_local = try f.allocLocalValue(.{ | 5027 | const input_local = try f.allocLocalValue(.{ .type = input_ty }); |
| 5004 | .type = input_ty, | ||
| 5005 | .alignment = .none, | ||
| 5006 | }); | ||
| 5007 | try f.allocs.put(gpa, input_local.new_local, false); | 5028 | try f.allocs.put(gpa, input_local.new_local, false); |
| 5008 | // Do not render the declaration as `const` qualified if we're generating an | 5029 | // Do not render the declaration as `const` qualified if we're generating an |
| 5009 | // explicit `register` local, as GCC will ignore the constraint completely. | 5030 | // explicit `register` local, as GCC will ignore the constraint completely. |
| ... | @@ -5056,7 +5077,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5056,7 +5077,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5056 | } | 5077 | } |
| 5057 | 5078 | ||
| 5058 | const desc = mem.sliceTo(asm_source[src_i..], ']'); | 5079 | const desc = mem.sliceTo(asm_source[src_i..], ']'); |
| 5059 | if (mem.indexOfScalar(u8, desc, ':')) |colon| { | 5080 | if (mem.findScalar(u8, desc, ':')) |colon| { |
| 5060 | const name = desc[0..colon]; | 5081 | const name = desc[0..colon]; |
| 5061 | const modifier = desc[colon + 1 ..]; | 5082 | const modifier = desc[colon + 1 ..]; |
| 5062 | 5083 | ||
| ... | @@ -5853,28 +5874,124 @@ fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5853,28 +5874,124 @@ fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5853 | else | 5874 | else |
| 5854 | unreachable; | 5875 | unreachable; |
| 5855 | 5876 | ||
| 5877 | const ref_ret = lowersToBigInt(inst_scalar_ty, zcu); | ||
| 5878 | const ref_operand = lowersToBigInt(scalar_ty, zcu); | ||
| 5879 | |||
| 5856 | const w = &f.code.writer; | 5880 | const w = &f.code.writer; |
| 5857 | const local = try f.allocLocal(inst, inst_ty); | 5881 | const local = try f.allocLocal(inst, inst_ty); |
| 5858 | const v = try Vectorize.start(f, inst, w, operand_ty); | 5882 | const v = try Vectorize.start(f, inst, w, operand_ty); |
| 5859 | try f.writeCValue(w, local, .other); | 5883 | if (ref_ret) { |
| 5860 | try v.elem(f, w); | 5884 | const inst_int_info = inst_scalar_ty.intInfo(zcu); |
| 5861 | try w.writeAll(" = "); | 5885 | if (inst_int_info.bits <= 128) { |
| 5886 | try w.writeAll("zig_"); | ||
| 5887 | try f.dg.renderTypeForBuiltinFnName(w, inst_scalar_ty); | ||
| 5888 | try w.print("_intCast_{c}{d}", .{ | ||
| 5889 | @as(u8, switch (inst_int_info.signedness) { | ||
| 5890 | .signed => 'i', | ||
| 5891 | .unsigned => 'u', | ||
| 5892 | }), | ||
| 5893 | std.math.ceilPowerOfTwoAssert(u16, @max(inst_int_info.bits, 32)), | ||
| 5894 | }); | ||
| 5895 | try w.writeAll("(&"); | ||
| 5896 | try f.writeCValue(w, local, .other); | ||
| 5897 | try v.elem(f, w); | ||
| 5898 | try w.writeAll(", "); | ||
| 5899 | } | ||
| 5900 | } else { | ||
| 5901 | try f.writeCValue(w, local, .other); | ||
| 5902 | try v.elem(f, w); | ||
| 5903 | try w.writeAll(" = "); | ||
| 5904 | } | ||
| 5862 | if (inst_scalar_ty.isInt(zcu) and scalar_ty.isRuntimeFloat()) { | 5905 | if (inst_scalar_ty.isInt(zcu) and scalar_ty.isRuntimeFloat()) { |
| 5863 | try w.writeAll("zig_wrap_"); | 5906 | const inst_int_info = inst_scalar_ty.intInfo(zcu); |
| 5864 | try f.dg.renderTypeForBuiltinFnName(w, inst_scalar_ty); | 5907 | if (inst_int_info.bits <= 128) try w.print("zig_{c}{d}_truncate_{[0]c}{[1]d}(", .{ |
| 5865 | try w.writeByte('('); | 5908 | @as(u8, switch (inst_int_info.signedness) { |
| 5909 | .signed => 'i', | ||
| 5910 | .unsigned => 'u', | ||
| 5911 | }), | ||
| 5912 | std.math.ceilPowerOfTwoAssert(u16, @max(inst_int_info.bits, 32)), | ||
| 5913 | }); | ||
| 5866 | } | 5914 | } |
| 5867 | try w.writeAll("zig_"); | 5915 | try w.writeAll("zig_"); |
| 5868 | try w.writeAll(operation); | 5916 | try w.writeAll(operation); |
| 5869 | try w.writeAll(compilerRtAbbrev(scalar_ty, zcu, target)); | 5917 | try w.writeAll(compilerRtAbbrev(scalar_ty, zcu, target)); |
| 5870 | try w.writeAll(compilerRtAbbrev(inst_scalar_ty, zcu, target)); | 5918 | try w.writeAll(compilerRtAbbrev(inst_scalar_ty, zcu, target)); |
| 5871 | try w.writeByte('('); | 5919 | try w.writeByte('('); |
| 5872 | try f.writeCValue(w, operand, .other); | 5920 | if (ref_ret) { |
| 5873 | try v.elem(f, w); | 5921 | const inst_int_info = inst_scalar_ty.intInfo(zcu); |
| 5922 | if (inst_int_info.bits > 128) { | ||
| 5923 | try w.writeByte('&'); | ||
| 5924 | try f.writeCValue(w, local, .other); | ||
| 5925 | try v.elem(f, w); | ||
| 5926 | try w.writeAll(", "); | ||
| 5927 | } | ||
| 5928 | } | ||
| 5929 | if (ref_operand) { | ||
| 5930 | const operand_int_info = scalar_ty.intInfo(zcu); | ||
| 5931 | if (operand_int_info.bits <= 128) { | ||
| 5932 | try w.print("zig_{c}{d}_intCast_", .{ | ||
| 5933 | @as(u8, switch (operand_int_info.signedness) { | ||
| 5934 | .signed => 'i', | ||
| 5935 | .unsigned => 'u', | ||
| 5936 | }), | ||
| 5937 | std.math.ceilPowerOfTwoAssert(u16, @max(operand_int_info.bits, 32)), | ||
| 5938 | }); | ||
| 5939 | try f.dg.renderTypeForBuiltinFnName(w, scalar_ty); | ||
| 5940 | try w.writeAll("(&"); | ||
| 5941 | switch (operand) { | ||
| 5942 | .constant => |val| try f.dg.renderValueAsLvalue(w, val), | ||
| 5943 | else => try f.writeCValue(w, operand, .other), | ||
| 5944 | } | ||
| 5945 | try v.elem(f, w); | ||
| 5946 | try f.dg.renderBuiltinInfo(w, scalar_ty, .none); | ||
| 5947 | try w.writeByte(')'); | ||
| 5948 | } else { | ||
| 5949 | try w.writeByte('&'); | ||
| 5950 | switch (operand) { | ||
| 5951 | .constant => |val| try f.dg.renderValueAsLvalue(w, val), | ||
| 5952 | else => try f.writeCValue(w, operand, .other), | ||
| 5953 | } | ||
| 5954 | try v.elem(f, w); | ||
| 5955 | try w.print(", {f}", .{fmtUnsignedIntLiteralSmall( | ||
| 5956 | target, | ||
| 5957 | .uint16_t, | ||
| 5958 | operand_int_info.bits, | ||
| 5959 | false, | ||
| 5960 | 10, | ||
| 5961 | .lower, | ||
| 5962 | )}); | ||
| 5963 | } | ||
| 5964 | } else { | ||
| 5965 | try f.writeCValue(w, operand, .other); | ||
| 5966 | try v.elem(f, w); | ||
| 5967 | } | ||
| 5968 | if (ref_ret) { | ||
| 5969 | const inst_int_info = inst_scalar_ty.intInfo(zcu); | ||
| 5970 | if (inst_int_info.bits > 128) try w.print(", {f}", .{fmtUnsignedIntLiteralSmall( | ||
| 5971 | target, | ||
| 5972 | .uint16_t, | ||
| 5973 | inst_int_info.bits, | ||
| 5974 | false, | ||
| 5975 | 10, | ||
| 5976 | .lower, | ||
| 5977 | )}); | ||
| 5978 | } | ||
| 5874 | try w.writeByte(')'); | 5979 | try w.writeByte(')'); |
| 5875 | if (inst_scalar_ty.isInt(zcu) and scalar_ty.isRuntimeFloat()) { | 5980 | if (inst_scalar_ty.isInt(zcu) and scalar_ty.isRuntimeFloat()) { |
| 5876 | try f.dg.renderBuiltinInfo(w, inst_scalar_ty, .bits); | 5981 | const inst_int_info = inst_scalar_ty.intInfo(zcu); |
| 5877 | try w.writeByte(')'); | 5982 | if (inst_int_info.bits <= 128) { |
| 5983 | try w.print(", {f}", .{ | ||
| 5984 | try f.dg.fmtIntLiteralDec(try pt.intValue(.u8, inst_int_info.bits), .other), | ||
| 5985 | }); | ||
| 5986 | try w.writeByte(')'); | ||
| 5987 | } | ||
| 5988 | } | ||
| 5989 | if (ref_ret) { | ||
| 5990 | const inst_int_info = inst_scalar_ty.intInfo(zcu); | ||
| 5991 | if (inst_int_info.bits <= 128) { | ||
| 5992 | try f.dg.renderBuiltinInfo(w, inst_scalar_ty, .none); | ||
| 5993 | try w.writeByte(')'); | ||
| 5994 | } | ||
| 5878 | } | 5995 | } |
| 5879 | try w.writeByte(';'); | 5996 | try w.writeByte(';'); |
| 5880 | try f.newline(); | 5997 | try f.newline(); |
| ... | @@ -5893,18 +6010,21 @@ fn airUnBuiltinCall( | ... | @@ -5893,18 +6010,21 @@ fn airUnBuiltinCall( |
| 5893 | const pt = f.dg.pt; | 6010 | const pt = f.dg.pt; |
| 5894 | const zcu = pt.zcu; | 6011 | const zcu = pt.zcu; |
| 5895 | 6012 | ||
| 5896 | const operand = try f.resolveInst(operand_ref); | ||
| 5897 | try reap(f, inst, &.{operand_ref}); | ||
| 5898 | const inst_ty = f.typeOfIndex(inst); | 6013 | const inst_ty = f.typeOfIndex(inst); |
| 5899 | const inst_scalar_ty = inst_ty.scalarType(zcu); | 6014 | const inst_scalar_ty = inst_ty.scalarType(zcu); |
| 5900 | const operand_ty = f.typeOf(operand_ref); | 6015 | const operand_ty = f.typeOf(operand_ref); |
| 5901 | const scalar_ty = operand_ty.scalarType(zcu); | 6016 | const scalar_ty = operand_ty.scalarType(zcu); |
| 6017 | const is_big = lowersToBigInt(operand_ty, zcu); | ||
| 6018 | |||
| 6019 | const operand = try f.resolveInst(operand_ref); | ||
| 6020 | if (!is_big) try reap(f, inst, &.{operand_ref}); | ||
| 5902 | 6021 | ||
| 5903 | const ref_ret = lowersToBigInt(inst_scalar_ty, zcu); | 6022 | const ref_ret = lowersToBigInt(inst_scalar_ty, zcu); |
| 5904 | const ref_arg = lowersToBigInt(scalar_ty, zcu); | 6023 | const ref_arg = lowersToBigInt(scalar_ty, zcu); |
| 5905 | 6024 | ||
| 5906 | const w = &f.code.writer; | 6025 | const w = &f.code.writer; |
| 5907 | const local = try f.allocLocal(inst, inst_ty); | 6026 | const local = try f.allocLocal(inst, inst_ty); |
| 6027 | if (is_big) try reap(f, inst, &.{operand_ref}); | ||
| 5908 | const v = try Vectorize.start(f, inst, w, operand_ty); | 6028 | const v = try Vectorize.start(f, inst, w, operand_ty); |
| 5909 | if (!ref_ret) { | 6029 | if (!ref_ret) { |
| 5910 | try f.writeCValue(w, local, .other); | 6030 | try f.writeCValue(w, local, .other); |
| ... | @@ -5920,8 +6040,13 @@ fn airUnBuiltinCall( | ... | @@ -5920,8 +6040,13 @@ fn airUnBuiltinCall( |
| 5920 | try v.elem(f, w); | 6040 | try v.elem(f, w); |
| 5921 | try w.writeAll(", "); | 6041 | try w.writeAll(", "); |
| 5922 | } | 6042 | } |
| 5923 | if (ref_arg) try w.writeByte('&'); | 6043 | if (ref_arg) { |
| 5924 | try f.writeCValue(w, operand, .other); | 6044 | try w.writeByte('&'); |
| 6045 | switch (operand) { | ||
| 6046 | .constant => |val| try f.dg.renderValueAsLvalue(w, val), | ||
| 6047 | else => try f.writeCValue(w, operand, .other), | ||
| 6048 | } | ||
| 6049 | } else try f.writeCValue(w, operand, .other); | ||
| 5925 | try v.elem(f, w); | 6050 | try v.elem(f, w); |
| 5926 | try f.dg.renderBuiltinInfo(w, scalar_ty, info); | 6051 | try f.dg.renderBuiltinInfo(w, scalar_ty, info); |
| 5927 | try w.writeAll(");"); | 6052 | try w.writeAll(");"); |
| ... | @@ -5941,8 +6066,9 @@ fn airBinBuiltinCall( | ... | @@ -5941,8 +6066,9 @@ fn airBinBuiltinCall( |
| 5941 | const zcu = pt.zcu; | 6066 | const zcu = pt.zcu; |
| 5942 | const bin_op = f.air.instructions.items(.data)[@backingInt(inst)].bin_op; | 6067 | const bin_op = f.air.instructions.items(.data)[@backingInt(inst)].bin_op; |
| 5943 | 6068 | ||
| 5944 | const operand_ty = f.typeOf(bin_op.lhs); | 6069 | const lhs_ty = f.typeOf(bin_op.lhs); |
| 5945 | const is_big = lowersToBigInt(operand_ty, zcu); | 6070 | const rhs_ty = f.typeOf(bin_op.rhs); |
| 6071 | const is_big = lowersToBigInt(lhs_ty, zcu); | ||
| 5946 | 6072 | ||
| 5947 | const lhs = try f.resolveInst(bin_op.lhs); | 6073 | const lhs = try f.resolveInst(bin_op.lhs); |
| 5948 | const rhs = try f.resolveInst(bin_op.rhs); | 6074 | const rhs = try f.resolveInst(bin_op.rhs); |
| ... | @@ -5950,22 +6076,31 @@ fn airBinBuiltinCall( | ... | @@ -5950,22 +6076,31 @@ fn airBinBuiltinCall( |
| 5950 | 6076 | ||
| 5951 | const inst_ty = f.typeOfIndex(inst); | 6077 | const inst_ty = f.typeOfIndex(inst); |
| 5952 | const inst_scalar_ty = inst_ty.scalarType(zcu); | 6078 | const inst_scalar_ty = inst_ty.scalarType(zcu); |
| 5953 | const scalar_ty = operand_ty.scalarType(zcu); | 6079 | const lhs_scalar_ty = lhs_ty.scalarType(zcu); |
| 6080 | const rhs_scalar_ty = rhs_ty.scalarType(zcu); | ||
| 5954 | 6081 | ||
| 5955 | const ref_ret = lowersToBigInt(inst_scalar_ty, zcu); | 6082 | const ref_ret = lowersToBigInt(inst_scalar_ty, zcu); |
| 5956 | const ref_arg = lowersToBigInt(scalar_ty, zcu); | 6083 | const ref_lhs = lowersToBigInt(lhs_scalar_ty, zcu); |
| 6084 | const ref_rhs = lowersToBigInt(rhs_scalar_ty, zcu); | ||
| 5957 | 6085 | ||
| 5958 | const w = &f.code.writer; | 6086 | const w = &f.code.writer; |
| 5959 | const local = try f.allocLocal(inst, inst_ty); | 6087 | const local = try f.allocLocal(inst, inst_ty); |
| 5960 | if (is_big) try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); | 6088 | if (is_big) try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 5961 | const v = try Vectorize.start(f, inst, w, operand_ty); | 6089 | const v = try Vectorize.start(f, inst, w, lhs_ty); |
| 5962 | if (!ref_ret) { | 6090 | if (!ref_ret) { |
| 5963 | try f.writeCValue(w, local, .other); | 6091 | try f.writeCValue(w, local, .other); |
| 5964 | try v.elem(f, w); | 6092 | try v.elem(f, w); |
| 5965 | try w.writeAll(" = "); | 6093 | try w.writeAll(" = "); |
| 5966 | } | 6094 | } |
| 5967 | try w.print("zig_{s}_", .{operation}); | 6095 | try w.print("zig_{s}_", .{operation}); |
| 5968 | try f.dg.renderTypeForBuiltinFnName(w, scalar_ty); | 6096 | try f.dg.renderTypeForBuiltinFnName(w, lhs_scalar_ty); |
| 6097 | switch (info) { | ||
| 6098 | .bits, .none, .big_temp_bits => {}, | ||
| 6099 | .bits_none => { | ||
| 6100 | try w.writeByte('_'); | ||
| 6101 | try f.dg.renderTypeForBuiltinFnName(w, rhs_scalar_ty); | ||
| 6102 | }, | ||
| 6103 | } | ||
| 5969 | try w.writeByte('('); | 6104 | try w.writeByte('('); |
| 5970 | if (ref_ret) { | 6105 | if (ref_ret) { |
| 5971 | try w.writeByte('&'); | 6106 | try w.writeByte('&'); |
| ... | @@ -5973,15 +6108,45 @@ fn airBinBuiltinCall( | ... | @@ -5973,15 +6108,45 @@ fn airBinBuiltinCall( |
| 5973 | try v.elem(f, w); | 6108 | try v.elem(f, w); |
| 5974 | try w.writeAll(", "); | 6109 | try w.writeAll(", "); |
| 5975 | } | 6110 | } |
| 5976 | if (ref_arg) try w.writeByte('&'); | 6111 | if (ref_lhs) { |
| 5977 | try f.writeCValue(w, lhs, .other); | 6112 | try w.writeByte('&'); |
| 6113 | switch (lhs) { | ||
| 6114 | .constant => |lhs_val| try f.dg.renderValueAsLvalue(w, lhs_val), | ||
| 6115 | else => try f.writeCValue(w, lhs, .other), | ||
| 6116 | } | ||
| 6117 | } else try f.writeCValue(w, lhs, .other); | ||
| 5978 | try v.elem(f, w); | 6118 | try v.elem(f, w); |
| 5979 | try w.writeAll(", "); | 6119 | try w.writeAll(", "); |
| 5980 | if (ref_arg) try w.writeByte('&'); | 6120 | if (ref_rhs) { |
| 5981 | try f.writeCValue(w, rhs, .other); | 6121 | try w.writeByte('&'); |
| 5982 | if (f.typeOf(bin_op.rhs).isVector(zcu)) try v.elem(f, w); | 6122 | switch (rhs) { |
| 5983 | try f.dg.renderBuiltinInfo(w, scalar_ty, info); | 6123 | .constant => |rhs_val| try f.dg.renderValueAsLvalue(w, rhs_val), |
| 5984 | try w.writeAll(");\n"); | 6124 | else => try f.writeCValue(w, rhs, .other), |
| 6125 | } | ||
| 6126 | } else try f.writeCValue(w, rhs, .other); | ||
| 6127 | try v.elem(f, w); | ||
| 6128 | try f.dg.renderBuiltinInfo(w, lhs_scalar_ty, info: switch (info) { | ||
| 6129 | .none => .none, | ||
| 6130 | .bits, .bits_none => .bits, | ||
| 6131 | .big_temp_bits => { | ||
| 6132 | if (lowersToBigInt(lhs_scalar_ty, zcu)) { | ||
| 6133 | const temp_local = try f.allocAlignedLocal(inst, .{ | ||
| 6134 | .type = lhs_scalar_ty, | ||
| 6135 | .array_len = 2, | ||
| 6136 | }); | ||
| 6137 | try w.writeAll(", &"); | ||
| 6138 | try f.writeCValue(w, temp_local, .other); | ||
| 6139 | try freeLocal(f, inst, temp_local.new_local, null); | ||
| 6140 | } | ||
| 6141 | break :info .none; | ||
| 6142 | }, | ||
| 6143 | }); | ||
| 6144 | switch (info) { | ||
| 6145 | .none, .bits, .big_temp_bits => {}, | ||
| 6146 | .bits_none => try f.dg.renderBuiltinInfo(w, rhs_scalar_ty, .none), | ||
| 6147 | } | ||
| 6148 | try w.writeAll(");"); | ||
| 6149 | try f.newline(); | ||
| 5985 | try v.end(f, inst, w); | 6150 | try v.end(f, inst, w); |
| 5986 | 6151 | ||
| 5987 | return local; | 6152 | return local; |
| ... | @@ -6029,12 +6194,22 @@ fn airCmpBuiltinCall( | ... | @@ -6029,12 +6194,22 @@ fn airCmpBuiltinCall( |
| 6029 | try v.elem(f, w); | 6194 | try v.elem(f, w); |
| 6030 | try w.writeAll(", "); | 6195 | try w.writeAll(", "); |
| 6031 | } | 6196 | } |
| 6032 | if (ref_arg) try w.writeByte('&'); | 6197 | if (ref_arg) { |
| 6033 | try f.writeCValue(w, lhs, .other); | 6198 | try w.writeByte('&'); |
| 6199 | switch (lhs) { | ||
| 6200 | .constant => |lhs_val| try f.dg.renderValueAsLvalue(w, lhs_val), | ||
| 6201 | else => try f.writeCValue(w, lhs, .other), | ||
| 6202 | } | ||
| 6203 | } else try f.writeCValue(w, lhs, .other); | ||
| 6034 | try v.elem(f, w); | 6204 | try v.elem(f, w); |
| 6035 | try w.writeAll(", "); | 6205 | try w.writeAll(", "); |
| 6036 | if (ref_arg) try w.writeByte('&'); | 6206 | if (ref_arg) { |
| 6037 | try f.writeCValue(w, rhs, .other); | 6207 | try w.writeByte('&'); |
| 6208 | switch (rhs) { | ||
| 6209 | .constant => |rhs_val| try f.dg.renderValueAsLvalue(w, rhs_val), | ||
| 6210 | else => try f.writeCValue(w, rhs, .other), | ||
| 6211 | } | ||
| 6212 | } else try f.writeCValue(w, rhs, .other); | ||
| 6038 | try v.elem(f, w); | 6213 | try v.elem(f, w); |
| 6039 | try f.dg.renderBuiltinInfo(w, scalar_ty, info); | 6214 | try f.dg.renderBuiltinInfo(w, scalar_ty, info); |
| 6040 | try w.writeByte(')'); | 6215 | try w.writeByte(')'); |
| ... | @@ -6595,7 +6770,8 @@ fn airShuffleOne(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6595,7 +6770,8 @@ fn airShuffleOne(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6595 | }, | 6770 | }, |
| 6596 | .value => |val| try f.dg.renderValue(w, .fromInterned(val), .other), | 6771 | .value => |val| try f.dg.renderValue(w, .fromInterned(val), .other), |
| 6597 | } | 6772 | } |
| 6598 | try w.writeAll(";\n"); | 6773 | try w.writeByte(';'); |
| 6774 | try f.newline(); | ||
| 6599 | } | 6775 | } |
| 6600 | 6776 | ||
| 6601 | return local; | 6777 | return local; |
| ... | @@ -6653,7 +6829,14 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6653,7 +6829,14 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6653 | const operand_ty = f.typeOf(reduce.operand); | 6829 | const operand_ty = f.typeOf(reduce.operand); |
| 6654 | const w = &f.code.writer; | 6830 | const w = &f.code.writer; |
| 6655 | 6831 | ||
| 6656 | const use_operator = scalar_ty.bitSize(zcu) <= 64; | 6832 | const use_operator, const is_big = if (scalar_ty.isInt(zcu)) switch (CType.classifyInt(scalar_ty, zcu)) { |
| 6833 | .void => unreachable, | ||
| 6834 | .small => |int| switch (int) { | ||
| 6835 | else => .{ true, false }, | ||
| 6836 | .zig_u128, .zig_i128 => .{ false, false }, | ||
| 6837 | }, | ||
| 6838 | .big => .{ false, true }, | ||
| 6839 | } else .{ false, false }; | ||
| 6657 | const op: union(enum) { | 6840 | const op: union(enum) { |
| 6658 | const Func = struct { operation: []const u8, info: BuiltinInfo = .none }; | 6841 | const Func = struct { operation: []const u8, info: BuiltinInfo = .none }; |
| 6659 | builtin: Func, | 6842 | builtin: Func, |
| ... | @@ -6742,25 +6925,57 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6742,25 +6925,57 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6742 | try f.newline(); | 6925 | try f.newline(); |
| 6743 | 6926 | ||
| 6744 | const v = try Vectorize.start(f, inst, w, operand_ty); | 6927 | const v = try Vectorize.start(f, inst, w, operand_ty); |
| 6745 | try f.writeCValue(w, accum, .other); | ||
| 6746 | switch (op) { | 6928 | switch (op) { |
| 6747 | .builtin => |func| { | 6929 | .builtin => |func| { |
| 6748 | try w.print(" = zig_{s}_", .{func.operation}); | 6930 | const prev_accum = if (is_big) prev_accum: { |
| 6931 | const prev_accum = try f.allocLocal(inst, scalar_ty); | ||
| 6932 | try f.writeCValue(w, prev_accum, .other); | ||
| 6933 | try w.writeAll(" = "); | ||
| 6934 | try f.writeCValue(w, accum, .other); | ||
| 6935 | try w.writeByte(';'); | ||
| 6936 | try f.newline(); | ||
| 6937 | break :prev_accum prev_accum; | ||
| 6938 | } else prev_accum: { | ||
| 6939 | try f.writeCValue(w, accum, .other); | ||
| 6940 | try w.writeAll(" = "); | ||
| 6941 | break :prev_accum accum; | ||
| 6942 | }; | ||
| 6943 | try w.print("zig_{s}_", .{func.operation}); | ||
| 6749 | try f.dg.renderTypeForBuiltinFnName(w, scalar_ty); | 6944 | try f.dg.renderTypeForBuiltinFnName(w, scalar_ty); |
| 6750 | try w.writeByte('('); | 6945 | try w.writeByte('('); |
| 6751 | try f.writeCValue(w, accum, .other); | 6946 | if (is_big) { |
| 6947 | try w.writeByte('&'); | ||
| 6948 | switch (accum) { | ||
| 6949 | .constant => |val| try f.dg.renderValueAsLvalue(w, val), | ||
| 6950 | else => try f.writeCValue(w, accum, .other), | ||
| 6951 | } | ||
| 6952 | try w.writeAll(", &"); | ||
| 6953 | switch (prev_accum) { | ||
| 6954 | .constant => |val| try f.dg.renderValueAsLvalue(w, val), | ||
| 6955 | else => try f.writeCValue(w, prev_accum, .other), | ||
| 6956 | } | ||
| 6957 | } else try f.writeCValue(w, prev_accum, .other); | ||
| 6752 | try w.writeAll(", "); | 6958 | try w.writeAll(", "); |
| 6753 | try f.writeCValue(w, operand, .other); | 6959 | if (is_big) { |
| 6960 | try w.writeByte('&'); | ||
| 6961 | switch (operand) { | ||
| 6962 | .constant => |val| try f.dg.renderValueAsLvalue(w, val), | ||
| 6963 | else => try f.writeCValue(w, operand, .other), | ||
| 6964 | } | ||
| 6965 | } else try f.writeCValue(w, operand, .other); | ||
| 6754 | try v.elem(f, w); | 6966 | try v.elem(f, w); |
| 6755 | try f.dg.renderBuiltinInfo(w, scalar_ty, func.info); | 6967 | try f.dg.renderBuiltinInfo(w, scalar_ty, func.info); |
| 6756 | try w.writeByte(')'); | 6968 | try w.writeByte(')'); |
| 6969 | if (is_big) try freeLocal(f, inst, prev_accum.new_local, null); | ||
| 6757 | }, | 6970 | }, |
| 6758 | .infix => |ass| { | 6971 | .infix => |ass| { |
| 6972 | try f.writeCValue(w, accum, .other); | ||
| 6759 | try w.writeAll(ass); | 6973 | try w.writeAll(ass); |
| 6760 | try f.writeCValue(w, operand, .other); | 6974 | try f.writeCValue(w, operand, .other); |
| 6761 | try v.elem(f, w); | 6975 | try v.elem(f, w); |
| 6762 | }, | 6976 | }, |
| 6763 | .ternary => |cmp| { | 6977 | .ternary => |cmp| { |
| 6978 | try f.writeCValue(w, accum, .other); | ||
| 6764 | try w.writeAll(" = "); | 6979 | try w.writeAll(" = "); |
| 6765 | try f.writeCValue(w, accum, .other); | 6980 | try f.writeCValue(w, accum, .other); |
| 6766 | try w.writeAll(cmp); | 6981 | try w.writeAll(cmp); |
| ... | @@ -7097,101 +7312,6 @@ fn writeMemoryOrder(w: *Writer, order: std.lang.AtomicOrder) !void { | ... | @@ -7097,101 +7312,6 @@ fn writeMemoryOrder(w: *Writer, order: std.lang.AtomicOrder) !void { |
| 7097 | return w.writeAll(toMemoryOrder(order)); | 7312 | return w.writeAll(toMemoryOrder(order)); |
| 7098 | } | 7313 | } |
| 7099 | 7314 | ||
| 7100 | fn toCallingConvention(cc: std.lang.CallingConvention, zcu: *Zcu) ?[]const u8 { | ||
| 7101 | if (zcu.getTarget().cCallingConvention()) |ccc| { | ||
| 7102 | if (cc.eql(ccc)) { | ||
| 7103 | return null; | ||
| 7104 | } | ||
| 7105 | } | ||
| 7106 | return switch (cc) { | ||
| 7107 | .auto, .naked => null, | ||
| 7108 | |||
| 7109 | .x86_16_cdecl => "cdecl", | ||
| 7110 | .x86_16_regparmcall => "regparmcall", | ||
| 7111 | .x86_64_sysv, .x86_sysv => "sysv_abi", | ||
| 7112 | .x86_64_win, .x86_win => "ms_abi", | ||
| 7113 | .x86_16_stdcall, .x86_stdcall => "stdcall", | ||
| 7114 | .x86_fastcall => "fastcall", | ||
| 7115 | .x86_thiscall => "thiscall", | ||
| 7116 | |||
| 7117 | .x86_vectorcall, | ||
| 7118 | .x86_64_vectorcall, | ||
| 7119 | => "vectorcall", | ||
| 7120 | |||
| 7121 | .x86_64_regcall_v3_sysv, | ||
| 7122 | .x86_64_regcall_v4_win, | ||
| 7123 | .x86_regcall_v3, | ||
| 7124 | .x86_regcall_v4_win, | ||
| 7125 | => "regcall", | ||
| 7126 | |||
| 7127 | .aarch64_vfabi => "aarch64_vector_pcs", | ||
| 7128 | .aarch64_vfabi_sve => "aarch64_sve_pcs", | ||
| 7129 | |||
| 7130 | .arm_aapcs => "pcs(\"aapcs\")", | ||
| 7131 | .arm_aapcs_vfp => "pcs(\"aapcs-vfp\")", | ||
| 7132 | |||
| 7133 | .arc_interrupt => |opts| switch (opts.type) { | ||
| 7134 | inline else => |t| "interrupt(\"" ++ @tagName(t) ++ "\")", | ||
| 7135 | }, | ||
| 7136 | |||
| 7137 | .arm_interrupt => |opts| switch (opts.type) { | ||
| 7138 | .generic => "interrupt", | ||
| 7139 | .irq => "interrupt(\"IRQ\")", | ||
| 7140 | .fiq => "interrupt(\"FIQ\")", | ||
| 7141 | .swi => "interrupt(\"SWI\")", | ||
| 7142 | .abort => "interrupt(\"ABORT\")", | ||
| 7143 | .undef => "interrupt(\"UNDEF\")", | ||
| 7144 | }, | ||
| 7145 | |||
| 7146 | .avr_signal => "signal", | ||
| 7147 | |||
| 7148 | .microblaze_interrupt => |opts| switch (opts.type) { | ||
| 7149 | .user => "save_volatiles", | ||
| 7150 | .regular => "interrupt_handler", | ||
| 7151 | .fast => "fast_interrupt", | ||
| 7152 | .breakpoint => "break_handler", | ||
| 7153 | }, | ||
| 7154 | |||
| 7155 | .mips_interrupt, | ||
| 7156 | .mips64_interrupt, | ||
| 7157 | => |opts| switch (opts.mode) { | ||
| 7158 | inline else => |m| "interrupt(\"" ++ @tagName(m) ++ "\")", | ||
| 7159 | }, | ||
| 7160 | |||
| 7161 | .riscv64_lp64_v, .riscv32_ilp32_v => "riscv_vector_cc", | ||
| 7162 | |||
| 7163 | .riscv32_interrupt, | ||
| 7164 | .riscv64_interrupt, | ||
| 7165 | => |opts| switch (opts.mode) { | ||
| 7166 | inline else => |m| "interrupt(\"" ++ @tagName(m) ++ "\")", | ||
| 7167 | }, | ||
| 7168 | |||
| 7169 | .sh_renesas => "renesas", | ||
| 7170 | .sh_interrupt => |opts| switch (opts.save) { | ||
| 7171 | .fpscr => "trapa_handler", // Implies `interrupt_handler`. | ||
| 7172 | .high => "interrupt_handler, nosave_low_regs", | ||
| 7173 | .full => "interrupt_handler", | ||
| 7174 | .bank => "interrupt_handler, resbank", | ||
| 7175 | }, | ||
| 7176 | |||
| 7177 | .m68k_rtd => "m68k_rtd", | ||
| 7178 | |||
| 7179 | .avr_interrupt, | ||
| 7180 | .csky_interrupt, | ||
| 7181 | .m68k_interrupt, | ||
| 7182 | .msp430_interrupt, | ||
| 7183 | .x86_16_interrupt, | ||
| 7184 | .x86_interrupt, | ||
| 7185 | .x86_64_interrupt, | ||
| 7186 | => "interrupt", | ||
| 7187 | |||
| 7188 | .ez80_tiflags, | ||
| 7189 | => "__tiflags__", | ||
| 7190 | |||
| 7191 | else => unreachable, // `Zcu.callconvSupported` | ||
| 7192 | }; | ||
| 7193 | } | ||
| 7194 | |||
| 7195 | fn toAtomicRmwSuffix(order: std.lang.AtomicRmwOp) []const u8 { | 7315 | fn toAtomicRmwSuffix(order: std.lang.AtomicRmwOp) []const u8 { |
| 7196 | return switch (order) { | 7316 | return switch (order) { |
| 7197 | .Xchg => "xchg", | 7317 | .Xchg => "xchg", |
| ... | @@ -7224,17 +7344,18 @@ fn signAbbrev(signedness: std.lang.Signedness) u8 { | ... | @@ -7224,17 +7344,18 @@ fn signAbbrev(signedness: std.lang.Signedness) u8 { |
| 7224 | 7344 | ||
| 7225 | fn compilerRtAbbrev(ty: Type, zcu: *Zcu, target: *const std.Target) []const u8 { | 7345 | fn compilerRtAbbrev(ty: Type, zcu: *Zcu, target: *const std.Target) []const u8 { |
| 7226 | return if (ty.isInt(zcu)) switch (ty.intInfo(zcu).bits) { | 7346 | return if (ty.isInt(zcu)) switch (ty.intInfo(zcu).bits) { |
| 7347 | 0 => unreachable, | ||
| 7227 | 1...32 => "si", | 7348 | 1...32 => "si", |
| 7228 | 33...64 => "di", | 7349 | 33...64 => "di", |
| 7229 | 65...128 => "ti", | 7350 | 65...128 => "ti", |
| 7230 | else => unreachable, | 7351 | else => "ei", |
| 7231 | } else if (ty.isRuntimeFloat()) switch (ty.floatBits(target)) { | 7352 | } else if (ty.isRuntimeFloat()) switch (ty.floatBits(target)) { |
| 7353 | else => unreachable, | ||
| 7232 | 16 => "hf", | 7354 | 16 => "hf", |
| 7233 | 32 => "sf", | 7355 | 32 => "sf", |
| 7234 | 64 => "df", | 7356 | 64 => "df", |
| 7235 | 80 => "xf", | 7357 | 80 => "xf", |
| 7236 | 128 => "tf", | 7358 | 128 => if (target.cpu.arch.isPowerPC()) "kf" else "tf", |
| 7237 | else => unreachable, | ||
| 7238 | } else unreachable; | 7359 | } else unreachable; |
| 7239 | } | 7360 | } |
| 7240 | 7361 | ||
| ... | @@ -7390,10 +7511,8 @@ fn fmtStringLiteral(str: []const u8, sentinel: ?u8) std.fmt.Alt(FormatStringCont | ... | @@ -7390,10 +7511,8 @@ fn fmtStringLiteral(str: []const u8, sentinel: ?u8) std.fmt.Alt(FormatStringCont |
| 7390 | return .{ .data = .{ .str = str, .sentinel = sentinel } }; | 7511 | return .{ .data = .{ .str = str, .sentinel = sentinel } }; |
| 7391 | } | 7512 | } |
| 7392 | 7513 | ||
| 7393 | fn undefPattern(comptime IntType: type) IntType { | 7514 | fn undefPattern(comptime Result: type) Result { |
| 7394 | const int_info = @typeInfo(IntType).int; | 7515 | return @bitCast(@as(@Int(.unsigned, @bitSizeOf(Result)), (1 << (@bitSizeOf(Result) | 1)) / 3)); |
| 7395 | const UnsignedType = @Int(.unsigned, int_info.bits); | ||
| 7396 | return @bitCast(@as(UnsignedType, (1 << (int_info.bits | 1)) / 3)); | ||
| 7397 | } | 7516 | } |
| 7398 | 7517 | ||
| 7399 | const FormatIntLiteralContext = struct { | 7518 | const FormatIntLiteralContext = struct { |
| ... | @@ -7580,11 +7699,9 @@ const FormatSignedIntLiteralSmall = struct { | ... | @@ -7580,11 +7699,9 @@ const FormatSignedIntLiteralSmall = struct { |
| 7580 | case: std.fmt.Case, | 7699 | case: std.fmt.Case, |
| 7581 | pub fn format(data: FormatSignedIntLiteralSmall, w: *Writer) Writer.Error!void { | 7700 | pub fn format(data: FormatSignedIntLiteralSmall, w: *Writer) Writer.Error!void { |
| 7582 | const bits = data.int_cty.bits(data.target); | 7701 | const bits = data.int_cty.bits(data.target); |
| 7583 | const max_int: i64 = @bitCast((@as(u64, 1) << @intCast(bits - 1)) - 1); | 7702 | if (data.val == @as(i64, std.math.maxInt(i64)) >> @intCast(64 - bits)) { |
| 7584 | const min_int: i64 = @bitCast(@as(u64, 1) << @intCast(bits - 1)); | ||
| 7585 | if (data.val == max_int) { | ||
| 7586 | return w.print("{s}_MAX", .{minMaxMacroPrefix(data.int_cty)}); | 7703 | return w.print("{s}_MAX", .{minMaxMacroPrefix(data.int_cty)}); |
| 7587 | } else if (data.val == min_int) { | 7704 | } else if (data.val == @as(i64, std.math.minInt(i64)) >> @intCast(64 - bits)) { |
| 7588 | return w.print("{s}_MIN", .{minMaxMacroPrefix(data.int_cty)}); | 7705 | return w.print("{s}_MIN", .{minMaxMacroPrefix(data.int_cty)}); |
| 7589 | } | 7706 | } |
| 7590 | if (data.val < 0) try w.writeByte('-'); | 7707 | if (data.val < 0) try w.writeByte('-'); |
| ... | @@ -7596,7 +7713,7 @@ const FormatSignedIntLiteralSmall = struct { | ... | @@ -7596,7 +7713,7 @@ const FormatSignedIntLiteralSmall = struct { |
| 7596 | 16 => try w.writeAll("0x"), | 7713 | 16 => try w.writeAll("0x"), |
| 7597 | else => unreachable, | 7714 | else => unreachable, |
| 7598 | } | 7715 | } |
| 7599 | // This `@abs` is safe thanks to the `min_int` case above. | 7716 | // This `@abs` is safe thanks to the min int check above. |
| 7600 | try w.printInt(@abs(data.val), data.base, data.case, .{}); | 7717 | try w.printInt(@abs(data.val), data.base, data.case, .{}); |
| 7601 | try w.writeAll(intLiteralSuffix(data.int_cty)); | 7718 | try w.writeAll(intLiteralSuffix(data.int_cty)); |
| 7602 | } | 7719 | } |
| ... | @@ -7610,8 +7727,7 @@ const FormatUnsignedIntLiteralSmall = struct { | ... | @@ -7610,8 +7727,7 @@ const FormatUnsignedIntLiteralSmall = struct { |
| 7610 | case: std.fmt.Case, | 7727 | case: std.fmt.Case, |
| 7611 | pub fn format(data: FormatUnsignedIntLiteralSmall, w: *Writer) Writer.Error!void { | 7728 | pub fn format(data: FormatUnsignedIntLiteralSmall, w: *Writer) Writer.Error!void { |
| 7612 | const bits = data.int_cty.bits(data.target); | 7729 | const bits = data.int_cty.bits(data.target); |
| 7613 | const max_int: u64 = @as(u64, std.math.maxInt(u64)) >> @intCast(64 - bits); | 7730 | if (data.val == @as(u64, std.math.maxInt(u64)) >> @intCast(64 - bits)) { |
| 7614 | if (data.val == max_int) { | ||
| 7615 | return w.print("{s}_MAX", .{minMaxMacroPrefix(data.int_cty)}); | 7731 | return w.print("{s}_MAX", .{minMaxMacroPrefix(data.int_cty)}); |
| 7616 | } | 7732 | } |
| 7617 | try w.writeAll(intLiteralPrefix(data.int_cty, data.is_global)); | 7733 | try w.writeAll(intLiteralPrefix(data.int_cty, data.is_global)); |
| ... | @@ -7735,6 +7851,31 @@ fn intLiteralSuffix(cty: CType.Int) []const u8 { | ... | @@ -7735,6 +7851,31 @@ fn intLiteralSuffix(cty: CType.Int) []const u8 { |
| 7735 | }; | 7851 | }; |
| 7736 | } | 7852 | } |
| 7737 | 7853 | ||
| 7854 | const F80Repr = packed struct { | ||
| 7855 | mantissa: u64, | ||
| 7856 | exponent: u16, | ||
| 7857 | |||
| 7858 | fn write(repr: F80Repr, w: *Writer, target: *const std.Target, is_global: bool) Writer.Error!void { | ||
| 7859 | try w.print("zig_{s}_repr_f80({f}, {f})", .{ | ||
| 7860 | if (is_global) "init" else "make", | ||
| 7861 | fmtUnsignedIntLiteralSmall(target, .uint64_t, repr.mantissa, is_global, 16, .lower), | ||
| 7862 | fmtUnsignedIntLiteralSmall(target, .uint16_t, repr.exponent, is_global, 16, .lower), | ||
| 7863 | }); | ||
| 7864 | } | ||
| 7865 | }; | ||
| 7866 | const F128Repr = packed struct { | ||
| 7867 | lo: u64, | ||
| 7868 | hi: u64, | ||
| 7869 | |||
| 7870 | fn write(repr: F128Repr, w: *Writer, target: *const std.Target, is_global: bool) Writer.Error!void { | ||
| 7871 | try w.print("zig_{s}_repr_f128({f}, {f})", .{ | ||
| 7872 | if (is_global) "init" else "make", | ||
| 7873 | fmtUnsignedIntLiteralSmall(target, .uint64_t, repr.hi, is_global, 16, .lower), | ||
| 7874 | fmtUnsignedIntLiteralSmall(target, .uint64_t, repr.lo, is_global, 16, .lower), | ||
| 7875 | }); | ||
| 7876 | } | ||
| 7877 | }; | ||
| 7878 | |||
| 7738 | const Materialize = struct { | 7879 | const Materialize = struct { |
| 7739 | local: CValue, | 7880 | local: CValue, |
| 7740 | 7881 |
src/codegen/c/type.zig+204-23| ... | @@ -44,8 +44,181 @@ pub const CType = union(enum) { | ... | @@ -44,8 +44,181 @@ pub const CType = union(enum) { |
| 44 | param_tys: []const CType, | 44 | param_tys: []const CType, |
| 45 | ret_ty: *const CType, | 45 | ret_ty: *const CType, |
| 46 | varargs: bool, | 46 | varargs: bool, |
| 47 | cc: CallingConvention, | ||
| 47 | }, | 48 | }, |
| 48 | 49 | ||
| 50 | pub const CallingConvention = enum { | ||
| 51 | c, | ||
| 52 | |||
| 53 | cdecl, | ||
| 54 | regparmcall, | ||
| 55 | sysv_abi, | ||
| 56 | ms_abi, | ||
| 57 | stdcall, | ||
| 58 | fastcall, | ||
| 59 | thiscall, | ||
| 60 | |||
| 61 | vectorcall, | ||
| 62 | |||
| 63 | regcall, | ||
| 64 | |||
| 65 | preserve_none, | ||
| 66 | |||
| 67 | aarch64_vector_pcs, | ||
| 68 | aarch64_sve_pcs, | ||
| 69 | |||
| 70 | @"pcs(\"aapcs\")", | ||
| 71 | @"pcs(\"aapcs-vfp\")", | ||
| 72 | |||
| 73 | @"interrupt(\"ilink1\")", | ||
| 74 | @"interrupt(\"ilink2\")", | ||
| 75 | @"interrupt(\"ilink\")", | ||
| 76 | @"interrupt(\"firq\")", | ||
| 77 | |||
| 78 | interrupt, | ||
| 79 | @"interrupt(\"IRQ\")", | ||
| 80 | @"interrupt(\"FIQ\")", | ||
| 81 | @"interrupt(\"SWI\")", | ||
| 82 | @"interrupt(\"ABORT\")", | ||
| 83 | @"interrupt(\"UNDEF\")", | ||
| 84 | |||
| 85 | signal, | ||
| 86 | |||
| 87 | save_volatiles, | ||
| 88 | interrupt_handler, | ||
| 89 | fast_interrupt, | ||
| 90 | break_handler, | ||
| 91 | |||
| 92 | @"interrupt(\"eic\")", | ||
| 93 | @"interrupt(\"sw0\")", | ||
| 94 | @"interrupt(\"sw1\")", | ||
| 95 | @"interrupt(\"hw0\")", | ||
| 96 | @"interrupt(\"hw1\")", | ||
| 97 | @"interrupt(\"hw2\")", | ||
| 98 | @"interrupt(\"hw3\")", | ||
| 99 | @"interrupt(\"hw4\")", | ||
| 100 | @"interrupt(\"hw5\")", | ||
| 101 | |||
| 102 | riscv_vector_cc, | ||
| 103 | @"interrupt(\"supervisor\")", | ||
| 104 | @"interrupt(\"machine\")", | ||
| 105 | |||
| 106 | renesas, | ||
| 107 | /// Implies `interrupt_handler`. | ||
| 108 | trapa_handler, | ||
| 109 | @"interrupt_handler, nosave_low_regs", | ||
| 110 | @"interrupt_handler, resbank", | ||
| 111 | |||
| 112 | m68k_rtd, | ||
| 113 | |||
| 114 | tiflags, | ||
| 115 | |||
| 116 | pub fn fromLang(cc: std.lang.CallingConvention, target: *const std.Target) CallingConvention { | ||
| 117 | if (target.cCallingConvention()) |ccc| { | ||
| 118 | if (cc.eql(ccc)) { | ||
| 119 | return .c; | ||
| 120 | } | ||
| 121 | } | ||
| 122 | return switch (cc) { | ||
| 123 | .auto, .naked => .c, | ||
| 124 | |||
| 125 | .x86_16_cdecl => .cdecl, | ||
| 126 | .x86_16_regparmcall => .regparmcall, | ||
| 127 | .x86_64_sysv, .x86_sysv => .sysv_abi, | ||
| 128 | .x86_64_win, .x86_win, .x86_mingw => .ms_abi, | ||
| 129 | .x86_16_stdcall, .x86_stdcall => .stdcall, | ||
| 130 | .x86_fastcall => .fastcall, | ||
| 131 | .x86_thiscall => .thiscall, | ||
| 132 | |||
| 133 | .x86_vectorcall, | ||
| 134 | .x86_64_vectorcall, | ||
| 135 | => .vectorcall, | ||
| 136 | |||
| 137 | .x86_64_regcall_v3_sysv, | ||
| 138 | .x86_64_regcall_v4_win, | ||
| 139 | .x86_regcall_v3, | ||
| 140 | .x86_regcall_v4_win, | ||
| 141 | => .regcall, | ||
| 142 | |||
| 143 | .x86_64_preserve_none, | ||
| 144 | .aarch64_preserve_none, | ||
| 145 | => .preserve_none, | ||
| 146 | |||
| 147 | .aarch64_vfabi => .aarch64_vector_pcs, | ||
| 148 | .aarch64_vfabi_sve => .aarch64_sve_pcs, | ||
| 149 | |||
| 150 | .arm_aapcs => .@"pcs(\"aapcs\")", | ||
| 151 | .arm_aapcs_vfp => .@"pcs(\"aapcs-vfp\")", | ||
| 152 | |||
| 153 | .arc_interrupt => |opts| switch (opts.type) { | ||
| 154 | .ilink1 => .@"interrupt(\"ilink1\")", | ||
| 155 | .ilink2 => .@"interrupt(\"ilink2\")", | ||
| 156 | .ilink => .@"interrupt(\"ilink\")", | ||
| 157 | .firq => .@"interrupt(\"firq\")", | ||
| 158 | }, | ||
| 159 | |||
| 160 | .arm_interrupt => |opts| switch (opts.type) { | ||
| 161 | .generic => .interrupt, | ||
| 162 | .irq => .@"interrupt(\"IRQ\")", | ||
| 163 | .fiq => .@"interrupt(\"FIQ\")", | ||
| 164 | .swi => .@"interrupt(\"SWI\")", | ||
| 165 | .abort => .@"interrupt(\"ABORT\")", | ||
| 166 | .undef => .@"interrupt(\"UNDEF\")", | ||
| 167 | }, | ||
| 168 | |||
| 169 | .avr_signal => .signal, | ||
| 170 | |||
| 171 | .microblaze_interrupt => |opts| switch (opts.type) { | ||
| 172 | .user => .save_volatiles, | ||
| 173 | .regular => .interrupt_handler, | ||
| 174 | .fast => .fast_interrupt, | ||
| 175 | .breakpoint => .break_handler, | ||
| 176 | }, | ||
| 177 | |||
| 178 | .mips_interrupt, .mips64_interrupt => |opts| switch (opts.mode) { | ||
| 179 | .eic => .@"interrupt(\"eic\")", | ||
| 180 | .sw0 => .@"interrupt(\"sw0\")", | ||
| 181 | .sw1 => .@"interrupt(\"sw1\")", | ||
| 182 | .hw0 => .@"interrupt(\"hw0\")", | ||
| 183 | .hw1 => .@"interrupt(\"hw1\")", | ||
| 184 | .hw2 => .@"interrupt(\"hw2\")", | ||
| 185 | .hw3 => .@"interrupt(\"hw3\")", | ||
| 186 | .hw4 => .@"interrupt(\"hw4\")", | ||
| 187 | .hw5 => .@"interrupt(\"hw5\")", | ||
| 188 | }, | ||
| 189 | |||
| 190 | .riscv64_lp64_v, .riscv32_ilp32_v => .riscv_vector_cc, | ||
| 191 | .riscv32_interrupt, .riscv64_interrupt => |opts| switch (opts.mode) { | ||
| 192 | .supervisor => .@"interrupt(\"supervisor\")", | ||
| 193 | .machine => .@"interrupt(\"machine\")", | ||
| 194 | }, | ||
| 195 | |||
| 196 | .sh_renesas => .renesas, | ||
| 197 | .sh_interrupt => |opts| switch (opts.save) { | ||
| 198 | .fpscr => .trapa_handler, | ||
| 199 | .high => .@"interrupt_handler, nosave_low_regs", | ||
| 200 | .full => .interrupt_handler, | ||
| 201 | .bank => .@"interrupt_handler, resbank", | ||
| 202 | }, | ||
| 203 | |||
| 204 | .m68k_rtd => .m68k_rtd, | ||
| 205 | |||
| 206 | .avr_interrupt, | ||
| 207 | .csky_interrupt, | ||
| 208 | .m68k_interrupt, | ||
| 209 | .msp430_interrupt, | ||
| 210 | .x86_16_interrupt, | ||
| 211 | .x86_interrupt, | ||
| 212 | .x86_64_interrupt, | ||
| 213 | => .interrupt, | ||
| 214 | |||
| 215 | .ez80_tiflags => .tiflags, | ||
| 216 | |||
| 217 | else => unreachable, // `Zcu.callconvSupported` | ||
| 218 | }; | ||
| 219 | } | ||
| 220 | }; | ||
| 221 | |||
| 49 | /// Returns `true` if this node has a postfix operator, meaning an `[...]` or `(...)` appears | 222 | /// Returns `true` if this node has a postfix operator, meaning an `[...]` or `(...)` appears |
| 50 | /// after the identifier in a declarator with this type. In this case, if this node is wrapped | 223 | /// after the identifier in a declarator with this type. In this case, if this node is wrapped |
| 51 | /// in a pointer type, we will need to add parentheses due to operator precedence. | 224 | /// in a pointer type, we will need to add parentheses due to operator precedence. |
| ... | @@ -130,28 +303,28 @@ pub const CType = union(enum) { | ... | @@ -130,28 +303,28 @@ pub const CType = union(enum) { |
| 130 | pub fn bits(int: Int, target: *const std.Target) u16 { | 303 | pub fn bits(int: Int, target: *const std.Target) u16 { |
| 131 | return switch (int) { | 304 | return switch (int) { |
| 132 | // zig fmt: off | 305 | // zig fmt: off |
| 133 | .char => target.cTypeBitSize(.char), | 306 | .char => target.cTypeBitSize(.char).?, |
| 134 | 307 | ||
| 135 | .@"unsigned short" => target.cTypeBitSize(.ushort), | 308 | .@"unsigned short" => target.cTypeBitSize(.ushort).?, |
| 136 | .@"unsigned int" => target.cTypeBitSize(.uint), | 309 | .@"unsigned int" => target.cTypeBitSize(.uint).?, |
| 137 | .@"unsigned long" => target.cTypeBitSize(.ulong), | 310 | .@"unsigned long" => target.cTypeBitSize(.ulong).?, |
| 138 | .@"unsigned long long" => target.cTypeBitSize(.ulonglong), | 311 | .@"unsigned long long" => target.cTypeBitSize(.ulonglong).?, |
| 139 | 312 | ||
| 140 | .@"signed short" => target.cTypeBitSize(.short), | 313 | .@"signed short" => target.cTypeBitSize(.short).?, |
| 141 | .@"signed int" => target.cTypeBitSize(.int), | 314 | .@"signed int" => target.cTypeBitSize(.int).?, |
| 142 | .@"signed long" => target.cTypeBitSize(.long), | 315 | .@"signed long" => target.cTypeBitSize(.long).?, |
| 143 | .@"signed long long" => target.cTypeBitSize(.longlong), | 316 | .@"signed long long" => target.cTypeBitSize(.longlong).?, |
| 144 | 317 | ||
| 145 | .uintptr_t, .intptr_t => target.ptrBitWidth(), | 318 | .uintptr_t, .intptr_t => target.ptrBitWidth(), |
| 146 | 319 | ||
| 147 | .uint8_t, .int8_t => 8, | 320 | .uint8_t, .int8_t => 8, |
| 148 | .uint16_t, .int16_t => 16, | 321 | .uint16_t, .int16_t => 16, |
| 149 | .uint24_t, .int24_t => 24, | 322 | .uint24_t, .int24_t => 24, |
| 150 | .uint32_t, .int32_t => 32, | 323 | .uint32_t, .int32_t => 32, |
| 151 | .uint48_t, .int48_t => 48, | 324 | .uint48_t, .int48_t => 48, |
| 152 | .uint64_t, .int64_t => 64, | 325 | .uint64_t, .int64_t => 64, |
| 153 | .zig_u128, .zig_i128 => 128, | 326 | .zig_u128, .zig_i128 => 128, |
| 154 | // zig fmt: on | 327 | // zig fmt: on |
| 155 | }; | 328 | }; |
| 156 | } | 329 | } |
| 157 | }; | 330 | }; |
| ... | @@ -376,6 +549,7 @@ pub const CType = union(enum) { | ... | @@ -376,6 +549,7 @@ pub const CType = union(enum) { |
| 376 | .ret_ty = ret_cty_buf, | 549 | .ret_ty = ret_cty_buf, |
| 377 | .param_tys = param_cty_buf, | 550 | .param_tys = param_cty_buf, |
| 378 | .varargs = func_type.is_var_args, | 551 | .varargs = func_type.is_var_args, |
| 552 | .cc = .fromLang(func_type.cc, zcu.getTarget()), | ||
| 379 | } }; | 553 | } }; |
| 380 | } | 554 | } |
| 381 | try deps.addType(gpa, cur_ty, allow_incomplete); | 555 | try deps.addType(gpa, cur_ty, allow_incomplete); |
| ... | @@ -763,6 +937,13 @@ pub const CType = union(enum) { | ... | @@ -763,6 +937,13 @@ pub const CType = union(enum) { |
| 763 | try w.writeByte('('); | 937 | try w.writeByte('('); |
| 764 | }, | 938 | }, |
| 765 | } | 939 | } |
| 940 | switch (ptr.elem_ty.*) { | ||
| 941 | else => {}, | ||
| 942 | .function => |function| switch (function.cc) { | ||
| 943 | .c => {}, | ||
| 944 | else => |cc| try w.print("zig_callconv({t}) ", .{cc}), | ||
| 945 | }, | ||
| 946 | } | ||
| 766 | try w.writeByte('*'); | 947 | try w.writeByte('*'); |
| 767 | }, | 948 | }, |
| 768 | 949 | ||
| ... | @@ -812,7 +993,7 @@ pub const CType = union(enum) { | ... | @@ -812,7 +993,7 @@ pub const CType = union(enum) { |
| 812 | => {}, | 993 | => {}, |
| 813 | 994 | ||
| 814 | .pointer => |ptr| { | 995 | .pointer => |ptr| { |
| 815 | // Match opening paren "(" write `writeTypePrefix`. | 996 | // Match opening paren "(" in `writeTypePrefix`. |
| 816 | switch (ptr.elem_ty.kind()) { | 997 | switch (ptr.elem_ty.kind()) { |
| 817 | .specifier, .pointer => {}, | 998 | .specifier, .pointer => {}, |
| 818 | .postfix_op => try w.writeByte(')'), | 999 | .postfix_op => try w.writeByte(')'), |
src/codegen/c/type/render_defs.zig+143-155| ... | @@ -21,16 +21,21 @@ pub fn defineAligned( | ... | @@ -21,16 +21,21 @@ pub fn defineAligned( |
| 21 | if (complete and alignment.compareStrict(.lt, ty.abiAlignment(zcu))) { | 21 | if (complete and alignment.compareStrict(.lt, ty.abiAlignment(zcu))) { |
| 22 | try w.print("zig_under_align({d}) ", .{alignment.toByteUnits().?}); | 22 | try w.print("zig_under_align({d}) ", .{alignment.toByteUnits().?}); |
| 23 | } | 23 | } |
| 24 | try w.print("{f}{f}{f}; /* align({d}) {f} */\n", .{ | 24 | try w.print("{f}{f}{f};", .{ |
| 25 | cty.fmtDeclaratorPrefix(zcu), | 25 | cty.fmtDeclaratorPrefix(zcu), |
| 26 | name_cty.fmtTypeName(zcu), | 26 | name_cty.fmtTypeName(zcu), |
| 27 | cty.fmtDeclaratorSuffix(zcu), | 27 | cty.fmtDeclaratorSuffix(zcu), |
| 28 | }); | ||
| 29 | if (!zcu.comp.config.root_strip) try w.print(" /* align({d}) {f} */", .{ | ||
| 28 | alignment.toByteUnits().?, | 30 | alignment.toByteUnits().?, |
| 29 | ty.fmt(pt), | 31 | ty.fmt(pt), |
| 30 | }); | 32 | }); |
| 33 | try w.writeByte('\n'); | ||
| 31 | } | 34 | } |
| 32 | /// Renders the definition of a big-int `struct`. | 35 | /// Renders the definition of a big-int `struct`. |
| 33 | pub fn defineBigInt(big: CType.BigInt, w: *Writer, zcu: *const Zcu) Writer.Error!void { | 36 | pub fn defineBigInt(big: CType.BigInt, w: *Writer, zcu: *const Zcu) Writer.Error!void { |
| 37 | const target = zcu.getTarget(); | ||
| 38 | const bits = big.limb_size.bits() *| big.limbs_len; | ||
| 34 | const name_cty: CType = .{ .bigint = .{ | 39 | const name_cty: CType = .{ .bigint = .{ |
| 35 | .limb_size = big.limb_size, | 40 | .limb_size = big.limb_size, |
| 36 | .limbs_len = big.limbs_len, | 41 | .limbs_len = big.limbs_len, |
| ... | @@ -41,12 +46,20 @@ pub fn defineBigInt(big: CType.BigInt, w: *Writer, zcu: *const Zcu) Writer.Error | ... | @@ -41,12 +46,20 @@ pub fn defineBigInt(big: CType.BigInt, w: *Writer, zcu: *const Zcu) Writer.Error |
| 41 | .elem_ty = &limb_cty, | 46 | .elem_ty = &limb_cty, |
| 42 | .nonstring = limb_cty.isStringElem(), | 47 | .nonstring = limb_cty.isStringElem(), |
| 43 | } }; | 48 | } }; |
| 44 | try w.print("{f} {{ {f}limbs{f}; }}; /* {d} bits */\n", .{ | 49 | try w.print("{f} {{ {f}limbs{f}; }};", .{ |
| 45 | name_cty.fmtTypeName(zcu), | 50 | name_cty.fmtTypeName(zcu), |
| 46 | array_cty.fmtDeclaratorPrefix(zcu), | 51 | array_cty.fmtDeclaratorPrefix(zcu), |
| 47 | array_cty.fmtDeclaratorSuffix(zcu), | 52 | array_cty.fmtDeclaratorSuffix(zcu), |
| 48 | big.limb_size.bits() * @as(u17, big.limbs_len), | ||
| 49 | }); | 53 | }); |
| 54 | if (!zcu.comp.config.root_strip) try w.print(" /* u{d}, i{d} */", .{ bits, bits }); | ||
| 55 | try w.writeByte('\n'); | ||
| 56 | try writeStaticAssertCTypeLayout( | ||
| 57 | name_cty, | ||
| 58 | std.zig.target.intByteSize(target, bits), | ||
| 59 | .fromByteUnits(std.zig.target.intAlignment(target, bits)), | ||
| 60 | w, | ||
| 61 | zcu, | ||
| 62 | ); | ||
| 50 | } | 63 | } |
| 51 | 64 | ||
| 52 | /// Renders a forward declaration of the `struct` which represents an error union whose payload type | 65 | /// Renders a forward declaration of the `struct` which represents an error union whose payload type |
| ... | @@ -81,27 +94,28 @@ pub fn errunionDefineComplete( | ... | @@ -81,27 +94,28 @@ pub fn errunionDefineComplete( |
| 81 | if (payload_ty.hasRuntimeBits(zcu)) { | 94 | if (payload_ty.hasRuntimeBits(zcu)) { |
| 82 | const payload_cty: CType = try .lower(payload_ty, deps, arena, zcu); | 95 | const payload_cty: CType = try .lower(payload_ty, deps, arena, zcu); |
| 83 | try w.print( | 96 | try w.print( |
| 84 | \\{f} {{ /* anyerror!{f} */ | 97 | \\{f} {{ |
| 85 | \\ {f}payload{f}; | 98 | \\ {f}payload{f}; |
| 86 | \\ {f}error{f}; | 99 | \\ {f}error{f}; |
| 87 | \\}}; | 100 | \\}}; |
| 88 | \\ | ||
| 89 | , .{ | 101 | , .{ |
| 90 | name_cty.fmtTypeName(zcu), | 102 | name_cty.fmtTypeName(zcu), |
| 91 | payload_ty.fmt(pt), | ||
| 92 | payload_cty.fmtDeclaratorPrefix(zcu), | 103 | payload_cty.fmtDeclaratorPrefix(zcu), |
| 93 | payload_cty.fmtDeclaratorSuffix(zcu), | 104 | payload_cty.fmtDeclaratorSuffix(zcu), |
| 94 | error_cty.fmtDeclaratorPrefix(zcu), | 105 | error_cty.fmtDeclaratorPrefix(zcu), |
| 95 | error_cty.fmtDeclaratorSuffix(zcu), | 106 | error_cty.fmtDeclaratorSuffix(zcu), |
| 96 | }); | 107 | }); |
| 97 | } else { | 108 | } else { |
| 98 | try w.print("{f} {{ {f}error{f}; }}; /* anyerror!{f} */\n", .{ | 109 | try w.print("{f} {{ {f}error{f}; }};", .{ |
| 99 | name_cty.fmtTypeName(zcu), | 110 | name_cty.fmtTypeName(zcu), |
| 100 | error_cty.fmtDeclaratorPrefix(zcu), | 111 | error_cty.fmtDeclaratorPrefix(zcu), |
| 101 | error_cty.fmtDeclaratorSuffix(zcu), | 112 | error_cty.fmtDeclaratorSuffix(zcu), |
| 102 | payload_ty.fmt(pt), | ||
| 103 | }); | 113 | }); |
| 104 | } | 114 | } |
| 115 | if (!zcu.comp.config.root_strip) try w.print(" /* anyerror!{f} */", .{ | ||
| 116 | payload_ty.fmt(pt), | ||
| 117 | }); | ||
| 118 | try w.writeByte('\n'); | ||
| 105 | } | 119 | } |
| 106 | 120 | ||
| 107 | /// If the Zig type `ty` lowers to a `struct` or `union` type, renders a forward declaration of that | 121 | /// If the Zig type `ty` lowers to a `struct` or `union` type, renders a forward declaration of that |
| ... | @@ -141,10 +155,13 @@ pub fn defineIncomplete(ty: Type, w: *Writer, pt: Zcu.PerThread) Writer.Error!vo | ... | @@ -141,10 +155,13 @@ pub fn defineIncomplete(ty: Type, w: *Writer, pt: Zcu.PerThread) Writer.Error!vo |
| 141 | }, | 155 | }, |
| 142 | else => return, | 156 | else => return, |
| 143 | }; | 157 | }; |
| 144 | try w.print("typedef void {f}; /* {f} */\n", .{ | 158 | try w.print("typedef void {f};", .{ |
| 145 | name_cty.fmtTypeName(zcu), | 159 | name_cty.fmtTypeName(zcu), |
| 160 | }); | ||
| 161 | if (!zcu.comp.config.root_strip) try w.print(" /* {f} */", .{ | ||
| 146 | ty.fmt(pt), | 162 | ty.fmt(pt), |
| 147 | }); | 163 | }); |
| 164 | try w.writeByte('\n'); | ||
| 148 | } | 165 | } |
| 149 | 166 | ||
| 150 | /// If the Zig type `ty` lowers to a `struct` or `union` type, or to a `typedef`, renders the | 167 | /// If the Zig type `ty` lowers to a `struct` or `union` type, or to a `typedef`, renders the |
| ... | @@ -163,13 +180,13 @@ pub fn defineComplete( | ... | @@ -163,13 +180,13 @@ pub fn defineComplete( |
| 163 | 180 | ||
| 164 | ty.assertHasLayout(zcu); | 181 | ty.assertHasLayout(zcu); |
| 165 | 182 | ||
| 166 | switch (ty.zigTypeTag(zcu)) { | 183 | const check_cty = check_cty: switch (ty.zigTypeTag(zcu)) { |
| 167 | .@"fn" => if (!ty.fnHasRuntimeBits(zcu)) { | 184 | .@"fn" => if (!ty.fnHasRuntimeBits(zcu)) { |
| 168 | const name_cty: CType = .{ .@"fn" = ty }; | 185 | const name_cty: CType = .{ .@"fn" = ty }; |
| 169 | try w.print("typedef void {f}; /* {f} */\n", .{ | 186 | try w.print("typedef void {f};", .{ |
| 170 | name_cty.fmtTypeName(zcu), | 187 | name_cty.fmtTypeName(zcu), |
| 171 | ty.fmt(pt), | ||
| 172 | }); | 188 | }); |
| 189 | break :check_cty null; | ||
| 173 | } else { | 190 | } else { |
| 174 | const ip = &zcu.intern_pool; | 191 | const ip = &zcu.intern_pool; |
| 175 | const func_type = ip.indexToKey(ty.toIntern()).func_type; | 192 | const func_type = ip.indexToKey(ty.toIntern()).func_type; |
| ... | @@ -186,10 +203,12 @@ pub fn defineComplete( | ... | @@ -186,10 +203,12 @@ pub fn defineComplete( |
| 186 | const name_cty: CType = .{ .@"fn" = ty }; | 203 | const name_cty: CType = .{ .@"fn" = ty }; |
| 187 | const ret_cty: CType = try .lower(effective_ret_ty, deps, arena, zcu); | 204 | const ret_cty: CType = try .lower(effective_ret_ty, deps, arena, zcu); |
| 188 | 205 | ||
| 189 | try w.print("typedef {f}{f}(", .{ | 206 | try w.print("typedef {f}", .{ret_cty.fmtDeclaratorPrefix(zcu)}); |
| 190 | ret_cty.fmtDeclaratorPrefix(zcu), | 207 | switch (CType.CallingConvention.fromLang(func_type.cc, zcu.getTarget())) { |
| 191 | name_cty.fmtTypeName(zcu), | 208 | .c => {}, |
| 192 | }); | 209 | else => |cc| try w.print("zig_callconv({t}) ", .{cc}), |
| 210 | } | ||
| 211 | try w.print("{f}(", .{name_cty.fmtTypeName(zcu)}); | ||
| 193 | var any_params = false; | 212 | var any_params = false; |
| 194 | for (func_type.param_types.get(ip)) |param_ty_ip| { | 213 | for (func_type.param_types.get(ip)) |param_ty_ip| { |
| 195 | const param_ty: Type = .fromInterned(param_ty_ip); | 214 | const param_ty: Type = .fromInterned(param_ty_ip); |
| ... | @@ -205,88 +224,85 @@ pub fn defineComplete( | ... | @@ -205,88 +224,85 @@ pub fn defineComplete( |
| 205 | } else if (!any_params) { | 224 | } else if (!any_params) { |
| 206 | try w.writeAll("void"); | 225 | try w.writeAll("void"); |
| 207 | } | 226 | } |
| 208 | try w.print("){f}; /* {f} */\n", .{ | 227 | try w.print("){f};", .{ret_cty.fmtDeclaratorSuffixIgnoreNonstring(zcu)}); |
| 209 | ret_cty.fmtDeclaratorSuffixIgnoreNonstring(zcu), | 228 | break :check_cty null; |
| 210 | ty.fmt(pt), | ||
| 211 | }); | ||
| 212 | }, | 229 | }, |
| 213 | .@"enum" => { | 230 | .@"enum" => { |
| 214 | const name_cty: CType = .{ .@"enum" = ty }; | 231 | const name_cty: CType = .{ .@"enum" = ty }; |
| 215 | const cty: CType = try .lower(ty.backingIntType(zcu), deps, arena, zcu); | 232 | const cty: CType = try .lower(ty.backingIntType(zcu), deps, arena, zcu); |
| 216 | try w.print("typedef {f}{f}{f}; /* {f} */\n", .{ | 233 | try w.print("typedef {f}{f}{f};", .{ |
| 217 | cty.fmtDeclaratorPrefix(zcu), | 234 | cty.fmtDeclaratorPrefix(zcu), |
| 218 | name_cty.fmtTypeName(zcu), | 235 | name_cty.fmtTypeName(zcu), |
| 219 | cty.fmtDeclaratorSuffix(zcu), | 236 | cty.fmtDeclaratorSuffix(zcu), |
| 220 | ty.fmt(pt), | ||
| 221 | }); | 237 | }); |
| 238 | break :check_cty null; | ||
| 222 | }, | 239 | }, |
| 223 | .@"struct" => if (ty.isTuple(zcu)) { | 240 | .@"struct" => if (ty.isTuple(zcu)) |
| 224 | try defineTuple(ty, deps, arena, w, pt); | 241 | if (ty.hasRuntimeBits(zcu)) try defineTuple(ty, deps, arena, w, pt) else return |
| 225 | } else switch (ty.containerLayout(zcu)) { | 242 | else switch (ty.containerLayout(zcu)) { |
| 226 | .auto, .@"extern" => try defineStruct(ty, deps, arena, w, pt), | 243 | .auto, .@"extern" => if (ty.hasRuntimeBits(zcu)) try defineStruct(ty, deps, arena, w, pt) else return, |
| 227 | .@"packed" => try defineBitpack(ty, deps, arena, w, pt), | 244 | .@"packed" => try defineBitpack(ty, deps, arena, w, pt), |
| 228 | }, | 245 | }, |
| 229 | .@"union" => switch (ty.containerLayout(zcu)) { | 246 | .@"union" => switch (ty.containerLayout(zcu)) { |
| 230 | .auto => try defineUnionAuto(ty, deps, arena, w, pt), | 247 | .auto => if (ty.hasRuntimeBits(zcu)) try defineUnionAuto(ty, deps, arena, w, pt) else return, |
| 231 | .@"extern" => try defineUnionExtern(ty, deps, arena, w, pt), | 248 | .@"extern" => if (ty.hasRuntimeBits(zcu)) try defineUnionExtern(ty, deps, arena, w, pt) else return, |
| 232 | .@"packed" => try defineBitpack(ty, deps, arena, w, pt), | 249 | .@"packed" => try defineBitpack(ty, deps, arena, w, pt), |
| 233 | }, | 250 | }, |
| 234 | .pointer => if (ty.isSlice(zcu)) { | 251 | .pointer => if (ty.isSlice(zcu)) { |
| 235 | const name_cty: CType = .{ .slice = ty }; | 252 | const name_cty: CType = .{ .slice = ty }; |
| 236 | const ptr_cty: CType = try .lower(ty.slicePtrFieldType(zcu), deps, arena, zcu); | 253 | const ptr_cty: CType = try .lower(ty.slicePtrFieldType(zcu), deps, arena, zcu); |
| 237 | try w.print( | 254 | try w.print( |
| 238 | \\{f} {{ /* {f} */ | 255 | \\{f} {{ |
| 239 | \\ {f}ptr{f}; | 256 | \\ {f}ptr{f}; |
| 240 | \\ size_t len; | 257 | \\ uintptr_t len; |
| 241 | \\}}; | 258 | \\}}; |
| 242 | \\ | ||
| 243 | , .{ | 259 | , .{ |
| 244 | name_cty.fmtTypeName(zcu), | 260 | name_cty.fmtTypeName(zcu), |
| 245 | ty.fmt(pt), | ||
| 246 | ptr_cty.fmtDeclaratorPrefix(zcu), | 261 | ptr_cty.fmtDeclaratorPrefix(zcu), |
| 247 | ptr_cty.fmtDeclaratorSuffix(zcu), | 262 | ptr_cty.fmtDeclaratorSuffix(zcu), |
| 248 | }); | 263 | }); |
| 249 | // Don't bother with `writeStaticAssertLayout`---there's not really any way we could mess | 264 | break :check_cty switch (ty.toIntern()) { |
| 250 | // slices up, and they're all obviously the same layout. | 265 | .slice_const_u8_sentinel_0_type => name_cty, |
| 251 | }, | 266 | else => null, |
| 267 | }; | ||
| 268 | } else return, | ||
| 252 | .optional => switch (CType.classifyOptional(ty, zcu)) { | 269 | .optional => switch (CType.classifyOptional(ty, zcu)) { |
| 253 | .error_set, | 270 | .error_set, |
| 254 | .ptr_like, | 271 | .ptr_like, |
| 255 | .slice_like, | 272 | .slice_like, |
| 256 | .npv_payload, | 273 | .npv_payload, |
| 257 | => {}, | 274 | => return, |
| 258 | 275 | ||
| 259 | .opv_payload => { | 276 | .opv_payload => { |
| 260 | const name_cty: CType = .{ .opt = ty }; | 277 | const name_cty: CType = .{ .opt = ty }; |
| 261 | try w.print("{f} {{ bool is_null; }}; /* {f} */\n", .{ | 278 | try w.print("{f} {{ bool is_null; }};", .{ |
| 262 | name_cty.fmtTypeName(zcu), | 279 | name_cty.fmtTypeName(zcu), |
| 263 | ty.fmt(pt), | ||
| 264 | }); | 280 | }); |
| 265 | try writeStaticAssertLayout(ty, name_cty, w, zcu); | 281 | break :check_cty switch (ty.toIntern()) { |
| 282 | .optional_noreturn_type => name_cty, | ||
| 283 | else => null, | ||
| 284 | }; | ||
| 266 | }, | 285 | }, |
| 267 | 286 | ||
| 268 | .@"struct" => { | 287 | .@"struct" => { |
| 269 | const name_cty: CType = .{ .opt = ty }; | 288 | const name_cty: CType = .{ .opt = ty }; |
| 270 | const payload_cty: CType = try .lower(ty.optionalChild(zcu), deps, arena, zcu); | 289 | const payload_cty: CType = try .lower(ty.optionalChild(zcu), deps, arena, zcu); |
| 271 | try w.print( | 290 | try w.print( |
| 272 | \\{f} {{ /* {f} */ | 291 | \\{f} {{ |
| 273 | \\ {f}payload{f}; | 292 | \\ {f}payload{f}; |
| 274 | \\ bool is_null; | 293 | \\ bool is_null; |
| 275 | \\}}; | 294 | \\}}; |
| 276 | \\ | ||
| 277 | , .{ | 295 | , .{ |
| 278 | name_cty.fmtTypeName(zcu), | 296 | name_cty.fmtTypeName(zcu), |
| 279 | ty.fmt(pt), | ||
| 280 | payload_cty.fmtDeclaratorPrefix(zcu), | 297 | payload_cty.fmtDeclaratorPrefix(zcu), |
| 281 | payload_cty.fmtDeclaratorSuffix(zcu), | 298 | payload_cty.fmtDeclaratorSuffix(zcu), |
| 282 | }); | 299 | }); |
| 283 | try writeStaticAssertLayout(ty, name_cty, w, zcu); | 300 | break :check_cty name_cty; |
| 284 | }, | 301 | }, |
| 285 | }, | 302 | }, |
| 286 | .array => if (ty.hasRuntimeBits(zcu)) { | 303 | .array => if (ty.hasRuntimeBits(zcu)) { |
| 287 | const elem_ty = ty.childType(zcu); | ||
| 288 | const name_cty: CType = .{ .arr = ty }; | 304 | const name_cty: CType = .{ .arr = ty }; |
| 289 | const elem_cty: CType = try .lower(elem_ty, deps, arena, zcu); | 305 | const elem_cty: CType = try .lower(ty.childType(zcu), deps, arena, zcu); |
| 290 | const array_cty: CType = .{ .array = .{ | 306 | const array_cty: CType = .{ .array = .{ |
| 291 | .len = ty.arrayLenIncludingSentinel(zcu), | 307 | .len = ty.arrayLenIncludingSentinel(zcu), |
| 292 | .elem_ty = &elem_cty, | 308 | .elem_ty = &elem_cty, |
| ... | @@ -296,43 +312,35 @@ pub fn defineComplete( | ... | @@ -296,43 +312,35 @@ pub fn defineComplete( |
| 296 | break :nonstring Value.compareHetero(s, .neq, .zero_comptime_int, zcu); | 312 | break :nonstring Value.compareHetero(s, .neq, .zero_comptime_int, zcu); |
| 297 | }, | 313 | }, |
| 298 | } }; | 314 | } }; |
| 299 | if (elem_ty.defaultStructFieldAlignment(.auto, zcu) == elem_ty.abiAlignment(zcu)) { | 315 | try w.print("{f} {{ {f}array{f}; }};", .{ |
| 300 | try w.print("{f} {{ {f}array{f}; }}; /* {f} */\n", .{ | 316 | name_cty.fmtTypeName(zcu), |
| 301 | name_cty.fmtTypeName(zcu), | 317 | array_cty.fmtDeclaratorPrefix(zcu), |
| 302 | array_cty.fmtDeclaratorPrefix(zcu), | 318 | array_cty.fmtDeclaratorSuffix(zcu), |
| 303 | array_cty.fmtDeclaratorSuffix(zcu), | 319 | }); |
| 304 | ty.fmt(pt), | 320 | break :check_cty name_cty; |
| 305 | }); | 321 | } else return, |
| 306 | } else { | ||
| 307 | try w.print("zig_packed({f} {{ zig_under_align({d}) {f}array{f}; }}); /* {f} */\n", .{ | ||
| 308 | name_cty.fmtTypeName(zcu), | ||
| 309 | elem_ty.abiAlignment(zcu).toByteUnits().?, | ||
| 310 | array_cty.fmtDeclaratorPrefix(zcu), | ||
| 311 | array_cty.fmtDeclaratorSuffix(zcu), | ||
| 312 | ty.fmt(pt), | ||
| 313 | }); | ||
| 314 | } | ||
| 315 | try writeStaticAssertLayout(ty, name_cty, w, zcu); | ||
| 316 | }, | ||
| 317 | .vector => if (ty.hasRuntimeBits(zcu)) { | 322 | .vector => if (ty.hasRuntimeBits(zcu)) { |
| 318 | const elem_ty = ty.childType(zcu); | ||
| 319 | const name_cty: CType = .{ .vec = ty }; | 323 | const name_cty: CType = .{ .vec = ty }; |
| 320 | const elem_cty: CType = try .lower(elem_ty, deps, arena, zcu); | 324 | const elem_cty: CType = try .lower(ty.childType(zcu), deps, arena, zcu); |
| 321 | const array_cty: CType = .{ .array = .{ | 325 | const array_cty: CType = .{ .array = .{ |
| 322 | .len = ty.arrayLenIncludingSentinel(zcu), | 326 | .len = ty.arrayLenIncludingSentinel(zcu), |
| 323 | .elem_ty = &elem_cty, | 327 | .elem_ty = &elem_cty, |
| 324 | .nonstring = elem_cty.isStringElem(), | 328 | .nonstring = elem_cty.isStringElem(), |
| 325 | } }; | 329 | } }; |
| 326 | try w.print("{f} {{ {f}array{f}; }}; /* {f} */\n", .{ | 330 | try w.print("{f} {{ {f}array{f}; }};", .{ |
| 327 | name_cty.fmtTypeName(zcu), | 331 | name_cty.fmtTypeName(zcu), |
| 328 | array_cty.fmtDeclaratorPrefix(zcu), | 332 | array_cty.fmtDeclaratorPrefix(zcu), |
| 329 | array_cty.fmtDeclaratorSuffix(zcu), | 333 | array_cty.fmtDeclaratorSuffix(zcu), |
| 330 | ty.fmt(pt), | ||
| 331 | }); | 334 | }); |
| 332 | try writeStaticAssertLayout(ty, name_cty, w, zcu); | 335 | break :check_cty name_cty; |
| 333 | }, | 336 | } else return, |
| 334 | else => {}, | 337 | else => return, |
| 335 | } | 338 | }; |
| 339 | if (!zcu.comp.config.root_strip) try w.print(" /* {f} */", .{ | ||
| 340 | ty.fmt(pt), | ||
| 341 | }); | ||
| 342 | try w.writeByte('\n'); | ||
| 343 | if (check_cty) |cty| try writeStaticAssertTypeLayout(ty, cty, w, zcu); | ||
| 336 | } | 344 | } |
| 337 | fn defineBitpack( | 345 | fn defineBitpack( |
| 338 | ty: Type, | 346 | ty: Type, |
| ... | @@ -340,16 +348,16 @@ fn defineBitpack( | ... | @@ -340,16 +348,16 @@ fn defineBitpack( |
| 340 | arena: Allocator, | 348 | arena: Allocator, |
| 341 | w: *Writer, | 349 | w: *Writer, |
| 342 | pt: Zcu.PerThread, | 350 | pt: Zcu.PerThread, |
| 343 | ) (Allocator.Error || Writer.Error)!void { | 351 | ) (Allocator.Error || Writer.Error)!?CType { |
| 344 | const zcu = pt.zcu; | 352 | const zcu = pt.zcu; |
| 345 | const name_cty: CType = .{ .bitpack = ty }; | 353 | const name_cty: CType = .{ .bitpack = ty }; |
| 346 | const cty: CType = try .lower(ty.backingIntType(zcu), deps, arena, zcu); | 354 | const cty: CType = try .lower(ty.backingIntType(zcu), deps, arena, zcu); |
| 347 | try w.print("typedef {f}{f}{f}; /* {f} */\n", .{ | 355 | try w.print("typedef {f}{f}{f};", .{ |
| 348 | cty.fmtDeclaratorPrefix(zcu), | 356 | cty.fmtDeclaratorPrefix(zcu), |
| 349 | name_cty.fmtTypeName(zcu), | 357 | name_cty.fmtTypeName(zcu), |
| 350 | cty.fmtDeclaratorSuffix(zcu), | 358 | cty.fmtDeclaratorSuffix(zcu), |
| 351 | ty.fmt(pt), | ||
| 352 | }); | 359 | }); |
| 360 | return null; | ||
| 353 | } | 361 | } |
| 354 | fn defineTuple( | 362 | fn defineTuple( |
| 355 | ty: Type, | 363 | ty: Type, |
| ... | @@ -357,72 +365,54 @@ fn defineTuple( | ... | @@ -357,72 +365,54 @@ fn defineTuple( |
| 357 | arena: Allocator, | 365 | arena: Allocator, |
| 358 | w: *Writer, | 366 | w: *Writer, |
| 359 | pt: Zcu.PerThread, | 367 | pt: Zcu.PerThread, |
| 360 | ) (Allocator.Error || Writer.Error)!void { | 368 | ) (Allocator.Error || Writer.Error)!CType { |
| 361 | const zcu = pt.zcu; | 369 | const zcu = pt.zcu; |
| 362 | if (!ty.hasRuntimeBits(zcu)) return; | ||
| 363 | const ip = &zcu.intern_pool; | 370 | const ip = &zcu.intern_pool; |
| 364 | const tuple = ip.indexToKey(ty.toIntern()).tuple_type; | 371 | const tuple = ip.indexToKey(ty.toIntern()).tuple_type; |
| 365 | 372 | ||
| 366 | const tuple_align = ty.abiAlignment(zcu); | 373 | // Fields cannot be underaligned, because tuple fields cannot have specified alignments. |
| 374 | // However, overaligned fields are possible thanks to intermediate zero-bit fields. | ||
| 367 | 375 | ||
| 368 | // If there are any underaligned fields, we need to byte-pack the tuple. | 376 | const tuple_align = ty.abiAlignment(zcu); |
| 369 | const pack: bool = pack: { | ||
| 370 | var offset: u64 = 0; | ||
| 371 | for (tuple.types.get(ip)) |field_ty_ip| { | ||
| 372 | const field_ty: Type = .fromInterned(field_ty_ip); | ||
| 373 | if (!field_ty.hasRuntimeBits(zcu)) continue; | ||
| 374 | const natural_align = field_ty.defaultStructFieldAlignment(.auto, zcu); | ||
| 375 | const natural_offset = natural_align.forward(offset); | ||
| 376 | offset = field_ty.abiAlignment(zcu).forward(offset); | ||
| 377 | if (offset < natural_offset) break :pack true; | ||
| 378 | // Also pack if any field is more aligned than the tuple should be. | ||
| 379 | if (natural_align.compareStrict(.gt, tuple_align)) break :pack true; | ||
| 380 | offset += field_ty.abiSize(zcu); | ||
| 381 | } | ||
| 382 | break :pack false; | ||
| 383 | }; | ||
| 384 | 377 | ||
| 385 | // If the alignment of other fields would not give the tuple sufficient alignment, we | 378 | // If the alignment of other fields would not give the tuple sufficient alignment, we |
| 386 | // need to align the first field (which does not affect its offset, because 0 is always | 379 | // need to align the first field (which does not affect its offset, because 0 is always |
| 387 | // well-aligned) to indirectly specify the tuple alignment. | 380 | // well-aligned) to indirectly specify the tuple alignment. |
| 388 | const overalign: bool = switch (pack) { | 381 | const overalign: bool = for (tuple.types.get(ip)) |field_ty_ip| { |
| 389 | true => tuple_align.compareStrict(.gt, .@"1"), | 382 | const field_ty: Type = .fromInterned(field_ty_ip); |
| 390 | false => for (tuple.types.get(ip)) |field_ty_ip| { | 383 | if (!field_ty.hasRuntimeBits(zcu)) continue; |
| 391 | const field_ty: Type = .fromInterned(field_ty_ip); | 384 | const natural_align = field_ty.abiAlignment(zcu); |
| 392 | if (!field_ty.hasRuntimeBits(zcu)) continue; | 385 | if (natural_align.compareStrict(.gte, tuple_align)) break false; |
| 393 | const natural_align = field_ty.defaultStructFieldAlignment(.auto, zcu); | 386 | } else true; |
| 394 | if (natural_align.compareStrict(.gte, tuple_align)) break false; | ||
| 395 | } else true, | ||
| 396 | }; | ||
| 397 | 387 | ||
| 398 | if (pack) try w.writeAll("zig_packed("); | ||
| 399 | const name_cty: CType = .{ .@"struct" = ty }; | 388 | const name_cty: CType = .{ .@"struct" = ty }; |
| 400 | try w.print("{f} {{ /* {f} */\n", .{ | 389 | try w.print("{f} {{\n", .{ |
| 401 | name_cty.fmtTypeName(zcu), | 390 | name_cty.fmtTypeName(zcu), |
| 402 | ty.fmt(pt), | ||
| 403 | }); | 391 | }); |
| 404 | var zig_offset: u64 = 0; | 392 | var zig_offset: u64 = 0; |
| 405 | var c_offset: u64 = 0; | 393 | var c_offset: u64 = 0; |
| 406 | for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty_ip, field_val_ip, field_index| { | 394 | for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty_ip, field_val_ip, field_index| { |
| 407 | if (field_val_ip != .none) continue; // `comptime` field | 395 | if (field_val_ip != .none) continue; // `comptime` field |
| 408 | const field_ty: Type = .fromInterned(field_ty_ip); | 396 | const field_ty: Type = .fromInterned(field_ty_ip); |
| 409 | zig_offset = field_ty.abiAlignment(zcu).forward(zig_offset); | 397 | const field_align = field_ty.abiAlignment(zcu); |
| 398 | zig_offset = field_align.forward(zig_offset); | ||
| 410 | if (!field_ty.hasRuntimeBits(zcu)) continue; | 399 | if (!field_ty.hasRuntimeBits(zcu)) continue; |
| 411 | if (!pack) c_offset = field_ty.defaultStructFieldAlignment(.auto, zcu).forward(c_offset); | 400 | c_offset = field_align.forward(c_offset); |
| 412 | try w.writeByte(' '); | 401 | try w.writeByte(' '); |
| 413 | if (zig_offset == 0 and overalign) { | 402 | if (zig_offset == 0 and overalign) { |
| 414 | // This is the first field; specify its alignment to align the tuple. | 403 | // This is the first field; specify its alignment to align the tuple. |
| 415 | try writeFieldAlign(field_ty, tuple_align, w, zcu); | 404 | try writeFieldAlign(field_ty, tuple_align, w, zcu); |
| 416 | } else if (zig_offset > c_offset) { | 405 | } else switch (zig_offset - c_offset) { |
| 417 | // This field needs to be underaligned or overaligned compared to what its | 406 | 0 => {}, |
| 418 | // offset would otherwise be. | 407 | else => |need_bytes| { |
| 419 | const need_align: Alignment = .minStrict( | 408 | // This field needs to be overaligned compared to what its offset would otherwise be. |
| 420 | tuple_align, // don't make the tuple more aligned than it should be | 409 | const need_align: Alignment = .fromLog2Units(std.math.log2_int(u64, need_bytes) + 1); |
| 421 | .fromLog2Units(@ctz(zig_offset)), | 410 | assert(need_align.compareStrict(.lte, tuple_align)); |
| 422 | ); | 411 | try writeFieldAlign(field_ty, need_align, w, zcu); |
| 423 | try writeFieldAlign(field_ty, need_align, w, zcu); | 412 | c_offset = need_align.forward(c_offset); |
| 424 | c_offset = need_align.forward(c_offset); | 413 | }, |
| 425 | } | 414 | } |
| 415 | assert(c_offset == zig_offset); | ||
| 426 | const field_cty: CType = try .lower(field_ty, deps, arena, zcu); | 416 | const field_cty: CType = try .lower(field_ty, deps, arena, zcu); |
| 427 | try w.print("{f}f{d}{f};\n", .{ | 417 | try w.print("{f}f{d}{f};\n", .{ |
| 428 | field_cty.fmtDeclaratorPrefix(zcu), | 418 | field_cty.fmtDeclaratorPrefix(zcu), |
| ... | @@ -433,11 +423,8 @@ fn defineTuple( | ... | @@ -433,11 +423,8 @@ fn defineTuple( |
| 433 | zig_offset += field_size; | 423 | zig_offset += field_size; |
| 434 | c_offset += field_size; | 424 | c_offset += field_size; |
| 435 | } | 425 | } |
| 436 | try w.writeByte('}'); | 426 | try w.writeAll("};"); |
| 437 | if (pack) try w.writeByte(')'); | 427 | return name_cty; |
| 438 | try w.writeAll(";\n"); | ||
| 439 | |||
| 440 | try writeStaticAssertLayout(ty, name_cty, w, zcu); | ||
| 441 | } | 428 | } |
| 442 | fn defineStruct( | 429 | fn defineStruct( |
| 443 | ty: Type, | 430 | ty: Type, |
| ... | @@ -445,9 +432,8 @@ fn defineStruct( | ... | @@ -445,9 +432,8 @@ fn defineStruct( |
| 445 | arena: Allocator, | 432 | arena: Allocator, |
| 446 | w: *Writer, | 433 | w: *Writer, |
| 447 | pt: Zcu.PerThread, | 434 | pt: Zcu.PerThread, |
| 448 | ) (Allocator.Error || Writer.Error)!void { | 435 | ) (Allocator.Error || Writer.Error)!CType { |
| 449 | const zcu = pt.zcu; | 436 | const zcu = pt.zcu; |
| 450 | if (!ty.hasRuntimeBits(zcu)) return; | ||
| 451 | const ip = &zcu.intern_pool; | 437 | const ip = &zcu.intern_pool; |
| 452 | 438 | ||
| 453 | const struct_type = ip.loadStructType(ty.toIntern()); | 439 | const struct_type = ip.loadStructType(ty.toIntern()); |
| ... | @@ -459,7 +445,7 @@ fn defineStruct( | ... | @@ -459,7 +445,7 @@ fn defineStruct( |
| 459 | while (it.next()) |field_index| { | 445 | while (it.next()) |field_index| { |
| 460 | const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[field_index]); | 446 | const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[field_index]); |
| 461 | if (!field_ty.hasRuntimeBits(zcu)) continue; | 447 | if (!field_ty.hasRuntimeBits(zcu)) continue; |
| 462 | const natural_align = field_ty.defaultStructFieldAlignment(struct_type.layout, zcu); | 448 | const natural_align = field_ty.abiAlignment(zcu); |
| 463 | const natural_offset = natural_align.forward(offset); | 449 | const natural_offset = natural_align.forward(offset); |
| 464 | const actual_offset = struct_type.field_offsets.get(ip)[field_index]; | 450 | const actual_offset = struct_type.field_offsets.get(ip)[field_index]; |
| 465 | if (actual_offset < natural_offset) break :pack true; | 451 | if (actual_offset < natural_offset) break :pack true; |
| ... | @@ -480,7 +466,7 @@ fn defineStruct( | ... | @@ -480,7 +466,7 @@ fn defineStruct( |
| 480 | while (it.next()) |field_index| { | 466 | while (it.next()) |field_index| { |
| 481 | const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[field_index]); | 467 | const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[field_index]); |
| 482 | if (!field_ty.hasRuntimeBits(zcu)) continue; | 468 | if (!field_ty.hasRuntimeBits(zcu)) continue; |
| 483 | const natural_align = field_ty.defaultStructFieldAlignment(struct_type.layout, zcu); | 469 | const natural_align = field_ty.abiAlignment(zcu); |
| 484 | if (natural_align.compareStrict(.gte, struct_type.alignment)) break :overalign false; | 470 | if (natural_align.compareStrict(.gte, struct_type.alignment)) break :overalign false; |
| 485 | } | 471 | } |
| 486 | break :overalign true; | 472 | break :overalign true; |
| ... | @@ -489,16 +475,15 @@ fn defineStruct( | ... | @@ -489,16 +475,15 @@ fn defineStruct( |
| 489 | 475 | ||
| 490 | if (pack) try w.writeAll("zig_packed("); | 476 | if (pack) try w.writeAll("zig_packed("); |
| 491 | const name_cty: CType = .{ .@"struct" = ty }; | 477 | const name_cty: CType = .{ .@"struct" = ty }; |
| 492 | try w.print("{f} {{ /* {f} */\n", .{ | 478 | try w.print("{f} {{\n", .{ |
| 493 | name_cty.fmtTypeName(zcu), | 479 | name_cty.fmtTypeName(zcu), |
| 494 | ty.fmt(pt), | ||
| 495 | }); | 480 | }); |
| 496 | var it = struct_type.iterateRuntimeOrder(ip); | 481 | var it = struct_type.iterateRuntimeOrder(ip); |
| 497 | var offset: u64 = 0; | 482 | var offset: u64 = 0; |
| 498 | while (it.next()) |field_index| { | 483 | while (it.next()) |field_index| { |
| 499 | const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[field_index]); | 484 | const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[field_index]); |
| 500 | if (!field_ty.hasRuntimeBits(zcu)) continue; | 485 | if (!field_ty.hasRuntimeBits(zcu)) continue; |
| 501 | const natural_align = field_ty.defaultStructFieldAlignment(struct_type.layout, zcu); | 486 | const natural_align = field_ty.abiAlignment(zcu); |
| 502 | const natural_offset = switch (pack) { | 487 | const natural_offset = switch (pack) { |
| 503 | true => offset, | 488 | true => offset, |
| 504 | false => natural_align.forward(offset), | 489 | false => natural_align.forward(offset), |
| ... | @@ -529,9 +514,8 @@ fn defineStruct( | ... | @@ -529,9 +514,8 @@ fn defineStruct( |
| 529 | assert(struct_type.alignment.forward(offset) == struct_type.size); | 514 | assert(struct_type.alignment.forward(offset) == struct_type.size); |
| 530 | try w.writeByte('}'); | 515 | try w.writeByte('}'); |
| 531 | if (pack) try w.writeByte(')'); | 516 | if (pack) try w.writeByte(')'); |
| 532 | try w.writeAll(";\n"); | 517 | try w.writeByte(';'); |
| 533 | 518 | return name_cty; | |
| 534 | try writeStaticAssertLayout(ty, name_cty, w, zcu); | ||
| 535 | } | 519 | } |
| 536 | fn defineUnionAuto( | 520 | fn defineUnionAuto( |
| 537 | ty: Type, | 521 | ty: Type, |
| ... | @@ -539,9 +523,8 @@ fn defineUnionAuto( | ... | @@ -539,9 +523,8 @@ fn defineUnionAuto( |
| 539 | arena: Allocator, | 523 | arena: Allocator, |
| 540 | w: *Writer, | 524 | w: *Writer, |
| 541 | pt: Zcu.PerThread, | 525 | pt: Zcu.PerThread, |
| 542 | ) (Allocator.Error || Writer.Error)!void { | 526 | ) (Allocator.Error || Writer.Error)!CType { |
| 543 | const zcu = pt.zcu; | 527 | const zcu = pt.zcu; |
| 544 | if (!ty.hasRuntimeBits(zcu)) return; | ||
| 545 | const ip = &zcu.intern_pool; | 528 | const ip = &zcu.intern_pool; |
| 546 | 529 | ||
| 547 | const union_type = ip.loadUnionType(ty.toIntern()); | 530 | const union_type = ip.loadUnionType(ty.toIntern()); |
| ... | @@ -553,7 +536,7 @@ fn defineUnionAuto( | ... | @@ -553,7 +536,7 @@ fn defineUnionAuto( |
| 553 | const pack: bool = for (union_type.field_types.get(ip)) |field_ty_ip| { | 536 | const pack: bool = for (union_type.field_types.get(ip)) |field_ty_ip| { |
| 554 | const field_ty: Type = .fromInterned(field_ty_ip); | 537 | const field_ty: Type = .fromInterned(field_ty_ip); |
| 555 | if (!field_ty.hasRuntimeBits(zcu)) continue; | 538 | if (!field_ty.hasRuntimeBits(zcu)) continue; |
| 556 | const natural_align = field_ty.defaultStructFieldAlignment(.auto, zcu); | 539 | const natural_align = field_ty.abiAlignment(zcu); |
| 557 | if (natural_align.compareStrict(.gt, union_type.alignment)) break true; | 540 | if (natural_align.compareStrict(.gt, union_type.alignment)) break true; |
| 558 | // The tag will immediately follow the payload. This layout may put the tag in what would | 541 | // The tag will immediately follow the payload. This layout may put the tag in what would |
| 559 | // otherwise be padding on the payload union, because if the most-aligned union field is not | 542 | // otherwise be padding on the payload union, because if the most-aligned union field is not |
| ... | @@ -571,7 +554,7 @@ fn defineUnionAuto( | ... | @@ -571,7 +554,7 @@ fn defineUnionAuto( |
| 571 | false => for (union_type.field_types.get(ip)) |field_ty_ip| { | 554 | false => for (union_type.field_types.get(ip)) |field_ty_ip| { |
| 572 | const field_ty: Type = .fromInterned(field_ty_ip); | 555 | const field_ty: Type = .fromInterned(field_ty_ip); |
| 573 | if (!field_ty.hasRuntimeBits(zcu)) continue; | 556 | if (!field_ty.hasRuntimeBits(zcu)) continue; |
| 574 | const natural_align = field_ty.defaultStructFieldAlignment(.auto, zcu); | 557 | const natural_align = field_ty.abiAlignment(zcu); |
| 575 | if (natural_align.compareStrict(.gte, union_type.alignment)) break false; | 558 | if (natural_align.compareStrict(.gte, union_type.alignment)) break false; |
| 576 | } else overalign: { | 559 | } else overalign: { |
| 577 | if (union_type.has_runtime_tag) { | 560 | if (union_type.has_runtime_tag) { |
| ... | @@ -585,9 +568,8 @@ fn defineUnionAuto( | ... | @@ -585,9 +568,8 @@ fn defineUnionAuto( |
| 585 | const payload_has_bits = !union_type.has_runtime_tag or union_type.size > enum_tag_ty.abiSize(zcu); | 568 | const payload_has_bits = !union_type.has_runtime_tag or union_type.size > enum_tag_ty.abiSize(zcu); |
| 586 | 569 | ||
| 587 | const name_cty: CType = .{ .union_auto = ty }; | 570 | const name_cty: CType = .{ .union_auto = ty }; |
| 588 | try w.print("{f} {{ /* {f} */\n", .{ | 571 | try w.print("{f} {{\n", .{ |
| 589 | name_cty.fmtTypeName(zcu), | 572 | name_cty.fmtTypeName(zcu), |
| 590 | ty.fmt(pt), | ||
| 591 | }); | 573 | }); |
| 592 | if (payload_has_bits) { | 574 | if (payload_has_bits) { |
| 593 | try w.writeByte(' '); | 575 | try w.writeByte(' '); |
| ... | @@ -619,9 +601,8 @@ fn defineUnionAuto( | ... | @@ -619,9 +601,8 @@ fn defineUnionAuto( |
| 619 | tag_cty.fmtDeclaratorSuffix(zcu), | 601 | tag_cty.fmtDeclaratorSuffix(zcu), |
| 620 | }); | 602 | }); |
| 621 | } | 603 | } |
| 622 | try w.writeAll("};\n"); | 604 | try w.writeAll("};"); |
| 623 | 605 | return name_cty; | |
| 624 | try writeStaticAssertLayout(ty, name_cty, w, zcu); | ||
| 625 | } | 606 | } |
| 626 | fn defineUnionExtern( | 607 | fn defineUnionExtern( |
| 627 | ty: Type, | 608 | ty: Type, |
| ... | @@ -629,9 +610,8 @@ fn defineUnionExtern( | ... | @@ -629,9 +610,8 @@ fn defineUnionExtern( |
| 629 | arena: Allocator, | 610 | arena: Allocator, |
| 630 | w: *Writer, | 611 | w: *Writer, |
| 631 | pt: Zcu.PerThread, | 612 | pt: Zcu.PerThread, |
| 632 | ) (Allocator.Error || Writer.Error)!void { | 613 | ) (Allocator.Error || Writer.Error)!CType { |
| 633 | const zcu = pt.zcu; | 614 | const zcu = pt.zcu; |
| 634 | if (!ty.hasRuntimeBits(zcu)) return; | ||
| 635 | const ip = &zcu.intern_pool; | 615 | const ip = &zcu.intern_pool; |
| 636 | 616 | ||
| 637 | const union_type = ip.loadUnionType(ty.toIntern()); | 617 | const union_type = ip.loadUnionType(ty.toIntern()); |
| ... | @@ -642,7 +622,7 @@ fn defineUnionExtern( | ... | @@ -642,7 +622,7 @@ fn defineUnionExtern( |
| 642 | const pack: bool = for (union_type.field_types.get(ip)) |field_ty_ip| { | 622 | const pack: bool = for (union_type.field_types.get(ip)) |field_ty_ip| { |
| 643 | const field_ty: Type = .fromInterned(field_ty_ip); | 623 | const field_ty: Type = .fromInterned(field_ty_ip); |
| 644 | if (!field_ty.hasRuntimeBits(zcu)) continue; | 624 | if (!field_ty.hasRuntimeBits(zcu)) continue; |
| 645 | const natural_align = field_ty.defaultStructFieldAlignment(.@"extern", zcu); | 625 | const natural_align = field_ty.abiAlignment(zcu); |
| 646 | if (natural_align.compareStrict(.gt, union_type.alignment)) break true; | 626 | if (natural_align.compareStrict(.gt, union_type.alignment)) break true; |
| 647 | } else false; | 627 | } else false; |
| 648 | 628 | ||
| ... | @@ -654,7 +634,7 @@ fn defineUnionExtern( | ... | @@ -654,7 +634,7 @@ fn defineUnionExtern( |
| 654 | false => for (union_type.field_types.get(ip)) |field_ty_ip| { | 634 | false => for (union_type.field_types.get(ip)) |field_ty_ip| { |
| 655 | const field_ty: Type = .fromInterned(field_ty_ip); | 635 | const field_ty: Type = .fromInterned(field_ty_ip); |
| 656 | if (!field_ty.hasRuntimeBits(zcu)) continue; | 636 | if (!field_ty.hasRuntimeBits(zcu)) continue; |
| 657 | const natural_align = field_ty.defaultStructFieldAlignment(.@"extern", zcu); | 637 | const natural_align = field_ty.abiAlignment(zcu); |
| 658 | if (natural_align.compareStrict(.gte, union_type.alignment)) break false; | 638 | if (natural_align.compareStrict(.gte, union_type.alignment)) break false; |
| 659 | } else overalign: { | 639 | } else overalign: { |
| 660 | if (union_type.has_runtime_tag) { | 640 | if (union_type.has_runtime_tag) { |
| ... | @@ -668,9 +648,8 @@ fn defineUnionExtern( | ... | @@ -668,9 +648,8 @@ fn defineUnionExtern( |
| 668 | if (pack) try w.writeAll("zig_packed("); | 648 | if (pack) try w.writeAll("zig_packed("); |
| 669 | 649 | ||
| 670 | const name_cty: CType = .{ .union_extern = ty }; | 650 | const name_cty: CType = .{ .union_extern = ty }; |
| 671 | try w.print("{f} {{ /* {f} */\n", .{ | 651 | try w.print("{f} {{\n", .{ |
| 672 | name_cty.fmtTypeName(zcu), | 652 | name_cty.fmtTypeName(zcu), |
| 673 | ty.fmt(pt), | ||
| 674 | }); | 653 | }); |
| 675 | 654 | ||
| 676 | for (0..enum_tag_ty.enumFieldCount(zcu)) |field_index| { | 655 | for (0..enum_tag_ty.enumFieldCount(zcu)) |field_index| { |
| ... | @@ -691,9 +670,8 @@ fn defineUnionExtern( | ... | @@ -691,9 +670,8 @@ fn defineUnionExtern( |
| 691 | } | 670 | } |
| 692 | try w.writeByte('}'); | 671 | try w.writeByte('}'); |
| 693 | if (pack) try w.writeByte(')'); | 672 | if (pack) try w.writeByte(')'); |
| 694 | try w.writeAll(";\n"); | 673 | try w.writeByte(';'); |
| 695 | 674 | return name_cty; | |
| 696 | try writeStaticAssertLayout(ty, name_cty, w, zcu); | ||
| 697 | } | 675 | } |
| 698 | 676 | ||
| 699 | /// Writes an annotation which, placed before a struct/union field declaration with field type `ty`, | 677 | /// Writes an annotation which, placed before a struct/union field declaration with field type `ty`, |
| ... | @@ -704,7 +682,7 @@ fn writeFieldAlign( | ... | @@ -704,7 +682,7 @@ fn writeFieldAlign( |
| 704 | w: *Writer, | 682 | w: *Writer, |
| 705 | zcu: *const Zcu, | 683 | zcu: *const Zcu, |
| 706 | ) Writer.Error!void { | 684 | ) Writer.Error!void { |
| 707 | if (alignment.compareStrict(.lt, ty.defaultStructFieldAlignment(.auto, zcu))) { | 685 | if (alignment.compareStrict(.lt, ty.abiAlignment(zcu))) { |
| 708 | try w.print("zig_under_align({d}) ", .{alignment.toByteUnits().?}); | 686 | try w.print("zig_under_align({d}) ", .{alignment.toByteUnits().?}); |
| 709 | } else { | 687 | } else { |
| 710 | try w.print("zig_align({d}) ", .{alignment.toByteUnits().?}); | 688 | try w.print("zig_align({d}) ", .{alignment.toByteUnits().?}); |
| ... | @@ -712,19 +690,29 @@ fn writeFieldAlign( | ... | @@ -712,19 +690,29 @@ fn writeFieldAlign( |
| 712 | } | 690 | } |
| 713 | 691 | ||
| 714 | /// Emits static assertions that the size and alignment of `cty` match those of the Zig type `ty`. | 692 | /// Emits static assertions that the size and alignment of `cty` match those of the Zig type `ty`. |
| 715 | fn writeStaticAssertLayout( | 693 | pub fn writeStaticAssertTypeLayout( |
| 716 | ty: Type, | 694 | ty: Type, |
| 717 | cty: CType, | 695 | cty: CType, |
| 718 | w: *Writer, | 696 | w: *Writer, |
| 719 | zcu: *const Zcu, | 697 | zcu: *const Zcu, |
| 698 | ) Writer.Error!void { | ||
| 699 | try writeStaticAssertCTypeLayout(cty, ty.abiSize(zcu), ty.abiAlignment(zcu), w, zcu); | ||
| 700 | } | ||
| 701 | |||
| 702 | /// Emits static assertions that the size and alignment of `cty` match the provided values. | ||
| 703 | pub fn writeStaticAssertCTypeLayout( | ||
| 704 | cty: CType, | ||
| 705 | expected_size: u64, | ||
| 706 | expected_alignment: Alignment, | ||
| 707 | w: *Writer, | ||
| 708 | zcu: *const Zcu, | ||
| 720 | ) Writer.Error!void { | 709 | ) Writer.Error!void { |
| 721 | try w.print( | 710 | try w.print( |
| 722 | \\zig_static_assert(sizeof ({f}) == {d}, "incorrect size"); | 711 | \\zig_static_assert(sizeof({f}) == {d} && zig_alignOf({f}) == {d}, "abi mismatch"); |
| 723 | \\zig_static_assert(_Alignof ({f}) == {d}, "incorrect alignment"); | ||
| 724 | \\ | 712 | \\ |
| 725 | , .{ | 713 | , .{ |
| 726 | cty.fmtTypeName(zcu), ty.abiSize(zcu), | 714 | cty.fmtTypeName(zcu), expected_size, |
| 727 | cty.fmtTypeName(zcu), ty.abiAlignment(zcu).toByteUnits().?, | 715 | cty.fmtTypeName(zcu), expected_alignment.toByteUnits().?, |
| 728 | }); | 716 | }); |
| 729 | } | 717 | } |
| 730 | 718 |
src/codegen/llvm.zig+722-544| ... | @@ -263,7 +263,7 @@ pub fn targetTriple(allocator: Allocator, target: *const std.Target) ![]const u8 | ... | @@ -263,7 +263,7 @@ pub fn targetTriple(allocator: Allocator, target: *const std.Target) ![]const u8 |
| 263 | => {}, | 263 | => {}, |
| 264 | .semver => |ver| if (target.os.tag == .wasi and ver.min.major == 0) { | 264 | .semver => |ver| if (target.os.tag == .wasi and ver.min.major == 0) { |
| 265 | try llvm_triple.print("p{d}", .{ver.min.minor}); | 265 | try llvm_triple.print("p{d}", .{ver.min.minor}); |
| 266 | } else { | 266 | } else if (target.os.tag != .amdhsa) { |
| 267 | try llvm_triple.print("{d}.{d}.{d}", .{ | 267 | try llvm_triple.print("{d}.{d}.{d}", .{ |
| 268 | ver.min.major, | 268 | ver.min.major, |
| 269 | ver.min.minor, | 269 | ver.min.minor, |
| ... | @@ -345,160 +345,6 @@ pub fn supportsTailCall(target: *const std.Target) bool { | ... | @@ -345,160 +345,6 @@ pub fn supportsTailCall(target: *const std.Target) bool { |
| 345 | }; | 345 | }; |
| 346 | } | 346 | } |
| 347 | 347 | ||
| 348 | pub fn dataLayout(target: *const std.Target) []const u8 { | ||
| 349 | // These data layouts should match Clang. | ||
| 350 | return switch (target.cpu.arch) { | ||
| 351 | .arc => "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-f32:32:32-i64:32-f64:32-a:0:32-n32", | ||
| 352 | .xcore => "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:32-f64:32-a:0:32-n32", | ||
| 353 | .hexagon => "e-m:e-p:32:32:32-a:0-n16:32-i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048", | ||
| 354 | .lanai => "E-m:e-p:32:32-i64:64-a:0:32-n32-S64", | ||
| 355 | .aarch64 => if (target.ofmt == .macho) | ||
| 356 | if (target.os.tag == .windows or target.os.tag == .uefi) | ||
| 357 | "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32" | ||
| 358 | else if (target.abi == .ilp32) | ||
| 359 | "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32" | ||
| 360 | else | ||
| 361 | "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32" | ||
| 362 | else if (target.os.tag == .windows or target.os.tag == .uefi) | ||
| 363 | "e-m:w-p270:32:32-p271:32:32-p272:64:64-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32" | ||
| 364 | else | ||
| 365 | "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32", | ||
| 366 | .aarch64_be => "E-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32", | ||
| 367 | .arm => if (target.ofmt == .macho) | ||
| 368 | "e-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" | ||
| 369 | else | ||
| 370 | "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64", | ||
| 371 | .armeb, .thumbeb => if (target.ofmt == .macho) | ||
| 372 | "E-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" | ||
| 373 | else | ||
| 374 | "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64", | ||
| 375 | .thumb => if (target.ofmt == .macho) | ||
| 376 | "e-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" | ||
| 377 | else if (target.os.tag == .windows or target.os.tag == .uefi) | ||
| 378 | "e-m:w-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" | ||
| 379 | else | ||
| 380 | "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64", | ||
| 381 | .avr => "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8:16-a:8", | ||
| 382 | .bpfeb => "E-m:e-p:64:64-i64:64-i128:128-n32:64-S128", | ||
| 383 | .bpfel => "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128", | ||
| 384 | .msp430 => "e-m:e-p:16:16-i32:16-i64:16-f32:16-f64:16-a:8-n8:16-S16", | ||
| 385 | .mips => "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64", | ||
| 386 | .mipsel => "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64", | ||
| 387 | .mips64 => switch (target.abi) { | ||
| 388 | .gnuabin32, .muslabin32, .abin32 => "E-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128", | ||
| 389 | else => "E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128", | ||
| 390 | }, | ||
| 391 | .mips64el => switch (target.abi) { | ||
| 392 | .gnuabin32, .muslabin32, .abin32 => "e-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128", | ||
| 393 | else => "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128", | ||
| 394 | }, | ||
| 395 | .m68k => "E-m:e-p:32:16:32-i8:8:8-i16:16:16-i32:16:32-n8:16:32-a:0:16-S16", | ||
| 396 | .powerpc => "E-m:e-p:32:32-Fn32-i64:64-n32", | ||
| 397 | .powerpcle => "e-m:e-p:32:32-Fn32-i64:64-n32", | ||
| 398 | .powerpc64 => switch (target.os.tag) { | ||
| 399 | .linux => "E-m:e-Fn32-i64:64-i128:128-n32:64-S128-v256:256:256-v512:512:512", | ||
| 400 | .ps3 => "E-m:e-p:32:32-Fi64-i64:64-i128:128-n32:64", | ||
| 401 | else => "E-m:e-Fn32-i64:64-i128:128-n32:64", | ||
| 402 | }, | ||
| 403 | .powerpc64le => if (target.os.tag == .linux) | ||
| 404 | "e-m:e-Fn32-i64:64-i128:128-n32:64-S128-v256:256:256-v512:512:512" | ||
| 405 | else | ||
| 406 | "e-m:e-Fn32-i64:64-i128:128-n32:64", | ||
| 407 | .nvptx => "e-p:32:32-p6:32:32-p7:32:32-i64:64-i128:128-i256:256-v16:16-v32:32-n16:32:64", | ||
| 408 | .nvptx64 => "e-p6:32:32-i64:64-i128:128-i256:256-v16:16-v32:32-n16:32:64", | ||
| 409 | .amdgcn => "e-m:e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128:128:48-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9", | ||
| 410 | .riscv32 => if (target.cpu.has(.riscv, .e)) | ||
| 411 | "e-m:e-p:32:32-i64:64-n32-S32" | ||
| 412 | else | ||
| 413 | "e-m:e-p:32:32-i64:64-n32-S128", | ||
| 414 | .riscv32be => if (target.cpu.has(.riscv, .e)) | ||
| 415 | "E-m:e-p:32:32-i64:64-n32-S32" | ||
| 416 | else | ||
| 417 | "E-m:e-p:32:32-i64:64-n32-S128", | ||
| 418 | .riscv64 => if (target.cpu.has(.riscv, .e)) | ||
| 419 | "e-m:e-p:64:64-i64:64-i128:128-n32:64-S64" | ||
| 420 | else | ||
| 421 | "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128", | ||
| 422 | .riscv64be => if (target.cpu.has(.riscv, .e)) | ||
| 423 | "E-m:e-p:64:64-i64:64-i128:128-n32:64-S64" | ||
| 424 | else | ||
| 425 | "E-m:e-p:64:64-i64:64-i128:128-n32:64-S128", | ||
| 426 | .sparc => "E-m:e-p:32:32-i64:64-i128:128-f128:64-n32-S64", | ||
| 427 | .sparc64 => "E-m:e-i64:64-i128:128-n32:64-S128", | ||
| 428 | .s390x => "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64", | ||
| 429 | .x86 => if (target.os.tag == .windows or target.os.tag == .uefi) switch (target.abi) { | ||
| 430 | .gnu => if (target.ofmt == .coff) | ||
| 431 | "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:32-n8:16:32-a:0:32-S32" | ||
| 432 | else | ||
| 433 | "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:32-n8:16:32-a:0:32-S32", | ||
| 434 | else => blk: { | ||
| 435 | const msvc = switch (target.abi) { | ||
| 436 | .none, .msvc => true, | ||
| 437 | else => false, | ||
| 438 | }; | ||
| 439 | |||
| 440 | break :blk if (target.ofmt == .coff) | ||
| 441 | if (msvc) | ||
| 442 | "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32-a:0:32-S32" | ||
| 443 | else | ||
| 444 | "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:32-n8:16:32-a:0:32-S32" | ||
| 445 | else if (msvc) | ||
| 446 | "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32-a:0:32-S32" | ||
| 447 | else | ||
| 448 | "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:32-n8:16:32-a:0:32-S32"; | ||
| 449 | }, | ||
| 450 | } else if (target.ofmt == .macho) | ||
| 451 | "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:128-f64:32:64-f80:32-n8:16:32-S128" | ||
| 452 | else | ||
| 453 | "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:128-f64:32:64-f80:32-n8:16:32-S128", | ||
| 454 | .x86_64 => if (target.os.tag.isDarwin() or target.ofmt == .macho) | ||
| 455 | "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" | ||
| 456 | else switch (target.abi) { | ||
| 457 | .gnux32, .muslx32, .x32 => "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", | ||
| 458 | else => if ((target.os.tag == .windows or target.os.tag == .uefi) and target.ofmt == .coff) | ||
| 459 | "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" | ||
| 460 | else | ||
| 461 | "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", | ||
| 462 | }, | ||
| 463 | .spirv32 => switch (target.os.tag) { | ||
| 464 | .vulkan, .opengl => "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1", | ||
| 465 | else => "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1", | ||
| 466 | }, | ||
| 467 | .spirv64 => "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1", | ||
| 468 | .wasm32 => if (target.os.tag == .emscripten) | ||
| 469 | "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-f128:64-n32:64-S128-ni:1:10:20" | ||
| 470 | else | ||
| 471 | "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20", | ||
| 472 | .wasm64 => if (target.os.tag == .emscripten) | ||
| 473 | "e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-i128:128-f128:64-n32:64-S128-ni:1:10:20" | ||
| 474 | else | ||
| 475 | "e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20", | ||
| 476 | .ve => "e-m:e-i64:64-n32:64-S128-v64:64:64-v128:64:64-v256:64:64-v512:64:64-v1024:64:64-v2048:64:64-v4096:64:64-v8192:64:64-v16384:64:64", | ||
| 477 | .csky => "e-m:e-S32-p:32:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:32-v128:32:32-a:0:32-Fi32-n32", | ||
| 478 | .loongarch32 => "e-m:e-p:32:32-i64:64-n32-S128", | ||
| 479 | .loongarch64 => "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128", | ||
| 480 | .xtensa => "e-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-n32", | ||
| 481 | |||
| 482 | .alpha, | ||
| 483 | .arceb, | ||
| 484 | .ez80, | ||
| 485 | .hppa, | ||
| 486 | .hppa64, | ||
| 487 | .kalimba, | ||
| 488 | .kvx, | ||
| 489 | .m88k, | ||
| 490 | .microblaze, | ||
| 491 | .microblazeel, | ||
| 492 | .or1k, | ||
| 493 | .propeller, | ||
| 494 | .sh, | ||
| 495 | .sheb, | ||
| 496 | .x86_16, | ||
| 497 | .xtensaeb, | ||
| 498 | => unreachable, // Gated by hasLlvmSupport(). | ||
| 499 | }; | ||
| 500 | } | ||
| 501 | |||
| 502 | // Avoid depending on `bindings.CodeModel` in the bitcode-only case. | 348 | // Avoid depending on `bindings.CodeModel` in the bitcode-only case. |
| 503 | const CodeModel = enum { | 349 | const CodeModel = enum { |
| 504 | default, | 350 | default, |
| ... | @@ -573,6 +419,8 @@ pub const Object = struct { | ... | @@ -573,6 +419,8 @@ pub const Object = struct { |
| 573 | val: InternPool.Index, | 419 | val: InternPool.Index, |
| 574 | @"addrspace": std.lang.AddressSpace, | 420 | @"addrspace": std.lang.AddressSpace, |
| 575 | }, Builder.Variable.Index), | 421 | }, Builder.Variable.Index), |
| 422 | /// Same as `uav_map` but for llvm values not originating from the frontend. | ||
| 423 | const_map: std.AutoHashMapUnmanaged(Builder.Constant, Builder.Variable.Index), | ||
| 576 | /// Maps enum types to their corresponding LLVM functions for implementing the `tag_name` instruction. | 424 | /// Maps enum types to their corresponding LLVM functions for implementing the `tag_name` instruction. |
| 577 | enum_tag_name_map: std.AutoHashMapUnmanaged(InternPool.Index, Builder.Function.Index), | 425 | enum_tag_name_map: std.AutoHashMapUnmanaged(InternPool.Index, Builder.Function.Index), |
| 578 | /// Serves the same purpose as `enum_tag_name_map` but for the `is_named_enum_value` instruction. | 426 | /// Serves the same purpose as `enum_tag_name_map` but for the `is_named_enum_value` instruction. |
| ... | @@ -616,8 +464,6 @@ pub const Object = struct { | ... | @@ -616,8 +464,6 @@ pub const Object = struct { |
| 616 | }); | 464 | }); |
| 617 | errdefer builder.deinit(); | 465 | errdefer builder.deinit(); |
| 618 | 466 | ||
| 619 | builder.data_layout = try builder.string(dataLayout(target)); | ||
| 620 | |||
| 621 | const debug_compile_unit, const debug_enums_fwd_ref, const debug_globals_fwd_ref = | 467 | const debug_compile_unit, const debug_enums_fwd_ref, const debug_globals_fwd_ref = |
| 622 | if (!builder.strip) debug_info: { | 468 | if (!builder.strip) debug_info: { |
| 623 | // We fully resolve all paths at this point to avoid lack of | 469 | // We fully resolve all paths at this point to avoid lack of |
| ... | @@ -653,7 +499,7 @@ pub const Object = struct { | ... | @@ -653,7 +499,7 @@ pub const Object = struct { |
| 653 | }), | 499 | }), |
| 654 | debug_enums_fwd_ref, | 500 | debug_enums_fwd_ref, |
| 655 | debug_globals_fwd_ref, | 501 | debug_globals_fwd_ref, |
| 656 | .{ .optimized = comp.root_mod.optimize_mode != .Debug }, | 502 | .{ .optimized = comp.root_mod.optimize_mode != .debug }, |
| 657 | ); | 503 | ); |
| 658 | 504 | ||
| 659 | try builder.addNamedMetadata(try builder.string("llvm.dbg.cu"), &.{debug_compile_unit}); | 505 | try builder.addNamedMetadata(try builder.string("llvm.dbg.cu"), &.{debug_compile_unit}); |
| ... | @@ -693,6 +539,7 @@ pub const Object = struct { | ... | @@ -693,6 +539,7 @@ pub const Object = struct { |
| 693 | .zcu = zcu, | 539 | .zcu = zcu, |
| 694 | .nav_map = .empty, | 540 | .nav_map = .empty, |
| 695 | .uav_map = .empty, | 541 | .uav_map = .empty, |
| 542 | .const_map = .empty, | ||
| 696 | .enum_tag_name_map = .empty, | 543 | .enum_tag_name_map = .empty, |
| 697 | .named_enum_map = .empty, | 544 | .named_enum_map = .empty, |
| 698 | .type_map = .empty, | 545 | .type_map = .empty, |
| ... | @@ -703,21 +550,22 @@ pub const Object = struct { | ... | @@ -703,21 +550,22 @@ pub const Object = struct { |
| 703 | return obj; | 550 | return obj; |
| 704 | } | 551 | } |
| 705 | 552 | ||
| 706 | pub fn deinit(self: *Object) void { | 553 | pub fn deinit(o: *Object) void { |
| 707 | const gpa = self.gpa; | 554 | const gpa = o.gpa; |
| 708 | self.type_pool.deinit(gpa); | 555 | o.type_pool.deinit(gpa); |
| 709 | self.lazy_abi_aligns.deinit(gpa); | 556 | o.lazy_abi_aligns.deinit(gpa); |
| 710 | self.debug_enums.deinit(gpa); | 557 | o.debug_enums.deinit(gpa); |
| 711 | self.debug_globals.deinit(gpa); | 558 | o.debug_globals.deinit(gpa); |
| 712 | self.debug_file_map.deinit(gpa); | 559 | o.debug_file_map.deinit(gpa); |
| 713 | self.debug_types.deinit(gpa); | 560 | o.debug_types.deinit(gpa); |
| 714 | self.nav_map.deinit(gpa); | 561 | o.nav_map.deinit(gpa); |
| 715 | self.uav_map.deinit(gpa); | 562 | o.uav_map.deinit(gpa); |
| 716 | self.enum_tag_name_map.deinit(gpa); | 563 | o.const_map.deinit(gpa); |
| 717 | self.named_enum_map.deinit(gpa); | 564 | o.enum_tag_name_map.deinit(gpa); |
| 718 | self.type_map.deinit(gpa); | 565 | o.named_enum_map.deinit(gpa); |
| 719 | self.builder.deinit(); | 566 | o.type_map.deinit(gpa); |
| 720 | self.* = undefined; | 567 | o.builder.deinit(); |
| 568 | o.* = undefined; | ||
| 721 | } | 569 | } |
| 722 | 570 | ||
| 723 | fn genErrorNameTable(o: *Object) Allocator.Error!void { | 571 | fn genErrorNameTable(o: *Object) Allocator.Error!void { |
| ... | @@ -741,16 +589,16 @@ pub const Object = struct { | ... | @@ -741,16 +589,16 @@ pub const Object = struct { |
| 741 | for (llvm_errors[1..], error_name_list) |*llvm_error, name| { | 589 | for (llvm_errors[1..], error_name_list) |*llvm_error, name| { |
| 742 | const name_string = try o.builder.stringNull(name.toSlice(ip)); | 590 | const name_string = try o.builder.stringNull(name.toSlice(ip)); |
| 743 | const name_init = try o.builder.stringConst(name_string); | 591 | const name_init = try o.builder.stringConst(name_string); |
| 744 | const name_variable_index = try o.builder.addVariable(.empty, name_init.typeOf(&o.builder), .default); | 592 | const name_llvm_variable = try o.builder.addVariable(.empty, name_init.typeOf(&o.builder), .default); |
| 745 | try name_variable_index.setInitializer(name_init, &o.builder); | 593 | try name_llvm_variable.setInitializer(name_init, &o.builder); |
| 746 | name_variable_index.setMutability(.constant, &o.builder); | 594 | name_llvm_variable.setMutability(.constant, &o.builder); |
| 747 | name_variable_index.setAlignment(comptime .fromByteUnits(1), &o.builder); | 595 | name_llvm_variable.setAlignment(comptime .fromByteUnits(1), &o.builder); |
| 748 | const global_index = name_variable_index.ptrConst(&o.builder).global; | 596 | const llvm_global = name_llvm_variable.ptrConst(&o.builder).global; |
| 749 | global_index.setLinkage(.private, &o.builder); | 597 | llvm_global.setLinkage(.private, &o.builder); |
| 750 | global_index.setUnnamedAddr(.unnamed_addr, &o.builder); | 598 | llvm_global.setUnnamedAddr(.unnamed_addr, &o.builder); |
| 751 | 599 | ||
| 752 | llvm_error.* = try o.builder.structConst(llvm_slice_ty, &.{ | 600 | llvm_error.* = try o.builder.structConst(llvm_slice_ty, &.{ |
| 753 | name_variable_index.toConst(&o.builder), | 601 | name_llvm_variable.toConst(&o.builder), |
| 754 | try o.builder.intConst(llvm_usize_ty, name_string.slice(&o.builder).?.len - 1), | 602 | try o.builder.intConst(llvm_usize_ty, name_string.slice(&o.builder).?.len - 1), |
| 755 | }); | 603 | }); |
| 756 | } | 604 | } |
| ... | @@ -770,7 +618,7 @@ pub const Object = struct { | ... | @@ -770,7 +618,7 @@ pub const Object = struct { |
| 770 | b.module_asm.appendSliceAssumeCapacity(assembly); | 618 | b.module_asm.appendSliceAssumeCapacity(assembly); |
| 771 | b.module_asm.appendAssumeCapacity('\n'); | 619 | b.module_asm.appendAssumeCapacity('\n'); |
| 772 | } | 620 | } |
| 773 | if (b.module_asm.getLast()) |last| { | 621 | if (b.module_asm.last()) |last| { |
| 774 | if (last != '\n') try b.module_asm.append(gpa, '\n'); | 622 | if (last != '\n') try b.module_asm.append(gpa, '\n'); |
| 775 | } | 623 | } |
| 776 | } | 624 | } |
| ... | @@ -1028,7 +876,7 @@ pub const Object = struct { | ... | @@ -1028,7 +876,7 @@ pub const Object = struct { |
| 1028 | 876 | ||
| 1029 | const optimize_mode = comp.root_mod.optimize_mode; | 877 | const optimize_mode = comp.root_mod.optimize_mode; |
| 1030 | 878 | ||
| 1031 | const opt_level: bindings.CodeGenOptLevel = if (optimize_mode == .Debug) | 879 | const opt_level: bindings.CodeGenOptLevel = if (optimize_mode == .debug) |
| 1032 | .None | 880 | .None |
| 1033 | else | 881 | else |
| 1034 | .Aggressive; | 882 | .Aggressive; |
| ... | @@ -1199,19 +1047,33 @@ pub const Object = struct { | ... | @@ -1199,19 +1047,33 @@ pub const Object = struct { |
| 1199 | global.dll_storage_class = .default; | 1047 | global.dll_storage_class = .default; |
| 1200 | global.unnamed_addr = .unnamed_addr; | 1048 | global.unnamed_addr = .unnamed_addr; |
| 1201 | } | 1049 | } |
| 1202 | llvm_function.setAlignment(switch (nav.resolved.?.@"align") { | 1050 | llvm_function.setAlignment(nav.resolved.?.@"align".toLlvm(), &o.builder); |
| 1203 | .none => fn_ty.abiAlignment(zcu).toLlvm(), | ||
| 1204 | else => |a| a.toLlvm(), | ||
| 1205 | }, &o.builder); | ||
| 1206 | llvm_function.setSection(s: { | 1051 | llvm_function.setSection(s: { |
| 1207 | const section = nav.resolved.?.@"linksection".toSlice(ip) orelse break :s .none; | 1052 | const section = nav.resolved.?.@"linksection".toSlice(ip) orelse break :s .none; |
| 1208 | break :s try o.builder.string(section); | 1053 | break :s try o.builder.string(section); |
| 1209 | }, &o.builder); | 1054 | }, &o.builder); |
| 1210 | try o.addLlvmFunctionAttributes(pt, func.owner_nav, llvm_function); | ||
| 1211 | 1055 | ||
| 1212 | var attributes = try llvm_function.ptrConst(&o.builder).attributes.toWip(&o.builder); | 1056 | var attributes: Builder.FunctionAttributes.Wip = .{}; |
| 1213 | defer attributes.deinit(&o.builder); | 1057 | defer attributes.deinit(&o.builder); |
| 1214 | 1058 | ||
| 1059 | // Function attributes that are independent of analysis results of the function body. | ||
| 1060 | try o.addCommonFnAttributes( | ||
| 1061 | &attributes, | ||
| 1062 | owner_mod, | ||
| 1063 | // Some backends don't respect the `naked` attribute in `TargetFrameLowering::hasFP()`, | ||
| 1064 | // so for these backends, LLVM will happily emit code that accesses the stack through | ||
| 1065 | // the frame pointer. This is nonsensical since what the `naked` attribute does is | ||
| 1066 | // suppress generation of the prologue and epilogue, and the prologue is where the | ||
| 1067 | // frame pointer normally gets set up. At time of writing, this is the case for at | ||
| 1068 | // least x86 and RISC-V. | ||
| 1069 | owner_mod.omit_frame_pointer or fn_info.cc == .naked, | ||
| 1070 | ); | ||
| 1071 | |||
| 1072 | try o.addCallingConventionFnAttributes(pt, llvm_function, &attributes, if (nav.getExtern(ip)) |@"extern"| .{ | ||
| 1073 | .name = nav.name.toSlice(ip), | ||
| 1074 | .lib_name = @"extern".lib_name.toSlice(ip), | ||
| 1075 | } else null, .fromIntern(fn_info, ip)); | ||
| 1076 | |||
| 1215 | const func_analysis = func.analysisUnordered(ip); | 1077 | const func_analysis = func.analysisUnordered(ip); |
| 1216 | if (func_analysis.is_noinline) { | 1078 | if (func_analysis.is_noinline) { |
| 1217 | try attributes.addFnAttr(.@"noinline", &o.builder); | 1079 | try attributes.addFnAttr(.@"noinline", &o.builder); |
| ... | @@ -1299,7 +1161,7 @@ pub const Object = struct { | ... | @@ -1299,7 +1161,7 @@ pub const Object = struct { |
| 1299 | .NoReturn = fn_info.return_type == .noreturn_type, | 1161 | .NoReturn = fn_info.return_type == .noreturn_type, |
| 1300 | }, | 1162 | }, |
| 1301 | .sp_flags = .{ | 1163 | .sp_flags = .{ |
| 1302 | .Optimized = owner_mod.optimize_mode != .Debug, | 1164 | .Optimized = owner_mod.optimize_mode != .debug, |
| 1303 | .Definition = true, | 1165 | .Definition = true, |
| 1304 | .LocalToUnit = is_internal_linkage, | 1166 | .LocalToUnit = is_internal_linkage, |
| 1305 | }, | 1167 | }, |
| ... | @@ -1324,7 +1186,7 @@ pub const Object = struct { | ... | @@ -1324,7 +1186,7 @@ pub const Object = struct { |
| 1324 | const counters_variable = try o.builder.addVariable(anon_name, .void, .default); | 1186 | const counters_variable = try o.builder.addVariable(anon_name, .void, .default); |
| 1325 | try o.used.append(gpa, counters_variable.toConst(&o.builder)); | 1187 | try o.used.append(gpa, counters_variable.toConst(&o.builder)); |
| 1326 | counters_variable.ptrConst(&o.builder).global.setLinkage(.private, &o.builder); | 1188 | counters_variable.ptrConst(&o.builder).global.setLinkage(.private, &o.builder); |
| 1327 | counters_variable.setAlignment(comptime Builder.Alignment.fromByteUnits(1), &o.builder); | 1189 | counters_variable.setAlignment(comptime .fromByteUnits(1), &o.builder); |
| 1328 | 1190 | ||
| 1329 | if (target.ofmt == .macho) { | 1191 | if (target.ofmt == .macho) { |
| 1330 | counters_variable.setSection(try o.builder.string("__DATA,__sancov_cntrs"), &o.builder); | 1192 | counters_variable.setSection(try o.builder.string("__DATA,__sancov_cntrs"), &o.builder); |
| ... | @@ -1507,10 +1369,6 @@ pub const Object = struct { | ... | @@ -1507,10 +1369,6 @@ pub const Object = struct { |
| 1507 | llvm_global.ptr(&o.builder).unnamed_addr = .unnamed_addr; | 1369 | llvm_global.ptr(&o.builder).unnamed_addr = .unnamed_addr; |
| 1508 | } | 1370 | } |
| 1509 | 1371 | ||
| 1510 | const llvm_align = switch (resolved.@"align") { | ||
| 1511 | .none => nav_ty.abiAlignment(zcu).toLlvm(), | ||
| 1512 | else => |a| a.toLlvm(), | ||
| 1513 | }; | ||
| 1514 | const llvm_section: Builder.String = if (resolved.@"linksection".toSlice(ip)) |section| s: { | 1372 | const llvm_section: Builder.String = if (resolved.@"linksection".toSlice(ip)) |section| s: { |
| 1515 | break :s try o.builder.string(section); | 1373 | break :s try o.builder.string(section); |
| 1516 | } else .none; | 1374 | } else .none; |
| ... | @@ -1519,13 +1377,20 @@ pub const Object = struct { | ... | @@ -1519,13 +1377,20 @@ pub const Object = struct { |
| 1519 | // can see are extern functions or other comptime function body values (e.g. undefined). Of | 1377 | // can see are extern functions or other comptime function body values (e.g. undefined). Of |
| 1520 | // these, only extern functions need to be lowered to LLVM functions. | 1378 | // these, only extern functions need to be lowered to LLVM functions. |
| 1521 | if (opt_extern != null and nav_ty.zigTypeTag(zcu) == .@"fn" and nav_ty.fnHasRuntimeBits(zcu)) { | 1379 | if (opt_extern != null and nav_ty.zigTypeTag(zcu) == .@"fn" and nav_ty.fnHasRuntimeBits(zcu)) { |
| 1380 | const fn_info = zcu.typeToFunc(nav_ty).?; | ||
| 1522 | const llvm_function: Builder.Function.Index = switch (llvm_global.ptrConst(&o.builder).kind) { | 1381 | const llvm_function: Builder.Function.Index = switch (llvm_global.ptrConst(&o.builder).kind) { |
| 1523 | .function => |function| function, // re-use existing `Builder.Function` | 1382 | .function => |function| function, // re-use existing `Builder.Function` |
| 1524 | .replaced, .alias, .variable => try llvm_global.toNewFunction(&o.builder), | 1383 | .replaced, .alias, .variable => try llvm_global.toNewFunction(&o.builder), |
| 1525 | }; | 1384 | }; |
| 1526 | llvm_function.setAlignment(llvm_align, &o.builder); | 1385 | llvm_function.setAlignment(resolved.@"align".toLlvm(), &o.builder); |
| 1527 | llvm_function.setSection(llvm_section, &o.builder); | 1386 | llvm_function.setSection(llvm_section, &o.builder); |
| 1528 | try o.addLlvmFunctionAttributes(pt, nav_id, llvm_function); | 1387 | var attributes: Builder.FunctionAttributes.Wip = .{}; |
| 1388 | defer attributes.deinit(&o.builder); | ||
| 1389 | try o.addCallingConventionFnAttributes(pt, llvm_function, &attributes, .{ | ||
| 1390 | .name = nav.name.toSlice(ip), | ||
| 1391 | .lib_name = opt_extern.?.lib_name.toSlice(ip), | ||
| 1392 | }, .fromIntern(fn_info, ip)); | ||
| 1393 | llvm_function.setAttributes(try attributes.finish(&o.builder), &o.builder); | ||
| 1529 | } else { | 1394 | } else { |
| 1530 | const file_scope = nav.srcInst(ip).resolveFile(ip); | 1395 | const file_scope = nav.srcInst(ip).resolveFile(ip); |
| 1531 | const mod = zcu.fileByIndex(file_scope).mod.?; | 1396 | const mod = zcu.fileByIndex(file_scope).mod.?; |
| ... | @@ -1534,7 +1399,10 @@ pub const Object = struct { | ... | @@ -1534,7 +1399,10 @@ pub const Object = struct { |
| 1534 | .variable => |variable| variable, // re-use existing `Builder.Variable` | 1399 | .variable => |variable| variable, // re-use existing `Builder.Variable` |
| 1535 | .replaced, .alias, .function => try llvm_global.toNewVariable(&o.builder), | 1400 | .replaced, .alias, .function => try llvm_global.toNewVariable(&o.builder), |
| 1536 | }; | 1401 | }; |
| 1537 | llvm_variable.setAlignment(llvm_align, &o.builder); | 1402 | llvm_variable.setAlignment(switch (resolved.@"align") { |
| 1403 | .none => nav_ty.abiAlignment(zcu).toLlvm(), | ||
| 1404 | else => |a| a.toLlvm(), | ||
| 1405 | }, &o.builder); | ||
| 1538 | llvm_variable.setSection(llvm_section, &o.builder); | 1406 | llvm_variable.setSection(llvm_section, &o.builder); |
| 1539 | llvm_variable.setMutability(if (resolved.@"const") .constant else .global, &o.builder); | 1407 | llvm_variable.setMutability(if (resolved.@"const") .constant else .global, &o.builder); |
| 1540 | try llvm_variable.setInitializer(if (opt_extern != null) .no_init else try o.lowerValue(resolved.value, .in_memory), &o.builder); | 1408 | try llvm_variable.setInitializer(if (opt_extern != null) .no_init else try o.lowerValue(resolved.value, .in_memory), &o.builder); |
| ... | @@ -1585,7 +1453,7 @@ pub const Object = struct { | ... | @@ -1585,7 +1453,7 @@ pub const Object = struct { |
| 1585 | const uav_ty = Value.fromInterned(uav).typeOf(zcu); | 1453 | const uav_ty = Value.fromInterned(uav).typeOf(zcu); |
| 1586 | const uav_ref = try o.lowerUavRef( | 1454 | const uav_ref = try o.lowerUavRef( |
| 1587 | uav, | 1455 | uav, |
| 1588 | uav_ty.abiAlignment(zcu), | 1456 | uav_ty.abiAlignment(zcu).toLlvm(), |
| 1589 | target_util.defaultAddressSpace(zcu.getTarget(), .global_constant), | 1457 | target_util.defaultAddressSpace(zcu.getTarget(), .global_constant), |
| 1590 | ); | 1458 | ); |
| 1591 | break :exp .{ uav_ty, uav_ref }; | 1459 | break :exp .{ uav_ty, uav_ref }; |
| ... | @@ -1599,7 +1467,7 @@ pub const Object = struct { | ... | @@ -1599,7 +1467,7 @@ pub const Object = struct { |
| 1599 | 1467 | ||
| 1600 | fn updateExportedGlobal( | 1468 | fn updateExportedGlobal( |
| 1601 | o: *Object, | 1469 | o: *Object, |
| 1602 | global_index: Builder.Global.Index, | 1470 | llvm_global: Builder.Global.Index, |
| 1603 | ty: Type, | 1471 | ty: Type, |
| 1604 | export_indices: []const Zcu.Export.Index, | 1472 | export_indices: []const Zcu.Export.Index, |
| 1605 | ) link.Error!void { | 1473 | ) link.Error!void { |
| ... | @@ -1634,18 +1502,21 @@ pub const Object = struct { | ... | @@ -1634,18 +1502,21 @@ pub const Object = struct { |
| 1634 | // make much sense: the linksection should be associated with the declaration itself rather | 1502 | // make much sense: the linksection should be associated with the declaration itself rather |
| 1635 | // than some particular symbol it is exported as! | 1503 | // than some particular symbol it is exported as! |
| 1636 | if (export_indices[0].ptr(zcu).opts.section.toSlice(ip)) |section_slice| { | 1504 | if (export_indices[0].ptr(zcu).opts.section.toSlice(ip)) |section_slice| { |
| 1637 | const variable = &global_index.ptrConst(&o.builder).kind.variable; | 1505 | const variable = &llvm_global.ptrConst(&o.builder).kind.variable; |
| 1638 | variable.setSection(try o.builder.string(section_slice), &o.builder); | 1506 | variable.setSection(try o.builder.string(section_slice), &o.builder); |
| 1639 | } | 1507 | } |
| 1640 | 1508 | ||
| 1641 | const llvm_global_ty = global_index.typeOf(&o.builder); | 1509 | const arch = comp.root_mod.resolved_target.result.cpu.arch; |
| 1510 | const workaround_alias_bugs = arch == .amdgcn or arch == .nvptx or arch == .nvptx64; | ||
| 1511 | |||
| 1512 | const llvm_global_ty = llvm_global.typeOf(&o.builder); | ||
| 1642 | 1513 | ||
| 1643 | // All exports are represented as aliases to the original global. | 1514 | // All exports are represented as aliases to the original global. |
| 1644 | 1515 | ||
| 1645 | // TODO: we currently do not delete old exports. To do that we'll need to track which | 1516 | // TODO: we currently do not delete old exports. To do that we'll need to track which |
| 1646 | // globals actually *are* exports. | 1517 | // globals actually *are* exports. |
| 1647 | 1518 | ||
| 1648 | for (export_indices) |export_idx| { | 1519 | for (export_indices, 0..) |export_idx, export_i| { |
| 1649 | const exp = export_idx.ptr(zcu); | 1520 | const exp = export_idx.ptr(zcu); |
| 1650 | const exp_name = try o.builder.strtabString(exp.opts.name.toSlice(ip)); | 1521 | const exp_name = try o.builder.strtabString(exp.opts.name.toSlice(ip)); |
| 1651 | 1522 | ||
| ... | @@ -1656,13 +1527,23 @@ pub const Object = struct { | ... | @@ -1656,13 +1527,23 @@ pub const Object = struct { |
| 1656 | // The name, aliasee, and type will be set within this block. Other properties of the | 1527 | // The name, aliasee, and type will be set within this block. Other properties of the |
| 1657 | // alias will be set below. | 1528 | // alias will be set below. |
| 1658 | const alias_global: Builder.Global.Index = global: { | 1529 | const alias_global: Builder.Global.Index = global: { |
| 1530 | |||
| 1531 | // WORKAROUND (see https://github.com/llvm/llvm-project/issues/213504, https://github.com/llvm/llvm-project/issues/214835) | ||
| 1532 | // For NVPTX, LLVM throws "NVPTX aliasee must be a non-kernel function definition" if we try to alias a kernel | ||
| 1533 | // On AMDGCN, LLVM does not generate an alias for the kernel descriptor symbol on associated functions | ||
| 1534 | // To solve these, we rename the global | ||
| 1535 | if (workaround_alias_bugs and export_i == 0) { | ||
| 1536 | try llvm_global.rename(exp_name, &o.builder); | ||
| 1537 | break :global llvm_global; | ||
| 1538 | } | ||
| 1539 | |||
| 1659 | const existing_global = o.builder.getGlobal(exp_name) orelse { | 1540 | const existing_global = o.builder.getGlobal(exp_name) orelse { |
| 1660 | // There is no existing global with this name, so make a new alias. | 1541 | // There is no existing global with this name, so make a new alias. |
| 1661 | const alias = try o.builder.addAlias( | 1542 | const alias = try o.builder.addAlias( |
| 1662 | exp_name, | 1543 | exp_name, |
| 1663 | llvm_global_ty, | 1544 | llvm_global_ty, |
| 1664 | .default, | 1545 | llvm_global.ptrConst(&o.builder).addr_space, |
| 1665 | global_index.toConst(), | 1546 | llvm_global.toConst(), |
| 1666 | ); | 1547 | ); |
| 1667 | break :global alias.ptrConst(&o.builder).global; | 1548 | break :global alias.ptrConst(&o.builder).global; |
| 1668 | }; | 1549 | }; |
| ... | @@ -1671,8 +1552,9 @@ pub const Object = struct { | ... | @@ -1671,8 +1552,9 @@ pub const Object = struct { |
| 1671 | switch (existing_global.ptrConst(&o.builder).kind) { | 1552 | switch (existing_global.ptrConst(&o.builder).kind) { |
| 1672 | .alias => |alias| { | 1553 | .alias => |alias| { |
| 1673 | // We can just repurpose the existing alias. | 1554 | // We can just repurpose the existing alias. |
| 1674 | alias.setAliasee(global_index.toConst(), &o.builder); | 1555 | alias.setAliasee(llvm_global.toConst(), &o.builder); |
| 1675 | alias.ptrConst(&o.builder).global.ptr(&o.builder).type = global_index.typeOf(&o.builder); | 1556 | alias.ptrConst(&o.builder).global.ptr(&o.builder).type = llvm_global.typeOf(&o.builder); |
| 1557 | alias.ptrConst(&o.builder).global.ptr(&o.builder).addr_space = llvm_global.ptrConst(&o.builder).addr_space; | ||
| 1676 | break :global existing_global; | 1558 | break :global existing_global; |
| 1677 | }, | 1559 | }, |
| 1678 | .variable, .function => { | 1560 | .variable, .function => { |
| ... | @@ -1682,13 +1564,13 @@ pub const Object = struct { | ... | @@ -1682,13 +1564,13 @@ pub const Object = struct { |
| 1682 | // We need to make a new global which is an alias. Replace this existing one | 1564 | // We need to make a new global which is an alias. Replace this existing one |
| 1683 | // with the target global, making the name available and fixing references | 1565 | // with the target global, making the name available and fixing references |
| 1684 | // to this global to point to the target. | 1566 | // to this global to point to the target. |
| 1685 | try existing_global.replace(global_index, &o.builder); | 1567 | try existing_global.replace(llvm_global, &o.builder); |
| 1686 | // The name is now free, so create an alias. | 1568 | // The name is now free, so create an alias. |
| 1687 | const alias = try o.builder.addAlias( | 1569 | const alias = try o.builder.addAlias( |
| 1688 | exp_name, | 1570 | exp_name, |
| 1689 | llvm_global_ty, | 1571 | llvm_global_ty, |
| 1690 | .default, | 1572 | llvm_global.ptrConst(&o.builder).addr_space, |
| 1691 | global_index.toConst(), | 1573 | llvm_global.toConst(), |
| 1692 | ); | 1574 | ); |
| 1693 | break :global alias.ptrConst(&o.builder).global; | 1575 | break :global alias.ptrConst(&o.builder).global; |
| 1694 | }, | 1576 | }, |
| ... | @@ -1721,11 +1603,11 @@ pub const Object = struct { | ... | @@ -1721,11 +1603,11 @@ pub const Object = struct { |
| 1721 | pub fn updateContainerType(o: *Object, pt: Zcu.PerThread, ty: InternPool.Index, success: bool) Allocator.Error!void { | 1603 | pub fn updateContainerType(o: *Object, pt: Zcu.PerThread, ty: InternPool.Index, success: bool) Allocator.Error!void { |
| 1722 | _ = o.type_map.remove(ty); | 1604 | _ = o.type_map.remove(ty); |
| 1723 | try o.type_pool.updateContainerType(pt, .{ .llvm = o }, ty, success); | 1605 | try o.type_pool.updateContainerType(pt, .{ .llvm = o }, ty, success); |
| 1724 | if (o.named_enum_map.get(ty)) |function_index| { | 1606 | if (o.named_enum_map.get(ty)) |llvm_function| { |
| 1725 | try o.updateIsNamedEnumValueFunction(.fromInterned(ty), function_index); | 1607 | try o.updateIsNamedEnumValueFunction(.fromInterned(ty), llvm_function); |
| 1726 | } | 1608 | } |
| 1727 | if (o.enum_tag_name_map.get(ty)) |function_index| { | 1609 | if (o.enum_tag_name_map.get(ty)) |llvm_function| { |
| 1728 | try o.updateEnumTagNameFunction(.fromInterned(ty), function_index); | 1610 | try o.updateEnumTagNameFunction(.fromInterned(ty), llvm_function); |
| 1729 | } | 1611 | } |
| 1730 | } | 1612 | } |
| 1731 | 1613 | ||
| ... | @@ -2098,7 +1980,7 @@ pub const Object = struct { | ... | @@ -2098,7 +1980,7 @@ pub const Object = struct { |
| 2098 | payload_offset * 8, | 1980 | payload_offset * 8, |
| 2099 | ); | 1981 | ); |
| 2100 | 1982 | ||
| 2101 | return try o.builder.debugStructType( | 1983 | return o.builder.debugStructType( |
| 2102 | name, | 1984 | name, |
| 2103 | null, // File | 1985 | null, // File |
| 2104 | o.debug_compile_unit.unwrap().?, // Scope | 1986 | o.debug_compile_unit.unwrap().?, // Scope |
| ... | @@ -2136,7 +2018,7 @@ pub const Object = struct { | ... | @@ -2136,7 +2018,7 @@ pub const Object = struct { |
| 2136 | defer debug_param_types.deinit(gpa); | 2018 | defer debug_param_types.deinit(gpa); |
| 2137 | 2019 | ||
| 2138 | // Return type goes first. | 2020 | // Return type goes first. |
| 2139 | if (try fnReturnStrat(o, fn_info) == .sret) { | 2021 | if (try fnReturnStrat(o, fn_info.cc, .fromInterned(fn_info.return_type)) == .sret) { |
| 2140 | // Actual return type is void, then first arg is the sret pointer. | 2022 | // Actual return type is void, then first arg is the sret pointer. |
| 2141 | const ptr_ty = try pt.singleMutPtrType(.fromInterned(fn_info.return_type)); | 2023 | const ptr_ty = try pt.singleMutPtrType(.fromInterned(fn_info.return_type)); |
| 2142 | debug_param_types.appendAssumeCapacity(try o.getDebugType(pt, .void)); | 2024 | debug_param_types.appendAssumeCapacity(try o.getDebugType(pt, .void)); |
| ... | @@ -2571,53 +2453,117 @@ pub const Object = struct { | ... | @@ -2571,53 +2453,117 @@ pub const Object = struct { |
| 2571 | fn namespaceToDebugScope(o: *Object, pt: Zcu.PerThread, namespace_index: InternPool.NamespaceIndex) !Builder.Metadata { | 2453 | fn namespaceToDebugScope(o: *Object, pt: Zcu.PerThread, namespace_index: InternPool.NamespaceIndex) !Builder.Metadata { |
| 2572 | const zcu = o.zcu; | 2454 | const zcu = o.zcu; |
| 2573 | const namespace = zcu.namespacePtr(namespace_index); | 2455 | const namespace = zcu.namespacePtr(namespace_index); |
| 2574 | if (namespace.parent == .none) return try o.getDebugFile(namespace.file_scope); | 2456 | if (namespace.parent == .none) return o.getDebugFile(namespace.file_scope); |
| 2575 | return o.getDebugType(pt, .fromInterned(namespace.owner_type)); | 2457 | return o.getDebugType(pt, .fromInterned(namespace.owner_type)); |
| 2576 | } | 2458 | } |
| 2577 | 2459 | ||
| 2578 | /// Sets the attributes and callconv of the given `Builder.Function`, which corresponds to the | 2460 | fn addCommonFnAttributes( |
| 2579 | /// given `Nav` (which is a function). | 2461 | o: *Object, |
| 2580 | fn addLlvmFunctionAttributes( | 2462 | attributes: *Builder.FunctionAttributes.Wip, |
| 2463 | owner_mod: *Module, | ||
| 2464 | omit_frame_pointer: bool, | ||
| 2465 | ) Allocator.Error!void { | ||
| 2466 | if (!owner_mod.red_zone) { | ||
| 2467 | try attributes.addFnAttr(.noredzone, &o.builder); | ||
| 2468 | } | ||
| 2469 | if (omit_frame_pointer) { | ||
| 2470 | try attributes.addFnAttr(.{ .string = .{ | ||
| 2471 | .kind = try o.builder.string("frame-pointer"), | ||
| 2472 | .value = try o.builder.string("none"), | ||
| 2473 | } }, &o.builder); | ||
| 2474 | } else { | ||
| 2475 | try attributes.addFnAttr(.{ .string = .{ | ||
| 2476 | .kind = try o.builder.string("frame-pointer"), | ||
| 2477 | .value = try o.builder.string("all"), | ||
| 2478 | } }, &o.builder); | ||
| 2479 | } | ||
| 2480 | try attributes.addFnAttr(.nounwind, &o.builder); | ||
| 2481 | if (owner_mod.unwind_tables != .none) { | ||
| 2482 | try attributes.addFnAttr( | ||
| 2483 | .{ .uwtable = if (owner_mod.unwind_tables == .async) .async else .sync }, | ||
| 2484 | &o.builder, | ||
| 2485 | ); | ||
| 2486 | } | ||
| 2487 | if (owner_mod.optimize_mode == .small) { | ||
| 2488 | try attributes.addFnAttr(.minsize, &o.builder); | ||
| 2489 | try attributes.addFnAttr(.optsize, &o.builder); | ||
| 2490 | } | ||
| 2491 | const target = &owner_mod.resolved_target.result; | ||
| 2492 | if (target.cpu.model.llvm_name) |s| { | ||
| 2493 | try attributes.addFnAttr(.{ .string = .{ | ||
| 2494 | .kind = try o.builder.string("target-cpu"), | ||
| 2495 | .value = try o.builder.string(s), | ||
| 2496 | } }, &o.builder); | ||
| 2497 | } | ||
| 2498 | if (owner_mod.resolved_target.llvm_cpu_features) |s| { | ||
| 2499 | try attributes.addFnAttr(.{ .string = .{ | ||
| 2500 | .kind = try o.builder.string("target-features"), | ||
| 2501 | .value = try o.builder.string(std.mem.span(s)), | ||
| 2502 | } }, &o.builder); | ||
| 2503 | } | ||
| 2504 | if (target.abi.float() == .soft) { | ||
| 2505 | // `use-soft-float` means "use software routines for floating point computations". In | ||
| 2506 | // other words, it configures how LLVM lowers basic float instructions like `fcmp`, | ||
| 2507 | // `fadd`, etc. The float calling convention is configured on `TargetMachine` and is | ||
| 2508 | // mostly an orthogonal concept, although obviously we do need hardware float operations | ||
| 2509 | // to actually be able to pass float values in float registers. | ||
| 2510 | // | ||
| 2511 | // Ideally, we would support something akin to the `-mfloat-abi=softfp` option that GCC | ||
| 2512 | // and Clang support for Arm32 and CSKY. We don't currently expose such an option in | ||
| 2513 | // Zig, and using CPU features as the source of truth for this makes for a miserable | ||
| 2514 | // user experience since people expect e.g. `arm-linux-gnueabi` to mean full soft float | ||
| 2515 | // unless the compiler has explicitly been told otherwise. (And note that our baseline | ||
| 2516 | // CPU models almost all include FPU features!) | ||
| 2517 | // | ||
| 2518 | // Revisit this at some point. | ||
| 2519 | try attributes.addFnAttr(.{ .string = .{ | ||
| 2520 | .kind = try o.builder.string("use-soft-float"), | ||
| 2521 | .value = try o.builder.string("true"), | ||
| 2522 | } }, &o.builder); | ||
| 2523 | |||
| 2524 | // This prevents LLVM from using FPU/SIMD code for things like `memcpy`. As for the | ||
| 2525 | // above, this should be revisited if `softfp` support is added. | ||
| 2526 | try attributes.addFnAttr(.noimplicitfloat, &o.builder); | ||
| 2527 | } | ||
| 2528 | } | ||
| 2529 | |||
| 2530 | pub fn addCallingConventionFnAttributes( | ||
| 2581 | o: *Object, | 2531 | o: *Object, |
| 2582 | pt: Zcu.PerThread, | 2532 | pt: Zcu.PerThread, |
| 2583 | nav_id: InternPool.Nav.Index, | 2533 | llvm_function: Builder.Function.Index, |
| 2584 | function_index: Builder.Function.Index, | 2534 | attributes: *Builder.FunctionAttributes.Wip, |
| 2535 | opt_extern: ?struct { | ||
| 2536 | name: []const u8, | ||
| 2537 | lib_name: ?[]const u8 = null, | ||
| 2538 | }, | ||
| 2539 | fn_info: FuncInfo, | ||
| 2585 | ) Allocator.Error!void { | 2540 | ) Allocator.Error!void { |
| 2586 | const zcu = o.zcu; | 2541 | const zcu = o.zcu; |
| 2587 | const ip = &zcu.intern_pool; | 2542 | const target = zcu.getTarget(); |
| 2588 | const nav = ip.getNav(nav_id); | ||
| 2589 | const owner_mod = zcu.navFileScope(nav_id).mod.?; | ||
| 2590 | const ty: Type = .fromInterned(nav.resolved.?.type); | ||
| 2591 | |||
| 2592 | const fn_info = zcu.typeToFunc(ty).?; | ||
| 2593 | const target = &owner_mod.resolved_target.result; | ||
| 2594 | 2543 | ||
| 2595 | var attributes: Builder.FunctionAttributes.Wip = .{}; | 2544 | if (fn_info.cc == .async) { |
| 2596 | defer attributes.deinit(&o.builder); | 2545 | @panic("TODO: LLVM backend lower async function"); |
| 2546 | } | ||
| 2597 | 2547 | ||
| 2598 | if (target.cpu.arch.isWasm()) if (nav.getExtern(ip)) |@"extern"| { | 2548 | if (target.cpu.arch.isWasm()) if (opt_extern) |@"extern"| { |
| 2599 | try attributes.addFnAttr(.{ .string = .{ | 2549 | try attributes.addFnAttr(.{ .string = .{ |
| 2600 | .kind = try o.builder.string("wasm-import-name"), | 2550 | .kind = try o.builder.string("wasm-import-name"), |
| 2601 | .value = try o.builder.string(nav.name.toSlice(ip)), | 2551 | .value = try o.builder.string(@"extern".name), |
| 2602 | } }, &o.builder); | 2552 | } }, &o.builder); |
| 2603 | if (@"extern".lib_name.toSlice(ip)) |lib_name_slice| { | 2553 | if (@"extern".lib_name) |lib_name| { |
| 2604 | if (!std.mem.eql(u8, lib_name_slice, "c")) try attributes.addFnAttr(.{ .string = .{ | 2554 | if (!std.mem.eql(u8, lib_name, "c")) try attributes.addFnAttr(.{ .string = .{ |
| 2605 | .kind = try o.builder.string("wasm-import-module"), | 2555 | .kind = try o.builder.string("wasm-import-module"), |
| 2606 | .value = try o.builder.string(lib_name_slice), | 2556 | .value = try o.builder.string(lib_name), |
| 2607 | } }, &o.builder); | 2557 | } }, &o.builder); |
| 2608 | } | 2558 | } |
| 2609 | }; | 2559 | }; |
| 2610 | 2560 | ||
| 2611 | if (fn_info.cc == .async) { | ||
| 2612 | @panic("TODO: LLVM backend lower async function"); | ||
| 2613 | } | ||
| 2614 | |||
| 2615 | const cc_info = toLlvmCallConv(fn_info.cc, target).?; | 2561 | const cc_info = toLlvmCallConv(fn_info.cc, target).?; |
| 2616 | 2562 | ||
| 2617 | function_index.setCallConv(cc_info.llvm_cc, &o.builder); | 2563 | llvm_function.setCallConv(cc_info.llvm_cc, &o.builder); |
| 2618 | 2564 | ||
| 2619 | if (cc_info.align_stack) { | 2565 | if (cc_info.align_stack) { |
| 2620 | try attributes.addFnAttr(.{ .alignstack = .wrap(.fromByteUnits(target.stackAlignment())) }, &o.builder); | 2566 | try attributes.addFnAttr(.{ .string = .{ .kind = try o.builder.string("stackrealign"), .value = .empty } }, &o.builder); |
| 2621 | } | 2567 | } |
| 2622 | 2568 | ||
| 2623 | if (cc_info.naked) { | 2569 | if (cc_info.naked) { |
| ... | @@ -2668,29 +2614,16 @@ pub const Object = struct { | ... | @@ -2668,29 +2614,16 @@ pub const Object = struct { |
| 2668 | else => {}, | 2614 | else => {}, |
| 2669 | } | 2615 | } |
| 2670 | 2616 | ||
| 2671 | // Function attributes that are independent of analysis results of the function body. | ||
| 2672 | try o.addCommonFnAttributes( | ||
| 2673 | &attributes, | ||
| 2674 | owner_mod, | ||
| 2675 | // Some backends don't respect the `naked` attribute in `TargetFrameLowering::hasFP()`, | ||
| 2676 | // so for these backends, LLVM will happily emit code that accesses the stack through | ||
| 2677 | // the frame pointer. This is nonsensical since what the `naked` attribute does is | ||
| 2678 | // suppress generation of the prologue and epilogue, and the prologue is where the | ||
| 2679 | // frame pointer normally gets set up. At time of writing, this is the case for at | ||
| 2680 | // least x86 and RISC-V. | ||
| 2681 | owner_mod.omit_frame_pointer or fn_info.cc == .naked, | ||
| 2682 | ); | ||
| 2683 | |||
| 2684 | if (fn_info.return_type == .noreturn_type) try attributes.addFnAttr(.noreturn, &o.builder); | 2617 | if (fn_info.return_type == .noreturn_type) try attributes.addFnAttr(.noreturn, &o.builder); |
| 2685 | 2618 | ||
| 2686 | var it = iterateParamTypes(o, fn_info); | 2619 | var it = iterateParamTypes(o, fn_info.cc, fn_info.param_types); |
| 2687 | if (try fnReturnStrat(o, fn_info) == .sret) { | 2620 | if (try fnReturnStrat(o, fn_info.cc, .fromInterned(fn_info.return_type)) == .sret) { |
| 2688 | // Sret pointers must not be address 0 | 2621 | try o.addSRetFnAttributes( |
| 2689 | try attributes.addParamAttr(it.llvm_index, .nonnull, &o.builder); | 2622 | attributes, |
| 2690 | try attributes.addParamAttr(it.llvm_index, .@"noalias", &o.builder); | 2623 | try o.lowerType(.fromInterned(fn_info.return_type), .in_memory), |
| 2691 | 2624 | Type.fromInterned(fn_info.return_type).abiAlignment(zcu).toLlvm(), | |
| 2692 | const raw_llvm_ret_ty = try o.lowerType(.fromInterned(fn_info.return_type), .in_memory); | 2625 | .declaration, |
| 2693 | try attributes.addParamAttr(it.llvm_index, .{ .sret = raw_llvm_ret_ty }, &o.builder); | 2626 | ); |
| 2694 | it.llvm_index += 1; | 2627 | it.llvm_index += 1; |
| 2695 | } else if (ccAbiPromoteInt(fn_info.cc, zcu, Type.fromInterned(fn_info.return_type))) |s| switch (s) { | 2628 | } else if (ccAbiPromoteInt(fn_info.cc, zcu, Type.fromInterned(fn_info.return_type))) |s| switch (s) { |
| 2696 | .signed => try attributes.addRetAttr(.signext, &o.builder), | 2629 | .signed => try attributes.addRetAttr(.signext, &o.builder), |
| ... | @@ -2709,9 +2642,9 @@ pub const Object = struct { | ... | @@ -2709,9 +2642,9 @@ pub const Object = struct { |
| 2709 | while (try it.next()) |lowering| switch (lowering) { | 2642 | while (try it.next()) |lowering| switch (lowering) { |
| 2710 | .byval => { | 2643 | .byval => { |
| 2711 | const param_index = it.zig_index - 1; | 2644 | const param_index = it.zig_index - 1; |
| 2712 | const param_ty: Type = .fromInterned(fn_info.param_types.get(ip)[param_index]); | 2645 | const param_ty: Type = .fromInterned(fn_info.param_types[param_index]); |
| 2713 | if (!isByRef(param_ty, zcu)) { | 2646 | if (!isByRef(param_ty, zcu)) { |
| 2714 | try o.addByValParamAttrs(pt, &attributes, param_ty, param_index, fn_info, it.llvm_index - 1); | 2647 | try o.addByValParamAttrs(pt, attributes, param_ty, param_index, fn_info, it.llvm_index - 1); |
| 2715 | } | 2648 | } |
| 2716 | 2649 | ||
| 2717 | if (remaining_inreg_int > 0 and | 2650 | if (remaining_inreg_int > 0 and |
| ... | @@ -2730,12 +2663,12 @@ pub const Object = struct { | ... | @@ -2730,12 +2663,12 @@ pub const Object = struct { |
| 2730 | } | 2663 | } |
| 2731 | }, | 2664 | }, |
| 2732 | .byref => { | 2665 | .byref => { |
| 2733 | const param_ty: Type = .fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]); | 2666 | const param_ty: Type = .fromInterned(fn_info.param_types[it.zig_index - 1]); |
| 2734 | try o.addByRefParamAttrs(&attributes, it.llvm_index - 1, it.byval_attr, param_ty); | 2667 | try o.addByRefParamAttrs(attributes, it.llvm_index - 1, it.byval_attr, param_ty); |
| 2735 | }, | 2668 | }, |
| 2736 | .byref_mut => try attributes.addParamAttr(it.llvm_index - 1, .noundef, &o.builder), | 2669 | .byref_mut => try attributes.addParamAttr(it.llvm_index - 1, .noundef, &o.builder), |
| 2737 | .slice => { | 2670 | .slice => { |
| 2738 | const param_ty: Type = .fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]); | 2671 | const param_ty: Type = .fromInterned(fn_info.param_types[it.zig_index - 1]); |
| 2739 | const ptr_info = param_ty.ptrInfo(zcu); | 2672 | const ptr_info = param_ty.ptrInfo(zcu); |
| 2740 | const llvm_ptr_index = it.llvm_index - 2; | 2673 | const llvm_ptr_index = it.llvm_index - 2; |
| 2741 | if (std.math.cast(u5, it.zig_index - 1)) |i| { | 2674 | if (std.math.cast(u5, it.zig_index - 1)) |i| { |
| ... | @@ -2767,94 +2700,205 @@ pub const Object = struct { | ... | @@ -2767,94 +2700,205 @@ pub const Object = struct { |
| 2767 | .i64_array, | 2700 | .i64_array, |
| 2768 | => continue, | 2701 | => continue, |
| 2769 | }; | 2702 | }; |
| 2770 | |||
| 2771 | function_index.setAttributes(try attributes.finish(&o.builder), &o.builder); | ||
| 2772 | } | 2703 | } |
| 2773 | 2704 | ||
| 2774 | fn addCommonFnAttributes( | 2705 | pub fn addSRetFnAttributes( |
| 2775 | o: *Object, | 2706 | o: *Object, |
| 2776 | attributes: *Builder.FunctionAttributes.Wip, | 2707 | attributes: *Builder.FunctionAttributes.Wip, |
| 2777 | owner_mod: *Module, | 2708 | ret_ty: Builder.Type, |
| 2778 | omit_frame_pointer: bool, | 2709 | ret_align: Builder.Alignment, |
| 2710 | location: enum { declaration, callsite }, | ||
| 2779 | ) Allocator.Error!void { | 2711 | ) Allocator.Error!void { |
| 2780 | if (!owner_mod.red_zone) { | 2712 | try attributes.addParamAttr(0, .dead_on_unwind, &o.builder); |
| 2781 | try attributes.addFnAttr(.noredzone, &o.builder); | 2713 | switch (location) { |
| 2782 | } | 2714 | .declaration => try attributes.addParamAttr(0, .@"noalias", &o.builder), |
| 2783 | if (omit_frame_pointer) { | 2715 | .callsite => {}, |
| 2784 | try attributes.addFnAttr(.{ .string = .{ | ||
| 2785 | .kind = try o.builder.string("frame-pointer"), | ||
| 2786 | .value = try o.builder.string("none"), | ||
| 2787 | } }, &o.builder); | ||
| 2788 | } else { | ||
| 2789 | try attributes.addFnAttr(.{ .string = .{ | ||
| 2790 | .kind = try o.builder.string("frame-pointer"), | ||
| 2791 | .value = try o.builder.string("all"), | ||
| 2792 | } }, &o.builder); | ||
| 2793 | } | ||
| 2794 | try attributes.addFnAttr(.nounwind, &o.builder); | ||
| 2795 | if (owner_mod.unwind_tables != .none) { | ||
| 2796 | try attributes.addFnAttr( | ||
| 2797 | .{ .uwtable = if (owner_mod.unwind_tables == .async) .async else .sync }, | ||
| 2798 | &o.builder, | ||
| 2799 | ); | ||
| 2800 | } | ||
| 2801 | if (owner_mod.optimize_mode == .ReleaseSmall) { | ||
| 2802 | try attributes.addFnAttr(.minsize, &o.builder); | ||
| 2803 | try attributes.addFnAttr(.optsize, &o.builder); | ||
| 2804 | } | ||
| 2805 | const target = &owner_mod.resolved_target.result; | ||
| 2806 | if (target.cpu.model.llvm_name) |s| { | ||
| 2807 | try attributes.addFnAttr(.{ .string = .{ | ||
| 2808 | .kind = try o.builder.string("target-cpu"), | ||
| 2809 | .value = try o.builder.string(s), | ||
| 2810 | } }, &o.builder); | ||
| 2811 | } | ||
| 2812 | if (owner_mod.resolved_target.llvm_cpu_features) |s| { | ||
| 2813 | try attributes.addFnAttr(.{ .string = .{ | ||
| 2814 | .kind = try o.builder.string("target-features"), | ||
| 2815 | .value = try o.builder.string(std.mem.span(s)), | ||
| 2816 | } }, &o.builder); | ||
| 2817 | } | ||
| 2818 | if (target.abi.float() == .soft) { | ||
| 2819 | // `use-soft-float` means "use software routines for floating point computations". In | ||
| 2820 | // other words, it configures how LLVM lowers basic float instructions like `fcmp`, | ||
| 2821 | // `fadd`, etc. The float calling convention is configured on `TargetMachine` and is | ||
| 2822 | // mostly an orthogonal concept, although obviously we do need hardware float operations | ||
| 2823 | // to actually be able to pass float values in float registers. | ||
| 2824 | // | ||
| 2825 | // Ideally, we would support something akin to the `-mfloat-abi=softfp` option that GCC | ||
| 2826 | // and Clang support for Arm32 and CSKY. We don't currently expose such an option in | ||
| 2827 | // Zig, and using CPU features as the source of truth for this makes for a miserable | ||
| 2828 | // user experience since people expect e.g. `arm-linux-gnueabi` to mean full soft float | ||
| 2829 | // unless the compiler has explicitly been told otherwise. (And note that our baseline | ||
| 2830 | // CPU models almost all include FPU features!) | ||
| 2831 | // | ||
| 2832 | // Revisit this at some point. | ||
| 2833 | try attributes.addFnAttr(.{ .string = .{ | ||
| 2834 | .kind = try o.builder.string("use-soft-float"), | ||
| 2835 | .value = try o.builder.string("true"), | ||
| 2836 | } }, &o.builder); | ||
| 2837 | |||
| 2838 | // This prevents LLVM from using FPU/SIMD code for things like `memcpy`. As for the | ||
| 2839 | // above, this should be revisited if `softfp` support is added. | ||
| 2840 | try attributes.addFnAttr(.noimplicitfloat, &o.builder); | ||
| 2841 | } | 2716 | } |
| 2717 | try attributes.addParamAttr(0, .writeonly, &o.builder); | ||
| 2718 | try attributes.addParamAttr(0, .{ .captures = .none }, &o.builder); | ||
| 2719 | try attributes.addParamAttr(0, .{ .sret = ret_ty }, &o.builder); | ||
| 2720 | try attributes.addParamAttr(0, .{ .@"align" = .wrap(ret_align) }, &o.builder); | ||
| 2842 | } | 2721 | } |
| 2843 | 2722 | ||
| 2844 | pub const TypeRepr = enum { | 2723 | pub const TypeRepr = enum { |
| 2845 | /// The representation of the type when it is being manipulated as a value in a function. | 2724 | /// The representation of the type when it is being manipulated as a value in a function. |
| 2846 | /// e.g. Zig `u5` -> LLVM `i5` | 2725 | /// e.g. Zig `u90` -> LLVM `i90` |
| 2847 | by_value, | 2726 | as_value, |
| 2848 | /// The representation of the type when it is stored in memory. | 2727 | /// The representation of the type when it is loaded from or stored to memory. |
| 2849 | /// e.g. Zig `u5` -> LLVM `i8` | 2728 | /// e.g. Zig `u90` -> LLVM `i96` |
| 2729 | memory_access, | ||
| 2730 | /// The representation of the type when it is in memory. | ||
| 2731 | /// e.g. Zig `u90` -> LLVM `[12 x i8]` | ||
| 2850 | in_memory, | 2732 | in_memory, |
| 2851 | }; | 2733 | }; |
| 2852 | 2734 | ||
| 2735 | pub fn intType(o: *Object, bits: u16, repr: TypeRepr) Allocator.Error!Builder.Type { | ||
| 2736 | switch (repr) { | ||
| 2737 | .as_value => return o.builder.intType(bits), | ||
| 2738 | .memory_access, .in_memory => {}, | ||
| 2739 | } | ||
| 2740 | const target = o.zcu.getTarget(); | ||
| 2741 | const abi_size = std.zig.target.intByteSize(target, bits); | ||
| 2742 | const llvm_bit_width = @as(u20, 8) * abi_size; | ||
| 2743 | switch (repr) { | ||
| 2744 | .as_value => unreachable, | ||
| 2745 | .memory_access => {}, | ||
| 2746 | .in_memory => { | ||
| 2747 | const zig_align = std.zig.target.intAlignment(target, bits); | ||
| 2748 | const llvm_align = o.builder.data_layout.getIntegerSpec(llvm_bit_width).abi_align; | ||
| 2749 | if (zig_align < llvm_align.toByteUnits().?) return o.builder.arrayType(abi_size, .i8); | ||
| 2750 | }, | ||
| 2751 | } | ||
| 2752 | return o.builder.intType(llvm_bit_width); | ||
| 2753 | } | ||
| 2754 | |||
| 2853 | pub fn errorIntType(o: *Object, repr: TypeRepr) Allocator.Error!Builder.Type { | 2755 | pub fn errorIntType(o: *Object, repr: TypeRepr) Allocator.Error!Builder.Type { |
| 2854 | return o.builder.intType(switch (repr) { | 2756 | return o.intType(o.zcu.errorSetBits(), repr); |
| 2855 | .by_value => o.zcu.errorSetBits(), | 2757 | } |
| 2856 | .in_memory => @intCast(Type.anyerror.abiSize(o.zcu) * 8), | 2758 | |
| 2857 | }); | 2759 | pub const SoftF80Layout = struct { |
| 2760 | alignment: InternPool.Alignment, | ||
| 2761 | /// byte offset of u64 field | ||
| 2762 | mantissa_offset: u64, | ||
| 2763 | /// byte offset of u16 field | ||
| 2764 | exponent_offset: u64, | ||
| 2765 | llvm_fields_len: u32, | ||
| 2766 | |||
| 2767 | pub const LlvmFieldTag = enum { mantissa, exponent, padding }; | ||
| 2768 | }; | ||
| 2769 | pub fn softF80Layout(o: *Object, opts: struct { | ||
| 2770 | llvm_field_tags_buf: []SoftF80Layout.LlvmFieldTag = &.{}, | ||
| 2771 | llvm_field_types_buf: []Builder.Type = &.{}, | ||
| 2772 | }) Allocator.Error!SoftF80Layout { | ||
| 2773 | const zcu = o.zcu; | ||
| 2774 | const target = zcu.getTarget(); | ||
| 2775 | assert(std.zig.target.compilerRtFloatAbi(target, 80) == .soft); | ||
| 2776 | // Current compiler rt soft abi, which is not yet affected by endianness for simplicity: | ||
| 2777 | // | ||
| 2778 | // typedef struct { uint64_t mantissa; uint16_t exponent; } f80; | ||
| 2779 | // | ||
| 2780 | var layout: SoftF80Layout = .{ | ||
| 2781 | .alignment = Type.f80.abiAlignment(zcu), | ||
| 2782 | .mantissa_offset = undefined, | ||
| 2783 | .exponent_offset = undefined, | ||
| 2784 | .llvm_fields_len = 0, | ||
| 2785 | }; | ||
| 2786 | var offset: u64 = 0; | ||
| 2787 | for ([2]SoftF80Layout.LlvmFieldTag{ .mantissa, .exponent }, [2]Type{ .u64, .u16 }) |field_tag, field_type| { | ||
| 2788 | const field_align = field_type.abiAlignment(zcu); | ||
| 2789 | assert(field_align.compareStrict(.lte, layout.alignment)); | ||
| 2790 | const field_offset = field_align.forward(offset); | ||
| 2791 | switch (field_offset - offset) { | ||
| 2792 | 0 => {}, | ||
| 2793 | else => |padding| { | ||
| 2794 | if (layout.llvm_fields_len < opts.llvm_field_tags_buf.len) | ||
| 2795 | opts.llvm_field_tags_buf[layout.llvm_fields_len] = .padding; | ||
| 2796 | if (layout.llvm_fields_len < opts.llvm_field_types_buf.len) | ||
| 2797 | opts.llvm_field_types_buf[layout.llvm_fields_len] = try o.builder.arrayType(padding, .i8); | ||
| 2798 | layout.llvm_fields_len += 1; | ||
| 2799 | }, | ||
| 2800 | } | ||
| 2801 | switch (field_tag) { | ||
| 2802 | .mantissa => layout.mantissa_offset = field_offset, | ||
| 2803 | .exponent => layout.exponent_offset = field_offset, | ||
| 2804 | .padding => unreachable, | ||
| 2805 | } | ||
| 2806 | if (layout.llvm_fields_len < opts.llvm_field_tags_buf.len) | ||
| 2807 | opts.llvm_field_tags_buf[layout.llvm_fields_len] = field_tag; | ||
| 2808 | if (layout.llvm_fields_len < opts.llvm_field_types_buf.len) | ||
| 2809 | opts.llvm_field_types_buf[layout.llvm_fields_len] = try o.lowerType(field_type, .in_memory); | ||
| 2810 | layout.llvm_fields_len += 1; | ||
| 2811 | offset = field_offset + field_type.abiSize(zcu); | ||
| 2812 | } | ||
| 2813 | const end = layout.alignment.forward(offset); | ||
| 2814 | assert(end == Type.f80.abiSize(zcu)); | ||
| 2815 | switch (end - offset) { | ||
| 2816 | 0 => {}, | ||
| 2817 | else => |padding| { | ||
| 2818 | if (layout.llvm_fields_len < opts.llvm_field_tags_buf.len) | ||
| 2819 | opts.llvm_field_tags_buf[layout.llvm_fields_len] = .padding; | ||
| 2820 | if (layout.llvm_fields_len < opts.llvm_field_types_buf.len) | ||
| 2821 | opts.llvm_field_types_buf[layout.llvm_fields_len] = try o.builder.arrayType(padding, .i8); | ||
| 2822 | layout.llvm_fields_len += 1; | ||
| 2823 | }, | ||
| 2824 | } | ||
| 2825 | return layout; | ||
| 2826 | } | ||
| 2827 | |||
| 2828 | pub const SoftF128Layout = struct { | ||
| 2829 | alignment: InternPool.Alignment, | ||
| 2830 | /// byte offset of u64 field | ||
| 2831 | lo_offset: u64, | ||
| 2832 | /// byte offset of u64 field | ||
| 2833 | hi_offset: u64, | ||
| 2834 | llvm_fields_len: u32, | ||
| 2835 | |||
| 2836 | pub const LlvmFieldTag = enum { lo, hi, padding }; | ||
| 2837 | }; | ||
| 2838 | pub fn softF128Layout(o: *Object, opts: struct { | ||
| 2839 | llvm_field_tags_buf: []SoftF128Layout.LlvmFieldTag = &.{}, | ||
| 2840 | llvm_field_types_buf: []Builder.Type = &.{}, | ||
| 2841 | }) Allocator.Error!SoftF128Layout { | ||
| 2842 | const zcu = o.zcu; | ||
| 2843 | const target = zcu.getTarget(); | ||
| 2844 | assert(std.zig.target.compilerRtFloatAbi(target, 128) == .soft); | ||
| 2845 | // Current compiler rt soft abi: | ||
| 2846 | // | ||
| 2847 | // #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ | ||
| 2848 | // typedef struct { uint64_t hi, lo; } f128; | ||
| 2849 | // #else | ||
| 2850 | // typedef struct { uint64_t lo, hi; } f128; | ||
| 2851 | // #endif | ||
| 2852 | // | ||
| 2853 | var layout: SoftF128Layout = .{ | ||
| 2854 | .alignment = Type.f128.abiAlignment(zcu), | ||
| 2855 | .lo_offset = undefined, | ||
| 2856 | .hi_offset = undefined, | ||
| 2857 | .llvm_fields_len = 0, | ||
| 2858 | }; | ||
| 2859 | var offset: u64 = 0; | ||
| 2860 | for (@as([2]SoftF128Layout.LlvmFieldTag, switch (target.cpu.arch.endian()) { | ||
| 2861 | .big => .{ .hi, .lo }, | ||
| 2862 | .little => .{ .lo, .hi }, | ||
| 2863 | }), [2]Type{ .u64, .u64 }) |field_tag, field_type| { | ||
| 2864 | const field_align = field_type.abiAlignment(zcu); | ||
| 2865 | assert(field_align.compareStrict(.lte, layout.alignment)); | ||
| 2866 | const field_offset = field_align.forward(offset); | ||
| 2867 | switch (field_offset - offset) { | ||
| 2868 | 0 => {}, | ||
| 2869 | else => |padding| { | ||
| 2870 | if (layout.llvm_fields_len < opts.llvm_field_tags_buf.len) | ||
| 2871 | opts.llvm_field_tags_buf[layout.llvm_fields_len] = .padding; | ||
| 2872 | if (layout.llvm_fields_len < opts.llvm_field_types_buf.len) | ||
| 2873 | opts.llvm_field_types_buf[layout.llvm_fields_len] = try o.builder.arrayType(padding, .i8); | ||
| 2874 | layout.llvm_fields_len += 1; | ||
| 2875 | }, | ||
| 2876 | } | ||
| 2877 | switch (field_tag) { | ||
| 2878 | .lo => layout.lo_offset = field_offset, | ||
| 2879 | .hi => layout.hi_offset = field_offset, | ||
| 2880 | .padding => unreachable, | ||
| 2881 | } | ||
| 2882 | if (layout.llvm_fields_len < opts.llvm_field_tags_buf.len) | ||
| 2883 | opts.llvm_field_tags_buf[layout.llvm_fields_len] = field_tag; | ||
| 2884 | if (layout.llvm_fields_len < opts.llvm_field_types_buf.len) | ||
| 2885 | opts.llvm_field_types_buf[layout.llvm_fields_len] = try o.lowerType(field_type, .in_memory); | ||
| 2886 | layout.llvm_fields_len += 1; | ||
| 2887 | offset = field_offset + field_type.abiSize(zcu); | ||
| 2888 | } | ||
| 2889 | const end = layout.alignment.forward(offset); | ||
| 2890 | assert(end == Type.f128.abiSize(zcu)); | ||
| 2891 | switch (end - offset) { | ||
| 2892 | 0 => {}, | ||
| 2893 | else => |padding| { | ||
| 2894 | if (layout.llvm_fields_len < opts.llvm_field_tags_buf.len) | ||
| 2895 | opts.llvm_field_tags_buf[layout.llvm_fields_len] = .padding; | ||
| 2896 | if (layout.llvm_fields_len < opts.llvm_field_types_buf.len) | ||
| 2897 | opts.llvm_field_types_buf[layout.llvm_fields_len] = try o.builder.arrayType(padding, .i8); | ||
| 2898 | layout.llvm_fields_len += 1; | ||
| 2899 | }, | ||
| 2900 | } | ||
| 2901 | return layout; | ||
| 2858 | } | 2902 | } |
| 2859 | 2903 | ||
| 2860 | pub fn lowerType(o: *Object, t: Type, repr: TypeRepr) Allocator.Error!Builder.Type { | 2904 | pub fn lowerType(o: *Object, t: Type, repr: TypeRepr) Allocator.Error!Builder.Type { |
| ... | @@ -2862,42 +2906,31 @@ pub const Object = struct { | ... | @@ -2862,42 +2906,31 @@ pub const Object = struct { |
| 2862 | const target = zcu.getTarget(); | 2906 | const target = zcu.getTarget(); |
| 2863 | const ip = &zcu.intern_pool; | 2907 | const ip = &zcu.intern_pool; |
| 2864 | 2908 | ||
| 2865 | if (repr == .by_value) { | 2909 | switch (repr) { |
| 2866 | assert(!isByRef(t, zcu)); // by-ref types must only be manipulated in memory | 2910 | .as_value => assert(!isByRef(t, zcu)), // by-ref types must only be manipulated in memory |
| 2911 | .memory_access, .in_memory => {}, | ||
| 2867 | } | 2912 | } |
| 2868 | 2913 | ||
| 2869 | return switch (t.toIntern()) { | 2914 | return switch (t.toIntern()) { |
| 2870 | .u0_type => unreachable, // no runtime bits | 2915 | .u0_type => unreachable, // no runtime bits |
| 2871 | inline .u1_type, | 2916 | .u1_type, .bool_type => try o.intType(1, repr), |
| 2872 | .u8_type, | 2917 | .u8_type, .i8_type => try o.intType(8, repr), |
| 2873 | .i8_type, | 2918 | .u16_type, .i16_type => try o.intType(16, repr), |
| 2874 | .u16_type, | 2919 | .u29_type => try o.intType(29, repr), |
| 2875 | .i16_type, | 2920 | .u32_type, .i32_type => try o.intType(32, repr), |
| 2876 | .u29_type, | 2921 | .u64_type, .i64_type => try o.intType(64, repr), |
| 2877 | .u32_type, | 2922 | .u80_type => try o.intType(80, repr), |
| 2878 | .i32_type, | 2923 | .u128_type, .i128_type => try o.intType(128, repr), |
| 2879 | .u64_type, | 2924 | .usize_type, .isize_type => try o.intType(target.ptrBitWidth(), repr), |
| 2880 | .i64_type, | 2925 | .c_char_type => try o.intType(target.cTypeBitSize(.char).?, repr), |
| 2881 | .u80_type, | 2926 | .c_short_type => try o.intType(target.cTypeBitSize(.short).?, repr), |
| 2882 | .u128_type, | 2927 | .c_ushort_type => try o.intType(target.cTypeBitSize(.ushort).?, repr), |
| 2883 | .i128_type, | 2928 | .c_int_type => try o.intType(target.cTypeBitSize(.int).?, repr), |
| 2884 | => |tag| switch (repr) { | 2929 | .c_uint_type => try o.intType(target.cTypeBitSize(.uint).?, repr), |
| 2885 | .by_value => @field(Builder.Type, "i" ++ @tagName(tag)[1 .. @tagName(tag).len - "_type".len]), | 2930 | .c_long_type => try o.intType(target.cTypeBitSize(.long).?, repr), |
| 2886 | .in_memory => try o.builder.intType(@intCast(t.abiSize(zcu) * 8)), | 2931 | .c_ulong_type => try o.intType(target.cTypeBitSize(.ulong).?, repr), |
| 2887 | }, | 2932 | .c_longlong_type => try o.intType(target.cTypeBitSize(.longlong).?, repr), |
| 2888 | .usize_type, .isize_type => try o.builder.intType(target.ptrBitWidth()), | 2933 | .c_ulonglong_type => try o.intType(target.cTypeBitSize(.ulonglong).?, repr), |
| 2889 | inline .c_char_type, | ||
| 2890 | .c_short_type, | ||
| 2891 | .c_ushort_type, | ||
| 2892 | .c_int_type, | ||
| 2893 | .c_uint_type, | ||
| 2894 | .c_long_type, | ||
| 2895 | .c_ulong_type, | ||
| 2896 | .c_longlong_type, | ||
| 2897 | .c_ulonglong_type, | ||
| 2898 | => |tag| try o.builder.intType(target.cTypeBitSize( | ||
| 2899 | @field(std.Target.CType, @tagName(tag)["c_".len .. @tagName(tag).len - "_type".len]), | ||
| 2900 | )), | ||
| 2901 | .c_longdouble_type, | 2934 | .c_longdouble_type, |
| 2902 | .f16_type, | 2935 | .f16_type, |
| 2903 | .f32_type, | 2936 | .f32_type, |
| ... | @@ -2905,11 +2938,44 @@ pub const Object = struct { | ... | @@ -2905,11 +2938,44 @@ pub const Object = struct { |
| 2905 | .f80_type, | 2938 | .f80_type, |
| 2906 | .f128_type, | 2939 | .f128_type, |
| 2907 | => switch (t.floatBits(target)) { | 2940 | => switch (t.floatBits(target)) { |
| 2908 | 16 => if (backendSupportsF16(target)) .half else .i16, | 2941 | 16 => |bits| switch (std.zig.target.compilerRtFloatAbi(target, bits)) { |
| 2909 | 32 => .float, | 2942 | .hard => .half, |
| 2910 | 64 => .double, | 2943 | .soft => .i16, |
| 2911 | 80 => if (backendSupportsF80(target)) .x86_fp80 else .i80, | 2944 | }, |
| 2912 | 128 => .fp128, | 2945 | 32 => |bits| switch (std.zig.target.compilerRtFloatAbi(target, bits)) { |
| 2946 | .hard => .float, | ||
| 2947 | .soft => .i32, | ||
| 2948 | }, | ||
| 2949 | 64 => |bits| switch (std.zig.target.compilerRtFloatAbi(target, bits)) { | ||
| 2950 | .hard => .double, | ||
| 2951 | .soft => .i64, | ||
| 2952 | }, | ||
| 2953 | 80 => |bits| switch (std.zig.target.compilerRtFloatAbi(target, bits)) { | ||
| 2954 | .hard => .x86_fp80, | ||
| 2955 | .soft => { | ||
| 2956 | var llvm_field_types_buf: [5]Builder.Type = undefined; | ||
| 2957 | const f80_layout = try o.softF80Layout(.{ | ||
| 2958 | .llvm_field_types_buf = &llvm_field_types_buf, | ||
| 2959 | }); | ||
| 2960 | return o.builder.structType( | ||
| 2961 | .normal, | ||
| 2962 | llvm_field_types_buf[0..f80_layout.llvm_fields_len], | ||
| 2963 | ); | ||
| 2964 | }, | ||
| 2965 | }, | ||
| 2966 | 128 => |bits| switch (std.zig.target.compilerRtFloatAbi(target, bits)) { | ||
| 2967 | .hard => .fp128, | ||
| 2968 | .soft => { | ||
| 2969 | var llvm_field_types_buf: [5]Builder.Type = undefined; | ||
| 2970 | const f128_layout = try o.softF128Layout(.{ | ||
| 2971 | .llvm_field_types_buf = &llvm_field_types_buf, | ||
| 2972 | }); | ||
| 2973 | return o.builder.structType( | ||
| 2974 | .normal, | ||
| 2975 | llvm_field_types_buf[0..f128_layout.llvm_fields_len], | ||
| 2976 | ); | ||
| 2977 | }, | ||
| 2978 | }, | ||
| 2913 | else => unreachable, | 2979 | else => unreachable, |
| 2914 | }, | 2980 | }, |
| 2915 | .anyopaque_type => { | 2981 | .anyopaque_type => { |
| ... | @@ -2918,7 +2984,6 @@ pub const Object = struct { | ... | @@ -2918,7 +2984,6 @@ pub const Object = struct { |
| 2918 | // @foo = external global i8 | 2984 | // @foo = external global i8 |
| 2919 | return .i8; | 2985 | return .i8; |
| 2920 | }, | 2986 | }, |
| 2921 | .bool_type => .i1, | ||
| 2922 | .anyerror_type => try o.errorIntType(repr), | 2987 | .anyerror_type => try o.errorIntType(repr), |
| 2923 | .void_type => unreachable, // no runtime bits | 2988 | .void_type => unreachable, // no runtime bits |
| 2924 | .type_type => unreachable, // no runtime bits | 2989 | .type_type => unreachable, // no runtime bits |
| ... | @@ -2968,10 +3033,7 @@ pub const Object = struct { | ... | @@ -2968,10 +3033,7 @@ pub const Object = struct { |
| 2968 | .none, | 3033 | .none, |
| 2969 | => unreachable, | 3034 | => unreachable, |
| 2970 | else => switch (ip.indexToKey(t.toIntern())) { | 3035 | else => switch (ip.indexToKey(t.toIntern())) { |
| 2971 | .int_type => |int_type| switch (repr) { | 3036 | .int_type => |int_type| o.intType(int_type.bits, repr), |
| 2972 | .by_value => try o.builder.intType(int_type.bits), | ||
| 2973 | .in_memory => try o.builder.intType(@intCast(t.abiSize(zcu) * 8)), | ||
| 2974 | }, | ||
| 2975 | .ptr_type => |ptr_type| type: { | 3037 | .ptr_type => |ptr_type| type: { |
| 2976 | const ptr_ty = try o.builder.ptrType( | 3038 | const ptr_ty = try o.builder.ptrType( |
| 2977 | toLlvmAddressSpace(ptr_type.flags.address_space, target), | 3039 | toLlvmAddressSpace(ptr_type.flags.address_space, target), |
| ... | @@ -2988,11 +3050,13 @@ pub const Object = struct { | ... | @@ -2988,11 +3050,13 @@ pub const Object = struct { |
| 2988 | array_type.lenIncludingSentinel(), | 3050 | array_type.lenIncludingSentinel(), |
| 2989 | try o.lowerType(.fromInterned(array_type.child), repr), | 3051 | try o.lowerType(.fromInterned(array_type.child), repr), |
| 2990 | ), | 3052 | ), |
| 2991 | .vector_type => |vector_type| o.builder.vectorType( | 3053 | .vector_type => |vector_type| if (isByRef(t, zcu)) { |
| 2992 | .normal, | 3054 | const child_llvm_ty = try o.lowerType(.fromInterned(vector_type.child), repr); |
| 2993 | vector_type.len, | 3055 | return o.builder.arrayType(vector_type.len, child_llvm_ty); |
| 2994 | try o.lowerType(.fromInterned(vector_type.child), .by_value), | 3056 | } else { |
| 2995 | ), | 3057 | const child_llvm_ty = try o.lowerType(.fromInterned(vector_type.child), .as_value); |
| 3058 | return o.builder.vectorType(.normal, vector_type.len, child_llvm_ty); | ||
| 3059 | }, | ||
| 2996 | .opt_type => |child_ty| { | 3060 | .opt_type => |child_ty| { |
| 2997 | // Must stay in sync with `opt_payload` logic in `lowerPtr`. | 3061 | // Must stay in sync with `opt_payload` logic in `lowerPtr`. |
| 2998 | switch (Type.fromInterned(child_ty).classify(zcu)) { | 3062 | switch (Type.fromInterned(child_ty).classify(zcu)) { |
| ... | @@ -3252,8 +3316,11 @@ pub const Object = struct { | ... | @@ -3252,8 +3316,11 @@ pub const Object = struct { |
| 3252 | return ty; | 3316 | return ty; |
| 3253 | }, | 3317 | }, |
| 3254 | .opaque_type, .spirv_type => unreachable, // no runtime bits | 3318 | .opaque_type, .spirv_type => unreachable, // no runtime bits |
| 3255 | .enum_type => try o.lowerType(t.backingIntType(zcu), repr), | 3319 | .enum_type => try o.intType(t.backingIntType(zcu).intInfo(zcu).bits, repr), |
| 3256 | .func_type => |func_type| try o.lowerFnType(t, func_type), | 3320 | .func_type => |func_type| { |
| 3321 | assert(t.fnHasRuntimeBits(zcu)); | ||
| 3322 | return o.lowerFnType(.fromIntern(func_type, ip)); | ||
| 3323 | }, | ||
| 3257 | .error_set_type, .inferred_error_set_type => try o.errorIntType(repr), | 3324 | .error_set_type, .inferred_error_set_type => try o.errorIntType(repr), |
| 3258 | // values, not types | 3325 | // values, not types |
| 3259 | .undef, | 3326 | .undef, |
| ... | @@ -3279,14 +3346,28 @@ pub const Object = struct { | ... | @@ -3279,14 +3346,28 @@ pub const Object = struct { |
| 3279 | }; | 3346 | }; |
| 3280 | } | 3347 | } |
| 3281 | 3348 | ||
| 3282 | fn lowerFnType(o: *Object, fn_ty: Type, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type { | 3349 | pub const FuncInfo = struct { |
| 3350 | cc: std.lang.CallingConvention, | ||
| 3351 | noalias_bits: u32 = 0, | ||
| 3352 | param_types: []const InternPool.Index, | ||
| 3353 | return_type: InternPool.Index = .void_type, | ||
| 3354 | is_var_args: bool = false, | ||
| 3355 | |||
| 3356 | pub fn fromIntern(fn_info: InternPool.Key.FuncType, ip: *InternPool) FuncInfo { | ||
| 3357 | return .{ | ||
| 3358 | .cc = fn_info.cc, | ||
| 3359 | .noalias_bits = fn_info.noalias_bits, | ||
| 3360 | .param_types = fn_info.param_types.get(ip), | ||
| 3361 | .return_type = fn_info.return_type, | ||
| 3362 | .is_var_args = fn_info.is_var_args, | ||
| 3363 | }; | ||
| 3364 | } | ||
| 3365 | }; | ||
| 3366 | pub fn lowerFnType(o: *Object, fn_info: FuncInfo) Allocator.Error!Builder.Type { | ||
| 3283 | const zcu = o.zcu; | 3367 | const zcu = o.zcu; |
| 3284 | const ip = &zcu.intern_pool; | ||
| 3285 | const target = zcu.getTarget(); | 3368 | const target = zcu.getTarget(); |
| 3286 | 3369 | ||
| 3287 | assert(fn_ty.fnHasRuntimeBits(zcu)); | 3370 | const ret_strat = try fnReturnStrat(o, fn_info.cc, .fromInterned(fn_info.return_type)); |
| 3288 | |||
| 3289 | const ret_strat = try fnReturnStrat(o, fn_info); | ||
| 3290 | 3371 | ||
| 3291 | var llvm_params: std.ArrayList(Builder.Type) = .empty; | 3372 | var llvm_params: std.ArrayList(Builder.Type) = .empty; |
| 3292 | defer llvm_params.deinit(o.gpa); | 3373 | defer llvm_params.deinit(o.gpa); |
| ... | @@ -3301,35 +3382,35 @@ pub const Object = struct { | ... | @@ -3301,35 +3382,35 @@ pub const Object = struct { |
| 3301 | try llvm_params.append(o.gpa, llvm_ptr_ty); | 3382 | try llvm_params.append(o.gpa, llvm_ptr_ty); |
| 3302 | } | 3383 | } |
| 3303 | 3384 | ||
| 3304 | var it = iterateParamTypes(o, fn_info); | 3385 | var it = iterateParamTypes(o, fn_info.cc, fn_info.param_types); |
| 3305 | while (try it.next()) |lowering| switch (lowering) { | 3386 | while (try it.next()) |lowering| switch (lowering) { |
| 3306 | .no_bits => continue, | 3387 | .no_bits => continue, |
| 3307 | .byval => { | 3388 | .byval => { |
| 3308 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]); | 3389 | const param_ty = Type.fromInterned(fn_info.param_types[it.zig_index - 1]); |
| 3309 | try llvm_params.append(o.gpa, try o.lowerType(param_ty, if (isByRef(param_ty, zcu)) .in_memory else .by_value)); | 3390 | try llvm_params.append(o.gpa, try o.lowerType(param_ty, if (isByRef(param_ty, zcu)) .memory_access else .as_value)); |
| 3310 | }, | 3391 | }, |
| 3311 | .byref, .byref_mut => { | 3392 | .byref, .byref_mut => { |
| 3312 | try llvm_params.append(o.gpa, .ptr); | 3393 | try llvm_params.append(o.gpa, .ptr); |
| 3313 | }, | 3394 | }, |
| 3314 | .abi_sized_int => { | 3395 | .abi_sized_int => { |
| 3315 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]); | 3396 | const param_ty = Type.fromInterned(fn_info.param_types[it.zig_index - 1]); |
| 3316 | try llvm_params.append(o.gpa, try o.builder.intType( | 3397 | try llvm_params.append(o.gpa, try o.builder.intType( |
| 3317 | @intCast(param_ty.abiSize(zcu) * 8), | 3398 | @intCast(param_ty.abiSize(zcu) * 8), |
| 3318 | )); | 3399 | )); |
| 3319 | }, | 3400 | }, |
| 3320 | .slice => { | 3401 | .slice => { |
| 3321 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]); | 3402 | const param_ty = Type.fromInterned(fn_info.param_types[it.zig_index - 1]); |
| 3322 | try llvm_params.appendSlice(o.gpa, &.{ | 3403 | try llvm_params.appendSlice(o.gpa, &.{ |
| 3323 | try o.builder.ptrType(toLlvmAddressSpace(param_ty.ptrAddressSpace(zcu), target)), | 3404 | try o.builder.ptrType(toLlvmAddressSpace(param_ty.ptrAddressSpace(zcu), target)), |
| 3324 | try o.lowerType(.usize, .by_value), | 3405 | try o.lowerType(.usize, .as_value), |
| 3325 | }); | 3406 | }); |
| 3326 | }, | 3407 | }, |
| 3327 | .multiple_llvm_types => { | 3408 | .multiple_llvm_types => { |
| 3328 | try llvm_params.appendSlice(o.gpa, it.types_buffer[0..it.types_len]); | 3409 | try llvm_params.appendSlice(o.gpa, it.types_buffer[0..it.types_len]); |
| 3329 | }, | 3410 | }, |
| 3330 | .float_array => |count| { | 3411 | .float_array => |count| { |
| 3331 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]); | 3412 | const param_ty = Type.fromInterned(fn_info.param_types[it.zig_index - 1]); |
| 3332 | const float_ty = try o.lowerType(aarch64_c_abi.getFloatArrayType(param_ty, zcu).?, .in_memory); | 3413 | const float_ty = try o.lowerType(aarch64_c_abi.getFloatArrayType(param_ty, zcu).?, .memory_access); |
| 3333 | try llvm_params.append(o.gpa, try o.builder.arrayType(count, float_ty)); | 3414 | try llvm_params.append(o.gpa, try o.builder.arrayType(count, float_ty)); |
| 3334 | }, | 3415 | }, |
| 3335 | .i32_array, .i64_array => |arr_len| { | 3416 | .i32_array, .i64_array => |arr_len| { |
| ... | @@ -3343,7 +3424,7 @@ pub const Object = struct { | ... | @@ -3343,7 +3424,7 @@ pub const Object = struct { |
| 3343 | 3424 | ||
| 3344 | const llvm_ret_ty: Builder.Type = switch (ret_strat) { | 3425 | const llvm_ret_ty: Builder.Type = switch (ret_strat) { |
| 3345 | .void, .sret => .void, | 3426 | .void, .sret => .void, |
| 3346 | .by_val => try o.lowerType(.fromInterned(fn_info.return_type), .by_value), | 3427 | .by_val => try o.lowerType(.fromInterned(fn_info.return_type), .as_value), |
| 3347 | .mem_cast => |llvm_ret_ty| llvm_ret_ty, | 3428 | .mem_cast => |llvm_ret_ty| llvm_ret_ty, |
| 3348 | }; | 3429 | }; |
| 3349 | const llvm_fn_kind: Builder.Type.Function.Kind = switch (fn_info.is_var_args) { | 3430 | const llvm_fn_kind: Builder.Type.Function.Kind = switch (fn_info.is_var_args) { |
| ... | @@ -3391,8 +3472,14 @@ pub const Object = struct { | ... | @@ -3391,8 +3472,14 @@ pub const Object = struct { |
| 3391 | .null => unreachable, // non-runtime value | 3472 | .null => unreachable, // non-runtime value |
| 3392 | .@"unreachable" => unreachable, // non-runtime value | 3473 | .@"unreachable" => unreachable, // non-runtime value |
| 3393 | 3474 | ||
| 3394 | .false => .false, | 3475 | .false => switch (repr) { |
| 3395 | .true => .true, | 3476 | .as_value => .false, |
| 3477 | .in_memory, .memory_access => try o.builder.intConst(.i8, 0), | ||
| 3478 | }, | ||
| 3479 | .true => switch (repr) { | ||
| 3480 | .as_value => .true, | ||
| 3481 | .in_memory, .memory_access => try o.builder.intConst(.i8, 1), | ||
| 3482 | }, | ||
| 3396 | }, | 3483 | }, |
| 3397 | .enum_literal => unreachable, // non-runtime value | 3484 | .enum_literal => unreachable, // non-runtime value |
| 3398 | .@"extern" => unreachable, // non-runtime value | 3485 | .@"extern" => unreachable, // non-runtime value |
| ... | @@ -3401,7 +3488,12 @@ pub const Object = struct { | ... | @@ -3401,7 +3488,12 @@ pub const Object = struct { |
| 3401 | var bigint_space: Value.BigIntSpace = undefined; | 3488 | var bigint_space: Value.BigIntSpace = undefined; |
| 3402 | const bigint = val.toBigInt(&bigint_space, zcu); | 3489 | const bigint = val.toBigInt(&bigint_space, zcu); |
| 3403 | const llvm_int_ty = try o.lowerType(ty, repr); | 3490 | const llvm_int_ty = try o.lowerType(ty, repr); |
| 3404 | return o.builder.bigIntConst(llvm_int_ty, bigint); | 3491 | if (llvm_int_ty.isInteger(&o.builder)) |
| 3492 | return o.builder.bigIntConst(llvm_int_ty, bigint); | ||
| 3493 | const buffer = try o.gpa.alloc(u8, llvm_int_ty.aggregateLen(&o.builder)); | ||
| 3494 | defer o.gpa.free(buffer); | ||
| 3495 | bigint.writeTwosComplement(buffer, target.cpu.arch.endian()); | ||
| 3496 | return o.builder.stringConst(try o.builder.string(buffer)); | ||
| 3405 | }, | 3497 | }, |
| 3406 | .err => |err| { | 3498 | .err => |err| { |
| 3407 | const int = zcu.intern_pool.getErrorValueIfExists(err.name).?; | 3499 | const int = zcu.intern_pool.getErrorValueIfExists(err.name).?; |
| ... | @@ -3456,18 +3548,12 @@ pub const Object = struct { | ... | @@ -3456,18 +3548,12 @@ pub const Object = struct { |
| 3456 | }, | 3548 | }, |
| 3457 | .enum_tag => |enum_tag| o.lowerValue(enum_tag.int, repr), | 3549 | .enum_tag => |enum_tag| o.lowerValue(enum_tag.int, repr), |
| 3458 | .float => switch (ty.floatBits(target)) { | 3550 | .float => switch (ty.floatBits(target)) { |
| 3459 | 16 => if (backendSupportsF16(target)) | ||
| 3460 | try o.builder.halfConst(val.toFloat(f16, zcu)) | ||
| 3461 | else | ||
| 3462 | try o.builder.intConst(.i16, @as(i16, @bitCast(val.toFloat(f16, zcu)))), | ||
| 3463 | 32 => try o.builder.floatConst(val.toFloat(f32, zcu)), | ||
| 3464 | 64 => try o.builder.doubleConst(val.toFloat(f64, zcu)), | ||
| 3465 | 80 => if (backendSupportsF80(target)) | ||
| 3466 | try o.builder.x86_fp80Const(val.toFloat(f80, zcu)) | ||
| 3467 | else | ||
| 3468 | try o.builder.intConst(.i80, @as(i80, @bitCast(val.toFloat(f80, zcu)))), | ||
| 3469 | 128 => try o.builder.fp128Const(val.toFloat(f128, zcu)), | ||
| 3470 | else => unreachable, | 3551 | else => unreachable, |
| 3552 | 16 => try o.f16Const(val.toFloat(f16, zcu)), | ||
| 3553 | 32 => try o.f32Const(val.toFloat(f32, zcu)), | ||
| 3554 | 64 => try o.f64Const(val.toFloat(f64, zcu)), | ||
| 3555 | 80 => try o.f80Const(val.toFloat(f80, zcu)), | ||
| 3556 | 128 => try o.f128Const(val.toFloat(f128, zcu)), | ||
| 3471 | }, | 3557 | }, |
| 3472 | .ptr => try o.lowerPtr(arg_val, 0), | 3558 | .ptr => try o.lowerPtr(arg_val, 0), |
| 3473 | .slice => |slice| return o.builder.structConst(try o.lowerType(ty, repr), &.{ | 3559 | .slice => |slice| return o.builder.structConst(try o.lowerType(ty, repr), &.{ |
| ... | @@ -3586,12 +3672,13 @@ pub const Object = struct { | ... | @@ -3586,12 +3672,13 @@ pub const Object = struct { |
| 3586 | }, | 3672 | }, |
| 3587 | .vector_type => |vector_type| { | 3673 | .vector_type => |vector_type| { |
| 3588 | const vector_ty = try o.lowerType(ty, repr); | 3674 | const vector_ty = try o.lowerType(ty, repr); |
| 3675 | const ExpectedContents = [Builder.expected_fields_len]Builder.Constant; | ||
| 3676 | var bfa_buf: ExpectedContents = undefined; | ||
| 3677 | var bfa: std.heap.BufferFirstAllocator = .init(@ptrCast(&bfa_buf), o.gpa); | ||
| 3678 | const allocator = bfa.allocator(); | ||
| 3679 | const is_by_ref = isByRef(ty, zcu); | ||
| 3589 | switch (aggregate.storage) { | 3680 | switch (aggregate.storage) { |
| 3590 | .bytes, .elems => { | 3681 | .bytes, .elems => { |
| 3591 | const ExpectedContents = [Builder.expected_fields_len]Builder.Constant; | ||
| 3592 | var bfa_buf: ExpectedContents = undefined; | ||
| 3593 | var bfa: std.heap.BufferFirstAllocator = .init(@ptrCast(&bfa_buf), o.gpa); | ||
| 3594 | const allocator = bfa.allocator(); | ||
| 3595 | const vals = try allocator.alloc(Builder.Constant, vector_type.len); | 3682 | const vals = try allocator.alloc(Builder.Constant, vector_type.len); |
| 3596 | defer allocator.free(vals); | 3683 | defer allocator.free(vals); |
| 3597 | 3684 | ||
| ... | @@ -3600,16 +3687,21 @@ pub const Object = struct { | ... | @@ -3600,16 +3687,21 @@ pub const Object = struct { |
| 3600 | result_val.* = try o.builder.intConst(.i8, byte); | 3687 | result_val.* = try o.builder.intConst(.i8, byte); |
| 3601 | }, | 3688 | }, |
| 3602 | .elems => |elems| for (vals, elems) |*result_val, elem| { | 3689 | .elems => |elems| for (vals, elems) |*result_val, elem| { |
| 3603 | result_val.* = try o.lowerValue(elem, .by_value); | 3690 | result_val.* = try o.lowerValue(elem, if (is_by_ref) repr else .as_value); |
| 3604 | }, | 3691 | }, |
| 3605 | .repeated_elem => unreachable, | 3692 | .repeated_elem => unreachable, |
| 3606 | } | 3693 | } |
| 3607 | return o.builder.vectorConst(vector_ty, vals); | 3694 | return if (is_by_ref) |
| 3695 | o.builder.arrayConst(vector_ty, vals) | ||
| 3696 | else | ||
| 3697 | o.builder.vectorConst(vector_ty, vals); | ||
| 3608 | }, | 3698 | }, |
| 3609 | .repeated_elem => |elem| return o.builder.splatConst( | 3699 | .repeated_elem => |elem| if (is_by_ref) { |
| 3610 | vector_ty, | 3700 | const vals = try allocator.alloc(Builder.Constant, vector_type.len); |
| 3611 | try o.lowerValue(elem, .by_value), | 3701 | defer allocator.free(vals); |
| 3612 | ), | 3702 | @memset(vals, try o.lowerValue(elem, repr)); |
| 3703 | return o.builder.arrayConst(vector_ty, vals); | ||
| 3704 | } else return o.builder.splatConst(vector_ty, try o.lowerValue(elem, .as_value)), | ||
| 3613 | } | 3705 | } |
| 3614 | }, | 3706 | }, |
| 3615 | .tuple_type => |tuple| { | 3707 | .tuple_type => |tuple| { |
| ... | @@ -3837,6 +3929,117 @@ pub const Object = struct { | ... | @@ -3837,6 +3929,117 @@ pub const Object = struct { |
| 3837 | }; | 3929 | }; |
| 3838 | } | 3930 | } |
| 3839 | 3931 | ||
| 3932 | pub fn f16Const(o: *Object, val: f16) Allocator.Error!Builder.Constant { | ||
| 3933 | return switch (std.zig.target.compilerRtFloatAbi(o.zcu.getTarget(), 16)) { | ||
| 3934 | .hard => o.builder.halfConst(val), | ||
| 3935 | .soft => o.builder.intConst(.i16, @as(u16, @bitCast(val))), | ||
| 3936 | }; | ||
| 3937 | } | ||
| 3938 | |||
| 3939 | pub fn f32Const(o: *Object, val: f32) Allocator.Error!Builder.Constant { | ||
| 3940 | return switch (std.zig.target.compilerRtFloatAbi(o.zcu.getTarget(), 32)) { | ||
| 3941 | .hard => o.builder.floatConst(val), | ||
| 3942 | .soft => o.builder.intConst(.i32, @as(u32, @bitCast(val))), | ||
| 3943 | }; | ||
| 3944 | } | ||
| 3945 | |||
| 3946 | pub fn f64Const(o: *Object, val: f64) Allocator.Error!Builder.Constant { | ||
| 3947 | return switch (std.zig.target.compilerRtFloatAbi(o.zcu.getTarget(), 64)) { | ||
| 3948 | .hard => o.builder.doubleConst(val), | ||
| 3949 | .soft => o.builder.intConst(.i64, @as(u64, @bitCast(val))), | ||
| 3950 | }; | ||
| 3951 | } | ||
| 3952 | |||
| 3953 | pub fn f80Const(o: *Object, val: f80) Allocator.Error!Builder.Constant { | ||
| 3954 | switch (std.zig.target.compilerRtFloatAbi(o.zcu.getTarget(), 80)) { | ||
| 3955 | .hard => return o.builder.x86_fp80Const(val), | ||
| 3956 | .soft => {}, | ||
| 3957 | } | ||
| 3958 | var llvm_field_tags_buf: [5]SoftF80Layout.LlvmFieldTag = undefined; | ||
| 3959 | var llvm_field_types_buf: [5]Builder.Type = undefined; | ||
| 3960 | const f80_layout = try o.softF80Layout(.{ | ||
| 3961 | .llvm_field_tags_buf = &llvm_field_tags_buf, | ||
| 3962 | .llvm_field_types_buf = &llvm_field_types_buf, | ||
| 3963 | }); | ||
| 3964 | const llvm_field_types = llvm_field_types_buf[0..f80_layout.llvm_fields_len]; | ||
| 3965 | const f80_llvm_ty = try o.builder.structType(.normal, llvm_field_types); | ||
| 3966 | const f80_repr: packed struct { mantissa: u64, exponent: u16 } = @bitCast(val); | ||
| 3967 | var llvm_field_vals_buf: [5]Builder.Constant = undefined; | ||
| 3968 | const llvm_field_vals = llvm_field_vals_buf[0..f80_layout.llvm_fields_len]; | ||
| 3969 | for ( | ||
| 3970 | llvm_field_vals, | ||
| 3971 | llvm_field_tags_buf[0..f80_layout.llvm_fields_len], | ||
| 3972 | llvm_field_types, | ||
| 3973 | ) |*llvm_field_val, llvm_field_tag, llvm_field_type| | ||
| 3974 | llvm_field_val.* = switch (llvm_field_tag) { | ||
| 3975 | .mantissa => try o.builder.intConst(llvm_field_type, f80_repr.mantissa), | ||
| 3976 | .exponent => try o.builder.intConst(llvm_field_type, f80_repr.exponent), | ||
| 3977 | .padding => try o.builder.undefConst(llvm_field_type), | ||
| 3978 | }; | ||
| 3979 | return o.builder.structConst(f80_llvm_ty, llvm_field_vals); | ||
| 3980 | } | ||
| 3981 | |||
| 3982 | pub fn f128Const(o: *Object, val: f128) Allocator.Error!Builder.Constant { | ||
| 3983 | switch (std.zig.target.compilerRtFloatAbi(o.zcu.getTarget(), 128)) { | ||
| 3984 | .hard => return o.builder.fp128Const(val), | ||
| 3985 | .soft => {}, | ||
| 3986 | } | ||
| 3987 | var llvm_field_tags_buf: [5]SoftF128Layout.LlvmFieldTag = undefined; | ||
| 3988 | var llvm_field_types_buf: [5]Builder.Type = undefined; | ||
| 3989 | const f128_layout = try o.softF128Layout(.{ | ||
| 3990 | .llvm_field_tags_buf = &llvm_field_tags_buf, | ||
| 3991 | .llvm_field_types_buf = &llvm_field_types_buf, | ||
| 3992 | }); | ||
| 3993 | const llvm_field_types = llvm_field_types_buf[0..f128_layout.llvm_fields_len]; | ||
| 3994 | const f128_llvm_ty = try o.builder.structType(.normal, llvm_field_types); | ||
| 3995 | const f128_repr: packed struct { lo: u64, hi: u64 } = @bitCast(val); | ||
| 3996 | var llvm_field_vals_buf: [5]Builder.Constant = undefined; | ||
| 3997 | const llvm_field_vals = llvm_field_vals_buf[0..f128_layout.llvm_fields_len]; | ||
| 3998 | for ( | ||
| 3999 | llvm_field_vals, | ||
| 4000 | llvm_field_tags_buf[0..f128_layout.llvm_fields_len], | ||
| 4001 | llvm_field_types, | ||
| 4002 | ) |*llvm_field_val, llvm_field_tag, llvm_field_type| | ||
| 4003 | llvm_field_val.* = switch (llvm_field_tag) { | ||
| 4004 | .lo => try o.builder.intConst(llvm_field_type, f128_repr.lo), | ||
| 4005 | .hi => try o.builder.intConst(llvm_field_type, f128_repr.hi), | ||
| 4006 | .padding => try o.builder.undefConst(llvm_field_type), | ||
| 4007 | }; | ||
| 4008 | return o.builder.structConst(f128_llvm_ty, llvm_field_vals); | ||
| 4009 | } | ||
| 4010 | |||
| 4011 | pub fn lowerConstRef( | ||
| 4012 | o: *Object, | ||
| 4013 | constant: Builder.Constant, | ||
| 4014 | @"align": Builder.Alignment, | ||
| 4015 | ) Allocator.Error!Builder.Constant { | ||
| 4016 | assert(@"align" != .default); | ||
| 4017 | const zcu = o.zcu; | ||
| 4018 | const gpa = zcu.comp.gpa; | ||
| 4019 | const gop = try o.const_map.getOrPut(gpa, constant); | ||
| 4020 | if (gop.found_existing) { | ||
| 4021 | // Keep the greater of the two alignments. | ||
| 4022 | const llvm_variable = gop.value_ptr.*; | ||
| 4023 | const llvm_old_align = llvm_variable.getAlignment(&o.builder); | ||
| 4024 | const llvm_new_align = llvm_old_align.max(@"align"); | ||
| 4025 | llvm_variable.setAlignment(llvm_new_align, &o.builder); | ||
| 4026 | return llvm_variable.ptrConst(&o.builder).global.toConst(); | ||
| 4027 | } | ||
| 4028 | errdefer assert(o.const_map.remove(constant)); | ||
| 4029 | |||
| 4030 | const llvm_ty = constant.typeOf(&o.builder); | ||
| 4031 | const llvm_addrspace = toLlvmAddressSpace(.generic, zcu.getTarget()); | ||
| 4032 | const llvm_variable = try o.builder.addVariable(.empty, llvm_ty, llvm_addrspace); | ||
| 4033 | gop.value_ptr.* = llvm_variable; | ||
| 4034 | try llvm_variable.setInitializer(constant, &o.builder); | ||
| 4035 | llvm_variable.setMutability(.constant, &o.builder); | ||
| 4036 | llvm_variable.setAlignment(@"align", &o.builder); | ||
| 4037 | const llvm_global = llvm_variable.ptrConst(&o.builder).global; | ||
| 4038 | llvm_global.setLinkage(.private, &o.builder); | ||
| 4039 | llvm_global.setUnnamedAddr(.unnamed_addr, &o.builder); | ||
| 4040 | return llvm_global.toConst(); | ||
| 4041 | } | ||
| 4042 | |||
| 3840 | fn lowerPtr( | 4043 | fn lowerPtr( |
| 3841 | o: *Object, | 4044 | o: *Object, |
| 3842 | ptr_val: InternPool.Index, | 4045 | ptr_val: InternPool.Index, |
| ... | @@ -3856,7 +4059,7 @@ pub const Object = struct { | ... | @@ -3856,7 +4059,7 @@ pub const Object = struct { |
| 3856 | const orig_ptr_ty: Type = .fromInterned(uav.orig_ty); | 4059 | const orig_ptr_ty: Type = .fromInterned(uav.orig_ty); |
| 3857 | const base_ptr = try o.lowerUavRef( | 4060 | const base_ptr = try o.lowerUavRef( |
| 3858 | uav.val, | 4061 | uav.val, |
| 3859 | orig_ptr_ty.ptrAlignment(zcu), | 4062 | orig_ptr_ty.ptrAlignment(zcu).toLlvm(), |
| 3860 | orig_ptr_ty.ptrAddressSpace(zcu), | 4063 | orig_ptr_ty.ptrAddressSpace(zcu), |
| 3861 | ); | 4064 | ); |
| 3862 | return o.builder.gepConst(.inbounds, .i8, base_ptr, null, &.{ | 4065 | return o.builder.gepConst(.inbounds, .i8, base_ptr, null, &.{ |
| ... | @@ -3865,8 +4068,8 @@ pub const Object = struct { | ... | @@ -3865,8 +4068,8 @@ pub const Object = struct { |
| 3865 | }, | 4068 | }, |
| 3866 | .int => try o.builder.castConst( | 4069 | .int => try o.builder.castConst( |
| 3867 | .inttoptr, | 4070 | .inttoptr, |
| 3868 | try o.builder.intConst(try o.lowerType(.usize, .by_value), offset), | 4071 | try o.builder.intConst(try o.lowerType(.usize, .as_value), offset), |
| 3869 | try o.lowerType(.fromInterned(ptr.ty), .by_value), | 4072 | try o.lowerType(.fromInterned(ptr.ty), .as_value), |
| 3870 | ), | 4073 | ), |
| 3871 | .eu_payload => |eu_ptr| try o.lowerPtr( | 4074 | .eu_payload => |eu_ptr| try o.lowerPtr( |
| 3872 | eu_ptr, | 4075 | eu_ptr, |
| ... | @@ -3908,12 +4111,12 @@ pub const Object = struct { | ... | @@ -3908,12 +4111,12 @@ pub const Object = struct { |
| 3908 | 4111 | ||
| 3909 | pub fn lowerPtrToVoid( | 4112 | pub fn lowerPtrToVoid( |
| 3910 | o: *Object, | 4113 | o: *Object, |
| 3911 | /// Must not be `.none`. | 4114 | /// Must not be `.default`. |
| 3912 | @"align": InternPool.Alignment, | 4115 | @"align": Builder.Alignment, |
| 3913 | @"addrspace": std.lang.AddressSpace, | 4116 | @"addrspace": std.lang.AddressSpace, |
| 3914 | ) Allocator.Error!Builder.Constant { | 4117 | ) Allocator.Error!Builder.Constant { |
| 3915 | const addr: u64 = @"align".toByteUnits().?; | 4118 | const addr: u64 = @"align".toByteUnits().?; |
| 3916 | const llvm_usize = try o.lowerType(.usize, .by_value); | 4119 | const llvm_usize = try o.lowerType(.usize, .as_value); |
| 3917 | const llvm_addr = try o.builder.intConst(llvm_usize, addr); | 4120 | const llvm_addr = try o.builder.intConst(llvm_usize, addr); |
| 3918 | const llvm_ptr_ty = try o.builder.ptrType(toLlvmAddressSpace(@"addrspace", o.zcu.getTarget())); | 4121 | const llvm_ptr_ty = try o.builder.ptrType(toLlvmAddressSpace(@"addrspace", o.zcu.getTarget())); |
| 3919 | return o.builder.castConst(.inttoptr, llvm_addr, llvm_ptr_ty); | 4122 | return o.builder.castConst(.inttoptr, llvm_addr, llvm_ptr_ty); |
| ... | @@ -3922,11 +4125,11 @@ pub const Object = struct { | ... | @@ -3922,11 +4125,11 @@ pub const Object = struct { |
| 3922 | pub fn lowerUavRef( | 4125 | pub fn lowerUavRef( |
| 3923 | o: *Object, | 4126 | o: *Object, |
| 3924 | uav_val: InternPool.Index, | 4127 | uav_val: InternPool.Index, |
| 3925 | /// Must not be `.none`. | 4128 | /// Must not be `.default`. |
| 3926 | @"align": InternPool.Alignment, | 4129 | @"align": Builder.Alignment, |
| 3927 | @"addrspace": std.lang.AddressSpace, | 4130 | @"addrspace": std.lang.AddressSpace, |
| 3928 | ) Allocator.Error!Builder.Constant { | 4131 | ) Allocator.Error!Builder.Constant { |
| 3929 | assert(@"align" != .none); | 4132 | assert(@"align" != .default); |
| 3930 | 4133 | ||
| 3931 | const zcu = o.zcu; | 4134 | const zcu = o.zcu; |
| 3932 | const ip = &zcu.intern_pool; | 4135 | const ip = &zcu.intern_pool; |
| ... | @@ -3951,19 +4154,18 @@ pub const Object = struct { | ... | @@ -3951,19 +4154,18 @@ pub const Object = struct { |
| 3951 | // Keep the greater of the two alignments. | 4154 | // Keep the greater of the two alignments. |
| 3952 | const llvm_variable = gop.value_ptr.*; | 4155 | const llvm_variable = gop.value_ptr.*; |
| 3953 | const llvm_old_align = llvm_variable.getAlignment(&o.builder); | 4156 | const llvm_old_align = llvm_variable.getAlignment(&o.builder); |
| 3954 | const llvm_new_align = llvm_old_align.max(@"align".toLlvm()); | 4157 | const llvm_new_align = llvm_old_align.max(@"align"); |
| 3955 | llvm_variable.setAlignment(llvm_new_align, &o.builder); | 4158 | llvm_variable.setAlignment(llvm_new_align, &o.builder); |
| 3956 | return llvm_variable.ptrConst(&o.builder).global.toConst(); | 4159 | return llvm_variable.ptrConst(&o.builder).global.toConst(); |
| 3957 | } | 4160 | } |
| 3958 | errdefer assert(o.uav_map.remove(.{ .val = uav_val, .@"addrspace" = @"addrspace" })); | 4161 | errdefer assert(o.uav_map.remove(.{ .val = uav_val, .@"addrspace" = @"addrspace" })); |
| 3959 | 4162 | ||
| 3960 | const llvm_ty = try o.lowerType(uav_ty, .in_memory); | ||
| 3961 | const llvm_name = try o.builder.strtabStringFmt("__anon_{d}", .{@backingInt(uav_val)}); | 4163 | const llvm_name = try o.builder.strtabStringFmt("__anon_{d}", .{@backingInt(uav_val)}); |
| 3962 | const llvm_variable = try o.builder.addVariable(llvm_name, llvm_ty, llvm_addrspace); | 4164 | const llvm_variable = try o.builder.addVariable(llvm_name, .void, llvm_addrspace); |
| 3963 | gop.value_ptr.* = llvm_variable; | 4165 | gop.value_ptr.* = llvm_variable; |
| 3964 | try llvm_variable.setInitializer(try o.lowerValue(uav_val, .in_memory), &o.builder); | 4166 | try llvm_variable.setInitializer(try o.lowerValue(uav_val, .in_memory), &o.builder); |
| 3965 | llvm_variable.setMutability(.constant, &o.builder); | 4167 | llvm_variable.setMutability(.constant, &o.builder); |
| 3966 | llvm_variable.setAlignment(@"align".toLlvm(), &o.builder); | 4168 | llvm_variable.setAlignment(@"align", &o.builder); |
| 3967 | const llvm_global = llvm_variable.ptrConst(&o.builder).global; | 4169 | const llvm_global = llvm_variable.ptrConst(&o.builder).global; |
| 3968 | llvm_global.setLinkage(if (o.builder.strip) .private else .internal, &o.builder); | 4170 | llvm_global.setLinkage(if (o.builder.strip) .private else .internal, &o.builder); |
| 3969 | llvm_global.setUnnamedAddr(.unnamed_addr, &o.builder); | 4171 | llvm_global.setUnnamedAddr(.unnamed_addr, &o.builder); |
| ... | @@ -3982,7 +4184,7 @@ pub const Object = struct { | ... | @@ -3982,7 +4184,7 @@ pub const Object = struct { |
| 3982 | .none => nav_ty.abiAlignment(zcu), | 4184 | .none => nav_ty.abiAlignment(zcu), |
| 3983 | else => |a| a, | 4185 | else => |a| a, |
| 3984 | }; | 4186 | }; |
| 3985 | return o.lowerPtrToVoid(nav_align, nav.resolved.?.@"addrspace"); | 4187 | return o.lowerPtrToVoid(nav_align.toLlvm(), nav.resolved.?.@"addrspace"); |
| 3986 | } | 4188 | } |
| 3987 | 4189 | ||
| 3988 | const gop = try o.nav_map.getOrPut(gpa, nav_id); | 4190 | const gop = try o.nav_map.getOrPut(gpa, nav_id); |
| ... | @@ -4011,7 +4213,7 @@ pub const Object = struct { | ... | @@ -4011,7 +4213,7 @@ pub const Object = struct { |
| 4011 | attributes: *Builder.FunctionAttributes.Wip, | 4213 | attributes: *Builder.FunctionAttributes.Wip, |
| 4012 | param_ty: Type, | 4214 | param_ty: Type, |
| 4013 | param_index: u32, | 4215 | param_index: u32, |
| 4014 | fn_info: InternPool.Key.FuncType, | 4216 | fn_info: FuncInfo, |
| 4015 | llvm_arg_i: u32, | 4217 | llvm_arg_i: u32, |
| 4016 | ) Allocator.Error!void { | 4218 | ) Allocator.Error!void { |
| 4017 | const zcu = o.zcu; | 4219 | const zcu = o.zcu; |
| ... | @@ -4051,19 +4253,26 @@ pub const Object = struct { | ... | @@ -4051,19 +4253,26 @@ pub const Object = struct { |
| 4051 | }; | 4253 | }; |
| 4052 | } | 4254 | } |
| 4053 | 4255 | ||
| 4256 | pub const Byval = struct { alignment: InternPool.Alignment = .none }; | ||
| 4054 | pub fn addByRefParamAttrs( | 4257 | pub fn addByRefParamAttrs( |
| 4055 | o: *Object, | 4258 | o: *Object, |
| 4056 | attributes: *Builder.FunctionAttributes.Wip, | 4259 | attributes: *Builder.FunctionAttributes.Wip, |
| 4057 | llvm_arg_i: u32, | 4260 | llvm_arg_i: u32, |
| 4058 | byval: bool, | 4261 | maybe_byval: ?Byval, |
| 4059 | param_ty: Type, | 4262 | param_ty: Type, |
| 4060 | ) Allocator.Error!void { | 4263 | ) Allocator.Error!void { |
| 4061 | const llvm_param_ty = try o.lowerType(param_ty, .in_memory); | 4264 | const llvm_param_ty = try o.lowerType(param_ty, .in_memory); |
| 4062 | const alignment = param_ty.abiAlignment(o.zcu).toLlvm(); | ||
| 4063 | try attributes.addParamAttr(llvm_arg_i, .nonnull, &o.builder); | ||
| 4064 | try attributes.addParamAttr(llvm_arg_i, .readonly, &o.builder); | 4265 | try attributes.addParamAttr(llvm_arg_i, .readonly, &o.builder); |
| 4065 | try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = .wrap(alignment) }, &o.builder); | 4266 | try attributes.addParamAttr(llvm_arg_i, .nonnull, &o.builder); |
| 4066 | if (byval) try attributes.addParamAttr(llvm_arg_i, .{ .byval = llvm_param_ty }, &o.builder); | 4267 | try attributes.addParamAttr(llvm_arg_i, .noundef, &o.builder); |
| 4268 | const alignment = if (maybe_byval) |byval| alignment: { | ||
| 4269 | try attributes.addParamAttr(llvm_arg_i, .{ .byval = llvm_param_ty }, &o.builder); | ||
| 4270 | break :alignment byval.alignment; | ||
| 4271 | } else .none; | ||
| 4272 | try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = .wrap(switch (alignment) { | ||
| 4273 | .none => param_ty.abiAlignment(o.zcu), | ||
| 4274 | else => alignment, | ||
| 4275 | }.toLlvm()) }, &o.builder); | ||
| 4067 | } | 4276 | } |
| 4068 | 4277 | ||
| 4069 | pub fn getErrorNameTable(o: *Object) Allocator.Error!Builder.Variable.Index { | 4278 | pub fn getErrorNameTable(o: *Object) Allocator.Error!Builder.Variable.Index { |
| ... | @@ -4071,18 +4280,18 @@ pub const Object = struct { | ... | @@ -4071,18 +4280,18 @@ pub const Object = struct { |
| 4071 | 4280 | ||
| 4072 | const name = try o.builder.strtabString("__zig_error_name_table"); | 4281 | const name = try o.builder.strtabString("__zig_error_name_table"); |
| 4073 | // TODO: Address space | 4282 | // TODO: Address space |
| 4074 | const variable_index = try o.builder.addVariable(name, .ptr, .default); | 4283 | const llvm_variable = try o.builder.addVariable(name, .ptr, .default); |
| 4075 | variable_index.setMutability(.constant, &o.builder); | 4284 | llvm_variable.setMutability(.constant, &o.builder); |
| 4076 | variable_index.setAlignment( | 4285 | llvm_variable.setAlignment( |
| 4077 | Type.slice_const_u8_sentinel_0.abiAlignment(o.zcu).toLlvm(), | 4286 | Type.slice_const_u8_sentinel_0.abiAlignment(o.zcu).toLlvm(), |
| 4078 | &o.builder, | 4287 | &o.builder, |
| 4079 | ); | 4288 | ); |
| 4080 | const global_index = variable_index.ptrConst(&o.builder).global; | 4289 | const llvm_global = llvm_variable.ptrConst(&o.builder).global; |
| 4081 | global_index.setLinkage(.private, &o.builder); | 4290 | llvm_global.setLinkage(.private, &o.builder); |
| 4082 | global_index.setUnnamedAddr(.unnamed_addr, &o.builder); | 4291 | llvm_global.setUnnamedAddr(.unnamed_addr, &o.builder); |
| 4083 | 4292 | ||
| 4084 | o.error_name_table = variable_index; | 4293 | o.error_name_table = llvm_variable; |
| 4085 | return variable_index; | 4294 | return llvm_variable; |
| 4086 | } | 4295 | } |
| 4087 | 4296 | ||
| 4088 | pub fn getErrorsLen(o: *Object) Allocator.Error!Builder.Variable.Index { | 4297 | pub fn getErrorsLen(o: *Object) Allocator.Error!Builder.Variable.Index { |
| ... | @@ -4090,13 +4299,13 @@ pub const Object = struct { | ... | @@ -4090,13 +4299,13 @@ pub const Object = struct { |
| 4090 | if (o.errors_len_variable == .none) { | 4299 | if (o.errors_len_variable == .none) { |
| 4091 | const llvm_err_int_ty = try o.errorIntType(.in_memory); | 4300 | const llvm_err_int_ty = try o.errorIntType(.in_memory); |
| 4092 | const name = try builder.strtabString("__zig_errors_len"); | 4301 | const name = try builder.strtabString("__zig_errors_len"); |
| 4093 | const variable_index = try builder.addVariable(name, llvm_err_int_ty, .default); | 4302 | const llvm_variable = try builder.addVariable(name, llvm_err_int_ty, .default); |
| 4094 | variable_index.setMutability(.constant, builder); | 4303 | llvm_variable.setMutability(.constant, builder); |
| 4095 | variable_index.setAlignment(Type.errorAbiAlignment(o.zcu).toLlvm(), builder); | 4304 | llvm_variable.setAlignment(Type.errorAbiAlignment(o.zcu).toLlvm(), builder); |
| 4096 | const global_index = variable_index.ptrConst(&o.builder).global; | 4305 | const llvm_global = llvm_variable.ptrConst(&o.builder).global; |
| 4097 | global_index.setLinkage(.private, builder); | 4306 | llvm_global.setLinkage(.private, builder); |
| 4098 | global_index.setUnnamedAddr(.unnamed_addr, builder); | 4307 | llvm_global.setUnnamedAddr(.unnamed_addr, builder); |
| 4099 | o.errors_len_variable = variable_index; | 4308 | o.errors_len_variable = llvm_variable; |
| 4100 | } | 4309 | } |
| 4101 | return o.errors_len_variable; | 4310 | return o.errors_len_variable; |
| 4102 | } | 4311 | } |
| ... | @@ -4108,43 +4317,43 @@ pub const Object = struct { | ... | @@ -4108,43 +4317,43 @@ pub const Object = struct { |
| 4108 | const gop = try o.enum_tag_name_map.getOrPut(o.gpa, enum_ty.toIntern()); | 4317 | const gop = try o.enum_tag_name_map.getOrPut(o.gpa, enum_ty.toIntern()); |
| 4109 | if (gop.found_existing) return gop.value_ptr.*; | 4318 | if (gop.found_existing) return gop.value_ptr.*; |
| 4110 | errdefer assert(o.enum_tag_name_map.remove(enum_ty.toIntern())); | 4319 | errdefer assert(o.enum_tag_name_map.remove(enum_ty.toIntern())); |
| 4111 | const function_index = try o.builder.addFunction( | 4320 | const llvm_function = try o.builder.addFunction( |
| 4112 | // Dummy function type; `updateEnumTagNameFunction` will replace it with the correct type. | 4321 | // Dummy function type; `updateEnumTagNameFunction` will replace it with the correct type. |
| 4113 | // TODO: change the builder API so we don't need to do this. | 4322 | // TODO: change the builder API so we don't need to do this. |
| 4114 | try o.builder.fnType(.void, &.{}, .normal), | 4323 | try o.builder.fnType(.void, &.{}, .normal), |
| 4115 | try o.builder.strtabStringFmt("__zig_tag_name_{f}", .{enum_ty.containerTypeName(ip).fmt(ip)}), | 4324 | try o.builder.strtabStringFmt("__zig_tag_name_{f}", .{enum_ty.containerTypeName(ip).fmt(ip)}), |
| 4116 | toLlvmAddressSpace(.generic, zcu.getTarget()), | 4325 | toLlvmAddressSpace(.generic, zcu.getTarget()), |
| 4117 | ); | 4326 | ); |
| 4118 | gop.value_ptr.* = function_index; | 4327 | gop.value_ptr.* = llvm_function; |
| 4119 | try o.updateEnumTagNameFunction(enum_ty, function_index); | 4328 | try o.updateEnumTagNameFunction(enum_ty, llvm_function); |
| 4120 | return function_index; | 4329 | return llvm_function; |
| 4121 | } | 4330 | } |
| 4122 | fn updateEnumTagNameFunction( | 4331 | fn updateEnumTagNameFunction( |
| 4123 | o: *Object, | 4332 | o: *Object, |
| 4124 | enum_ty: Type, | 4333 | enum_ty: Type, |
| 4125 | function_index: Builder.Function.Index, | 4334 | llvm_function: Builder.Function.Index, |
| 4126 | ) Allocator.Error!void { | 4335 | ) Allocator.Error!void { |
| 4127 | const zcu = o.zcu; | 4336 | const zcu = o.zcu; |
| 4128 | const ip = &zcu.intern_pool; | 4337 | const ip = &zcu.intern_pool; |
| 4129 | const loaded_enum = ip.loadEnumType(enum_ty.toIntern()); | 4338 | const loaded_enum = ip.loadEnumType(enum_ty.toIntern()); |
| 4130 | 4339 | ||
| 4131 | const llvm_usize_ty = try o.lowerType(.usize, .by_value); | 4340 | const llvm_usize_ty = try o.lowerType(.usize, .as_value); |
| 4132 | const llvm_ret_ty = try o.lowerType(.slice_const_u8_sentinel_0, .by_value); | 4341 | const llvm_ret_ty = try o.lowerType(.slice_const_u8_sentinel_0, .as_value); |
| 4133 | const llvm_int_ty = try o.lowerType(.fromInterned(loaded_enum.int_tag_type), .by_value); | 4342 | const llvm_int_ty = try o.lowerType(.fromInterned(loaded_enum.int_tag_type), .as_value); |
| 4134 | 4343 | ||
| 4135 | function_index.ptrConst(&o.builder).global.ptr(&o.builder).type = | 4344 | llvm_function.ptrConst(&o.builder).global.ptr(&o.builder).type = |
| 4136 | try o.builder.fnType(llvm_ret_ty, &.{llvm_int_ty}, .normal); | 4345 | try o.builder.fnType(llvm_ret_ty, &.{llvm_int_ty}, .normal); |
| 4137 | 4346 | ||
| 4138 | var attributes: Builder.FunctionAttributes.Wip = .{}; | 4347 | var attributes: Builder.FunctionAttributes.Wip = .{}; |
| 4139 | defer attributes.deinit(&o.builder); | 4348 | defer attributes.deinit(&o.builder); |
| 4140 | try o.addCommonFnAttributes(&attributes, zcu.root_mod, zcu.root_mod.omit_frame_pointer); | 4349 | try o.addCommonFnAttributes(&attributes, zcu.root_mod, zcu.root_mod.omit_frame_pointer); |
| 4141 | 4350 | ||
| 4142 | function_index.setLinkage(if (o.builder.strip) .private else .internal, &o.builder); | 4351 | llvm_function.setLinkage(if (o.builder.strip) .private else .internal, &o.builder); |
| 4143 | function_index.setCallConv(.fastcc, &o.builder); | 4352 | llvm_function.setCallConv(.fastcc, &o.builder); |
| 4144 | function_index.setAttributes(try attributes.finish(&o.builder), &o.builder); | 4353 | llvm_function.setAttributes(try attributes.finish(&o.builder), &o.builder); |
| 4145 | 4354 | ||
| 4146 | var wip = try Builder.WipFunction.init(&o.builder, .{ | 4355 | var wip = try Builder.WipFunction.init(&o.builder, .{ |
| 4147 | .function = function_index, | 4356 | .function = llvm_function, |
| 4148 | .strip = true, | 4357 | .strip = true, |
| 4149 | }); | 4358 | }); |
| 4150 | defer wip.deinit(); | 4359 | defer wip.deinit(); |
| ... | @@ -4163,23 +4372,23 @@ pub const Object = struct { | ... | @@ -4163,23 +4372,23 @@ pub const Object = struct { |
| 4163 | for (0..loaded_enum.field_names.len) |field_index| { | 4372 | for (0..loaded_enum.field_names.len) |field_index| { |
| 4164 | const name = try o.builder.stringNull(loaded_enum.field_names.get(ip)[field_index].toSlice(ip)); | 4373 | const name = try o.builder.stringNull(loaded_enum.field_names.get(ip)[field_index].toSlice(ip)); |
| 4165 | const name_init = try o.builder.stringConst(name); | 4374 | const name_init = try o.builder.stringConst(name); |
| 4166 | const name_variable_index = try o.builder.addVariable(.empty, name_init.typeOf(&o.builder), .default); | 4375 | const name_llvm_variable = try o.builder.addVariable(.empty, name_init.typeOf(&o.builder), .default); |
| 4167 | try name_variable_index.setInitializer(name_init, &o.builder); | 4376 | try name_llvm_variable.setInitializer(name_init, &o.builder); |
| 4168 | name_variable_index.setMutability(.constant, &o.builder); | 4377 | name_llvm_variable.setMutability(.constant, &o.builder); |
| 4169 | name_variable_index.setAlignment(comptime Builder.Alignment.fromByteUnits(1), &o.builder); | 4378 | name_llvm_variable.setAlignment(comptime .fromByteUnits(1), &o.builder); |
| 4170 | const name_global_index = name_variable_index.ptrConst(&o.builder).global; | 4379 | const name_llvm_global = name_llvm_variable.ptrConst(&o.builder).global; |
| 4171 | name_global_index.setLinkage(.private, &o.builder); | 4380 | name_llvm_global.setLinkage(.private, &o.builder); |
| 4172 | name_global_index.setUnnamedAddr(.unnamed_addr, &o.builder); | 4381 | name_llvm_global.setUnnamedAddr(.unnamed_addr, &o.builder); |
| 4173 | 4382 | ||
| 4174 | const name_val = try o.builder.structValue(llvm_ret_ty, &.{ | 4383 | const name_val = try o.builder.structValue(llvm_ret_ty, &.{ |
| 4175 | name_global_index.toConst(), | 4384 | name_llvm_global.toConst(), |
| 4176 | try o.builder.intConst(llvm_usize_ty, name.slice(&o.builder).?.len - 1), | 4385 | try o.builder.intConst(llvm_usize_ty, name.slice(&o.builder).?.len - 1), |
| 4177 | }); | 4386 | }); |
| 4178 | 4387 | ||
| 4179 | const return_block = try wip.block(1, "Name"); | 4388 | const return_block = try wip.block(1, "Name"); |
| 4180 | const llvm_tag_val = switch (loaded_enum.field_values.getOrNone(ip, field_index)) { | 4389 | const llvm_tag_val = switch (loaded_enum.field_values.getOrNone(ip, field_index)) { |
| 4181 | .none => try o.builder.intConst(llvm_int_ty, field_index), // auto-numbered | 4390 | .none => try o.builder.intConst(llvm_int_ty, field_index), // auto-numbered |
| 4182 | else => |tag_val_ip| try o.lowerValue(tag_val_ip, .by_value), | 4391 | else => |tag_val_ip| try o.lowerValue(tag_val_ip, .as_value), |
| 4183 | }; | 4392 | }; |
| 4184 | try wip_switch.addCase(llvm_tag_val, return_block, &wip); | 4393 | try wip_switch.addCase(llvm_tag_val, return_block, &wip); |
| 4185 | 4394 | ||
| ... | @@ -4205,40 +4414,40 @@ pub const Object = struct { | ... | @@ -4205,40 +4414,40 @@ pub const Object = struct { |
| 4205 | const gop = try o.named_enum_map.getOrPut(o.gpa, enum_ty.toIntern()); | 4414 | const gop = try o.named_enum_map.getOrPut(o.gpa, enum_ty.toIntern()); |
| 4206 | if (gop.found_existing) return gop.value_ptr.*; | 4415 | if (gop.found_existing) return gop.value_ptr.*; |
| 4207 | errdefer assert(o.named_enum_map.remove(enum_ty.toIntern())); | 4416 | errdefer assert(o.named_enum_map.remove(enum_ty.toIntern())); |
| 4208 | const function_index = try o.builder.addFunction( | 4417 | const llvm_function = try o.builder.addFunction( |
| 4209 | // Dummy function type; `updateIsNamedEnumValue` will replace it with the correct type. | 4418 | // Dummy function type; `updateIsNamedEnumValue` will replace it with the correct type. |
| 4210 | // TODO: change the builder API so we don't need to do this. | 4419 | // TODO: change the builder API so we don't need to do this. |
| 4211 | try o.builder.fnType(.void, &.{}, .normal), | 4420 | try o.builder.fnType(.void, &.{}, .normal), |
| 4212 | try o.builder.strtabStringFmt("__zig_is_named_enum_value_{f}", .{enum_ty.containerTypeName(ip).fmt(ip)}), | 4421 | try o.builder.strtabStringFmt("__zig_is_named_enum_value_{f}", .{enum_ty.containerTypeName(ip).fmt(ip)}), |
| 4213 | toLlvmAddressSpace(.generic, zcu.getTarget()), | 4422 | toLlvmAddressSpace(.generic, zcu.getTarget()), |
| 4214 | ); | 4423 | ); |
| 4215 | gop.value_ptr.* = function_index; | 4424 | gop.value_ptr.* = llvm_function; |
| 4216 | try o.updateIsNamedEnumValueFunction(enum_ty, function_index); | 4425 | try o.updateIsNamedEnumValueFunction(enum_ty, llvm_function); |
| 4217 | return function_index; | 4426 | return llvm_function; |
| 4218 | } | 4427 | } |
| 4219 | fn updateIsNamedEnumValueFunction( | 4428 | fn updateIsNamedEnumValueFunction( |
| 4220 | o: *Object, | 4429 | o: *Object, |
| 4221 | enum_ty: Type, | 4430 | enum_ty: Type, |
| 4222 | function_index: Builder.Function.Index, | 4431 | llvm_function: Builder.Function.Index, |
| 4223 | ) Allocator.Error!void { | 4432 | ) Allocator.Error!void { |
| 4224 | const zcu = o.zcu; | 4433 | const zcu = o.zcu; |
| 4225 | const ip = &zcu.intern_pool; | 4434 | const ip = &zcu.intern_pool; |
| 4226 | const loaded_enum = ip.loadEnumType(enum_ty.toIntern()); | 4435 | const loaded_enum = ip.loadEnumType(enum_ty.toIntern()); |
| 4227 | 4436 | ||
| 4228 | const llvm_int_ty = try o.lowerType(.fromInterned(loaded_enum.int_tag_type), .by_value); | 4437 | const llvm_int_ty = try o.lowerType(.fromInterned(loaded_enum.int_tag_type), .as_value); |
| 4229 | function_index.ptrConst(&o.builder).global.ptr(&o.builder).type = | 4438 | llvm_function.ptrConst(&o.builder).global.ptr(&o.builder).type = |
| 4230 | try o.builder.fnType(.i1, &.{llvm_int_ty}, .normal); | 4439 | try o.builder.fnType(.i1, &.{llvm_int_ty}, .normal); |
| 4231 | 4440 | ||
| 4232 | var attributes: Builder.FunctionAttributes.Wip = .{}; | 4441 | var attributes: Builder.FunctionAttributes.Wip = .{}; |
| 4233 | defer attributes.deinit(&o.builder); | 4442 | defer attributes.deinit(&o.builder); |
| 4234 | try o.addCommonFnAttributes(&attributes, zcu.root_mod, zcu.root_mod.omit_frame_pointer); | 4443 | try o.addCommonFnAttributes(&attributes, zcu.root_mod, zcu.root_mod.omit_frame_pointer); |
| 4235 | 4444 | ||
| 4236 | function_index.setLinkage(if (o.builder.strip) .private else .internal, &o.builder); | 4445 | llvm_function.setLinkage(if (o.builder.strip) .private else .internal, &o.builder); |
| 4237 | function_index.setCallConv(.fastcc, &o.builder); | 4446 | llvm_function.setCallConv(.fastcc, &o.builder); |
| 4238 | function_index.setAttributes(try attributes.finish(&o.builder), &o.builder); | 4447 | llvm_function.setAttributes(try attributes.finish(&o.builder), &o.builder); |
| 4239 | 4448 | ||
| 4240 | var wip: Builder.WipFunction = try .init(&o.builder, .{ | 4449 | var wip: Builder.WipFunction = try .init(&o.builder, .{ |
| 4241 | .function = function_index, | 4450 | .function = llvm_function, |
| 4242 | .strip = true, | 4451 | .strip = true, |
| 4243 | }); | 4452 | }); |
| 4244 | defer wip.deinit(); | 4453 | defer wip.deinit(); |
| ... | @@ -4252,7 +4461,7 @@ pub const Object = struct { | ... | @@ -4252,7 +4461,7 @@ pub const Object = struct { |
| 4252 | 4461 | ||
| 4253 | if (loaded_enum.field_values.len > 0) { | 4462 | if (loaded_enum.field_values.len > 0) { |
| 4254 | for (loaded_enum.field_values.get(ip)) |tag_val_ip| { | 4463 | for (loaded_enum.field_values.get(ip)) |tag_val_ip| { |
| 4255 | const llvm_tag_val = try o.lowerValue(tag_val_ip, .by_value); | 4464 | const llvm_tag_val = try o.lowerValue(tag_val_ip, .as_value); |
| 4256 | try wip_switch.addCase(llvm_tag_val, named_block, &wip); | 4465 | try wip_switch.addCase(llvm_tag_val, named_block, &wip); |
| 4257 | } | 4466 | } |
| 4258 | } else { | 4467 | } else { |
| ... | @@ -4274,20 +4483,27 @@ pub const Object = struct { | ... | @@ -4274,20 +4483,27 @@ pub const Object = struct { |
| 4274 | 4483 | ||
| 4275 | pub fn getLibcFunction( | 4484 | pub fn getLibcFunction( |
| 4276 | o: *Object, | 4485 | o: *Object, |
| 4486 | pt: Zcu.PerThread, | ||
| 4277 | fn_name: Builder.StrtabString, | 4487 | fn_name: Builder.StrtabString, |
| 4278 | param_types: []const Builder.Type, | 4488 | fn_info: FuncInfo, |
| 4279 | return_type: Builder.Type, | ||
| 4280 | ) Allocator.Error!Builder.Function.Index { | 4489 | ) Allocator.Error!Builder.Function.Index { |
| 4281 | if (o.builder.getGlobal(fn_name)) |global| return switch (global.ptrConst(&o.builder).kind) { | 4490 | if (o.builder.getGlobal(fn_name)) |global| return switch (global.ptrConst(&o.builder).kind) { |
| 4282 | .alias => |alias| alias.getAliasee(&o.builder).ptrConst(&o.builder).kind.function, | 4491 | .alias => |alias| alias.getAliasee(&o.builder).ptrConst(&o.builder).kind.function, |
| 4283 | .function => |function| function, | 4492 | .function => |function| function, |
| 4284 | .variable, .replaced => unreachable, | 4493 | .variable, .replaced => unreachable, |
| 4285 | }; | 4494 | }; |
| 4286 | return o.builder.addFunction( | 4495 | const llvm_function = try o.builder.addFunction( |
| 4287 | try o.builder.fnType(return_type, param_types, .normal), | 4496 | try o.lowerFnType(fn_info), |
| 4288 | fn_name, | 4497 | fn_name, |
| 4289 | toLlvmAddressSpace(.generic, o.zcu.getTarget()), | 4498 | toLlvmAddressSpace(.generic, o.zcu.getTarget()), |
| 4290 | ); | 4499 | ); |
| 4500 | var attributes: Builder.FunctionAttributes.Wip = .{}; | ||
| 4501 | defer attributes.deinit(&o.builder); | ||
| 4502 | try o.addCallingConventionFnAttributes(pt, llvm_function, &attributes, .{ | ||
| 4503 | .name = fn_name.slice(&o.builder).?, | ||
| 4504 | }, fn_info); | ||
| 4505 | llvm_function.setAttributes(try attributes.finish(&o.builder), &o.builder); | ||
| 4506 | return llvm_function; | ||
| 4291 | } | 4507 | } |
| 4292 | }; | 4508 | }; |
| 4293 | 4509 | ||
| ... | @@ -4324,7 +4540,7 @@ pub fn toLlvmCallConv(cc: std.lang.CallingConvention, target: *const std.Target) | ... | @@ -4324,7 +4540,7 @@ pub fn toLlvmCallConv(cc: std.lang.CallingConvention, target: *const std.Target) |
| 4324 | std.lang.CallingConvention.SpirvFragmentOptions, | 4540 | std.lang.CallingConvention.SpirvFragmentOptions, |
| 4325 | std.lang.CallingConvention.SpirvMeshOptions, | 4541 | std.lang.CallingConvention.SpirvMeshOptions, |
| 4326 | => .{ null, 0, 0 }, | 4542 | => .{ null, 0, 0 }, |
| 4327 | else => @compileError("TODO: toLlvmCallConv" ++ @tagName(pl)), | 4543 | else => @compileError("TODO: toLlvmCallConv(." ++ @tagName(pl) ++ ")"), |
| 4328 | }, | 4544 | }, |
| 4329 | }; | 4545 | }; |
| 4330 | return .{ | 4546 | return .{ |
| ... | @@ -4360,6 +4576,7 @@ pub fn toLlvmCallConvTag(cc_tag: std.lang.CallingConvention.Tag, target: *const | ... | @@ -4360,6 +4576,7 @@ pub fn toLlvmCallConvTag(cc_tag: std.lang.CallingConvention.Tag, target: *const |
| 4360 | null, | 4576 | null, |
| 4361 | .x86_64_vectorcall => .x86_vectorcallcc, | 4577 | .x86_64_vectorcall => .x86_vectorcallcc, |
| 4362 | .x86_64_interrupt => .x86_intrcc, | 4578 | .x86_64_interrupt => .x86_intrcc, |
| 4579 | .x86_64_preserve_none => .preserve_nonecc, | ||
| 4363 | .x86_stdcall => .x86_stdcallcc, | 4580 | .x86_stdcall => .x86_stdcallcc, |
| 4364 | .x86_fastcall => .x86_fastcallcc, | 4581 | .x86_fastcall => .x86_fastcallcc, |
| 4365 | .x86_thiscall => .x86_thiscallcc, | 4582 | .x86_thiscall => .x86_thiscallcc, |
| ... | @@ -4375,6 +4592,7 @@ pub fn toLlvmCallConvTag(cc_tag: std.lang.CallingConvention.Tag, target: *const | ... | @@ -4375,6 +4592,7 @@ pub fn toLlvmCallConvTag(cc_tag: std.lang.CallingConvention.Tag, target: *const |
| 4375 | .x86_interrupt => .x86_intrcc, | 4592 | .x86_interrupt => .x86_intrcc, |
| 4376 | .aarch64_vfabi => .aarch64_vector_pcs, | 4593 | .aarch64_vfabi => .aarch64_vector_pcs, |
| 4377 | .aarch64_vfabi_sve => .aarch64_sve_vector_pcs, | 4594 | .aarch64_vfabi_sve => .aarch64_sve_vector_pcs, |
| 4595 | .aarch64_preserve_none => .preserve_nonecc, | ||
| 4378 | .arm_aapcs => .arm_aapcscc, | 4596 | .arm_aapcs => .arm_aapcscc, |
| 4379 | .arm_aapcs_vfp => .arm_aapcs_vfpcc, | 4597 | .arm_aapcs_vfp => .arm_aapcs_vfpcc, |
| 4380 | .riscv64_lp64_v => .riscv_vectorcallcc, | 4598 | .riscv64_lp64_v => .riscv_vectorcallcc, |
| ... | @@ -4407,6 +4625,7 @@ pub fn toLlvmCallConvTag(cc_tag: std.lang.CallingConvention.Tag, target: *const | ... | @@ -4407,6 +4625,7 @@ pub fn toLlvmCallConvTag(cc_tag: std.lang.CallingConvention.Tag, target: *const |
| 4407 | .x86_16_interrupt, | 4625 | .x86_16_interrupt, |
| 4408 | .x86_sysv, | 4626 | .x86_sysv, |
| 4409 | .x86_win, | 4627 | .x86_win, |
| 4628 | .x86_mingw, | ||
| 4410 | .x86_thiscall_mingw, | 4629 | .x86_thiscall_mingw, |
| 4411 | .x86_64_x32, | 4630 | .x86_64_x32, |
| 4412 | .aarch64_aapcs, | 4631 | .aarch64_aapcs, |
| ... | @@ -4581,47 +4800,6 @@ fn toLlvmGlobalAddressSpace(wanted_address_space: std.lang.AddressSpace, target: | ... | @@ -4581,47 +4800,6 @@ fn toLlvmGlobalAddressSpace(wanted_address_space: std.lang.AddressSpace, target: |
| 4581 | }; | 4800 | }; |
| 4582 | } | 4801 | } |
| 4583 | 4802 | ||
| 4584 | /// This function returns true if we expect LLVM to lower f16 correctly | ||
| 4585 | /// and false if we expect LLVM to crash if it encounters an f16 type, | ||
| 4586 | /// or if it produces miscompilations. | ||
| 4587 | pub fn backendSupportsF16(target: *const std.Target) bool { | ||
| 4588 | return switch (target.cpu.arch) { | ||
| 4589 | .arm, | ||
| 4590 | .armeb, | ||
| 4591 | .thumb, | ||
| 4592 | .thumbeb, | ||
| 4593 | => target.abi.float() == .soft or target.cpu.has(.arm, .fullfp16), | ||
| 4594 | else => true, | ||
| 4595 | }; | ||
| 4596 | } | ||
| 4597 | |||
| 4598 | /// This function returns true if we expect LLVM to lower x86_fp80 correctly | ||
| 4599 | /// and false if we expect LLVM to crash if it encounters an x86_fp80 type, | ||
| 4600 | /// or if it produces miscompilations. | ||
| 4601 | pub fn backendSupportsF80(target: *const std.Target) bool { | ||
| 4602 | return switch (target.cpu.arch) { | ||
| 4603 | .x86, .x86_64 => !target.cpu.has(.x86, .soft_float), | ||
| 4604 | else => false, | ||
| 4605 | }; | ||
| 4606 | } | ||
| 4607 | |||
| 4608 | /// This function returns true if we expect LLVM to lower f128 correctly, | ||
| 4609 | /// and false if we expect LLVM to crash if it encounters an f128 type, | ||
| 4610 | /// or if it produces miscompilations. | ||
| 4611 | pub fn backendSupportsF128(target: *const std.Target) bool { | ||
| 4612 | return switch (target.cpu.arch) { | ||
| 4613 | // https://github.com/llvm/llvm-project/issues/121122 | ||
| 4614 | .amdgcn, | ||
| 4615 | => false, | ||
| 4616 | .arm, | ||
| 4617 | .armeb, | ||
| 4618 | .thumb, | ||
| 4619 | .thumbeb, | ||
| 4620 | => target.abi.float() == .soft or target.cpu.has(.arm, .fp_armv8), | ||
| 4621 | else => true, | ||
| 4622 | }; | ||
| 4623 | } | ||
| 4624 | |||
| 4625 | /// We need to insert extra padding if LLVM's isn't enough. | 4803 | /// We need to insert extra padding if LLVM's isn't enough. |
| 4626 | /// However we don't want to ever call LLVMABIAlignmentOfType or | 4804 | /// However we don't want to ever call LLVMABIAlignmentOfType or |
| 4627 | /// LLVMABISizeOfType because these functions will trip assertions | 4805 | /// LLVMABISizeOfType because these functions will trip assertions |
src/codegen/llvm/FuncGen.zig+1526-1040| ... | @@ -164,12 +164,12 @@ fn resolveValue(self: *FuncGen, val: Value) Allocator.Error!Builder.Constant { | ... | @@ -164,12 +164,12 @@ fn resolveValue(self: *FuncGen, val: Value) Allocator.Error!Builder.Constant { |
| 164 | const zcu = o.zcu; | 164 | const zcu = o.zcu; |
| 165 | const ty = val.typeOf(zcu); | 165 | const ty = val.typeOf(zcu); |
| 166 | if (!isByRef(ty, zcu)) { | 166 | if (!isByRef(ty, zcu)) { |
| 167 | return o.lowerValue(val.toIntern(), .by_value); | 167 | return o.lowerValue(val.toIntern(), .as_value); |
| 168 | } else { | 168 | } else { |
| 169 | // We need a pointer to a global constant, i.e. a UAV. | 169 | // We need a pointer to a global constant, i.e. a UAV. |
| 170 | return o.lowerUavRef( | 170 | return o.lowerUavRef( |
| 171 | val.toIntern(), | 171 | val.toIntern(), |
| 172 | ty.abiAlignment(zcu), | 172 | ty.abiAlignment(zcu).toLlvm(), |
| 173 | target_util.defaultAddressSpace(zcu.getTarget(), .global_constant), | 173 | target_util.defaultAddressSpace(zcu.getTarget(), .global_constant), |
| 174 | ); | 174 | ); |
| 175 | } | 175 | } |
| ... | @@ -190,10 +190,10 @@ pub fn genMainBody(fg: *FuncGen) TodoError!void { | ... | @@ -190,10 +190,10 @@ pub fn genMainBody(fg: *FuncGen) TodoError!void { |
| 190 | const fn_info = zcu.typeToFunc(fn_ty).?; | 190 | const fn_info = zcu.typeToFunc(fn_ty).?; |
| 191 | const param_types = fn_info.param_types.get(ip); | 191 | const param_types = fn_info.param_types.get(ip); |
| 192 | 192 | ||
| 193 | var it = iterateParamTypes(o, fn_info); | 193 | var it = iterateParamTypes(o, fn_info.cc, fn_info.param_types.get(ip)); |
| 194 | 194 | ||
| 195 | // Populate `fg.ret_ptr`... | 195 | // Populate `fg.ret_ptr`... |
| 196 | fg.ret_ptr = switch (try fnReturnStrat(o, fn_info)) { | 196 | fg.ret_ptr = switch (try fnReturnStrat(o, fn_info.cc, .fromInterned(fn_info.return_type))) { |
| 197 | .sret => rp: { | 197 | .sret => rp: { |
| 198 | defer it.llvm_index += 1; | 198 | defer it.llvm_index += 1; |
| 199 | break :rp fg.wip.arg(it.llvm_index); | 199 | break :rp fg.wip.arg(it.llvm_index); |
| ... | @@ -218,7 +218,7 @@ pub fn genMainBody(fg: *FuncGen) TodoError!void { | ... | @@ -218,7 +218,7 @@ pub fn genMainBody(fg: *FuncGen) TodoError!void { |
| 218 | switch (lowering) { | 218 | switch (lowering) { |
| 219 | .no_bits => continue, | 219 | .no_bits => continue, |
| 220 | .byval => { | 220 | .byval => { |
| 221 | assert(!it.byval_attr); | 221 | assert(it.byval_attr == null); |
| 222 | const param_index = it.zig_index - 1; | 222 | const param_index = it.zig_index - 1; |
| 223 | const param_ty: Type = .fromInterned(param_types[param_index]); | 223 | const param_ty: Type = .fromInterned(param_types[param_index]); |
| 224 | const param = fg.wip.arg(it.llvm_index - 1); | 224 | const param = fg.wip.arg(it.llvm_index - 1); |
| ... | @@ -237,15 +237,16 @@ pub fn genMainBody(fg: *FuncGen) TodoError!void { | ... | @@ -237,15 +237,16 @@ pub fn genMainBody(fg: *FuncGen) TodoError!void { |
| 237 | .byref, .byref_mut => { | 237 | .byref, .byref_mut => { |
| 238 | const param_ty: Type = .fromInterned(param_types[it.zig_index - 1]); | 238 | const param_ty: Type = .fromInterned(param_types[it.zig_index - 1]); |
| 239 | const param = fg.wip.arg(it.llvm_index - 1); | 239 | const param = fg.wip.arg(it.llvm_index - 1); |
| 240 | const alignment = if (it.byval_attr) |byval_attr| byval_attr.alignment else .none; | ||
| 240 | 241 | ||
| 241 | if (isByRef(param_ty, zcu)) { | 242 | if (alignment == .none and isByRef(param_ty, zcu)) { |
| 242 | args.appendAssumeCapacity(param); | 243 | args.appendAssumeCapacity(param); |
| 243 | } else { | 244 | } else { |
| 244 | args.appendAssumeCapacity(try fg.load(param, .none, param_ty, .normal)); | 245 | args.appendAssumeCapacity(try fg.load(param, alignment, param_ty, .normal)); |
| 245 | } | 246 | } |
| 246 | }, | 247 | }, |
| 247 | .abi_sized_int => { | 248 | .abi_sized_int => { |
| 248 | assert(!it.byval_attr); | 249 | assert(it.byval_attr == null); |
| 249 | const param_ty: Type = .fromInterned(param_types[it.zig_index - 1]); | 250 | const param_ty: Type = .fromInterned(param_types[it.zig_index - 1]); |
| 250 | const param = fg.wip.arg(it.llvm_index - 1); | 251 | const param = fg.wip.arg(it.llvm_index - 1); |
| 251 | 252 | ||
| ... | @@ -260,18 +261,18 @@ pub fn genMainBody(fg: *FuncGen) TodoError!void { | ... | @@ -260,18 +261,18 @@ pub fn genMainBody(fg: *FuncGen) TodoError!void { |
| 260 | } | 261 | } |
| 261 | }, | 262 | }, |
| 262 | .slice => { | 263 | .slice => { |
| 263 | assert(!it.byval_attr); | 264 | assert(it.byval_attr == null); |
| 264 | const param_ty: Type = .fromInterned(param_types[it.zig_index - 1]); | 265 | const param_ty: Type = .fromInterned(param_types[it.zig_index - 1]); |
| 265 | assert(!isByRef(param_ty, zcu)); | 266 | assert(!isByRef(param_ty, zcu)); |
| 266 | const slice_val = try fg.wip.buildAggregate( | 267 | const slice_val = try fg.wip.buildAggregate( |
| 267 | try o.lowerType(param_ty, .by_value), | 268 | try o.lowerType(param_ty, .as_value), |
| 268 | &.{ fg.wip.arg(it.llvm_index - 2), fg.wip.arg(it.llvm_index - 1) }, | 269 | &.{ fg.wip.arg(it.llvm_index - 2), fg.wip.arg(it.llvm_index - 1) }, |
| 269 | "", | 270 | "", |
| 270 | ); | 271 | ); |
| 271 | args.appendAssumeCapacity(slice_val); | 272 | args.appendAssumeCapacity(slice_val); |
| 272 | }, | 273 | }, |
| 273 | .multiple_llvm_types => { | 274 | .multiple_llvm_types => { |
| 274 | assert(!it.byval_attr); | 275 | assert(it.byval_attr == null); |
| 275 | const param_ty: Type = .fromInterned(param_types[it.zig_index - 1]); | 276 | const param_ty: Type = .fromInterned(param_types[it.zig_index - 1]); |
| 276 | const param_alignment = param_ty.abiAlignment(zcu); | 277 | const param_alignment = param_ty.abiAlignment(zcu); |
| 277 | const llvm_ty = try o.builder.arrayType(it.offsets_buffer[it.types_len], .i8); | 278 | const llvm_ty = try o.builder.arrayType(it.offsets_buffer[it.types_len], .i8); |
| ... | @@ -696,7 +697,7 @@ fn genBodyDebugScope( | ... | @@ -696,7 +697,7 @@ fn genBodyDebugScope( |
| 696 | .{ | 697 | .{ |
| 697 | .di_flags = .{ .StaticMember = true }, | 698 | .di_flags = .{ .StaticMember = true }, |
| 698 | .sp_flags = .{ | 699 | .sp_flags = .{ |
| 699 | .Optimized = mod.optimize_mode != .Debug, | 700 | .Optimized = mod.optimize_mode != .debug, |
| 700 | .Definition = true, | 701 | .Definition = true, |
| 701 | .LocalToUnit = true, // inline functions cannot be exported | 702 | .LocalToUnit = true, // inline functions cannot be exported |
| 702 | }, | 703 | }, |
| ... | @@ -721,29 +722,19 @@ fn genBodyDebugScope( | ... | @@ -721,29 +722,19 @@ fn genBodyDebugScope( |
| 721 | try self.genBody(body, coverage_point); | 722 | try self.genBody(body, coverage_point); |
| 722 | } | 723 | } |
| 723 | 724 | ||
| 724 | const CallAttr = enum { | 725 | fn airCall(fg: *FuncGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier) Allocator.Error!Builder.Value { |
| 725 | Auto, | 726 | const o = fg.object; |
| 726 | NeverTail, | ||
| 727 | NeverInline, | ||
| 728 | AlwaysTail, | ||
| 729 | AlwaysInline, | ||
| 730 | }; | ||
| 731 | |||
| 732 | fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier) Allocator.Error!Builder.Value { | ||
| 733 | const air_call = self.air.unwrapCall(inst); | ||
| 734 | const args = air_call.args; | ||
| 735 | const o = self.object; | ||
| 736 | const pt = self.pt; | ||
| 737 | const zcu = o.zcu; | 727 | const zcu = o.zcu; |
| 728 | const air_call = fg.air.unwrapCall(inst); | ||
| 729 | const args = air_call.args; | ||
| 738 | const ip = &zcu.intern_pool; | 730 | const ip = &zcu.intern_pool; |
| 739 | const callee_ty = self.typeOf(air_call.callee); | 731 | const callee_ty = fg.typeOf(air_call.callee); |
| 740 | const zig_fn_ty = switch (callee_ty.zigTypeTag(zcu)) { | 732 | const zig_fn_ty = switch (callee_ty.zigTypeTag(zcu)) { |
| 741 | .@"fn" => callee_ty, | 733 | .@"fn" => callee_ty, |
| 742 | .pointer => callee_ty.childType(zcu), | 734 | .pointer => callee_ty.childType(zcu), |
| 743 | else => unreachable, | 735 | else => unreachable, |
| 744 | }; | 736 | }; |
| 745 | const fn_info = zcu.typeToFunc(zig_fn_ty).?; | 737 | const fn_info = zcu.typeToFunc(zig_fn_ty).?; |
| 746 | const return_type: Type = .fromInterned(fn_info.return_type); | ||
| 747 | const llvm_fn = llvm_fn: { | 738 | const llvm_fn = llvm_fn: { |
| 748 | // If the callee is a function *body*, we need to use a pointer to the global. | 739 | // If the callee is a function *body*, we need to use a pointer to the global. |
| 749 | if (air_call.callee.toInterned()) |ip_index| switch (ip.indexToKey(ip_index)) { | 740 | if (air_call.callee.toInterned()) |ip_index| switch (ip.indexToKey(ip_index)) { |
| ... | @@ -752,22 +743,54 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier | ... | @@ -752,22 +743,54 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier |
| 752 | else => {}, | 743 | else => {}, |
| 753 | }; | 744 | }; |
| 754 | // Otherwise, the operand is already a function pointer (possibly runtime-known). | 745 | // Otherwise, the operand is already a function pointer (possibly runtime-known). |
| 755 | break :llvm_fn try self.resolveInst(air_call.callee); | 746 | break :llvm_fn try fg.resolveInst(air_call.callee); |
| 756 | }; | 747 | }; |
| 748 | |||
| 749 | const arg_types = try fg.gpa.alloc(InternPool.Index, args.len); | ||
| 750 | defer fg.gpa.free(arg_types); | ||
| 751 | const arg_values = try fg.gpa.alloc(Builder.Value, args.len); | ||
| 752 | defer fg.gpa.free(arg_values); | ||
| 753 | for (arg_types, arg_values, args) |*arg_type, *arg_value, arg| { | ||
| 754 | const arg_ty = fg.typeOf(arg); | ||
| 755 | arg_type.* = arg_ty.toIntern(); | ||
| 756 | arg_value.* = if (arg_ty.hasRuntimeBits(zcu)) try fg.resolveInst(arg) else .none; | ||
| 757 | } | ||
| 758 | return fg.buildCall(.{ | ||
| 759 | .is_unused = fg.liveness.isUnused(inst), | ||
| 760 | .modifier = modifier, | ||
| 761 | }, try o.lowerType(zig_fn_ty, .as_value), llvm_fn, .fromIntern(fn_info, ip), arg_types, arg_values); | ||
| 762 | } | ||
| 763 | |||
| 764 | fn buildCall( | ||
| 765 | fg: *FuncGen, | ||
| 766 | opts: struct { | ||
| 767 | is_unused: bool = false, | ||
| 768 | modifier: std.lang.CallModifier = .auto, | ||
| 769 | }, | ||
| 770 | llvm_fn_ty: Builder.Type, | ||
| 771 | llvm_fn: Builder.Value, | ||
| 772 | fn_info: Object.FuncInfo, | ||
| 773 | arg_types: []const InternPool.Index, | ||
| 774 | arg_values: []const Builder.Value, | ||
| 775 | ) Allocator.Error!Builder.Value { | ||
| 776 | const o = fg.object; | ||
| 777 | const pt = fg.pt; | ||
| 778 | const zcu = o.zcu; | ||
| 779 | const return_type: Type = .fromInterned(fn_info.return_type); | ||
| 757 | const target = zcu.getTarget(); | 780 | const target = zcu.getTarget(); |
| 758 | const ret_strat = try fnReturnStrat(o, fn_info); | 781 | const ret_strat = try fnReturnStrat(o, fn_info.cc, .fromInterned(fn_info.return_type)); |
| 759 | 782 | ||
| 760 | var llvm_args = std.array_list.Managed(Builder.Value).init(self.gpa); | 783 | var llvm_args: std.ArrayList(Builder.Value) = .empty; |
| 761 | defer llvm_args.deinit(); | 784 | defer llvm_args.deinit(fg.gpa); |
| 762 | 785 | ||
| 763 | var attributes: Builder.FunctionAttributes.Wip = .{}; | 786 | var attributes: Builder.FunctionAttributes.Wip = .{}; |
| 764 | defer attributes.deinit(&o.builder); | 787 | defer attributes.deinit(&o.builder); |
| 765 | 788 | ||
| 766 | if (self.disable_intrinsics) { | 789 | if (fg.disable_intrinsics) { |
| 767 | try attributes.addFnAttr(.nobuiltin, &o.builder); | 790 | try attributes.addFnAttr(.nobuiltin, &o.builder); |
| 768 | } | 791 | } |
| 769 | 792 | ||
| 770 | switch (modifier) { | 793 | switch (opts.modifier) { |
| 771 | .auto, .always_tail => {}, | 794 | .auto, .always_tail => {}, |
| 772 | .never_tail, .never_inline => try attributes.addFnAttr(.@"noinline", &o.builder), | 795 | .never_tail, .never_inline => try attributes.addFnAttr(.@"noinline", &o.builder), |
| 773 | .no_suspend, .always_inline, .compile_time => unreachable, | 796 | .no_suspend, .always_inline, .compile_time => unreachable, |
| ... | @@ -775,10 +798,11 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier | ... | @@ -775,10 +798,11 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier |
| 775 | 798 | ||
| 776 | const sret_alloc: ?Builder.Value = switch (ret_strat) { | 799 | const sret_alloc: ?Builder.Value = switch (ret_strat) { |
| 777 | .sret => sret_alloc: { | 800 | .sret => sret_alloc: { |
| 778 | try attributes.addParamAttr(0, .{ .sret = try o.lowerType(return_type, .in_memory) }, &o.builder); | 801 | const alignment = return_type.abiAlignment(zcu).toLlvm(); |
| 802 | try o.addSRetFnAttributes(&attributes, try o.lowerType(return_type, .in_memory), alignment, .callsite); | ||
| 779 | 803 | ||
| 780 | const ptr = try self.buildZigAlloca(return_type, .none); | 804 | const ptr = try fg.buildZigAlloca(return_type, .none); |
| 781 | try llvm_args.append(ptr); | 805 | try llvm_args.append(fg.gpa, ptr); |
| 782 | break :sret_alloc ptr; | 806 | break :sret_alloc ptr; |
| 783 | }, | 807 | }, |
| 784 | else => sret_alloc: { | 808 | else => sret_alloc: { |
| ... | @@ -792,132 +816,111 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier | ... | @@ -792,132 +816,111 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier |
| 792 | 816 | ||
| 793 | const err_return_tracing = fn_info.cc == .auto and zcu.comp.config.any_error_tracing; | 817 | const err_return_tracing = fn_info.cc == .auto and zcu.comp.config.any_error_tracing; |
| 794 | if (err_return_tracing) { | 818 | if (err_return_tracing) { |
| 795 | assert(self.err_ret_trace != .none); | 819 | assert(fg.err_ret_trace != .none); |
| 796 | try llvm_args.append(self.err_ret_trace); | 820 | try llvm_args.append(fg.gpa, fg.err_ret_trace); |
| 797 | } | 821 | } |
| 798 | |||
| 799 | var it = iterateParamTypes(o, fn_info); | ||
| 800 | while (try it.nextCall(self, args)) |lowering| switch (lowering) { | ||
| 801 | .no_bits => continue, | ||
| 802 | .byval => { | ||
| 803 | const arg = args[it.zig_index - 1]; | ||
| 804 | const param_ty = self.typeOf(arg); | ||
| 805 | const llvm_arg = try self.resolveInst(arg); | ||
| 806 | if (isByRef(param_ty, zcu)) { | ||
| 807 | const alignment = param_ty.abiAlignment(zcu).toLlvm(); | ||
| 808 | // We don't need to handle non-ABI-sized integer types in memory here since they are | ||
| 809 | // never by-ref. | ||
| 810 | const llvm_param_ty = try o.lowerType(param_ty, .in_memory); | ||
| 811 | const loaded = try self.wip.load(.normal, llvm_param_ty, llvm_arg, alignment, ""); | ||
| 812 | try llvm_args.append(loaded); | ||
| 813 | } else { | ||
| 814 | try llvm_args.append(llvm_arg); | ||
| 815 | } | ||
| 816 | }, | ||
| 817 | .byref => { | ||
| 818 | const arg = args[it.zig_index - 1]; | ||
| 819 | const param_ty = self.typeOf(arg); | ||
| 820 | const llvm_arg = try self.resolveInst(arg); | ||
| 821 | if (isByRef(param_ty, zcu)) { | ||
| 822 | try llvm_args.append(llvm_arg); | ||
| 823 | } else { | ||
| 824 | const arg_ptr = try self.buildZigAlloca(param_ty, .none); | ||
| 825 | try self.store(arg_ptr, .none, llvm_arg, param_ty, .normal); | ||
| 826 | try llvm_args.append(arg_ptr); | ||
| 827 | } | ||
| 828 | }, | ||
| 829 | .byref_mut => { | ||
| 830 | const arg = args[it.zig_index - 1]; | ||
| 831 | const param_ty = self.typeOf(arg); | ||
| 832 | const llvm_arg = try self.resolveInst(arg); | ||
| 833 | |||
| 834 | const arg_ptr = try self.buildZigAlloca(param_ty, .none); | ||
| 835 | try self.store(arg_ptr, .none, llvm_arg, param_ty, .normal); | ||
| 836 | try llvm_args.append(arg_ptr); | ||
| 837 | }, | ||
| 838 | .abi_sized_int => { | ||
| 839 | const arg = args[it.zig_index - 1]; | ||
| 840 | const param_ty = self.typeOf(arg); | ||
| 841 | const llvm_arg = try self.resolveInst(arg); | ||
| 842 | const int_llvm_ty = try o.builder.intType(@intCast(param_ty.abiSize(zcu) * 8)); | ||
| 843 | |||
| 844 | if (isByRef(param_ty, zcu)) { | ||
| 845 | const alignment = param_ty.abiAlignment(zcu).toLlvm(); | ||
| 846 | const loaded = try self.wip.load(.normal, int_llvm_ty, llvm_arg, alignment, ""); | ||
| 847 | try llvm_args.append(loaded); | ||
| 848 | } else { | ||
| 849 | // LLVM does not allow bitcasting structs so we must allocate | ||
| 850 | // a local, store as one type, and then load as another type. | ||
| 851 | const alignment = param_ty.abiAlignment(zcu).toLlvm(); | ||
| 852 | const ptr = try self.buildAlloca(int_llvm_ty, alignment); | ||
| 853 | try self.store(ptr, .none, llvm_arg, param_ty, .normal); | ||
| 854 | const loaded = try self.wip.load(.normal, int_llvm_ty, ptr, alignment, ""); | ||
| 855 | try llvm_args.append(loaded); | ||
| 856 | } | ||
| 857 | }, | ||
| 858 | .slice => { | ||
| 859 | const arg = args[it.zig_index - 1]; | ||
| 860 | const llvm_arg = try self.resolveInst(arg); | ||
| 861 | const ptr = try self.wip.extractValue(llvm_arg, &.{0}, ""); | ||
| 862 | const len = try self.wip.extractValue(llvm_arg, &.{1}, ""); | ||
| 863 | try llvm_args.appendSlice(&.{ ptr, len }); | ||
| 864 | }, | ||
| 865 | .multiple_llvm_types => { | ||
| 866 | const arg = args[it.zig_index - 1]; | ||
| 867 | const param_ty = self.typeOf(arg); | ||
| 868 | const llvm_arg = try self.resolveInst(arg); | ||
| 869 | const param_alignment = param_ty.abiAlignment(zcu); | ||
| 870 | const llvm_ty = try o.builder.arrayType(it.offsets_buffer[it.types_len], .i8); | ||
| 871 | const arg_ptr = try self.buildAlloca(llvm_ty, param_alignment.toLlvm()); | ||
| 872 | try self.store(arg_ptr, .none, llvm_arg, param_ty, .normal); | ||
| 873 | |||
| 874 | try llvm_args.ensureUnusedCapacity(it.types_len); | ||
| 875 | for (it.types_buffer[0..it.types_len], it.offsets_buffer[0..it.types_len]) |field_ty, offset| { | ||
| 876 | const field_ptr = try self.ptraddConst(arg_ptr, offset); | ||
| 877 | const loaded = try self.wip.load(.normal, field_ty, field_ptr, param_alignment.offset(offset).toLlvm(), ""); | ||
| 878 | llvm_args.appendAssumeCapacity(loaded); | ||
| 879 | } | ||
| 880 | }, | ||
| 881 | .float_array => |count| { | ||
| 882 | const arg = args[it.zig_index - 1]; | ||
| 883 | const arg_ty = self.typeOf(arg); | ||
| 884 | const arg_val = try self.resolveInst(arg); | ||
| 885 | |||
| 886 | const arg_ptr: Builder.Value = if (!isByRef(arg_ty, zcu)) ptr: { | ||
| 887 | const ptr = try self.buildZigAlloca(arg_ty, .none); | ||
| 888 | try self.store(ptr, .none, arg_val, arg_ty, .normal); | ||
| 889 | break :ptr ptr; | ||
| 890 | } else arg_val; | ||
| 891 | |||
| 892 | const float_ty = try o.lowerType(aarch64_c_abi.getFloatArrayType(arg_ty, zcu).?, .in_memory); | ||
| 893 | const array_ty = try o.builder.arrayType(count, float_ty); | ||
| 894 | 822 | ||
| 895 | const loaded = try self.wip.load(.normal, array_ty, arg_ptr, arg_ty.abiAlignment(zcu).toLlvm(), ""); | 823 | var it = iterateParamTypes(o, fn_info.cc, fn_info.param_types); |
| 896 | try llvm_args.append(loaded); | 824 | while (try it.nextCall(arg_types)) |lowering| { |
| 897 | }, | 825 | const arg_ty: Type = .fromInterned(arg_types[it.zig_index - 1]); |
| 898 | .i32_array, .i64_array => |arr_len| { | 826 | const arg_val = arg_values[it.zig_index - 1]; |
| 899 | const elem_size: u8 = if (lowering == .i32_array) 32 else 64; | 827 | switch (lowering) { |
| 900 | const arg = args[it.zig_index - 1]; | 828 | .no_bits => continue, |
| 901 | const arg_ty = self.typeOf(arg); | 829 | .byval => { |
| 902 | const arg_val = try self.resolveInst(arg); | 830 | if (isByRef(arg_ty, zcu)) { |
| 903 | 831 | const alignment = arg_ty.abiAlignment(zcu).toLlvm(); | |
| 904 | const arg_ptr: Builder.Value = if (!isByRef(arg_ty, zcu)) ptr: { | 832 | // We don't need to handle non-ABI-sized integer types in memory here since they are |
| 905 | const ptr = try self.buildZigAlloca(arg_ty, .none); | 833 | // never by-ref. |
| 906 | try self.store(ptr, .none, arg_val, arg_ty, .normal); | 834 | const llvm_arg_ty = try o.lowerType(arg_ty, .memory_access); |
| 907 | break :ptr ptr; | 835 | const loaded = try fg.wip.load(.normal, llvm_arg_ty, arg_val, alignment, ""); |
| 908 | } else arg_val; | 836 | try llvm_args.append(fg.gpa, loaded); |
| 837 | } else { | ||
| 838 | try llvm_args.append(fg.gpa, arg_val); | ||
| 839 | } | ||
| 840 | }, | ||
| 841 | .byref => { | ||
| 842 | if (isByRef(arg_ty, zcu)) { | ||
| 843 | try llvm_args.append(fg.gpa, arg_val); | ||
| 844 | } else { | ||
| 845 | const arg_ptr = try fg.buildZigAlloca(arg_ty, .none); | ||
| 846 | try fg.store(arg_ptr, .none, arg_val, arg_ty, .normal); | ||
| 847 | try llvm_args.append(fg.gpa, arg_ptr); | ||
| 848 | } | ||
| 849 | }, | ||
| 850 | .byref_mut => { | ||
| 851 | const arg_ptr = try fg.buildZigAlloca(arg_ty, .none); | ||
| 852 | try fg.store(arg_ptr, .none, arg_val, arg_ty, .normal); | ||
| 853 | try llvm_args.append(fg.gpa, arg_ptr); | ||
| 854 | }, | ||
| 855 | .abi_sized_int => { | ||
| 856 | const int_llvm_ty = try o.builder.intType(@intCast(arg_ty.abiSize(zcu) * 8)); | ||
| 909 | 857 | ||
| 910 | const array_ty = try o.builder.arrayType(arr_len, try o.builder.intType(@intCast(elem_size))); | 858 | if (isByRef(arg_ty, zcu)) { |
| 911 | const loaded = try self.wip.load(.normal, array_ty, arg_ptr, arg_ty.abiAlignment(zcu).toLlvm(), ""); | 859 | const alignment = arg_ty.abiAlignment(zcu).toLlvm(); |
| 912 | try llvm_args.append(loaded); | 860 | const loaded = try fg.wip.load(.normal, int_llvm_ty, arg_val, alignment, ""); |
| 913 | }, | 861 | try llvm_args.append(fg.gpa, loaded); |
| 914 | }; | 862 | } else { |
| 863 | // LLVM does not allow bitcasting structs so we must allocate | ||
| 864 | // a local, store as one type, and then load as another type. | ||
| 865 | const alignment = arg_ty.abiAlignment(zcu).toLlvm(); | ||
| 866 | const ptr = try fg.buildAlloca(int_llvm_ty, alignment); | ||
| 867 | try fg.store(ptr, .none, arg_val, arg_ty, .normal); | ||
| 868 | const loaded = try fg.wip.load(.normal, int_llvm_ty, ptr, alignment, ""); | ||
| 869 | try llvm_args.append(fg.gpa, loaded); | ||
| 870 | } | ||
| 871 | }, | ||
| 872 | .slice => { | ||
| 873 | const ptr = try fg.wip.extractValue(arg_val, &.{0}, ""); | ||
| 874 | const len = try fg.wip.extractValue(arg_val, &.{1}, ""); | ||
| 875 | try llvm_args.appendSlice(fg.gpa, &.{ ptr, len }); | ||
| 876 | }, | ||
| 877 | .multiple_llvm_types => { | ||
| 878 | const arg_alignment = arg_ty.abiAlignment(zcu); | ||
| 879 | const llvm_ty = try o.builder.arrayType(it.offsets_buffer[it.types_len], .i8); | ||
| 880 | const arg_ptr = try fg.buildAlloca(llvm_ty, arg_alignment.toLlvm()); | ||
| 881 | try fg.store(arg_ptr, .none, arg_val, arg_ty, .normal); | ||
| 882 | |||
| 883 | try llvm_args.ensureUnusedCapacity(fg.gpa, it.types_len); | ||
| 884 | for (it.types_buffer[0..it.types_len], it.offsets_buffer[0..it.types_len]) |field_ty, offset| { | ||
| 885 | const field_ptr = try fg.ptraddConst(arg_ptr, offset); | ||
| 886 | const loaded = try fg.wip.load(.normal, field_ty, field_ptr, arg_alignment.offset(offset).toLlvm(), ""); | ||
| 887 | llvm_args.appendAssumeCapacity(loaded); | ||
| 888 | } | ||
| 889 | }, | ||
| 890 | .float_array => |count| { | ||
| 891 | const arg_ptr: Builder.Value = if (!isByRef(arg_ty, zcu)) ptr: { | ||
| 892 | const ptr = try fg.buildZigAlloca(arg_ty, .none); | ||
| 893 | try fg.store(ptr, .none, arg_val, arg_ty, .normal); | ||
| 894 | break :ptr ptr; | ||
| 895 | } else arg_val; | ||
| 896 | |||
| 897 | const float_ty = try o.lowerType(aarch64_c_abi.getFloatArrayType(arg_ty, zcu).?, .memory_access); | ||
| 898 | const array_ty = try o.builder.arrayType(count, float_ty); | ||
| 899 | |||
| 900 | const loaded = try fg.wip.load(.normal, array_ty, arg_ptr, arg_ty.abiAlignment(zcu).toLlvm(), ""); | ||
| 901 | try llvm_args.append(fg.gpa, loaded); | ||
| 902 | }, | ||
| 903 | .i32_array, .i64_array => |arr_len| { | ||
| 904 | const elem_size: u8 = if (lowering == .i32_array) 32 else 64; | ||
| 905 | |||
| 906 | const arg_ptr: Builder.Value = if (!isByRef(arg_ty, zcu)) ptr: { | ||
| 907 | const ptr = try fg.buildZigAlloca(arg_ty, .none); | ||
| 908 | try fg.store(ptr, .none, arg_val, arg_ty, .normal); | ||
| 909 | break :ptr ptr; | ||
| 910 | } else arg_val; | ||
| 911 | |||
| 912 | const array_ty = try o.builder.arrayType(arr_len, try o.builder.intType(@intCast(elem_size))); | ||
| 913 | const loaded = try fg.wip.load(.normal, array_ty, arg_ptr, arg_ty.abiAlignment(zcu).toLlvm(), ""); | ||
| 914 | try llvm_args.append(fg.gpa, loaded); | ||
| 915 | }, | ||
| 916 | } | ||
| 917 | } | ||
| 915 | 918 | ||
| 916 | const cc_info = llvm.toLlvmCallConv(fn_info.cc, target).?; | 919 | const cc_info = llvm.toLlvmCallConv(fn_info.cc, target).?; |
| 917 | 920 | ||
| 918 | { | 921 | { |
| 919 | // Add argument attributes. | 922 | // Add argument attributes. |
| 920 | it = iterateParamTypes(o, fn_info); | 923 | it = iterateParamTypes(o, fn_info.cc, fn_info.param_types); |
| 921 | it.llvm_index += @intFromBool(ret_strat == .sret); | 924 | it.llvm_index += @intFromBool(ret_strat == .sret); |
| 922 | it.llvm_index += @intFromBool(err_return_tracing); | 925 | it.llvm_index += @intFromBool(err_return_tracing); |
| 923 | var remaining_inreg_int = cc_info.inreg_int_params; | 926 | var remaining_inreg_int = cc_info.inreg_int_params; |
| ... | @@ -925,7 +928,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier | ... | @@ -925,7 +928,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier |
| 925 | while (try it.next()) |lowering| switch (lowering) { | 928 | while (try it.next()) |lowering| switch (lowering) { |
| 926 | .byval => { | 929 | .byval => { |
| 927 | const param_index = it.zig_index - 1; | 930 | const param_index = it.zig_index - 1; |
| 928 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[param_index]); | 931 | const param_ty = Type.fromInterned(fn_info.param_types[param_index]); |
| 929 | if (!isByRef(param_ty, zcu)) { | 932 | if (!isByRef(param_ty, zcu)) { |
| 930 | try o.addByValParamAttrs(pt, &attributes, param_ty, param_index, fn_info, it.llvm_index - 1); | 933 | try o.addByValParamAttrs(pt, &attributes, param_ty, param_index, fn_info, it.llvm_index - 1); |
| 931 | } | 934 | } |
| ... | @@ -947,7 +950,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier | ... | @@ -947,7 +950,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier |
| 947 | }, | 950 | }, |
| 948 | .byref => { | 951 | .byref => { |
| 949 | const param_index = it.zig_index - 1; | 952 | const param_index = it.zig_index - 1; |
| 950 | const param_ty: Type = .fromInterned(fn_info.param_types.get(ip)[param_index]); | 953 | const param_ty: Type = .fromInterned(fn_info.param_types[param_index]); |
| 951 | try o.addByRefParamAttrs(&attributes, it.llvm_index - 1, it.byval_attr, param_ty); | 954 | try o.addByRefParamAttrs(&attributes, it.llvm_index - 1, it.byval_attr, param_ty); |
| 952 | }, | 955 | }, |
| 953 | .byref_mut => try attributes.addParamAttr(it.llvm_index - 1, .noundef, &o.builder), | 956 | .byref_mut => try attributes.addParamAttr(it.llvm_index - 1, .noundef, &o.builder), |
| ... | @@ -961,8 +964,8 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier | ... | @@ -961,8 +964,8 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier |
| 961 | => continue, | 964 | => continue, |
| 962 | 965 | ||
| 963 | .slice => { | 966 | .slice => { |
| 964 | assert(!it.byval_attr); | 967 | assert(it.byval_attr == null); |
| 965 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]); | 968 | const param_ty = Type.fromInterned(fn_info.param_types[it.zig_index - 1]); |
| 966 | const ptr_info = param_ty.ptrInfo(zcu); | 969 | const ptr_info = param_ty.ptrInfo(zcu); |
| 967 | const llvm_arg_i = it.llvm_index - 2; | 970 | const llvm_arg_i = it.llvm_index - 2; |
| 968 | 971 | ||
| ... | @@ -989,8 +992,8 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier | ... | @@ -989,8 +992,8 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier |
| 989 | }; | 992 | }; |
| 990 | } | 993 | } |
| 991 | 994 | ||
| 992 | const call = try self.wip.call( | 995 | const call = try fg.wip.call( |
| 993 | switch (modifier) { | 996 | switch (opts.modifier) { |
| 994 | .auto, .never_inline => .normal, | 997 | .auto, .never_inline => .normal, |
| 995 | .never_tail => .notail, | 998 | .never_tail => .notail, |
| 996 | .always_tail => .musttail, | 999 | .always_tail => .musttail, |
| ... | @@ -998,19 +1001,14 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier | ... | @@ -998,19 +1001,14 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier |
| 998 | }, | 1001 | }, |
| 999 | cc_info.llvm_cc, | 1002 | cc_info.llvm_cc, |
| 1000 | try attributes.finish(&o.builder), | 1003 | try attributes.finish(&o.builder), |
| 1001 | try o.lowerType(zig_fn_ty, .by_value), | 1004 | llvm_fn_ty, |
| 1002 | llvm_fn, | 1005 | llvm_fn, |
| 1003 | llvm_args.items, | 1006 | llvm_args.items, |
| 1004 | "", | 1007 | "", |
| 1005 | ); | 1008 | ); |
| 1006 | 1009 | ||
| 1007 | if (fn_info.return_type == .noreturn_type and modifier != .always_tail) { | 1010 | if (opts.is_unused) return .none; |
| 1008 | return .none; | 1011 | if (fn_info.return_type == .noreturn_type and opts.modifier != .always_tail) return .none; |
| 1009 | } | ||
| 1010 | |||
| 1011 | if (self.liveness.isUnused(inst)) { | ||
| 1012 | return .none; | ||
| 1013 | } | ||
| 1014 | 1012 | ||
| 1015 | // We exit this `switch` if we have a pointer to the return value. | 1013 | // We exit this `switch` if we have a pointer to the return value. |
| 1016 | const ret_val_ptr: Builder.Value = switch (ret_strat) { | 1014 | const ret_val_ptr: Builder.Value = switch (ret_strat) { |
| ... | @@ -1020,15 +1018,15 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier | ... | @@ -1020,15 +1018,15 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier |
| 1020 | .sret => sret_alloc.?, | 1018 | .sret => sret_alloc.?, |
| 1021 | .mem_cast => |llvm_ret_ty| ret_val_ptr: { | 1019 | .mem_cast => |llvm_ret_ty| ret_val_ptr: { |
| 1022 | const alignment = return_type.abiAlignment(zcu).toLlvm(); | 1020 | const alignment = return_type.abiAlignment(zcu).toLlvm(); |
| 1023 | const ptr = try self.buildAlloca(llvm_ret_ty, alignment); | 1021 | const ptr = try fg.buildAlloca(llvm_ret_ty, alignment); |
| 1024 | _ = try self.wip.store(.normal, call, ptr, alignment); | 1022 | _ = try fg.wip.store(.normal, call, ptr, alignment); |
| 1025 | break :ret_val_ptr ptr; | 1023 | break :ret_val_ptr ptr; |
| 1026 | }, | 1024 | }, |
| 1027 | }; | 1025 | }; |
| 1028 | if (isByRef(return_type, zcu)) { | 1026 | if (isByRef(return_type, zcu)) { |
| 1029 | return ret_val_ptr; | 1027 | return ret_val_ptr; |
| 1030 | } else { | 1028 | } else { |
| 1031 | return self.load(ret_val_ptr, .none, return_type, .normal); | 1029 | return fg.load(ret_val_ptr, .none, return_type, .normal); |
| 1032 | } | 1030 | } |
| 1033 | } | 1031 | } |
| 1034 | 1032 | ||
| ... | @@ -1038,7 +1036,7 @@ fn buildSimplePanic(fg: *FuncGen, panic_id: Zcu.SimplePanicId) Allocator.Error!v | ... | @@ -1038,7 +1036,7 @@ fn buildSimplePanic(fg: *FuncGen, panic_id: Zcu.SimplePanicId) Allocator.Error!v |
| 1038 | const target = zcu.getTarget(); | 1036 | const target = zcu.getTarget(); |
| 1039 | const panic_func = zcu.funcInfo(zcu.std_lang_decl_values.get(panic_id.toStdLangDecl())); | 1037 | const panic_func = zcu.funcInfo(zcu.std_lang_decl_values.get(panic_id.toStdLangDecl())); |
| 1040 | const fn_info = zcu.typeToFunc(.fromInterned(panic_func.ty)).?; | 1038 | const fn_info = zcu.typeToFunc(.fromInterned(panic_func.ty)).?; |
| 1041 | const llvm_panic_fn_ty = try o.lowerType(.fromInterned(panic_func.ty), .by_value); | 1039 | const llvm_panic_fn_ty = try o.lowerType(.fromInterned(panic_func.ty), .as_value); |
| 1042 | 1040 | ||
| 1043 | const llvm_panic_fn_ref = try o.lowerNavRef(panic_func.owner_nav); | 1041 | const llvm_panic_fn_ref = try o.lowerNavRef(panic_func.owner_nav); |
| 1044 | 1042 | ||
| ... | @@ -1067,7 +1065,7 @@ fn airRet(self: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error!vo | ... | @@ -1067,7 +1065,7 @@ fn airRet(self: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error!vo |
| 1067 | 1065 | ||
| 1068 | const fn_info = zcu.typeToFunc(Type.fromInterned(ip.getNav(self.nav_index).resolved.?.type)).?; | 1066 | const fn_info = zcu.typeToFunc(Type.fromInterned(ip.getNav(self.nav_index).resolved.?.type)).?; |
| 1069 | 1067 | ||
| 1070 | const ret_strat = try fnReturnStrat(o, fn_info); | 1068 | const ret_strat = try fnReturnStrat(o, fn_info.cc, .fromInterned(fn_info.return_type)); |
| 1071 | const val_is_undef = if (un_op.toInterned()) |i| Value.fromInterned(i).isUndef(zcu) else false; | 1069 | const val_is_undef = if (un_op.toInterned()) |i| Value.fromInterned(i).isUndef(zcu) else false; |
| 1072 | const ret_ty_align = ret_ty.abiAlignment(zcu); | 1070 | const ret_ty_align = ret_ty.abiAlignment(zcu); |
| 1073 | 1071 | ||
| ... | @@ -1076,7 +1074,7 @@ fn airRet(self: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error!vo | ... | @@ -1076,7 +1074,7 @@ fn airRet(self: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error!vo |
| 1076 | .none => try self.buildZigAlloca(ret_ty, .none), | 1074 | .none => try self.buildZigAlloca(ret_ty, .none), |
| 1077 | else => |rp| rp, | 1075 | else => |rp| rp, |
| 1078 | }; | 1076 | }; |
| 1079 | const len = try o.builder.intValue(try o.lowerType(.usize, .by_value), ret_ty.abiSize(zcu)); | 1077 | const len = try o.builder.intValue(try o.lowerType(.usize, .as_value), ret_ty.abiSize(zcu)); |
| 1080 | _ = try self.wip.callMemSet( | 1078 | _ = try self.wip.callMemSet( |
| 1081 | rp, | 1079 | rp, |
| 1082 | ret_ty_align.toLlvm(), | 1080 | ret_ty_align.toLlvm(), |
| ... | @@ -1141,7 +1139,7 @@ fn airRetLoad(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!void { | ... | @@ -1141,7 +1139,7 @@ fn airRetLoad(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!void { |
| 1141 | const ret_ty = ptr_ty.childType(zcu); | 1139 | const ret_ty = ptr_ty.childType(zcu); |
| 1142 | const fn_info = zcu.typeToFunc(.fromInterned(ip.getNav(self.nav_index).resolved.?.type)).?; | 1140 | const fn_info = zcu.typeToFunc(.fromInterned(ip.getNav(self.nav_index).resolved.?.type)).?; |
| 1143 | const ptr = try self.resolveInst(un_op); | 1141 | const ptr = try self.resolveInst(un_op); |
| 1144 | switch (try fnReturnStrat(o, fn_info)) { | 1142 | switch (try fnReturnStrat(o, fn_info.cc, .fromInterned(fn_info.return_type))) { |
| 1145 | .void => _ = try self.wip.retVoid(), | 1143 | .void => _ = try self.wip.retVoid(), |
| 1146 | .sret => { | 1144 | .sret => { |
| 1147 | assert(self.ret_ptr != .none); | 1145 | assert(self.ret_ptr != .none); |
| ... | @@ -1165,7 +1163,7 @@ fn airCVaArg(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value | ... | @@ -1165,7 +1163,7 @@ fn airCVaArg(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value |
| 1165 | const ty_op = self.air.instructions.items(.data)[@backingInt(inst)].ty_op; | 1163 | const ty_op = self.air.instructions.items(.data)[@backingInt(inst)].ty_op; |
| 1166 | const list = try self.resolveInst(ty_op.operand); | 1164 | const list = try self.resolveInst(ty_op.operand); |
| 1167 | const arg_ty = ty_op.ty.toType(); | 1165 | const arg_ty = ty_op.ty.toType(); |
| 1168 | const llvm_arg_ty = try self.object.lowerType(arg_ty, .by_value); | 1166 | const llvm_arg_ty = try self.object.lowerType(arg_ty, .as_value); |
| 1169 | 1167 | ||
| 1170 | return self.wip.vaArg(list, llvm_arg_ty, ""); | 1168 | return self.wip.vaArg(list, llvm_arg_ty, ""); |
| 1171 | } | 1169 | } |
| ... | @@ -1378,7 +1376,7 @@ fn lowerBlock( | ... | @@ -1378,7 +1376,7 @@ fn lowerBlock( |
| 1378 | if (have_block_result) { | 1376 | if (have_block_result) { |
| 1379 | const llvm_ty: Builder.Type = switch (isByRef(inst_ty, zcu)) { | 1377 | const llvm_ty: Builder.Type = switch (isByRef(inst_ty, zcu)) { |
| 1380 | true => .ptr, | 1378 | true => .ptr, |
| 1381 | false => try o.lowerType(inst_ty, .by_value), | 1379 | false => try o.lowerType(inst_ty, .as_value), |
| 1382 | }; | 1380 | }; |
| 1383 | parent_bb.ptr(&self.wip).incoming = @intCast(breaks.list.len); | 1381 | parent_bb.ptr(&self.wip).incoming = @intCast(breaks.list.len); |
| 1384 | const phi = try self.wip.phi(llvm_ty, ""); | 1382 | const phi = try self.wip.phi(llvm_ty, ""); |
| ... | @@ -1485,7 +1483,7 @@ fn lowerSwitchDispatch( | ... | @@ -1485,7 +1483,7 @@ fn lowerSwitchDispatch( |
| 1485 | const table_index = try self.wip.conv( | 1483 | const table_index = try self.wip.conv( |
| 1486 | .unsigned, | 1484 | .unsigned, |
| 1487 | try self.wip.bin(.@"sub nuw", cond, jmp_table.min.toValue(), ""), | 1485 | try self.wip.bin(.@"sub nuw", cond, jmp_table.min.toValue(), ""), |
| 1488 | try o.lowerType(.usize, .by_value), | 1486 | try o.lowerType(.usize, .as_value), |
| 1489 | "", | 1487 | "", |
| 1490 | ); | 1488 | ); |
| 1491 | const target_ptr_ptr = try self.ptraddScaled( | 1489 | const target_ptr_ptr = try self.ptraddScaled( |
| ... | @@ -1510,7 +1508,7 @@ fn lowerSwitchDispatch( | ... | @@ -1510,7 +1508,7 @@ fn lowerSwitchDispatch( |
| 1510 | // The switch prongs will correspond to our scalar cases. Ranges will | 1508 | // The switch prongs will correspond to our scalar cases. Ranges will |
| 1511 | // be handled by conditional branches in the `else` prong. | 1509 | // be handled by conditional branches in the `else` prong. |
| 1512 | 1510 | ||
| 1513 | const llvm_usize = try o.lowerType(.usize, .by_value); | 1511 | const llvm_usize = try o.lowerType(.usize, .as_value); |
| 1514 | const cond_int = if (cond_ty.zigTypeTag(zcu) == .pointer) | 1512 | const cond_int = if (cond_ty.zigTypeTag(zcu) == .pointer) |
| 1515 | try self.wip.cast(.ptrtoint, cond, llvm_usize, "") | 1513 | try self.wip.cast(.ptrtoint, cond, llvm_usize, "") |
| 1516 | else | 1514 | else |
| ... | @@ -1725,7 +1723,7 @@ fn lowerTry( | ... | @@ -1725,7 +1723,7 @@ fn lowerTry( |
| 1725 | if (err_union_ty.isVolatilePtr(zcu)) .@"volatile" else .normal, | 1723 | if (err_union_ty.isVolatilePtr(zcu)) .@"volatile" else .normal, |
| 1726 | ); | 1724 | ); |
| 1727 | }; | 1725 | }; |
| 1728 | const zero = try o.builder.intValue(try o.errorIntType(.by_value), 0); | 1726 | const zero = try o.builder.intValue(try o.errorIntType(.as_value), 0); |
| 1729 | const is_err = try fg.wip.icmp(.ne, loaded, zero, ""); | 1727 | const is_err = try fg.wip.icmp(.ne, loaded, zero, ""); |
| 1730 | 1728 | ||
| 1731 | const return_block = try fg.wip.block(1, "TryRet"); | 1729 | const return_block = try fg.wip.block(1, "TryRet"); |
| ... | @@ -1862,8 +1860,8 @@ fn airSwitchBr(self: *FuncGen, inst: Air.Inst.Index, is_dispatch_loop: bool) Tod | ... | @@ -1862,8 +1860,8 @@ fn airSwitchBr(self: *FuncGen, inst: Air.Inst.Index, is_dispatch_loop: bool) Tod |
| 1862 | const table_includes_else = item_count != table_len; | 1860 | const table_includes_else = item_count != table_len; |
| 1863 | 1861 | ||
| 1864 | break :jmp_table .{ | 1862 | break :jmp_table .{ |
| 1865 | .min = try o.lowerValue(min.toIntern(), .by_value), | 1863 | .min = try o.lowerValue(min.toIntern(), .as_value), |
| 1866 | .max = try o.lowerValue(max.toIntern(), .by_value), | 1864 | .max = try o.lowerValue(max.toIntern(), .as_value), |
| 1867 | .in_bounds_hint = if (table_includes_else) .none else switch (switch_br.getElseHint()) { | 1865 | .in_bounds_hint = if (table_includes_else) .none else switch (switch_br.getElseHint()) { |
| 1868 | .none, .cold => .none, | 1866 | .none, .cold => .none, |
| 1869 | .unpredictable => .unpredictable, | 1867 | .unpredictable => .unpredictable, |
| ... | @@ -2021,142 +2019,102 @@ fn airArrayToSlice(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder | ... | @@ -2021,142 +2019,102 @@ fn airArrayToSlice(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder |
| 2021 | const ty_op = self.air.instructions.items(.data)[@backingInt(inst)].ty_op; | 2019 | const ty_op = self.air.instructions.items(.data)[@backingInt(inst)].ty_op; |
| 2022 | const operand_ty = self.typeOf(ty_op.operand); | 2020 | const operand_ty = self.typeOf(ty_op.operand); |
| 2023 | const array_ty = operand_ty.childType(zcu); | 2021 | const array_ty = operand_ty.childType(zcu); |
| 2024 | const llvm_usize = try o.lowerType(.usize, .by_value); | 2022 | const llvm_usize = try o.lowerType(.usize, .as_value); |
| 2025 | const len = try o.builder.intValue(llvm_usize, array_ty.arrayLen(zcu)); | 2023 | const len = try o.builder.intValue(llvm_usize, array_ty.arrayLen(zcu)); |
| 2026 | const slice_llvm_ty = try o.lowerType(self.typeOfIndex(inst), .by_value); | 2024 | const slice_llvm_ty = try o.lowerType(self.typeOfIndex(inst), .as_value); |
| 2027 | const operand = try self.resolveInst(ty_op.operand); | 2025 | const operand = try self.resolveInst(ty_op.operand); |
| 2028 | return self.wip.buildAggregate(slice_llvm_ty, &.{ operand, len }, ""); | 2026 | return self.wip.buildAggregate(slice_llvm_ty, &.{ operand, len }, ""); |
| 2029 | } | 2027 | } |
| 2030 | 2028 | ||
| 2031 | fn airFloatFromInt(self: *FuncGen, inst: Air.Inst.Index) TodoError!Builder.Value { | 2029 | fn airFloatFromInt(fg: *FuncGen, inst: Air.Inst.Index) TodoError!Builder.Value { |
| 2032 | const o = self.object; | 2030 | const o = fg.object; |
| 2033 | const zcu = o.zcu; | 2031 | const zcu = o.zcu; |
| 2034 | const ty_op = self.air.instructions.items(.data)[@backingInt(inst)].ty_op; | 2032 | const ty_op = fg.air.instructions.items(.data)[@backingInt(inst)].ty_op; |
| 2035 | 2033 | ||
| 2036 | const operand = try self.resolveInst(ty_op.operand); | 2034 | const operand = try fg.resolveInst(ty_op.operand); |
| 2037 | const operand_ty = self.typeOf(ty_op.operand); | 2035 | const operand_ty = fg.typeOf(ty_op.operand); |
| 2038 | const operand_scalar_ty = operand_ty.scalarType(zcu); | 2036 | const operand_scalar_ty = operand_ty.scalarType(zcu); |
| 2039 | const is_signed_int = operand_scalar_ty.isSignedInt(zcu); | 2037 | const operand_scalar_info = operand_scalar_ty.intInfo(zcu); |
| 2040 | 2038 | ||
| 2041 | const dest_ty = self.typeOfIndex(inst); | 2039 | const dest_ty = fg.typeOfIndex(inst); |
| 2042 | const dest_scalar_ty = dest_ty.scalarType(zcu); | 2040 | const dest_scalar_ty = dest_ty.scalarType(zcu); |
| 2043 | const dest_llvm_ty = try o.lowerType(dest_ty, .by_value); | ||
| 2044 | const target = zcu.getTarget(); | 2041 | const target = zcu.getTarget(); |
| 2045 | 2042 | ||
| 2046 | if (intrinsicsAllowed(dest_scalar_ty, target)) return self.wip.conv( | 2043 | if (intrinsicsAllowed(.compiler_rt, dest_scalar_ty, target)) |
| 2047 | if (is_signed_int) .signed else .unsigned, | 2044 | return fg.wip.conv(.fromStdLang(operand_scalar_info.signedness), operand, try o.lowerType(dest_ty, .as_value), ""); |
| 2048 | operand, | ||
| 2049 | dest_llvm_ty, | ||
| 2050 | "", | ||
| 2051 | ); | ||
| 2052 | 2045 | ||
| 2053 | const rt_int_bits = compilerRtIntBits(@intCast(operand_scalar_ty.bitSize(zcu))) orelse { | 2046 | const rt_int_ty = compilerRtPromoteInt(operand_scalar_info) orelse { |
| 2054 | return self.todo("float_from_int on {d} bit integer", .{operand_scalar_ty.bitSize(zcu)}); | 2047 | return fg.todo("float_from_int on {d} bit integer", .{operand_scalar_info.bits}); |
| 2055 | }; | 2048 | }; |
| 2056 | const rt_int_ty = try o.builder.intType(rt_int_bits); | 2049 | const vector_len = if (operand_ty.isVector(zcu)) operand_ty.vectorLen(zcu) else null; |
| 2057 | var extended = try self.wip.conv( | 2050 | const rt_llvm_int_ty = try o.lowerType(rt_int_ty, .as_value); |
| 2058 | if (is_signed_int) .signed else .unsigned, | 2051 | const extended = try fg.wip.conv( |
| 2052 | .fromStdLang(operand_scalar_info.signedness), | ||
| 2059 | operand, | 2053 | operand, |
| 2060 | rt_int_ty, | 2054 | if (vector_len) |len| |
| 2055 | try o.builder.vectorType(.normal, len, rt_llvm_int_ty) | ||
| 2056 | else | ||
| 2057 | rt_llvm_int_ty, | ||
| 2061 | "", | 2058 | "", |
| 2062 | ); | 2059 | ); |
| 2063 | const dest_bits = dest_scalar_ty.floatBits(target); | ||
| 2064 | const compiler_rt_operand_abbrev = compilerRtIntAbbrev(rt_int_bits); | ||
| 2065 | const compiler_rt_dest_abbrev = compilerRtFloatAbbrev(dest_bits); | ||
| 2066 | const sign_prefix = if (is_signed_int) "" else "un"; | ||
| 2067 | const fn_name = try o.builder.strtabStringFmt("__float{s}{s}i{s}f", .{ | 2060 | const fn_name = try o.builder.strtabStringFmt("__float{s}{s}i{s}f", .{ |
| 2068 | sign_prefix, | 2061 | switch (operand_scalar_info.signedness) { |
| 2069 | compiler_rt_operand_abbrev, | 2062 | .signed => "", |
| 2070 | compiler_rt_dest_abbrev, | 2063 | .unsigned => "un", |
| 2064 | }, | ||
| 2065 | compilerRtIntAbbrev(rt_int_ty.intInfo(zcu).bits), | ||
| 2066 | compilerRtFloatAbbrev(target, dest_scalar_ty.floatBits(target)), | ||
| 2071 | }); | 2067 | }); |
| 2072 | 2068 | return fg.buildElementwiseCall(fn_name, .{ | |
| 2073 | var param_type = rt_int_ty; | 2069 | .cc = target.cCallingConvention().?, |
| 2074 | if (rt_int_bits == 128 and (target.os.tag == .windows and target.cpu.arch == .x86_64)) { | 2070 | .param_types = &.{rt_int_ty.toIntern()}, |
| 2075 | // On Windows x86-64, "ti" functions must use Vector(2, u64) instead of the standard | 2071 | .return_type = dest_scalar_ty.toIntern(), |
| 2076 | // i128 calling convention to adhere to the ABI that LLVM expects compiler-rt to have. | 2072 | }, &.{extended}, vector_len); |
| 2077 | param_type = try o.builder.vectorType(.normal, 2, .i64); | ||
| 2078 | extended = try self.wip.cast(.bitcast, extended, param_type, ""); | ||
| 2079 | } | ||
| 2080 | |||
| 2081 | const libc_fn = try o.getLibcFunction(fn_name, &.{param_type}, dest_llvm_ty); | ||
| 2082 | return self.wip.call( | ||
| 2083 | .normal, | ||
| 2084 | .ccc, | ||
| 2085 | .none, | ||
| 2086 | libc_fn.typeOf(&o.builder), | ||
| 2087 | libc_fn.toValue(&o.builder), | ||
| 2088 | &.{extended}, | ||
| 2089 | "", | ||
| 2090 | ); | ||
| 2091 | } | 2073 | } |
| 2092 | 2074 | ||
| 2093 | fn airIntFromFloat( | 2075 | fn airIntFromFloat( |
| 2094 | self: *FuncGen, | 2076 | fg: *FuncGen, |
| 2095 | inst: Air.Inst.Index, | 2077 | inst: Air.Inst.Index, |
| 2096 | fast: Builder.FastMathKind, | 2078 | fast: Builder.FastMathKind, |
| 2097 | ) TodoError!Builder.Value { | 2079 | ) TodoError!Builder.Value { |
| 2098 | _ = fast; | 2080 | _ = fast; |
| 2099 | 2081 | ||
| 2100 | const o = self.object; | 2082 | const o = fg.object; |
| 2101 | const zcu = o.zcu; | 2083 | const zcu = o.zcu; |
| 2102 | const target = zcu.getTarget(); | 2084 | const target = zcu.getTarget(); |
| 2103 | const ty_op = self.air.instructions.items(.data)[@backingInt(inst)].ty_op; | 2085 | const ty_op = fg.air.instructions.items(.data)[@backingInt(inst)].ty_op; |
| 2104 | 2086 | ||
| 2105 | const operand = try self.resolveInst(ty_op.operand); | 2087 | const operand = try fg.resolveInst(ty_op.operand); |
| 2106 | const operand_ty = self.typeOf(ty_op.operand); | 2088 | const operand_ty = fg.typeOf(ty_op.operand); |
| 2107 | const operand_scalar_ty = operand_ty.scalarType(zcu); | 2089 | const operand_scalar_ty = operand_ty.scalarType(zcu); |
| 2108 | 2090 | ||
| 2109 | const dest_ty = self.typeOfIndex(inst); | 2091 | const dest_ty = fg.typeOfIndex(inst); |
| 2110 | const dest_scalar_ty = dest_ty.scalarType(zcu); | 2092 | const dest_scalar_ty = dest_ty.scalarType(zcu); |
| 2111 | const dest_llvm_ty = try o.lowerType(dest_ty, .by_value); | 2093 | const dest_llvm_ty = try o.lowerType(dest_ty, .as_value); |
| 2094 | const dest_scalar_info = dest_scalar_ty.intInfo(zcu); | ||
| 2112 | 2095 | ||
| 2113 | if (intrinsicsAllowed(operand_scalar_ty, target)) { | 2096 | if (intrinsicsAllowed(.compiler_rt, operand_scalar_ty, target)) { |
| 2114 | // TODO set fast math flag | 2097 | // TODO set fast math flag |
| 2115 | return self.wip.conv( | 2098 | return fg.wip.conv(.fromStdLang(dest_scalar_info.signedness), operand, dest_llvm_ty, ""); |
| 2116 | if (dest_scalar_ty.isSignedInt(zcu)) .signed else .unsigned, | ||
| 2117 | operand, | ||
| 2118 | dest_llvm_ty, | ||
| 2119 | "", | ||
| 2120 | ); | ||
| 2121 | } | 2099 | } |
| 2122 | 2100 | ||
| 2123 | const rt_int_bits = compilerRtIntBits(@intCast(dest_scalar_ty.bitSize(zcu))) orelse { | 2101 | const rt_int_ty = compilerRtPromoteInt(dest_scalar_info) orelse { |
| 2124 | return self.todo("int_from_float to {d} bit integer", .{dest_scalar_ty.bitSize(zcu)}); | 2102 | return fg.todo("int_from_float to {d} bit integer", .{dest_scalar_info.bits}); |
| 2125 | }; | 2103 | }; |
| 2126 | const ret_ty = try o.builder.intType(rt_int_bits); | ||
| 2127 | const libc_ret_ty = if (rt_int_bits == 128 and (target.os.tag == .windows and target.cpu.arch == .x86_64)) b: { | ||
| 2128 | // On Windows x86-64, "ti" functions must use Vector(2, u64) instead of the standard | ||
| 2129 | // i128 calling convention to adhere to the ABI that LLVM expects compiler-rt to have. | ||
| 2130 | break :b try o.builder.vectorType(.normal, 2, .i64); | ||
| 2131 | } else ret_ty; | ||
| 2132 | |||
| 2133 | const operand_bits = operand_scalar_ty.floatBits(target); | ||
| 2134 | const compiler_rt_operand_abbrev = compilerRtFloatAbbrev(operand_bits); | ||
| 2135 | |||
| 2136 | const compiler_rt_dest_abbrev = compilerRtIntAbbrev(rt_int_bits); | ||
| 2137 | const sign_prefix = if (dest_scalar_ty.isSignedInt(zcu)) "" else "uns"; | ||
| 2138 | |||
| 2139 | const fn_name = try o.builder.strtabStringFmt("__fix{s}{s}f{s}i", .{ | 2104 | const fn_name = try o.builder.strtabStringFmt("__fix{s}{s}f{s}i", .{ |
| 2140 | sign_prefix, | 2105 | switch (dest_scalar_info.signedness) { |
| 2141 | compiler_rt_operand_abbrev, | 2106 | .signed => "", |
| 2142 | compiler_rt_dest_abbrev, | 2107 | .unsigned => "uns", |
| 2108 | }, | ||
| 2109 | compilerRtFloatAbbrev(target, operand_scalar_ty.floatBits(target)), | ||
| 2110 | compilerRtIntAbbrev(rt_int_ty.intInfo(zcu).bits), | ||
| 2143 | }); | 2111 | }); |
| 2144 | 2112 | const result = try fg.buildElementwiseCall(fn_name, .{ | |
| 2145 | const operand_llvm_ty = try o.lowerType(operand_ty, .by_value); | 2113 | .cc = target.cCallingConvention().?, |
| 2146 | const libc_fn = try o.getLibcFunction(fn_name, &.{operand_llvm_ty}, libc_ret_ty); | 2114 | .param_types = &.{operand_scalar_ty.toIntern()}, |
| 2147 | var result = try self.wip.call( | 2115 | .return_type = rt_int_ty.toIntern(), |
| 2148 | .normal, | 2116 | }, &.{operand}, if (operand_ty.isVector(zcu)) operand_ty.vectorLen(zcu) else null); |
| 2149 | .ccc, | 2117 | return fg.wip.cast(.trunc, result, try o.lowerType(dest_ty, .as_value), ""); |
| 2150 | .none, | ||
| 2151 | libc_fn.typeOf(&o.builder), | ||
| 2152 | libc_fn.toValue(&o.builder), | ||
| 2153 | &.{operand}, | ||
| 2154 | "", | ||
| 2155 | ); | ||
| 2156 | |||
| 2157 | if (libc_ret_ty != ret_ty) result = try self.wip.cast(.bitcast, result, ret_ty, ""); | ||
| 2158 | if (ret_ty != dest_llvm_ty) result = try self.wip.cast(.trunc, result, dest_llvm_ty, ""); | ||
| 2159 | return result; | ||
| 2160 | } | 2118 | } |
| 2161 | 2119 | ||
| 2162 | fn sliceOrArrayPtr(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator.Error!Builder.Value { | 2120 | fn sliceOrArrayPtr(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator.Error!Builder.Value { |
| ... | @@ -2167,7 +2125,7 @@ fn sliceOrArrayPtr(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator.Error!B | ... | @@ -2167,7 +2125,7 @@ fn sliceOrArrayPtr(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator.Error!B |
| 2167 | fn sliceOrArrayLenInBytes(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator.Error!Builder.Value { | 2125 | fn sliceOrArrayLenInBytes(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator.Error!Builder.Value { |
| 2168 | const o = fg.object; | 2126 | const o = fg.object; |
| 2169 | const zcu = o.zcu; | 2127 | const zcu = o.zcu; |
| 2170 | const llvm_usize = try o.lowerType(.usize, .by_value); | 2128 | const llvm_usize = try o.lowerType(.usize, .as_value); |
| 2171 | switch (ty.ptrSize(zcu)) { | 2129 | switch (ty.ptrSize(zcu)) { |
| 2172 | .slice => { | 2130 | .slice => { |
| 2173 | const len = try fg.wip.extractValue(ptr, &.{1}, ""); | 2131 | const len = try fg.wip.extractValue(ptr, &.{1}, ""); |
| ... | @@ -2365,7 +2323,7 @@ fn airAggFieldVal(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder. | ... | @@ -2365,7 +2323,7 @@ fn airAggFieldVal(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder. |
| 2365 | }, | 2323 | }, |
| 2366 | .float => { | 2324 | .float => { |
| 2367 | // bitcast int->float | 2325 | // bitcast int->float |
| 2368 | return self.wip.cast(.bitcast, field_int_val, try o.lowerType(field_ty, .by_value), ""); | 2326 | return self.wip.cast(.bitcast, field_int_val, try o.lowerType(field_ty, .as_value), ""); |
| 2369 | }, | 2327 | }, |
| 2370 | } | 2328 | } |
| 2371 | } | 2329 | } |
| ... | @@ -2395,8 +2353,8 @@ fn airFieldParentPtr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Build | ... | @@ -2395,8 +2353,8 @@ fn airFieldParentPtr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Build |
| 2395 | const field_offset = parent_ty.structFieldOffset(extra.field_index, zcu); | 2353 | const field_offset = parent_ty.structFieldOffset(extra.field_index, zcu); |
| 2396 | if (field_offset == 0) return field_ptr; | 2354 | if (field_offset == 0) return field_ptr; |
| 2397 | 2355 | ||
| 2398 | const res_ty = try o.lowerType(ty_pl.ty.toType(), .by_value); | 2356 | const res_ty = try o.lowerType(ty_pl.ty.toType(), .as_value); |
| 2399 | const llvm_usize = try o.lowerType(.usize, .by_value); | 2357 | const llvm_usize = try o.lowerType(.usize, .as_value); |
| 2400 | 2358 | ||
| 2401 | const field_ptr_int = try self.wip.cast(.ptrtoint, field_ptr, llvm_usize, ""); | 2359 | const field_ptr_int = try self.wip.cast(.ptrtoint, field_ptr, llvm_usize, ""); |
| 2402 | const base_ptr_int = try self.wip.bin( | 2360 | const base_ptr_int = try self.wip.bin( |
| ... | @@ -2516,7 +2474,7 @@ fn airDbgVarVal(self: *FuncGen, inst: Air.Inst.Index, is_arg: bool) Allocator.Er | ... | @@ -2516,7 +2474,7 @@ fn airDbgVarVal(self: *FuncGen, inst: Air.Inst.Index, is_arg: bool) Allocator.Er |
| 2516 | }, | 2474 | }, |
| 2517 | "", | 2475 | "", |
| 2518 | ); | 2476 | ); |
| 2519 | } else if (owner_mod.optimize_mode == .Debug and !self.is_naked) { | 2477 | } else if (owner_mod.optimize_mode == .debug and !self.is_naked) { |
| 2520 | // We avoid taking this path for naked functions because there's no guarantee that such | 2478 | // We avoid taking this path for naked functions because there's no guarantee that such |
| 2521 | // functions even have a valid stack pointer, making the `alloca` + `store` unsafe. | 2479 | // functions even have a valid stack pointer, making the `alloca` + `store` unsafe. |
| 2522 | 2480 | ||
| ... | @@ -2612,7 +2570,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) TodoError!Builder.Value { | ... | @@ -2612,7 +2570,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) TodoError!Builder.Value { |
| 2612 | const output_inst = try self.resolveInst(output.operand); | 2570 | const output_inst = try self.resolveInst(output.operand); |
| 2613 | const output_ty = self.typeOf(output.operand); | 2571 | const output_ty = self.typeOf(output.operand); |
| 2614 | assert(output_ty.zigTypeTag(zcu) == .pointer); | 2572 | assert(output_ty.zigTypeTag(zcu) == .pointer); |
| 2615 | const elem_llvm_ty = try o.lowerType(output_ty.childType(zcu), .by_value); | 2573 | const elem_llvm_ty = try o.lowerType(output_ty.childType(zcu), .as_value); |
| 2616 | 2574 | ||
| 2617 | switch (constraint[0]) { | 2575 | switch (constraint[0]) { |
| 2618 | '=' => {}, | 2576 | '=' => {}, |
| ... | @@ -2650,7 +2608,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) TodoError!Builder.Value { | ... | @@ -2650,7 +2608,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) TodoError!Builder.Value { |
| 2650 | llvm_ret_indirect[output.index] = false; | 2608 | llvm_ret_indirect[output.index] = false; |
| 2651 | 2609 | ||
| 2652 | const ret_ty = self.typeOfIndex(inst); | 2610 | const ret_ty = self.typeOfIndex(inst); |
| 2653 | llvm_ret_types[llvm_ret_i] = try o.lowerType(ret_ty, .by_value); | 2611 | llvm_ret_types[llvm_ret_i] = try o.lowerType(ret_ty, .as_value); |
| 2654 | llvm_ret_i += 1; | 2612 | llvm_ret_i += 1; |
| 2655 | } | 2613 | } |
| 2656 | 2614 | ||
| ... | @@ -2689,7 +2647,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) TodoError!Builder.Value { | ... | @@ -2689,7 +2647,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) TodoError!Builder.Value { |
| 2689 | llvm_param_types[llvm_param_i] = arg_llvm_value.typeOfWip(&self.wip); | 2647 | llvm_param_types[llvm_param_i] = arg_llvm_value.typeOfWip(&self.wip); |
| 2690 | } else { | 2648 | } else { |
| 2691 | const alignment = arg_ty.abiAlignment(zcu).toLlvm(); | 2649 | const alignment = arg_ty.abiAlignment(zcu).toLlvm(); |
| 2692 | const arg_llvm_ty = try o.lowerType(arg_ty, .by_value); | 2650 | const arg_llvm_ty = try o.lowerType(arg_ty, .as_value); |
| 2693 | const load_inst = try self.wip.load(.normal, arg_llvm_ty, arg_llvm_value, alignment, ""); | 2651 | const load_inst = try self.wip.load(.normal, arg_llvm_ty, arg_llvm_value, alignment, ""); |
| 2694 | llvm_param_values[llvm_param_i] = load_inst; | 2652 | llvm_param_values[llvm_param_i] = load_inst; |
| 2695 | llvm_param_types[llvm_param_i] = arg_llvm_ty; | 2653 | llvm_param_types[llvm_param_i] = arg_llvm_ty; |
| ... | @@ -2729,7 +2687,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) TodoError!Builder.Value { | ... | @@ -2729,7 +2687,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) TodoError!Builder.Value { |
| 2729 | llvm_param_attrs[llvm_param_i] = if (constraint[0] == '*') blk: { | 2687 | llvm_param_attrs[llvm_param_i] = if (constraint[0] == '*') blk: { |
| 2730 | if (!is_by_ref) self.maybeMarkAllowZeroAccess(arg_ty.ptrInfo(zcu)); | 2688 | if (!is_by_ref) self.maybeMarkAllowZeroAccess(arg_ty.ptrInfo(zcu)); |
| 2731 | 2689 | ||
| 2732 | break :blk try o.lowerType(if (is_by_ref) arg_ty else arg_ty.childType(zcu), .by_value); | 2690 | break :blk try o.lowerType(if (is_by_ref) arg_ty else arg_ty.childType(zcu), .as_value); |
| 2733 | } else .none; | 2691 | } else .none; |
| 2734 | 2692 | ||
| 2735 | llvm_param_i += 1; | 2693 | llvm_param_i += 1; |
| ... | @@ -2743,7 +2701,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) TodoError!Builder.Value { | ... | @@ -2743,7 +2701,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) TodoError!Builder.Value { |
| 2743 | if (constraint[0] != '+') continue; | 2701 | if (constraint[0] != '+') continue; |
| 2744 | 2702 | ||
| 2745 | const rw_ty = self.typeOf(output.operand); | 2703 | const rw_ty = self.typeOf(output.operand); |
| 2746 | const llvm_elem_ty = try o.lowerType(rw_ty.childType(zcu), .by_value); | 2704 | const llvm_elem_ty = try o.lowerType(rw_ty.childType(zcu), .as_value); |
| 2747 | if (llvm_ret_indirect[output.index]) { | 2705 | if (llvm_ret_indirect[output.index]) { |
| 2748 | llvm_param_values[llvm_param_i] = llvm_rw_vals[output.index]; | 2706 | llvm_param_values[llvm_param_i] = llvm_rw_vals[output.index]; |
| 2749 | llvm_param_types[llvm_param_i] = llvm_rw_vals[output.index].typeOfWip(&self.wip); | 2707 | llvm_param_types[llvm_param_i] = llvm_rw_vals[output.index].typeOfWip(&self.wip); |
| ... | @@ -2957,7 +2915,7 @@ fn airIsNonNull( | ... | @@ -2957,7 +2915,7 @@ fn airIsNonNull( |
| 2957 | )); | 2915 | )); |
| 2958 | return self.wip.icmp(cond, slice_ptr, try o.builder.nullValue(ptr_ty), ""); | 2916 | return self.wip.icmp(cond, slice_ptr, try o.builder.nullValue(ptr_ty), ""); |
| 2959 | } | 2917 | } |
| 2960 | return self.wip.icmp(cond, loaded, try o.builder.zeroInitValue(try o.lowerType(optional_ty, .by_value)), ""); | 2918 | return self.wip.icmp(cond, loaded, try o.builder.zeroInitValue(try o.lowerType(optional_ty, .as_value)), ""); |
| 2961 | } | 2919 | } |
| 2962 | 2920 | ||
| 2963 | comptime assert(optional_layout_version == 3); | 2921 | comptime assert(optional_layout_version == 3); |
| ... | @@ -2986,18 +2944,17 @@ fn airIsErr( | ... | @@ -2986,18 +2944,17 @@ fn airIsErr( |
| 2986 | const operand_ty = self.typeOf(un_op); | 2944 | const operand_ty = self.typeOf(un_op); |
| 2987 | const err_union_ty = if (operand_is_ptr) operand_ty.childType(zcu) else operand_ty; | 2945 | const err_union_ty = if (operand_is_ptr) operand_ty.childType(zcu) else operand_ty; |
| 2988 | const payload_ty = err_union_ty.errorUnionPayload(zcu); | 2946 | const payload_ty = err_union_ty.errorUnionPayload(zcu); |
| 2989 | const zero_err = try o.builder.intValue(try o.errorIntType(.by_value), 0); | 2947 | const zero_err = try o.builder.intValue(try o.errorIntType(.as_value), 0); |
| 2990 | 2948 | ||
| 2991 | const access_kind: Builder.MemoryAccessKind = | 2949 | const access_kind: Builder.MemoryAccessKind = |
| 2992 | if (operand_is_ptr and operand_ty.isVolatilePtr(zcu)) .@"volatile" else .normal; | 2950 | if (operand_is_ptr and operand_ty.isVolatilePtr(zcu)) .@"volatile" else .normal; |
| 2993 | 2951 | ||
| 2994 | if (err_union_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu)) { | 2952 | if (err_union_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu)) { |
| 2995 | const val: Builder.Constant = switch (cond) { | 2953 | return switch (cond) { |
| 2996 | .eq => .true, // 0 == 0 | 2954 | .eq => .true, // 0 == 0 |
| 2997 | .ne => .false, // 0 != 0 | 2955 | .ne => .false, // 0 != 0 |
| 2998 | else => unreachable, | 2956 | else => unreachable, |
| 2999 | }; | 2957 | }; |
| 3000 | return val.toValue(); | ||
| 3001 | } | 2958 | } |
| 3002 | 2959 | ||
| 3003 | if (operand_is_ptr) self.maybeMarkAllowZeroAccess(operand_ty.ptrInfo(zcu)); | 2960 | if (operand_is_ptr) self.maybeMarkAllowZeroAccess(operand_ty.ptrInfo(zcu)); |
| ... | @@ -3156,7 +3113,7 @@ fn airErrUnionPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) Allocator.Erro | ... | @@ -3156,7 +3113,7 @@ fn airErrUnionPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) Allocator.Erro |
| 3156 | const err_union_ptr_align = err_union_ptr_ty.ptrAlignment(zcu); | 3113 | const err_union_ptr_align = err_union_ptr_ty.ptrAlignment(zcu); |
| 3157 | 3114 | ||
| 3158 | const payload_ty = err_union_ty.errorUnionPayload(zcu); | 3115 | const payload_ty = err_union_ty.errorUnionPayload(zcu); |
| 3159 | const non_error_val = try o.builder.intValue(try o.errorIntType(.by_value), 0); | 3116 | const non_error_val = try o.builder.intValue(try o.errorIntType(.as_value), 0); |
| 3160 | 3117 | ||
| 3161 | const access_kind: Builder.MemoryAccessKind = | 3118 | const access_kind: Builder.MemoryAccessKind = |
| 3162 | if (err_union_ptr_ty.isVolatilePtr(zcu)) .@"volatile" else .normal; | 3119 | if (err_union_ptr_ty.isVolatilePtr(zcu)) .@"volatile" else .normal; |
| ... | @@ -3234,7 +3191,7 @@ fn airWrapErrUnionPayload(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error! | ... | @@ -3234,7 +3191,7 @@ fn airWrapErrUnionPayload(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error! |
| 3234 | const payload_ty = self.typeOf(ty_op.operand); | 3191 | const payload_ty = self.typeOf(ty_op.operand); |
| 3235 | assert(payload_ty.hasRuntimeBits(zcu)); | 3192 | assert(payload_ty.hasRuntimeBits(zcu)); |
| 3236 | assert(isByRef(err_un_ty, zcu)); // error unions with runtime bits are always by-ref | 3193 | assert(isByRef(err_un_ty, zcu)); // error unions with runtime bits are always by-ref |
| 3237 | const ok_err_code = try o.builder.intValue(try o.errorIntType(.by_value), 0); | 3194 | const ok_err_code = try o.builder.intValue(try o.errorIntType(.as_value), 0); |
| 3238 | 3195 | ||
| 3239 | const result_ptr = try self.buildZigAlloca(err_un_ty, .none); | 3196 | const result_ptr = try self.buildZigAlloca(err_un_ty, .none); |
| 3240 | 3197 | ||
| ... | @@ -3273,7 +3230,7 @@ fn airWasmMemorySize(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Build | ... | @@ -3273,7 +3230,7 @@ fn airWasmMemorySize(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Build |
| 3273 | const o = self.object; | 3230 | const o = self.object; |
| 3274 | const pl_op = self.air.instructions.items(.data)[@backingInt(inst)].pl_op; | 3231 | const pl_op = self.air.instructions.items(.data)[@backingInt(inst)].pl_op; |
| 3275 | const index = pl_op.payload; | 3232 | const index = pl_op.payload; |
| 3276 | const llvm_usize = try o.lowerType(.usize, .by_value); | 3233 | const llvm_usize = try o.lowerType(.usize, .as_value); |
| 3277 | return self.wip.callIntrinsic(.normal, .none, .@"wasm.memory.size", &.{llvm_usize}, &.{ | 3234 | return self.wip.callIntrinsic(.normal, .none, .@"wasm.memory.size", &.{llvm_usize}, &.{ |
| 3278 | try o.builder.intValue(.i32, index), | 3235 | try o.builder.intValue(.i32, index), |
| 3279 | }, ""); | 3236 | }, ""); |
| ... | @@ -3283,7 +3240,7 @@ fn airWasmMemoryGrow(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Build | ... | @@ -3283,7 +3240,7 @@ fn airWasmMemoryGrow(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Build |
| 3283 | const o = self.object; | 3240 | const o = self.object; |
| 3284 | const pl_op = self.air.instructions.items(.data)[@backingInt(inst)].pl_op; | 3241 | const pl_op = self.air.instructions.items(.data)[@backingInt(inst)].pl_op; |
| 3285 | const index = pl_op.payload; | 3242 | const index = pl_op.payload; |
| 3286 | const llvm_isize = try o.lowerType(.isize, .by_value); | 3243 | const llvm_isize = try o.lowerType(.isize, .as_value); |
| 3287 | return self.wip.callIntrinsic(.normal, .none, .@"wasm.memory.grow", &.{llvm_isize}, &.{ | 3244 | return self.wip.callIntrinsic(.normal, .none, .@"wasm.memory.grow", &.{llvm_isize}, &.{ |
| 3288 | try o.builder.intValue(.i32, index), try self.resolveInst(pl_op.operand), | 3245 | try o.builder.intValue(.i32, index), try self.resolveInst(pl_op.operand), |
| 3289 | }, ""); | 3246 | }, ""); |
| ... | @@ -3310,7 +3267,7 @@ fn airMin(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { | ... | @@ -3310,7 +3267,7 @@ fn airMin(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 3310 | .normal, | 3267 | .normal, |
| 3311 | .none, | 3268 | .none, |
| 3312 | if (scalar_ty.isSignedInt(zcu)) .smin else .umin, | 3269 | if (scalar_ty.isSignedInt(zcu)) .smin else .umin, |
| 3313 | &.{try o.lowerType(inst_ty, .by_value)}, | 3270 | &.{try o.lowerType(inst_ty, .as_value)}, |
| 3314 | &.{ lhs, rhs }, | 3271 | &.{ lhs, rhs }, |
| 3315 | "", | 3272 | "", |
| 3316 | ); | 3273 | ); |
| ... | @@ -3330,7 +3287,7 @@ fn airMax(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { | ... | @@ -3330,7 +3287,7 @@ fn airMax(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 3330 | .normal, | 3287 | .normal, |
| 3331 | .none, | 3288 | .none, |
| 3332 | if (scalar_ty.isSignedInt(zcu)) .smax else .umax, | 3289 | if (scalar_ty.isSignedInt(zcu)) .smax else .umax, |
| 3333 | &.{try o.lowerType(inst_ty, .by_value)}, | 3290 | &.{try o.lowerType(inst_ty, .as_value)}, |
| 3334 | &.{ lhs, rhs }, | 3291 | &.{ lhs, rhs }, |
| 3335 | "", | 3292 | "", |
| 3336 | ); | 3293 | ); |
| ... | @@ -3342,7 +3299,7 @@ fn airSlice(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value | ... | @@ -3342,7 +3299,7 @@ fn airSlice(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value |
| 3342 | const ptr = try self.resolveInst(bin_op.lhs); | 3299 | const ptr = try self.resolveInst(bin_op.lhs); |
| 3343 | const len = try self.resolveInst(bin_op.rhs); | 3300 | const len = try self.resolveInst(bin_op.rhs); |
| 3344 | const inst_ty = self.typeOfIndex(inst); | 3301 | const inst_ty = self.typeOfIndex(inst); |
| 3345 | return self.wip.buildAggregate(try self.object.lowerType(inst_ty, .by_value), &.{ ptr, len }, ""); | 3302 | return self.wip.buildAggregate(try self.object.lowerType(inst_ty, .as_value), &.{ ptr, len }, ""); |
| 3346 | } | 3303 | } |
| 3347 | 3304 | ||
| 3348 | fn airAdd(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allocator.Error!Builder.Value { | 3305 | fn airAdd(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allocator.Error!Builder.Value { |
| ... | @@ -3373,7 +3330,7 @@ fn airSafeArithmetic( | ... | @@ -3373,7 +3330,7 @@ fn airSafeArithmetic( |
| 3373 | const scalar_ty = inst_ty.scalarType(zcu); | 3330 | const scalar_ty = inst_ty.scalarType(zcu); |
| 3374 | 3331 | ||
| 3375 | const intrinsic = if (scalar_ty.isSignedInt(zcu)) signed_intrinsic else unsigned_intrinsic; | 3332 | const intrinsic = if (scalar_ty.isSignedInt(zcu)) signed_intrinsic else unsigned_intrinsic; |
| 3376 | const llvm_inst_ty = try o.lowerType(inst_ty, .by_value); | 3333 | const llvm_inst_ty = try o.lowerType(inst_ty, .as_value); |
| 3377 | const results = | 3334 | const results = |
| 3378 | try fg.wip.callIntrinsic(.normal, .none, intrinsic, &.{llvm_inst_ty}, &.{ lhs, rhs }, ""); | 3335 | try fg.wip.callIntrinsic(.normal, .none, intrinsic, &.{llvm_inst_ty}, &.{ lhs, rhs }, ""); |
| 3379 | 3336 | ||
| ... | @@ -3423,7 +3380,7 @@ fn airAddSat(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value | ... | @@ -3423,7 +3380,7 @@ fn airAddSat(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value |
| 3423 | .normal, | 3380 | .normal, |
| 3424 | .none, | 3381 | .none, |
| 3425 | if (scalar_ty.isSignedInt(zcu)) .@"sadd.sat" else .@"uadd.sat", | 3382 | if (scalar_ty.isSignedInt(zcu)) .@"sadd.sat" else .@"uadd.sat", |
| 3426 | &.{try o.lowerType(inst_ty, .by_value)}, | 3383 | &.{try o.lowerType(inst_ty, .as_value)}, |
| 3427 | &.{ lhs, rhs }, | 3384 | &.{ lhs, rhs }, |
| 3428 | "", | 3385 | "", |
| 3429 | ); | 3386 | ); |
| ... | @@ -3462,7 +3419,7 @@ fn airSubSat(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value | ... | @@ -3462,7 +3419,7 @@ fn airSubSat(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value |
| 3462 | .normal, | 3419 | .normal, |
| 3463 | .none, | 3420 | .none, |
| 3464 | if (scalar_ty.isSignedInt(zcu)) .@"ssub.sat" else .@"usub.sat", | 3421 | if (scalar_ty.isSignedInt(zcu)) .@"ssub.sat" else .@"usub.sat", |
| 3465 | &.{try o.lowerType(inst_ty, .by_value)}, | 3422 | &.{try o.lowerType(inst_ty, .as_value)}, |
| 3466 | &.{ lhs, rhs }, | 3423 | &.{ lhs, rhs }, |
| 3467 | "", | 3424 | "", |
| 3468 | ); | 3425 | ); |
| ... | @@ -3501,7 +3458,7 @@ fn airMulSat(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value | ... | @@ -3501,7 +3458,7 @@ fn airMulSat(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value |
| 3501 | .normal, | 3458 | .normal, |
| 3502 | .none, | 3459 | .none, |
| 3503 | if (scalar_ty.isSignedInt(zcu)) .@"smul.fix.sat" else .@"umul.fix.sat", | 3460 | if (scalar_ty.isSignedInt(zcu)) .@"smul.fix.sat" else .@"umul.fix.sat", |
| 3504 | &.{try o.lowerType(inst_ty, .by_value)}, | 3461 | &.{try o.lowerType(inst_ty, .as_value)}, |
| 3505 | &.{ lhs, rhs, .@"0" }, | 3462 | &.{ lhs, rhs, .@"0" }, |
| 3506 | "", | 3463 | "", |
| 3507 | ); | 3464 | ); |
| ... | @@ -3545,8 +3502,8 @@ fn airDivFloor(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) | ... | @@ -3545,8 +3502,8 @@ fn airDivFloor(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) |
| 3545 | return self.buildFloatOp(.floor, fast, inst_ty, 1, .{result}); | 3502 | return self.buildFloatOp(.floor, fast, inst_ty, 1, .{result}); |
| 3546 | } | 3503 | } |
| 3547 | if (scalar_ty.isSignedInt(zcu)) { | 3504 | if (scalar_ty.isSignedInt(zcu)) { |
| 3548 | const scalar_llvm_ty = try o.lowerType(scalar_ty, .by_value); | 3505 | const scalar_llvm_ty = try o.lowerType(scalar_ty, .as_value); |
| 3549 | const inst_llvm_ty = try o.lowerType(inst_ty, .by_value); | 3506 | const inst_llvm_ty = try o.lowerType(inst_ty, .as_value); |
| 3550 | 3507 | ||
| 3551 | const ExpectedContents = [std.math.big.int.calcTwosCompLimbCount(256)]std.math.big.Limb; | 3508 | const ExpectedContents = [std.math.big.int.calcTwosCompLimbCount(256)]std.math.big.Limb; |
| 3552 | var bfa_buf: ExpectedContents = undefined; | 3509 | var bfa_buf: ExpectedContents = undefined; |
| ... | @@ -3594,8 +3551,8 @@ fn airDivCeil(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) | ... | @@ -3594,8 +3551,8 @@ fn airDivCeil(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) |
| 3594 | return self.buildFloatOp(.ceil, fast, inst_ty, 1, .{result}); | 3551 | return self.buildFloatOp(.ceil, fast, inst_ty, 1, .{result}); |
| 3595 | } | 3552 | } |
| 3596 | if (scalar_ty.isSignedInt(zcu)) { | 3553 | if (scalar_ty.isSignedInt(zcu)) { |
| 3597 | const scalar_llvm_ty = try o.lowerType(scalar_ty, .by_value); | 3554 | const scalar_llvm_ty = try o.lowerType(scalar_ty, .as_value); |
| 3598 | const inst_llvm_ty = try o.lowerType(inst_ty, .by_value); | 3555 | const inst_llvm_ty = try o.lowerType(inst_ty, .as_value); |
| 3599 | 3556 | ||
| 3600 | const ExpectedContents = [std.math.big.int.calcTwosCompLimbCount(256)]std.math.big.Limb; | 3557 | const ExpectedContents = [std.math.big.int.calcTwosCompLimbCount(256)]std.math.big.Limb; |
| 3601 | var bfa_buf: ExpectedContents = undefined; | 3558 | var bfa_buf: ExpectedContents = undefined; |
| ... | @@ -3634,8 +3591,8 @@ fn airDivCeil(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) | ... | @@ -3634,8 +3591,8 @@ fn airDivCeil(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) |
| 3634 | const correction = try self.wip.cast(.zext, need_correction, inst_llvm_ty, "divCeil.correction"); | 3591 | const correction = try self.wip.cast(.zext, need_correction, inst_llvm_ty, "divCeil.correction"); |
| 3635 | return self.wip.bin(.@"add nsw", div, correction, "divCeil"); | 3592 | return self.wip.bin(.@"add nsw", div, correction, "divCeil"); |
| 3636 | } else { | 3593 | } else { |
| 3637 | const scalar_llvm_ty = try o.lowerType(scalar_ty, .by_value); | 3594 | const scalar_llvm_ty = try o.lowerType(scalar_ty, .as_value); |
| 3638 | const inst_llvm_ty = try o.lowerType(inst_ty, .by_value); | 3595 | const inst_llvm_ty = try o.lowerType(inst_ty, .as_value); |
| 3639 | 3596 | ||
| 3640 | const zero = try o.builder.splatValue( | 3597 | const zero = try o.builder.splatValue( |
| 3641 | inst_llvm_ty, | 3598 | inst_llvm_ty, |
| ... | @@ -3692,15 +3649,17 @@ fn airMod(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allo | ... | @@ -3692,15 +3649,17 @@ fn airMod(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allo |
| 3692 | const lhs = try self.resolveInst(bin_op.lhs); | 3649 | const lhs = try self.resolveInst(bin_op.lhs); |
| 3693 | const rhs = try self.resolveInst(bin_op.rhs); | 3650 | const rhs = try self.resolveInst(bin_op.rhs); |
| 3694 | const inst_ty = self.typeOfIndex(inst); | 3651 | const inst_ty = self.typeOfIndex(inst); |
| 3695 | const inst_llvm_ty = try o.lowerType(inst_ty, .by_value); | ||
| 3696 | const scalar_ty = inst_ty.scalarType(zcu); | 3652 | const scalar_ty = inst_ty.scalarType(zcu); |
| 3697 | 3653 | ||
| 3698 | if (scalar_ty.isRuntimeFloat()) { | 3654 | if (scalar_ty.isRuntimeFloat()) { |
| 3699 | const a = try self.buildFloatOp(.fmod, fast, inst_ty, 2, .{ lhs, rhs }); | 3655 | const a = try self.buildFloatOp(.fmod, fast, inst_ty, 2, .{ lhs, rhs }); |
| 3700 | const b = try self.buildFloatOp(.add, fast, inst_ty, 2, .{ a, rhs }); | 3656 | const b = try self.buildFloatOp(.add, fast, inst_ty, 2, .{ a, rhs }); |
| 3701 | const c = try self.buildFloatOp(.fmod, fast, inst_ty, 2, .{ b, rhs }); | 3657 | const c = try self.buildFloatOp(.fmod, fast, inst_ty, 2, .{ b, rhs }); |
| 3702 | const zero = try o.builder.zeroInitValue(inst_llvm_ty); | 3658 | const zero = if (isByRef(inst_ty, zcu)) zero: { |
| 3703 | const ltz = try self.buildFloatCmp(fast, .lt, inst_ty, .{ lhs, zero }); | 3659 | const zero = try o.builder.zeroInitConst(try o.lowerType(inst_ty, .in_memory)); |
| 3660 | break :zero try o.lowerConstRef(zero, inst_ty.abiAlignment(zcu).toLlvm()); | ||
| 3661 | } else try o.builder.zeroInitConst(try o.lowerType(inst_ty, .as_value)); | ||
| 3662 | const ltz = try self.buildFloatCmp(fast, .lt, inst_ty, .{ lhs, zero.toValue() }); | ||
| 3704 | return self.wip.select(fast, ltz, c, a, ""); | 3663 | return self.wip.select(fast, ltz, c, a, ""); |
| 3705 | } | 3664 | } |
| 3706 | if (scalar_ty.isSignedInt(zcu)) { | 3665 | if (scalar_ty.isSignedInt(zcu)) { |
| ... | @@ -3709,6 +3668,7 @@ fn airMod(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allo | ... | @@ -3709,6 +3668,7 @@ fn airMod(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allo |
| 3709 | var bfa: std.heap.BufferFirstAllocator = .init(@ptrCast(&bfa_buf), self.gpa); | 3668 | var bfa: std.heap.BufferFirstAllocator = .init(@ptrCast(&bfa_buf), self.gpa); |
| 3710 | const allocator = bfa.allocator(); | 3669 | const allocator = bfa.allocator(); |
| 3711 | 3670 | ||
| 3671 | const inst_llvm_ty = try o.lowerType(inst_ty, .as_value); | ||
| 3712 | const scalar_bits = scalar_ty.intInfo(zcu).bits; | 3672 | const scalar_bits = scalar_ty.intInfo(zcu).bits; |
| 3713 | var smin_big_int: std.math.big.int.Mutable = .{ | 3673 | var smin_big_int: std.math.big.int.Mutable = .{ |
| 3714 | .limbs = try allocator.alloc( | 3674 | .limbs = try allocator.alloc( |
| ... | @@ -3721,7 +3681,7 @@ fn airMod(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allo | ... | @@ -3721,7 +3681,7 @@ fn airMod(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allo |
| 3721 | defer allocator.free(smin_big_int.limbs); | 3681 | defer allocator.free(smin_big_int.limbs); |
| 3722 | smin_big_int.setTwosCompIntLimit(.min, .signed, scalar_bits); | 3682 | smin_big_int.setTwosCompIntLimit(.min, .signed, scalar_bits); |
| 3723 | const smin = try o.builder.splatValue(inst_llvm_ty, try o.builder.bigIntConst( | 3683 | const smin = try o.builder.splatValue(inst_llvm_ty, try o.builder.bigIntConst( |
| 3724 | try o.lowerType(scalar_ty, .by_value), | 3684 | try o.lowerType(scalar_ty, .as_value), |
| 3725 | smin_big_int.toConst(), | 3685 | smin_big_int.toConst(), |
| 3726 | )); | 3686 | )); |
| 3727 | 3687 | ||
| ... | @@ -3757,7 +3717,7 @@ fn airPtrSub(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value | ... | @@ -3757,7 +3717,7 @@ fn airPtrSub(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value |
| 3757 | const ty_pl = self.air.instructions.items(.data)[@backingInt(inst)].ty_pl; | 3717 | const ty_pl = self.air.instructions.items(.data)[@backingInt(inst)].ty_pl; |
| 3758 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; | 3718 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 3759 | const ptr_or_slice = try self.resolveInst(bin_op.lhs); | 3719 | const ptr_or_slice = try self.resolveInst(bin_op.lhs); |
| 3760 | const llvm_usize_ty = try o.lowerType(.usize, .by_value); | 3720 | const llvm_usize_ty = try o.lowerType(.usize, .as_value); |
| 3761 | const ptr_ty = self.typeOf(bin_op.lhs); | 3721 | const ptr_ty = self.typeOf(bin_op.lhs); |
| 3762 | const elem_ty = ptr_ty.indexableElem(zcu); | 3722 | const elem_ty = ptr_ty.indexableElem(zcu); |
| 3763 | const ptr = switch (ptr_ty.ptrSize(zcu)) { | 3723 | const ptr = switch (ptr_ty.ptrSize(zcu)) { |
| ... | @@ -3790,7 +3750,7 @@ fn airOverflow( | ... | @@ -3790,7 +3750,7 @@ fn airOverflow( |
| 3790 | assert(isByRef(inst_ty, zcu)); // auto structs are by-ref | 3750 | assert(isByRef(inst_ty, zcu)); // auto structs are by-ref |
| 3791 | 3751 | ||
| 3792 | const intrinsic = if (scalar_ty.isSignedInt(zcu)) signed_intrinsic else unsigned_intrinsic; | 3752 | const intrinsic = if (scalar_ty.isSignedInt(zcu)) signed_intrinsic else unsigned_intrinsic; |
| 3793 | const llvm_lhs_ty = try o.lowerType(lhs_ty, .by_value); | 3753 | const llvm_lhs_ty = try o.lowerType(lhs_ty, .as_value); |
| 3794 | const results = | 3754 | const results = |
| 3795 | try self.wip.callIntrinsic(.normal, .none, intrinsic, &.{llvm_lhs_ty}, &.{ lhs, rhs }, ""); | 3755 | try self.wip.callIntrinsic(.normal, .none, intrinsic, &.{llvm_lhs_ty}, &.{ lhs, rhs }, ""); |
| 3796 | 3756 | ||
| ... | @@ -3818,34 +3778,97 @@ fn airOverflow( | ... | @@ -3818,34 +3778,97 @@ fn airOverflow( |
| 3818 | } | 3778 | } |
| 3819 | 3779 | ||
| 3820 | fn buildElementwiseCall( | 3780 | fn buildElementwiseCall( |
| 3821 | self: *FuncGen, | 3781 | fg: *FuncGen, |
| 3822 | llvm_fn: Builder.Function.Index, | 3782 | fn_name: Builder.StrtabString, |
| 3823 | args_vectors: []const Builder.Value, | 3783 | fn_info: Object.FuncInfo, |
| 3824 | result_vector: Builder.Value, | 3784 | arg_values: []const Builder.Value, |
| 3825 | vector_len: usize, | 3785 | vector_len: ?u32, |
| 3826 | ) Allocator.Error!Builder.Value { | 3786 | ) Allocator.Error!Builder.Value { |
| 3827 | const o = self.object; | 3787 | const o = fg.object; |
| 3828 | assert(args_vectors.len <= 3); | 3788 | const zcu = o.zcu; |
| 3789 | const llvm_fn = try fg.object.getLibcFunction(fg.pt, fn_name, fn_info); | ||
| 3790 | |||
| 3791 | const iterations = vector_len orelse 1; | ||
| 3792 | const ret_ty: Type = .fromInterned(fn_info.return_type); | ||
| 3793 | const ret_is_by_ref = isByRef(ret_ty, zcu); | ||
| 3794 | if (iterations > 1 and (fn_info.return_type == .void_type or ret_is_by_ref) and | ||
| 3795 | for (fn_info.param_types) |param_type| { | ||
| 3796 | if (!isByRef(.fromInterned(param_type), zcu)) break false; | ||
| 3797 | } else true) | ||
| 3798 | { | ||
| 3799 | const entry_block = fg.wip.cursor.block; | ||
| 3800 | const loop_block = try fg.wip.block(2, "elementwise.loop"); | ||
| 3801 | const done_block = try fg.wip.block(1, "elementwise.done"); | ||
| 3802 | |||
| 3803 | const result_ptr = if (fn_info.return_type == .void_type) .none else result_ptr: { | ||
| 3804 | const ret_llvm_ty = try o.lowerType(ret_ty, .in_memory); | ||
| 3805 | break :result_ptr try fg.buildAlloca( | ||
| 3806 | if (vector_len) |len| try o.builder.arrayType(len, ret_llvm_ty) else ret_llvm_ty, | ||
| 3807 | ret_ty.abiAlignment(zcu).toLlvm(), | ||
| 3808 | ); | ||
| 3809 | }; | ||
| 3810 | _ = try fg.wip.br(loop_block); | ||
| 3829 | 3811 | ||
| 3830 | var i: usize = 0; | 3812 | fg.wip.cursor = .{ .block = loop_block }; |
| 3831 | var result = result_vector; | 3813 | const index = try fg.wip.phi(.i32, "elementwise.index"); |
| 3832 | while (i < vector_len) : (i += 1) { | ||
| 3833 | const index_i32 = try o.builder.intValue(.i32, i); | ||
| 3834 | 3814 | ||
| 3835 | var args: [3]Builder.Value = undefined; | 3815 | var arg_elems_buf: [3]Builder.Value = undefined; |
| 3836 | for (args[0..args_vectors.len], args_vectors) |*arg_elem, arg_vector| { | 3816 | const arg_elems = arg_elems_buf[0..arg_values.len]; |
| 3837 | arg_elem.* = try self.wip.extractElement(arg_vector, index_i32, ""); | 3817 | for (arg_elems, fn_info.param_types, arg_values) |*arg_elem, param_type, arg_value| { |
| 3818 | const arg_elem_ptr = try fg.ptraddScaled(arg_value, index.toValue(), Type.fromInterned(param_type).abiSize(zcu)); | ||
| 3819 | arg_elem.* = try fg.load(arg_elem_ptr, .none, .fromInterned(param_type), .normal); | ||
| 3838 | } | 3820 | } |
| 3839 | const result_elem = try self.wip.call( | 3821 | const result_elem = try fg.buildCall(.{}, llvm_fn.typeOf(&o.builder), llvm_fn.toValue(&o.builder), fn_info, fn_info.param_types, arg_elems); |
| 3840 | .normal, | 3822 | if (fn_info.return_type == .void_type) { |
| 3841 | .ccc, | 3823 | assert(result_elem == .none); |
| 3842 | .none, | 3824 | } else if (result_elem != .none) { |
| 3843 | llvm_fn.typeOf(&o.builder), | 3825 | const result_elem_ptr = try fg.ptraddScaled(result_ptr, index.toValue(), ret_ty.abiSize(zcu)); |
| 3844 | llvm_fn.toValue(&o.builder), | 3826 | try fg.store(result_elem_ptr, .none, result_elem, ret_ty, .normal); |
| 3845 | args[0..args_vectors.len], | 3827 | } |
| 3846 | "", | 3828 | |
| 3829 | const next_index = try fg.wip.bin(.@"add nuw", index.toValue(), try o.builder.intValue(.i32, 1), "elementwise.next_index"); | ||
| 3830 | index.finish(&.{ try o.builder.intValue(.i32, 0), next_index }, &.{ entry_block, loop_block }, &fg.wip); | ||
| 3831 | const is_done = try fg.wip.icmp(.eq, next_index, try o.builder.intValue(.i32, iterations), "elementwise.is_done"); | ||
| 3832 | _ = try fg.wip.brCond(is_done, done_block, loop_block, .none); | ||
| 3833 | |||
| 3834 | fg.wip.cursor = .{ .block = done_block }; | ||
| 3835 | return result_ptr; | ||
| 3836 | } | ||
| 3837 | |||
| 3838 | var result = if (fn_info.return_type == .void_type) .none else if (ret_is_by_ref) result: { | ||
| 3839 | const ret_llvm_ty = try o.lowerType(ret_ty, .in_memory); | ||
| 3840 | break :result try fg.buildAlloca( | ||
| 3841 | if (vector_len) |len| try o.builder.arrayType(len, ret_llvm_ty) else ret_llvm_ty, | ||
| 3842 | ret_ty.abiAlignment(zcu).toLlvm(), | ||
| 3847 | ); | 3843 | ); |
| 3848 | result = try self.wip.insertElement(result, result_elem, index_i32, ""); | 3844 | } else if (vector_len) |len| try o.builder.poisonValue( |
| 3845 | try o.builder.vectorType(.normal, len, try o.lowerType(ret_ty, .as_value)), | ||
| 3846 | ) else .none; | ||
| 3847 | for (0..iterations) |index| { | ||
| 3848 | const index_value = try o.builder.intValue(.i32, index); | ||
| 3849 | var arg_elems_buf: [3]Builder.Value = undefined; | ||
| 3850 | const arg_elems = arg_elems_buf[0..arg_values.len]; | ||
| 3851 | for (arg_elems, fn_info.param_types, arg_values) |*arg_elem_value, param_type, arg_value| { | ||
| 3852 | const arg_ty: Type = .fromInterned(param_type); | ||
| 3853 | if (isByRef(arg_ty, zcu)) { | ||
| 3854 | const arg_elem_ptr = try fg.ptraddConst(arg_value, index * arg_ty.abiSize(zcu)); | ||
| 3855 | arg_elem_value.* = try fg.load(arg_elem_ptr, .none, .fromInterned(param_type), .normal); | ||
| 3856 | } else if (vector_len) |_| { | ||
| 3857 | arg_elem_value.* = try fg.wip.extractElement(arg_value, index_value, "elementwise.arg_elem"); | ||
| 3858 | } else arg_elem_value.* = arg_value; | ||
| 3859 | } | ||
| 3860 | const result_elem = try fg.buildCall(.{}, llvm_fn.typeOf(&o.builder), llvm_fn.toValue(&o.builder), fn_info, fn_info.param_types, arg_elems); | ||
| 3861 | if (fn_info.return_type == .void_type) { | ||
| 3862 | assert(result_elem == .none); | ||
| 3863 | } else if (ret_is_by_ref) { | ||
| 3864 | const result_elem_ptr = try fg.ptraddConst(result, index * ret_ty.abiSize(zcu)); | ||
| 3865 | try fg.store(result_elem_ptr, .none, result_elem, ret_ty, .normal); | ||
| 3866 | } else if (vector_len) |_| { | ||
| 3867 | result = try fg.wip.insertElement(result, result_elem, index_value, "elementwise.result"); | ||
| 3868 | } else { | ||
| 3869 | assert(result == .none); | ||
| 3870 | result = result_elem; | ||
| 3871 | } | ||
| 3849 | } | 3872 | } |
| 3850 | return result; | 3873 | return result; |
| 3851 | } | 3874 | } |
| ... | @@ -3853,19 +3876,18 @@ fn buildElementwiseCall( | ... | @@ -3853,19 +3876,18 @@ fn buildElementwiseCall( |
| 3853 | /// Creates a floating point comparison by lowering to the appropriate | 3876 | /// Creates a floating point comparison by lowering to the appropriate |
| 3854 | /// hardware instruction or softfloat routine for the target | 3877 | /// hardware instruction or softfloat routine for the target |
| 3855 | fn buildFloatCmp( | 3878 | fn buildFloatCmp( |
| 3856 | self: *FuncGen, | 3879 | fg: *FuncGen, |
| 3857 | fast: Builder.FastMathKind, | 3880 | fast: Builder.FastMathKind, |
| 3858 | pred: math.CompareOperator, | 3881 | pred: math.CompareOperator, |
| 3859 | ty: Type, | 3882 | ty: Type, |
| 3860 | params: [2]Builder.Value, | 3883 | params: [2]Builder.Value, |
| 3861 | ) Allocator.Error!Builder.Value { | 3884 | ) Allocator.Error!Builder.Value { |
| 3862 | const o = self.object; | 3885 | const o = fg.object; |
| 3863 | const zcu = o.zcu; | 3886 | const zcu = o.zcu; |
| 3864 | const target = zcu.getTarget(); | 3887 | const target = zcu.getTarget(); |
| 3865 | const scalar_ty = ty.scalarType(zcu); | 3888 | const scalar_ty = ty.scalarType(zcu); |
| 3866 | const scalar_llvm_ty = try o.lowerType(scalar_ty, .by_value); | ||
| 3867 | 3889 | ||
| 3868 | if (intrinsicsAllowed(scalar_ty, target)) { | 3890 | if (intrinsicsAllowed(.compiler_rt, scalar_ty, target)) { |
| 3869 | const cond: Builder.FloatCondition = switch (pred) { | 3891 | const cond: Builder.FloatCondition = switch (pred) { |
| 3870 | .eq => .oeq, | 3892 | .eq => .oeq, |
| 3871 | .neq => .une, | 3893 | .neq => .une, |
| ... | @@ -3874,53 +3896,33 @@ fn buildFloatCmp( | ... | @@ -3874,53 +3896,33 @@ fn buildFloatCmp( |
| 3874 | .gt => .ogt, | 3896 | .gt => .ogt, |
| 3875 | .gte => .oge, | 3897 | .gte => .oge, |
| 3876 | }; | 3898 | }; |
| 3877 | return self.wip.fcmp(fast, cond, params[0], params[1], ""); | 3899 | return fg.wip.fcmp(fast, cond, params[0], params[1], ""); |
| 3878 | } | 3900 | } |
| 3879 | 3901 | ||
| 3880 | const float_bits = scalar_ty.floatBits(target); | 3902 | const fn_name = try o.builder.strtabStringFmt("__{s}{s}f2", .{ |
| 3881 | const compiler_rt_float_abbrev = compilerRtFloatAbbrev(float_bits); | 3903 | switch (pred) { |
| 3882 | const fn_base_name = switch (pred) { | 3904 | .neq => "ne", |
| 3883 | .neq => "ne", | 3905 | .eq => "eq", |
| 3884 | .eq => "eq", | 3906 | .lt => "lt", |
| 3885 | .lt => "lt", | 3907 | .lte => "le", |
| 3886 | .lte => "le", | 3908 | .gt => "gt", |
| 3887 | .gt => "gt", | 3909 | .gte => "ge", |
| 3888 | .gte => "ge", | 3910 | }, |
| 3889 | }; | 3911 | compilerRtFloatAbbrev(target, scalar_ty.floatBits(target)), |
| 3890 | const fn_name = try o.builder.strtabStringFmt("__{s}{s}f2", .{ fn_base_name, compiler_rt_float_abbrev }); | 3912 | }); |
| 3891 | 3913 | const result = try fg.buildElementwiseCall(fn_name, .{ | |
| 3892 | const libc_fn = try o.getLibcFunction(fn_name, &.{ scalar_llvm_ty, scalar_llvm_ty }, .i32); | 3914 | .cc = target.cCallingConvention().?, |
| 3893 | 3915 | .param_types = &.{ scalar_ty.toIntern(), scalar_ty.toIntern() }, | |
| 3894 | const int_cond: Builder.IntegerCondition = switch (pred) { | 3916 | .return_type = .i32_type, |
| 3917 | }, &params, if (ty.isVector(zcu)) ty.vectorLen(zcu) else null); | ||
| 3918 | return fg.wip.icmp(switch (pred) { | ||
| 3895 | .eq => .eq, | 3919 | .eq => .eq, |
| 3896 | .neq => .ne, | 3920 | .neq => .ne, |
| 3897 | .lt => .slt, | 3921 | .lt => .slt, |
| 3898 | .lte => .sle, | 3922 | .lte => .sle, |
| 3899 | .gt => .sgt, | 3923 | .gt => .sgt, |
| 3900 | .gte => .sge, | 3924 | .gte => .sge, |
| 3901 | }; | 3925 | }, result, try o.builder.splatValue(result.typeOfWip(&fg.wip), .@"0"), ""); |
| 3902 | |||
| 3903 | if (ty.zigTypeTag(zcu) == .vector) { | ||
| 3904 | const vec_len = ty.vectorLen(zcu); | ||
| 3905 | const vector_result_ty = try o.builder.vectorType(.normal, vec_len, .i32); | ||
| 3906 | |||
| 3907 | const init = try o.builder.poisonValue(vector_result_ty); | ||
| 3908 | const result = try self.buildElementwiseCall(libc_fn, &params, init, vec_len); | ||
| 3909 | |||
| 3910 | const zero_vector = try o.builder.splatValue(vector_result_ty, .@"0"); | ||
| 3911 | return self.wip.icmp(int_cond, result, zero_vector, ""); | ||
| 3912 | } | ||
| 3913 | |||
| 3914 | const result = try self.wip.call( | ||
| 3915 | .normal, | ||
| 3916 | .ccc, | ||
| 3917 | .none, | ||
| 3918 | libc_fn.typeOf(&o.builder), | ||
| 3919 | libc_fn.toValue(&o.builder), | ||
| 3920 | &params, | ||
| 3921 | "", | ||
| 3922 | ); | ||
| 3923 | return self.wip.icmp(int_cond, result, .@"0", ""); | ||
| 3924 | } | 3926 | } |
| 3925 | 3927 | ||
| 3926 | const FloatOp = enum { | 3928 | const FloatOp = enum { |
| ... | @@ -3949,32 +3951,30 @@ const FloatOp = enum { | ... | @@ -3949,32 +3951,30 @@ const FloatOp = enum { |
| 3949 | trunc, | 3951 | trunc, |
| 3950 | }; | 3952 | }; |
| 3951 | 3953 | ||
| 3952 | const FloatOpStrat = union(enum) { | ||
| 3953 | intrinsic: []const u8, | ||
| 3954 | libc: Builder.String, | ||
| 3955 | }; | ||
| 3956 | |||
| 3957 | /// Creates a floating point operation (add, sub, fma, sqrt, exp, etc.) | 3954 | /// Creates a floating point operation (add, sub, fma, sqrt, exp, etc.) |
| 3958 | /// by lowering to the appropriate hardware instruction or softfloat | 3955 | /// by lowering to the appropriate hardware instruction or softfloat |
| 3959 | /// routine for the target | 3956 | /// routine for the target |
| 3960 | fn buildFloatOp( | 3957 | fn buildFloatOp( |
| 3961 | self: *FuncGen, | 3958 | fg: *FuncGen, |
| 3962 | comptime op: FloatOp, | 3959 | comptime op: FloatOp, |
| 3963 | fast: Builder.FastMathKind, | 3960 | fast: Builder.FastMathKind, |
| 3964 | ty: Type, | 3961 | ty: Type, |
| 3965 | comptime params_len: usize, | 3962 | comptime params_len: usize, |
| 3966 | params: [params_len]Builder.Value, | 3963 | params: [params_len]Builder.Value, |
| 3967 | ) Allocator.Error!Builder.Value { | 3964 | ) Allocator.Error!Builder.Value { |
| 3968 | const o = self.object; | 3965 | const o = fg.object; |
| 3969 | const zcu = o.zcu; | 3966 | const zcu = o.zcu; |
| 3970 | const target = zcu.getTarget(); | 3967 | const target = zcu.getTarget(); |
| 3971 | const scalar_ty = ty.scalarType(zcu); | 3968 | const scalar_ty = ty.scalarType(zcu); |
| 3972 | const llvm_ty = try o.lowerType(ty, .by_value); | ||
| 3973 | 3969 | ||
| 3974 | if (op != .tan and intrinsicsAllowed(scalar_ty, target)) switch (op) { | 3970 | switch (op) { |
| 3975 | // Some operations are dedicated LLVM instructions, not available as intrinsics | 3971 | // Some operations are dedicated LLVM instructions, not available as intrinsics |
| 3976 | .neg => return self.wip.un(.fneg, params[0], ""), | 3972 | .neg => if (intrinsicsAllowed(.compiler_rt, scalar_ty, target)) return fg.wip.un(.fneg, params[0], ""), |
| 3977 | .add, .sub, .mul, .div, .fmod => return self.wip.bin(switch (fast) { | 3973 | .add, .sub, .mul, .div, .fmod => if (intrinsicsAllowed(switch (op) { |
| 3974 | else => unreachable, | ||
| 3975 | .add, .sub, .mul, .div => .compiler_rt, | ||
| 3976 | .fmod => .libc, | ||
| 3977 | }, scalar_ty, target)) return fg.wip.bin(switch (fast) { | ||
| 3978 | .normal => switch (op) { | 3978 | .normal => switch (op) { |
| 3979 | .add => .fadd, | 3979 | .add => .fadd, |
| 3980 | .sub => .fsub, | 3980 | .sub => .fsub, |
| ... | @@ -3992,6 +3992,7 @@ fn buildFloatOp( | ... | @@ -3992,6 +3992,7 @@ fn buildFloatOp( |
| 3992 | else => unreachable, | 3992 | else => unreachable, |
| 3993 | }, | 3993 | }, |
| 3994 | }, params[0], params[1], ""), | 3994 | }, params[0], params[1], ""), |
| 3995 | .fma, | ||
| 3995 | .fmax, | 3996 | .fmax, |
| 3996 | .fmin, | 3997 | .fmin, |
| 3997 | .ceil, | 3998 | .ceil, |
| ... | @@ -4006,9 +4007,10 @@ fn buildFloatOp( | ... | @@ -4006,9 +4007,10 @@ fn buildFloatOp( |
| 4006 | .round, | 4007 | .round, |
| 4007 | .sin, | 4008 | .sin, |
| 4008 | .sqrt, | 4009 | .sqrt, |
| 4010 | .tan, | ||
| 4009 | .trunc, | 4011 | .trunc, |
| 4010 | .fma, | 4012 | => if (intrinsicsAllowed(.libc, scalar_ty, target)) return fg.wip.callIntrinsic(fast, .none, switch (op) { |
| 4011 | => return self.wip.callIntrinsic(fast, .none, switch (op) { | 4013 | .fma => .fma, |
| 4012 | .fmax => .maxnum, | 4014 | .fmax => .maxnum, |
| 4013 | .fmin => .minnum, | 4015 | .fmin => .minnum, |
| 4014 | .ceil => .ceil, | 4016 | .ceil => .ceil, |
| ... | @@ -4023,39 +4025,154 @@ fn buildFloatOp( | ... | @@ -4023,39 +4025,154 @@ fn buildFloatOp( |
| 4023 | .round => .round, | 4025 | .round => .round, |
| 4024 | .sin => .sin, | 4026 | .sin => .sin, |
| 4025 | .sqrt => .sqrt, | 4027 | .sqrt => .sqrt, |
| 4028 | .tan => .tan, | ||
| 4026 | .trunc => .trunc, | 4029 | .trunc => .trunc, |
| 4027 | .fma => .fma, | ||
| 4028 | else => unreachable, | 4030 | else => unreachable, |
| 4029 | }, &.{llvm_ty}, &params, ""), | 4031 | }, &.{try o.lowerType(ty, .as_value)}, &params, ""), |
| 4030 | .tan => unreachable, | 4032 | } |
| 4031 | }; | ||
| 4032 | 4033 | ||
| 4033 | const float_bits = scalar_ty.floatBits(target); | 4034 | const float_bits = scalar_ty.floatBits(target); |
| 4034 | const fn_name = switch (op) { | 4035 | const fn_name = switch (op) { |
| 4035 | .neg => { | 4036 | // In these cases we can generate a softfloat operation by modifying the sign bit using a bitwise operation. |
| 4036 | // In this case we can generate a softfloat negation by XORing the | 4037 | .neg, .fabs => if (isByRef(scalar_ty, zcu)) { |
| 4037 | // bits with a constant. | 4038 | const is_vector = ty.toIntern() != scalar_ty.toIntern(); |
| 4039 | const result_ptr = try fg.buildZigAlloca(ty, .none); | ||
| 4040 | const entry_block = fg.wip.cursor.block; | ||
| 4041 | const loop_block, const done_block, const llvm_usize_ty, const offset, const elem, const result_elem = if (is_vector) loop: { | ||
| 4042 | const loop_block = try fg.wip.block(2, "neg_fabs.loop"); | ||
| 4043 | const done_block = try fg.wip.block(1, "neg_fabs.done"); | ||
| 4044 | _ = try fg.wip.br(loop_block); | ||
| 4045 | |||
| 4046 | fg.wip.cursor = .{ .block = loop_block }; | ||
| 4047 | const llvm_usize_ty = try o.lowerType(.usize, .as_value); | ||
| 4048 | const offset = try fg.wip.phi(llvm_usize_ty, "neg_fabs.offset"); | ||
| 4049 | break :loop .{ | ||
| 4050 | loop_block, | ||
| 4051 | done_block, | ||
| 4052 | llvm_usize_ty, | ||
| 4053 | offset, | ||
| 4054 | try fg.ptraddScaled(params[0], offset.toValue(), 1), | ||
| 4055 | try fg.ptraddScaled(result_ptr, offset.toValue(), 1), | ||
| 4056 | }; | ||
| 4057 | } else .{ undefined, undefined, undefined, undefined, params[0], result_ptr }; | ||
| 4058 | switch (scalar_ty.floatBits(target)) { | ||
| 4059 | else => unreachable, | ||
| 4060 | 80 => { | ||
| 4061 | const f80_layout = o.softF80Layout(.{}) catch unreachable; | ||
| 4062 | const mantissa = try fg.load( | ||
| 4063 | try fg.ptraddConst(elem, f80_layout.mantissa_offset), | ||
| 4064 | f80_layout.alignment.offset(f80_layout.mantissa_offset), | ||
| 4065 | .u64, | ||
| 4066 | .normal, | ||
| 4067 | ); | ||
| 4068 | const exponent = try fg.load( | ||
| 4069 | try fg.ptraddConst(elem, f80_layout.exponent_offset), | ||
| 4070 | f80_layout.alignment.offset(f80_layout.exponent_offset), | ||
| 4071 | .u16, | ||
| 4072 | .normal, | ||
| 4073 | ); | ||
| 4074 | const exponent_sign_bit: u16 = 1 << (16 - 1); | ||
| 4075 | const updated_exponent = try fg.wip.bin(switch (op) { | ||
| 4076 | else => unreachable, | ||
| 4077 | .neg => .xor, | ||
| 4078 | .fabs => .@"and", | ||
| 4079 | }, exponent, try o.builder.intValue(.i16, switch (op) { | ||
| 4080 | else => unreachable, | ||
| 4081 | .neg => exponent_sign_bit, | ||
| 4082 | .fabs => exponent_sign_bit - 1, | ||
| 4083 | }), "neg_fabs.updated_exponent"); | ||
| 4084 | try fg.store( | ||
| 4085 | try fg.ptraddConst(result_elem, f80_layout.mantissa_offset), | ||
| 4086 | f80_layout.alignment.offset(f80_layout.mantissa_offset), | ||
| 4087 | mantissa, | ||
| 4088 | .u64, | ||
| 4089 | .normal, | ||
| 4090 | ); | ||
| 4091 | try fg.store( | ||
| 4092 | try fg.ptraddConst(result_elem, f80_layout.exponent_offset), | ||
| 4093 | f80_layout.alignment.offset(f80_layout.exponent_offset), | ||
| 4094 | updated_exponent, | ||
| 4095 | .u16, | ||
| 4096 | .normal, | ||
| 4097 | ); | ||
| 4098 | }, | ||
| 4099 | 128 => { | ||
| 4100 | const f128_layout = o.softF128Layout(.{}) catch unreachable; | ||
| 4101 | const lo = try fg.load( | ||
| 4102 | try fg.ptraddConst(elem, f128_layout.lo_offset), | ||
| 4103 | f128_layout.alignment.offset(f128_layout.lo_offset), | ||
| 4104 | .u64, | ||
| 4105 | .normal, | ||
| 4106 | ); | ||
| 4107 | const hi = try fg.load( | ||
| 4108 | try fg.ptraddConst(elem, f128_layout.hi_offset), | ||
| 4109 | f128_layout.alignment.offset(f128_layout.hi_offset), | ||
| 4110 | .u64, | ||
| 4111 | .normal, | ||
| 4112 | ); | ||
| 4113 | const hi_sign_bit: u64 = 1 << (64 - 1); | ||
| 4114 | const updated_hi = try fg.wip.bin(switch (op) { | ||
| 4115 | else => unreachable, | ||
| 4116 | .neg => .xor, | ||
| 4117 | .fabs => .@"and", | ||
| 4118 | }, hi, try o.builder.intValue(.i64, switch (op) { | ||
| 4119 | else => unreachable, | ||
| 4120 | .neg => hi_sign_bit, | ||
| 4121 | .fabs => hi_sign_bit - 1, | ||
| 4122 | }), "neg_fabs.updated_hi"); | ||
| 4123 | try fg.store( | ||
| 4124 | try fg.ptraddConst(result_elem, f128_layout.lo_offset), | ||
| 4125 | f128_layout.alignment.offset(f128_layout.lo_offset), | ||
| 4126 | lo, | ||
| 4127 | .u64, | ||
| 4128 | .normal, | ||
| 4129 | ); | ||
| 4130 | try fg.store( | ||
| 4131 | try fg.ptraddConst(result_elem, f128_layout.hi_offset), | ||
| 4132 | f128_layout.alignment.offset(f128_layout.hi_offset), | ||
| 4133 | updated_hi, | ||
| 4134 | .u64, | ||
| 4135 | .normal, | ||
| 4136 | ); | ||
| 4137 | }, | ||
| 4138 | } | ||
| 4139 | if (is_vector) { | ||
| 4140 | const next_offset = try fg.wip.bin(.@"add nuw", offset.toValue(), try o.builder.intValue(llvm_usize_ty, scalar_ty.abiSize(zcu)), "neg_fabs.next_offset"); | ||
| 4141 | offset.finish(&.{ try o.builder.intValue(llvm_usize_ty, 0), next_offset }, &.{ entry_block, loop_block }, &fg.wip); | ||
| 4142 | const is_done = try fg.wip.icmp(.eq, next_offset, try o.builder.intValue(llvm_usize_ty, ty.abiSize(zcu)), "neg_fabs.is_done"); | ||
| 4143 | _ = try fg.wip.brCond(is_done, done_block, loop_block, .none); | ||
| 4144 | |||
| 4145 | fg.wip.cursor = .{ .block = done_block }; | ||
| 4146 | } | ||
| 4147 | return result_ptr; | ||
| 4148 | } else { | ||
| 4038 | const int_ty = try o.builder.intType(@intCast(float_bits)); | 4149 | const int_ty = try o.builder.intType(@intCast(float_bits)); |
| 4039 | const cast_ty = switch (ty.zigTypeTag(zcu)) { | 4150 | const cast_ty = switch (ty.zigTypeTag(zcu)) { |
| 4040 | .vector => try o.builder.vectorType(.normal, ty.vectorLen(zcu), int_ty), | 4151 | .vector => try o.builder.vectorType(.normal, ty.vectorLen(zcu), int_ty), |
| 4041 | else => int_ty, | 4152 | else => int_ty, |
| 4042 | }; | 4153 | }; |
| 4043 | const sign_mask = try o.builder.splatValue( | 4154 | const sign_bit = @as(u128, 1) << @intCast(float_bits - 1); |
| 4044 | cast_ty, | 4155 | const bitwise_rhs = try o.builder.splatValue(cast_ty, try o.builder.intConst(int_ty, switch (op) { |
| 4045 | try o.builder.intConst(int_ty, @as(u128, 1) << @intCast(float_bits - 1)), | 4156 | else => unreachable, |
| 4046 | ); | 4157 | .neg => sign_bit, |
| 4047 | const bitcasted_operand = try self.wip.cast(.bitcast, params[0], cast_ty, ""); | 4158 | .fabs => sign_bit - 1, |
| 4048 | const result = try self.wip.bin(.xor, bitcasted_operand, sign_mask, ""); | 4159 | })); |
| 4049 | return self.wip.cast(.bitcast, result, llvm_ty, ""); | 4160 | const bitcasted_operand = try fg.wip.cast(.bitcast, params[0], cast_ty, ""); |
| 4161 | const result = try fg.wip.bin(switch (op) { | ||
| 4162 | else => unreachable, | ||
| 4163 | .neg => .xor, | ||
| 4164 | .fabs => .@"and", | ||
| 4165 | }, bitcasted_operand, bitwise_rhs, ""); | ||
| 4166 | const llvm_ty = try o.lowerType(ty, .as_value); | ||
| 4167 | return fg.wip.cast(.bitcast, result, llvm_ty, ""); | ||
| 4050 | }, | 4168 | }, |
| 4051 | .add, .sub, .div, .mul => try o.builder.strtabStringFmt("__{s}{s}f3", .{ | 4169 | .add, .sub, .div, .mul => try o.builder.strtabStringFmt("__{s}{s}f3", .{ |
| 4052 | @tagName(op), compilerRtFloatAbbrev(float_bits), | 4170 | @tagName(op), compilerRtFloatAbbrev(target, float_bits), |
| 4053 | }), | 4171 | }), |
| 4054 | .ceil, | 4172 | .ceil, |
| 4055 | .cos, | 4173 | .cos, |
| 4056 | .exp, | 4174 | .exp, |
| 4057 | .exp2, | 4175 | .exp2, |
| 4058 | .fabs, | ||
| 4059 | .floor, | 4176 | .floor, |
| 4060 | .fma, | 4177 | .fma, |
| 4061 | .fmax, | 4178 | .fmax, |
| ... | @@ -4073,27 +4190,27 @@ fn buildFloatOp( | ... | @@ -4073,27 +4190,27 @@ fn buildFloatOp( |
| 4073 | libcFloatPrefix(float_bits), @tagName(op), libcFloatSuffix(float_bits), | 4190 | libcFloatPrefix(float_bits), @tagName(op), libcFloatSuffix(float_bits), |
| 4074 | }), | 4191 | }), |
| 4075 | }; | 4192 | }; |
| 4193 | return fg.buildElementwiseCall(fn_name, .{ | ||
| 4194 | .cc = target.cCallingConvention().?, | ||
| 4195 | .param_types = &@as([params_len]InternPool.Index, @splat(scalar_ty.toIntern())), | ||
| 4196 | .return_type = scalar_ty.toIntern(), | ||
| 4197 | }, &params, if (ty.isVector(zcu)) ty.vectorLen(zcu) else null); | ||
| 4198 | } | ||
| 4076 | 4199 | ||
| 4077 | const scalar_llvm_ty = try o.lowerType(scalar_ty, .by_value); | 4200 | /// Creates a floating point cast operation by lowering to the specified softfloat routine. |
| 4078 | const libc_fn = try o.getLibcFunction( | 4201 | fn buildFloatCastCall( |
| 4079 | fn_name, | 4202 | fg: *FuncGen, |
| 4080 | @as([3]Builder.Type, @splat(scalar_llvm_ty))[0..params.len], | 4203 | dest_ty: Type, |
| 4081 | scalar_llvm_ty, | 4204 | fn_name: Builder.StrtabString, |
| 4082 | ); | 4205 | operand_ty: Type, |
| 4083 | if (ty.zigTypeTag(zcu) == .vector) { | 4206 | operand: Builder.Value, |
| 4084 | const result = try o.builder.poisonValue(llvm_ty); | 4207 | ) Allocator.Error!Builder.Value { |
| 4085 | return self.buildElementwiseCall(libc_fn, &params, result, ty.vectorLen(zcu)); | 4208 | const zcu = fg.object.zcu; |
| 4086 | } | 4209 | return fg.buildElementwiseCall(fn_name, .{ |
| 4087 | 4210 | .cc = zcu.getTarget().cCallingConvention().?, | |
| 4088 | return self.wip.call( | 4211 | .param_types = &.{operand_ty.scalarType(zcu).toIntern()}, |
| 4089 | fast.toCallKind(), | 4212 | .return_type = dest_ty.scalarType(zcu).toIntern(), |
| 4090 | .ccc, | 4213 | }, &.{operand}, if (operand_ty.isVector(zcu)) operand_ty.vectorLen(zcu) else null); |
| 4091 | .none, | ||
| 4092 | libc_fn.typeOf(&o.builder), | ||
| 4093 | libc_fn.toValue(&o.builder), | ||
| 4094 | &params, | ||
| 4095 | "", | ||
| 4096 | ); | ||
| 4097 | } | 4214 | } |
| 4098 | 4215 | ||
| 4099 | fn airMulAdd(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { | 4216 | fn airMulAdd(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| ... | @@ -4129,7 +4246,7 @@ fn airShlWithOverflow(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Buil | ... | @@ -4129,7 +4246,7 @@ fn airShlWithOverflow(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Buil |
| 4129 | const dest_ty = self.typeOfIndex(inst); | 4246 | const dest_ty = self.typeOfIndex(inst); |
| 4130 | assert(isByRef(dest_ty, zcu)); // auto structs are by-ref | 4247 | assert(isByRef(dest_ty, zcu)); // auto structs are by-ref |
| 4131 | 4248 | ||
| 4132 | const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(lhs_ty, .by_value), ""); | 4249 | const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(lhs_ty, .as_value), ""); |
| 4133 | 4250 | ||
| 4134 | const result = try self.wip.bin(.shl, lhs, casted_rhs, ""); | 4251 | const result = try self.wip.bin(.shl, lhs, casted_rhs, ""); |
| 4135 | const reconstructed = try self.wip.bin(if (lhs_scalar_ty.isSignedInt(zcu)) | 4252 | const reconstructed = try self.wip.bin(if (lhs_scalar_ty.isSignedInt(zcu)) |
| ... | @@ -4196,7 +4313,7 @@ fn airShlExact(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Val | ... | @@ -4196,7 +4313,7 @@ fn airShlExact(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Val |
| 4196 | } | 4313 | } |
| 4197 | const lhs_scalar_ty = lhs_ty.scalarType(zcu); | 4314 | const lhs_scalar_ty = lhs_ty.scalarType(zcu); |
| 4198 | 4315 | ||
| 4199 | const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(lhs_ty, .by_value), ""); | 4316 | const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(lhs_ty, .as_value), ""); |
| 4200 | return self.wip.bin(if (lhs_scalar_ty.isSignedInt(zcu)) | 4317 | return self.wip.bin(if (lhs_scalar_ty.isSignedInt(zcu)) |
| 4201 | .@"shl nsw" | 4318 | .@"shl nsw" |
| 4202 | else | 4319 | else |
| ... | @@ -4217,7 +4334,7 @@ fn airShl(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { | ... | @@ -4217,7 +4334,7 @@ fn airShl(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 4217 | // features which we do not use. Therefore this branch is currently impossible. | 4334 | // features which we do not use. Therefore this branch is currently impossible. |
| 4218 | unreachable; | 4335 | unreachable; |
| 4219 | } | 4336 | } |
| 4220 | const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(lhs_ty, .by_value), ""); | 4337 | const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(lhs_ty, .as_value), ""); |
| 4221 | return self.wip.bin(.shl, lhs, casted_rhs, ""); | 4338 | return self.wip.bin(.shl, lhs, casted_rhs, ""); |
| 4222 | } | 4339 | } |
| 4223 | 4340 | ||
| ... | @@ -4231,8 +4348,8 @@ fn airShlSat(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value | ... | @@ -4231,8 +4348,8 @@ fn airShlSat(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value |
| 4231 | 4348 | ||
| 4232 | const lhs_ty = self.typeOf(bin_op.lhs); | 4349 | const lhs_ty = self.typeOf(bin_op.lhs); |
| 4233 | const lhs_info = lhs_ty.intInfo(zcu); | 4350 | const lhs_info = lhs_ty.intInfo(zcu); |
| 4234 | const llvm_lhs_ty = try o.lowerType(lhs_ty, .by_value); | 4351 | const llvm_lhs_ty = try o.lowerType(lhs_ty, .as_value); |
| 4235 | const llvm_lhs_scalar_ty = try o.lowerType(lhs_ty.scalarType(zcu), .by_value); | 4352 | const llvm_lhs_scalar_ty = try o.lowerType(lhs_ty.scalarType(zcu), .as_value); |
| 4236 | 4353 | ||
| 4237 | const rhs_ty = self.typeOf(bin_op.rhs); | 4354 | const rhs_ty = self.typeOf(bin_op.rhs); |
| 4238 | if (lhs_ty.isVector(zcu) and !rhs_ty.isVector(zcu)) { | 4355 | if (lhs_ty.isVector(zcu) and !rhs_ty.isVector(zcu)) { |
| ... | @@ -4242,8 +4359,8 @@ fn airShlSat(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value | ... | @@ -4242,8 +4359,8 @@ fn airShlSat(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value |
| 4242 | } | 4359 | } |
| 4243 | const rhs_info = rhs_ty.intInfo(zcu); | 4360 | const rhs_info = rhs_ty.intInfo(zcu); |
| 4244 | assert(rhs_info.signedness == .unsigned); | 4361 | assert(rhs_info.signedness == .unsigned); |
| 4245 | const llvm_rhs_ty = try o.lowerType(rhs_ty, .by_value); | 4362 | const llvm_rhs_ty = try o.lowerType(rhs_ty, .as_value); |
| 4246 | const llvm_rhs_scalar_ty = try o.lowerType(rhs_ty.scalarType(zcu), .by_value); | 4363 | const llvm_rhs_scalar_ty = try o.lowerType(rhs_ty.scalarType(zcu), .as_value); |
| 4247 | 4364 | ||
| 4248 | const result = try self.wip.callIntrinsic( | 4365 | const result = try self.wip.callIntrinsic( |
| 4249 | .normal, | 4366 | .normal, |
| ... | @@ -4319,7 +4436,7 @@ fn airShr(self: *FuncGen, inst: Air.Inst.Index, is_exact: bool) Allocator.Error! | ... | @@ -4319,7 +4436,7 @@ fn airShr(self: *FuncGen, inst: Air.Inst.Index, is_exact: bool) Allocator.Error! |
| 4319 | } | 4436 | } |
| 4320 | const lhs_scalar_ty = lhs_ty.scalarType(zcu); | 4437 | const lhs_scalar_ty = lhs_ty.scalarType(zcu); |
| 4321 | 4438 | ||
| 4322 | const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(lhs_ty, .by_value), ""); | 4439 | const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(lhs_ty, .as_value), ""); |
| 4323 | const is_signed_int = lhs_scalar_ty.isSignedInt(zcu); | 4440 | const is_signed_int = lhs_scalar_ty.isSignedInt(zcu); |
| 4324 | 4441 | ||
| 4325 | return self.wip.bin(if (is_exact) | 4442 | return self.wip.bin(if (is_exact) |
| ... | @@ -4340,7 +4457,7 @@ fn airAbs(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { | ... | @@ -4340,7 +4457,7 @@ fn airAbs(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 4340 | .normal, | 4457 | .normal, |
| 4341 | .none, | 4458 | .none, |
| 4342 | .abs, | 4459 | .abs, |
| 4343 | &.{try o.lowerType(operand_ty, .by_value)}, | 4460 | &.{try o.lowerType(operand_ty, .as_value)}, |
| 4344 | &.{ operand, .false }, | 4461 | &.{ operand, .false }, |
| 4345 | "", | 4462 | "", |
| 4346 | ), | 4463 | ), |
| ... | @@ -4354,7 +4471,7 @@ fn airIntCast(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error! | ... | @@ -4354,7 +4471,7 @@ fn airIntCast(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error! |
| 4354 | const zcu = o.zcu; | 4471 | const zcu = o.zcu; |
| 4355 | const ty_op = fg.air.instructions.items(.data)[@backingInt(inst)].ty_op; | 4472 | const ty_op = fg.air.instructions.items(.data)[@backingInt(inst)].ty_op; |
| 4356 | const dest_ty = fg.typeOfIndex(inst); | 4473 | const dest_ty = fg.typeOfIndex(inst); |
| 4357 | const dest_llvm_ty = try o.lowerType(dest_ty, .by_value); | 4474 | const dest_llvm_ty = try o.lowerType(dest_ty, .as_value); |
| 4358 | const operand = try fg.resolveInst(ty_op.operand); | 4475 | const operand = try fg.resolveInst(ty_op.operand); |
| 4359 | const operand_ty = fg.typeOf(ty_op.operand); | 4476 | const operand_ty = fg.typeOf(ty_op.operand); |
| 4360 | const operand_info = operand_ty.intInfo(zcu); | 4477 | const operand_info = operand_ty.intInfo(zcu); |
| ... | @@ -4382,8 +4499,8 @@ fn airIntCast(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error! | ... | @@ -4382,8 +4499,8 @@ fn airIntCast(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error! |
| 4382 | 4499 | ||
| 4383 | if (!have_min_check and !have_max_check) break :bounds_check; | 4500 | if (!have_min_check and !have_max_check) break :bounds_check; |
| 4384 | 4501 | ||
| 4385 | const operand_llvm_ty = try o.lowerType(operand_ty, .by_value); | 4502 | const operand_llvm_ty = try o.lowerType(operand_ty, .as_value); |
| 4386 | const operand_scalar_llvm_ty = try o.lowerType(operand_scalar, .by_value); | 4503 | const operand_scalar_llvm_ty = try o.lowerType(operand_scalar, .as_value); |
| 4387 | 4504 | ||
| 4388 | const is_vector = operand_ty.zigTypeTag(zcu) == .vector; | 4505 | const is_vector = operand_ty.zigTypeTag(zcu) == .vector; |
| 4389 | assert(is_vector == (dest_ty.zigTypeTag(zcu) == .vector)); | 4506 | assert(is_vector == (dest_ty.zigTypeTag(zcu) == .vector)); |
| ... | @@ -4461,7 +4578,7 @@ fn airIntCast(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error! | ... | @@ -4461,7 +4578,7 @@ fn airIntCast(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error! |
| 4461 | fn airTrunc(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { | 4578 | fn airTrunc(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 4462 | const ty_op = self.air.instructions.items(.data)[@backingInt(inst)].ty_op; | 4579 | const ty_op = self.air.instructions.items(.data)[@backingInt(inst)].ty_op; |
| 4463 | const operand = try self.resolveInst(ty_op.operand); | 4580 | const operand = try self.resolveInst(ty_op.operand); |
| 4464 | const dest_llvm_ty = try self.object.lowerType(self.typeOfIndex(inst), .by_value); | 4581 | const dest_llvm_ty = try self.object.lowerType(self.typeOfIndex(inst), .as_value); |
| 4465 | return self.wip.cast(.trunc, operand, dest_llvm_ty, ""); | 4582 | return self.wip.cast(.trunc, operand, dest_llvm_ty, ""); |
| 4466 | } | 4583 | } |
| 4467 | 4584 | ||
| ... | @@ -4471,32 +4588,20 @@ fn airFptrunc(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Valu | ... | @@ -4471,32 +4588,20 @@ fn airFptrunc(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Valu |
| 4471 | const ty_op = self.air.instructions.items(.data)[@backingInt(inst)].ty_op; | 4588 | const ty_op = self.air.instructions.items(.data)[@backingInt(inst)].ty_op; |
| 4472 | const operand = try self.resolveInst(ty_op.operand); | 4589 | const operand = try self.resolveInst(ty_op.operand); |
| 4473 | const operand_ty = self.typeOf(ty_op.operand); | 4590 | const operand_ty = self.typeOf(ty_op.operand); |
| 4591 | const operand_scalar_ty = operand_ty.scalarType(zcu); | ||
| 4474 | const dest_ty = self.typeOfIndex(inst); | 4592 | const dest_ty = self.typeOfIndex(inst); |
| 4593 | const dest_scalar_ty = dest_ty.scalarType(zcu); | ||
| 4475 | const target = zcu.getTarget(); | 4594 | const target = zcu.getTarget(); |
| 4476 | 4595 | ||
| 4477 | if (intrinsicsAllowed(dest_ty, target) and intrinsicsAllowed(operand_ty, target)) { | 4596 | if (intrinsicsAllowed(.compiler_rt, dest_scalar_ty, target) and |
| 4478 | return self.wip.cast(.fptrunc, operand, try o.lowerType(dest_ty, .by_value), ""); | 4597 | intrinsicsAllowed(.compiler_rt, operand_scalar_ty, target)) |
| 4479 | } else { | 4598 | return self.wip.cast(.fptrunc, operand, try o.lowerType(dest_ty, .as_value), ""); |
| 4480 | const operand_llvm_ty = try o.lowerType(operand_ty, .by_value); | 4599 | const dest_bits = dest_scalar_ty.floatBits(target); |
| 4481 | const dest_llvm_ty = try o.lowerType(dest_ty, .by_value); | 4600 | const src_bits = operand_scalar_ty.floatBits(target); |
| 4482 | 4601 | const fn_name = try o.builder.strtabStringFmt("__trunc{s}f{s}f2", .{ | |
| 4483 | const dest_bits = dest_ty.floatBits(target); | 4602 | compilerRtFloatAbbrev(target, src_bits), compilerRtFloatAbbrev(target, dest_bits), |
| 4484 | const src_bits = operand_ty.floatBits(target); | 4603 | }); |
| 4485 | const fn_name = try o.builder.strtabStringFmt("__trunc{s}f{s}f2", .{ | 4604 | return self.buildFloatCastCall(dest_ty, fn_name, operand_ty, operand); |
| 4486 | compilerRtFloatAbbrev(src_bits), compilerRtFloatAbbrev(dest_bits), | ||
| 4487 | }); | ||
| 4488 | |||
| 4489 | const libc_fn = try o.getLibcFunction(fn_name, &.{operand_llvm_ty}, dest_llvm_ty); | ||
| 4490 | return self.wip.call( | ||
| 4491 | .normal, | ||
| 4492 | .ccc, | ||
| 4493 | .none, | ||
| 4494 | libc_fn.typeOf(&o.builder), | ||
| 4495 | libc_fn.toValue(&o.builder), | ||
| 4496 | &.{operand}, | ||
| 4497 | "", | ||
| 4498 | ); | ||
| 4499 | } | ||
| 4500 | } | 4605 | } |
| 4501 | 4606 | ||
| 4502 | fn airFpext(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { | 4607 | fn airFpext(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| ... | @@ -4505,38 +4610,20 @@ fn airFpext(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value | ... | @@ -4505,38 +4610,20 @@ fn airFpext(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value |
| 4505 | const ty_op = self.air.instructions.items(.data)[@backingInt(inst)].ty_op; | 4610 | const ty_op = self.air.instructions.items(.data)[@backingInt(inst)].ty_op; |
| 4506 | const operand = try self.resolveInst(ty_op.operand); | 4611 | const operand = try self.resolveInst(ty_op.operand); |
| 4507 | const operand_ty = self.typeOf(ty_op.operand); | 4612 | const operand_ty = self.typeOf(ty_op.operand); |
| 4613 | const operand_scalar_ty = operand_ty.scalarType(zcu); | ||
| 4508 | const dest_ty = self.typeOfIndex(inst); | 4614 | const dest_ty = self.typeOfIndex(inst); |
| 4615 | const dest_scalar_ty = dest_ty.scalarType(zcu); | ||
| 4509 | const target = zcu.getTarget(); | 4616 | const target = zcu.getTarget(); |
| 4510 | 4617 | ||
| 4511 | if (intrinsicsAllowed(dest_ty, target) and intrinsicsAllowed(operand_ty, target)) { | 4618 | if (intrinsicsAllowed(.compiler_rt, dest_scalar_ty, target) and |
| 4512 | return self.wip.cast(.fpext, operand, try o.lowerType(dest_ty, .by_value), ""); | 4619 | intrinsicsAllowed(.compiler_rt, operand_scalar_ty, target)) |
| 4513 | } else { | 4620 | return self.wip.cast(.fpext, operand, try o.lowerType(dest_ty, .as_value), ""); |
| 4514 | const operand_llvm_ty = try o.lowerType(operand_ty, .by_value); | 4621 | const dest_bits = dest_scalar_ty.floatBits(target); |
| 4515 | const dest_llvm_ty = try o.lowerType(dest_ty, .by_value); | 4622 | const src_bits = operand_scalar_ty.floatBits(target); |
| 4516 | 4623 | const fn_name = try o.builder.strtabStringFmt("__extend{s}f{s}f2", .{ | |
| 4517 | const dest_bits = dest_ty.scalarType(zcu).floatBits(target); | 4624 | compilerRtFloatAbbrev(target, src_bits), compilerRtFloatAbbrev(target, dest_bits), |
| 4518 | const src_bits = operand_ty.scalarType(zcu).floatBits(target); | 4625 | }); |
| 4519 | const fn_name = try o.builder.strtabStringFmt("__extend{s}f{s}f2", .{ | 4626 | return self.buildFloatCastCall(dest_ty, fn_name, operand_ty, operand); |
| 4520 | compilerRtFloatAbbrev(src_bits), compilerRtFloatAbbrev(dest_bits), | ||
| 4521 | }); | ||
| 4522 | |||
| 4523 | const libc_fn = try o.getLibcFunction(fn_name, &.{operand_llvm_ty}, dest_llvm_ty); | ||
| 4524 | if (dest_ty.isVector(zcu)) return self.buildElementwiseCall( | ||
| 4525 | libc_fn, | ||
| 4526 | &.{operand}, | ||
| 4527 | try o.builder.poisonValue(dest_llvm_ty), | ||
| 4528 | dest_ty.vectorLen(zcu), | ||
| 4529 | ); | ||
| 4530 | return self.wip.call( | ||
| 4531 | .normal, | ||
| 4532 | .ccc, | ||
| 4533 | .none, | ||
| 4534 | libc_fn.typeOf(&o.builder), | ||
| 4535 | libc_fn.toValue(&o.builder), | ||
| 4536 | &.{operand}, | ||
| 4537 | "", | ||
| 4538 | ); | ||
| 4539 | } | ||
| 4540 | } | 4627 | } |
| 4541 | 4628 | ||
| 4542 | fn airBitCast(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error!Builder.Value { | 4629 | fn airBitCast(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error!Builder.Value { |
| ... | @@ -4558,28 +4645,161 @@ fn airBitCast(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error! | ... | @@ -4558,28 +4645,161 @@ fn airBitCast(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error! |
| 4558 | // * bool/int/float <-> bool/int/float | 4645 | // * bool/int/float <-> bool/int/float |
| 4559 | // * `@Vector(n, A)` <-> `@Vector(n, B)` | 4646 | // * `@Vector(n, A)` <-> `@Vector(n, B)` |
| 4560 | // | 4647 | // |
| 4561 | // All of these cases can be handled by LLVM's `bitcast` instruction. | 4648 | // Most of these cases can be handled by LLVM's `bitcast` instruction, except when |
| 4649 | // a non-native type like `f80` is used. | ||
| 4562 | 4650 | ||
| 4563 | assert(!isByRef(operand_ty, zcu)); | 4651 | if (isByRef(operand_ty, zcu)) { |
| 4564 | assert(!isByRef(dest_ty, zcu)); | 4652 | const operand_scalar_ty = operand_ty.scalarType(zcu); |
| 4653 | const target = zcu.getTarget(); | ||
| 4654 | const bits = operand_scalar_ty.floatBits(target); | ||
| 4655 | const dest_scalar_ty = dest_ty.scalarType(zcu); | ||
| 4656 | if (isByRef(dest_ty, zcu)) { | ||
| 4657 | assert(dest_scalar_ty.floatBits(target) == bits); | ||
| 4658 | return operand; | ||
| 4659 | } | ||
| 4660 | assert(dest_scalar_ty.intInfo(zcu).bits == bits); | ||
| 4565 | 4661 | ||
| 4566 | const llvm_dest_ty = try o.lowerType(dest_ty, .by_value); | 4662 | const len = if (operand_ty.toIntern() != operand_scalar_ty.toIntern()) |
| 4567 | const result = try fg.wip.cast(.bitcast, operand, llvm_dest_ty, ""); | 4663 | operand_ty.vectorLen(zcu) |
| 4568 | if (safety and dest_ty.zigTypeTag(zcu) == .@"enum" and !dest_ty.isNonexhaustiveEnum(zcu)) { | 4664 | else |
| 4569 | const llvm_fn = try o.getIsNamedEnumValueFunction(dest_ty); | 4665 | null; |
| 4570 | const is_valid_enum_val = try fg.wip.call( | 4666 | const operand_scalar_size = operand_scalar_ty.abiSize(zcu); |
| 4571 | .normal, | 4667 | var result = if (len) |_| |
| 4572 | .fastcc, | 4668 | try o.builder.poisonValue(try o.lowerType(dest_ty, .as_value)) |
| 4573 | .none, | 4669 | else |
| 4574 | llvm_fn.typeOf(&o.builder), | 4670 | undefined; |
| 4575 | llvm_fn.toValue(&o.builder), | 4671 | for (0..len orelse 1) |index| { |
| 4576 | &.{result}, | 4672 | const result_elem = result_elem: switch (bits) { |
| 4577 | "", | 4673 | else => unreachable, |
| 4578 | ); | 4674 | 80 => { |
| 4579 | const fail_block = try fg.wip.block(1, "ValidEnumFail"); | 4675 | const f80_layout = o.softF80Layout(.{}) catch unreachable; |
| 4580 | const ok_block = try fg.wip.block(1, "ValidEnumOk"); | 4676 | const mantissa = try fg.load( |
| 4581 | _ = try fg.wip.brCond(is_valid_enum_val, ok_block, fail_block, .none); | 4677 | try fg.ptraddConst(operand, operand_scalar_size * index + f80_layout.mantissa_offset), |
| 4582 | fg.wip.cursor = .{ .block = fail_block }; | 4678 | f80_layout.alignment.offset(f80_layout.mantissa_offset), |
| 4679 | .u64, | ||
| 4680 | .normal, | ||
| 4681 | ); | ||
| 4682 | const exponent = try fg.load( | ||
| 4683 | try fg.ptraddConst(operand, operand_scalar_size * index + f80_layout.exponent_offset), | ||
| 4684 | f80_layout.alignment.offset(f80_layout.exponent_offset), | ||
| 4685 | .u16, | ||
| 4686 | .normal, | ||
| 4687 | ); | ||
| 4688 | const casted_mantissa = try fg.wip.cast(.zext, mantissa, .i80, "bitCast.casted_mantissa"); | ||
| 4689 | const casted_exponent = try fg.wip.cast(.zext, exponent, .i80, "bitCast.casted_exponent"); | ||
| 4690 | const shifted_exponent = try fg.wip.bin(.@"shl nuw", casted_exponent, try o.builder.intValue(.i80, 64), "bitCast.shifted_exponent"); | ||
| 4691 | break :result_elem try fg.wip.bin(.@"or", casted_mantissa, shifted_exponent, "bitCast.result_elem"); | ||
| 4692 | }, | ||
| 4693 | 128 => { | ||
| 4694 | const f128_layout = o.softF128Layout(.{}) catch unreachable; | ||
| 4695 | const lo = try fg.load( | ||
| 4696 | try fg.ptraddConst(operand, operand_scalar_size * index + f128_layout.lo_offset), | ||
| 4697 | f128_layout.alignment.offset(f128_layout.lo_offset), | ||
| 4698 | .u64, | ||
| 4699 | .normal, | ||
| 4700 | ); | ||
| 4701 | const hi = try fg.load( | ||
| 4702 | try fg.ptraddConst(operand, operand_scalar_size * index + f128_layout.hi_offset), | ||
| 4703 | f128_layout.alignment.offset(f128_layout.hi_offset), | ||
| 4704 | .u64, | ||
| 4705 | .normal, | ||
| 4706 | ); | ||
| 4707 | const casted_lo = try fg.wip.cast(.zext, lo, .i128, "bitCast.casted_lo"); | ||
| 4708 | const casted_hi = try fg.wip.cast(.zext, hi, .i128, "bitCast.casted_hi"); | ||
| 4709 | const shifted_hi = try fg.wip.bin(.@"shl nuw", casted_hi, try o.builder.intValue(.i128, 64), "bitCast.shifted_hi"); | ||
| 4710 | break :result_elem try fg.wip.bin(.@"or", casted_lo, shifted_hi, "bitCast.result_elem"); | ||
| 4711 | }, | ||
| 4712 | }; | ||
| 4713 | result = if (len) |_| | ||
| 4714 | try fg.wip.insertElement(result, result_elem, try o.builder.intValue(.i32, index), "elementwise.result") | ||
| 4715 | else | ||
| 4716 | result_elem; | ||
| 4717 | } | ||
| 4718 | return result; | ||
| 4719 | } | ||
| 4720 | |||
| 4721 | if (isByRef(dest_ty, zcu)) { | ||
| 4722 | const dest_scalar_ty = dest_ty.scalarType(zcu); | ||
| 4723 | const bits = dest_scalar_ty.floatBits(zcu.getTarget()); | ||
| 4724 | assert(dest_scalar_ty.isRuntimeFloat()); | ||
| 4725 | const operand_scalar_ty = operand_ty.scalarType(zcu); | ||
| 4726 | assert(operand_scalar_ty.intInfo(zcu).bits == bits); | ||
| 4727 | |||
| 4728 | const len = if (operand_ty.toIntern() != operand_scalar_ty.toIntern()) | ||
| 4729 | operand_ty.vectorLen(zcu) | ||
| 4730 | else | ||
| 4731 | null; | ||
| 4732 | const operand_scalar_size = operand_scalar_ty.abiSize(zcu); | ||
| 4733 | const result_ptr = try fg.buildZigAlloca(dest_ty, .none); | ||
| 4734 | for (0..len orelse 1) |index| { | ||
| 4735 | const operand_elem = if (len) |_| | ||
| 4736 | try fg.wip.extractElement(operand, try o.builder.intValue(.i32, index), "elementwise.operand_elem") | ||
| 4737 | else | ||
| 4738 | operand; | ||
| 4739 | switch (bits) { | ||
| 4740 | else => unreachable, | ||
| 4741 | 80 => { | ||
| 4742 | const f80_layout = o.softF80Layout(.{}) catch unreachable; | ||
| 4743 | const mantissa = try fg.wip.cast(.trunc, operand_elem, .i64, "bitCast.mantissa"); | ||
| 4744 | const shifted_exponent = try fg.wip.bin(.lshr, operand_elem, try o.builder.intValue(.i80, 64), "bitCast.shifted_exponent"); | ||
| 4745 | const exponent = try fg.wip.cast(.@"trunc nuw", shifted_exponent, .i16, "bitCast.exponent"); | ||
| 4746 | try fg.store( | ||
| 4747 | try fg.ptraddConst(result_ptr, operand_scalar_size * index + f80_layout.mantissa_offset), | ||
| 4748 | f80_layout.alignment.offset(f80_layout.mantissa_offset), | ||
| 4749 | mantissa, | ||
| 4750 | .u64, | ||
| 4751 | .normal, | ||
| 4752 | ); | ||
| 4753 | try fg.store( | ||
| 4754 | try fg.ptraddConst(result_ptr, operand_scalar_size * index + f80_layout.exponent_offset), | ||
| 4755 | f80_layout.alignment.offset(f80_layout.exponent_offset), | ||
| 4756 | exponent, | ||
| 4757 | .u16, | ||
| 4758 | .normal, | ||
| 4759 | ); | ||
| 4760 | }, | ||
| 4761 | 128 => { | ||
| 4762 | const f128_layout = o.softF128Layout(.{}) catch unreachable; | ||
| 4763 | const lo = try fg.wip.cast(.trunc, operand_elem, .i64, "bitCast.lo"); | ||
| 4764 | const shifted_hi = try fg.wip.bin(.lshr, operand_elem, try o.builder.intValue(.i128, 64), "bitCast.shifted_hi"); | ||
| 4765 | const hi = try fg.wip.cast(.@"trunc nuw", shifted_hi, .i64, "bitCast.hi"); | ||
| 4766 | try fg.store( | ||
| 4767 | try fg.ptraddConst(result_ptr, operand_scalar_size * index + f128_layout.lo_offset), | ||
| 4768 | f128_layout.alignment.offset(f128_layout.lo_offset), | ||
| 4769 | lo, | ||
| 4770 | .u64, | ||
| 4771 | .normal, | ||
| 4772 | ); | ||
| 4773 | try fg.store( | ||
| 4774 | try fg.ptraddConst(result_ptr, operand_scalar_size * index + f128_layout.hi_offset), | ||
| 4775 | f128_layout.alignment.offset(f128_layout.hi_offset), | ||
| 4776 | hi, | ||
| 4777 | .u64, | ||
| 4778 | .normal, | ||
| 4779 | ); | ||
| 4780 | }, | ||
| 4781 | } | ||
| 4782 | } | ||
| 4783 | return result_ptr; | ||
| 4784 | } | ||
| 4785 | |||
| 4786 | const llvm_dest_ty = try o.lowerType(dest_ty, .as_value); | ||
| 4787 | const result = try fg.wip.cast(.bitcast, operand, llvm_dest_ty, ""); | ||
| 4788 | if (safety and dest_ty.zigTypeTag(zcu) == .@"enum" and !dest_ty.isNonexhaustiveEnum(zcu)) { | ||
| 4789 | const llvm_fn = try o.getIsNamedEnumValueFunction(dest_ty); | ||
| 4790 | const is_valid_enum_val = try fg.wip.call( | ||
| 4791 | .normal, | ||
| 4792 | .fastcc, | ||
| 4793 | .none, | ||
| 4794 | llvm_fn.typeOf(&o.builder), | ||
| 4795 | llvm_fn.toValue(&o.builder), | ||
| 4796 | &.{result}, | ||
| 4797 | "", | ||
| 4798 | ); | ||
| 4799 | const fail_block = try fg.wip.block(1, "ValidEnumFail"); | ||
| 4800 | const ok_block = try fg.wip.block(1, "ValidEnumOk"); | ||
| 4801 | _ = try fg.wip.brCond(is_valid_enum_val, ok_block, fail_block, .none); | ||
| 4802 | fg.wip.cursor = .{ .block = fail_block }; | ||
| 4583 | try fg.buildSimplePanic(.invalid_enum_value); | 4803 | try fg.buildSimplePanic(.invalid_enum_value); |
| 4584 | fg.wip.cursor = .{ .block = ok_block }; | 4804 | fg.wip.cursor = .{ .block = ok_block }; |
| 4585 | } | 4805 | } |
| ... | @@ -4606,7 +4826,7 @@ fn airPtrFromInt(fg: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Val | ... | @@ -4606,7 +4826,7 @@ fn airPtrFromInt(fg: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Val |
| 4606 | assert(dest_ty.scalarType(zcu).isPtrAtRuntime(zcu)); | 4826 | assert(dest_ty.scalarType(zcu).isPtrAtRuntime(zcu)); |
| 4607 | 4827 | ||
| 4608 | const operand = try fg.resolveInst(ty_op.operand); | 4828 | const operand = try fg.resolveInst(ty_op.operand); |
| 4609 | const llvm_dest_ty = try o.lowerType(dest_ty, .by_value); | 4829 | const llvm_dest_ty = try o.lowerType(dest_ty, .as_value); |
| 4610 | return fg.wip.cast(.inttoptr, operand, llvm_dest_ty, ""); | 4830 | return fg.wip.cast(.inttoptr, operand, llvm_dest_ty, ""); |
| 4611 | } | 4831 | } |
| 4612 | 4832 | ||
| ... | @@ -4620,7 +4840,7 @@ fn airIntFromPtr(fg: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Val | ... | @@ -4620,7 +4840,7 @@ fn airIntFromPtr(fg: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Val |
| 4620 | assert(dest_ty.scalarType(zcu).toIntern() == .usize_type); | 4840 | assert(dest_ty.scalarType(zcu).toIntern() == .usize_type); |
| 4621 | 4841 | ||
| 4622 | const operand = try fg.resolveInst(ty_op.operand); | 4842 | const operand = try fg.resolveInst(ty_op.operand); |
| 4623 | const llvm_dest_ty = try o.lowerType(dest_ty, .by_value); | 4843 | const llvm_dest_ty = try o.lowerType(dest_ty, .as_value); |
| 4624 | return fg.wip.cast(.ptrtoint, operand, llvm_dest_ty, ""); | 4844 | return fg.wip.cast(.ptrtoint, operand, llvm_dest_ty, ""); |
| 4625 | } | 4845 | } |
| 4626 | 4846 | ||
| ... | @@ -4689,7 +4909,7 @@ fn airArg(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { | ... | @@ -4689,7 +4909,7 @@ fn airArg(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 4689 | }, | 4909 | }, |
| 4690 | "", | 4910 | "", |
| 4691 | ); | 4911 | ); |
| 4692 | } else if (mod.optimize_mode == .Debug) { | 4912 | } else if (mod.optimize_mode == .debug) { |
| 4693 | const alloca = try self.buildZigAlloca(inst_ty, .none); | 4913 | const alloca = try self.buildZigAlloca(inst_ty, .none); |
| 4694 | try self.store(alloca, .none, arg_val, inst_ty, .normal); | 4914 | try self.store(alloca, .none, arg_val, inst_ty, .normal); |
| 4695 | _ = try self.wip.callIntrinsic( | 4915 | _ = try self.wip.callIntrinsic( |
| ... | @@ -4730,7 +4950,7 @@ fn airAlloc(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value | ... | @@ -4730,7 +4950,7 @@ fn airAlloc(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value |
| 4730 | const ptr_align = ptr_ty.ptrAlignment(zcu); | 4950 | const ptr_align = ptr_ty.ptrAlignment(zcu); |
| 4731 | const elem_ty = ptr_ty.childType(zcu); | 4951 | const elem_ty = ptr_ty.childType(zcu); |
| 4732 | if (!elem_ty.hasRuntimeBits(zcu)) { | 4952 | if (!elem_ty.hasRuntimeBits(zcu)) { |
| 4733 | return (try o.lowerPtrToVoid(ptr_align, ptr_ty.ptrAddressSpace(zcu))).toValue(); | 4953 | return (try o.lowerPtrToVoid(ptr_align.toLlvm(), ptr_ty.ptrAddressSpace(zcu))).toValue(); |
| 4734 | } | 4954 | } |
| 4735 | return self.buildZigAlloca(elem_ty, ptr_align); | 4955 | return self.buildZigAlloca(elem_ty, ptr_align); |
| 4736 | } | 4956 | } |
| ... | @@ -4743,7 +4963,7 @@ fn airRetPtr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value | ... | @@ -4743,7 +4963,7 @@ fn airRetPtr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value |
| 4743 | const ptr_align = ptr_ty.ptrAlignment(zcu); | 4963 | const ptr_align = ptr_ty.ptrAlignment(zcu); |
| 4744 | const elem_ty = ptr_ty.childType(zcu); | 4964 | const elem_ty = ptr_ty.childType(zcu); |
| 4745 | if (!elem_ty.hasRuntimeBits(zcu)) { | 4965 | if (!elem_ty.hasRuntimeBits(zcu)) { |
| 4746 | return (try o.lowerPtrToVoid(ptr_align, ptr_ty.ptrAddressSpace(zcu))).toValue(); | 4966 | return (try o.lowerPtrToVoid(ptr_align.toLlvm(), ptr_ty.ptrAddressSpace(zcu))).toValue(); |
| 4747 | } | 4967 | } |
| 4748 | return self.buildZigAlloca(elem_ty, ptr_align); | 4968 | return self.buildZigAlloca(elem_ty, ptr_align); |
| 4749 | } | 4969 | } |
| ... | @@ -4754,10 +4974,7 @@ fn buildZigAlloca(fg: *FuncGen, ty: Type, @"align": InternPool.Alignment) Alloca | ... | @@ -4754,10 +4974,7 @@ fn buildZigAlloca(fg: *FuncGen, ty: Type, @"align": InternPool.Alignment) Alloca |
| 4754 | .none => ty.abiAlignment(o.zcu), | 4974 | .none => ty.abiAlignment(o.zcu), |
| 4755 | else => |a| a, | 4975 | else => |a| a, |
| 4756 | }; | 4976 | }; |
| 4757 | return fg.buildAlloca( | 4977 | return fg.buildAlloca(try o.lowerType(ty, .in_memory), resolved_align.toLlvm()); |
| 4758 | try o.lowerType(ty, .in_memory), | ||
| 4759 | resolved_align.toLlvm(), | ||
| 4760 | ); | ||
| 4761 | } | 4978 | } |
| 4762 | 4979 | ||
| 4763 | /// Unlike `WipFunction.alloca`, this puts the alloca instruction at the top of the function. | 4980 | /// Unlike `WipFunction.alloca`, this puts the alloca instruction at the top of the function. |
| ... | @@ -4820,7 +5037,7 @@ fn airStore(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error!Bu | ... | @@ -4820,7 +5037,7 @@ fn airStore(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error!Bu |
| 4820 | // unexpected call in the user's code. This is problematic if the code in question is | 5037 | // unexpected call in the user's code. This is problematic if the code in question is |
| 4821 | // not ready to correctly make calls yet, such as in our early PIE startup code, or in | 5038 | // not ready to correctly make calls yet, such as in our early PIE startup code, or in |
| 4822 | // the early stages of a dynamic linker, etc. | 5039 | // the early stages of a dynamic linker, etc. |
| 4823 | if (!safety and owner_mod.optimize_mode == .Debug) { | 5040 | if (!safety and owner_mod.optimize_mode == .debug) { |
| 4824 | return .none; | 5041 | return .none; |
| 4825 | } | 5042 | } |
| 4826 | 5043 | ||
| ... | @@ -4832,7 +5049,7 @@ fn airStore(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error!Bu | ... | @@ -4832,7 +5049,7 @@ fn airStore(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error!Bu |
| 4832 | return .none; | 5049 | return .none; |
| 4833 | } | 5050 | } |
| 4834 | 5051 | ||
| 4835 | const len = try o.builder.intValue(try o.lowerType(.usize, .by_value), elem_ty.abiSize(zcu)); | 5052 | const len = try o.builder.intValue(try o.lowerType(.usize, .as_value), elem_ty.abiSize(zcu)); |
| 4836 | _ = try fg.wip.callMemSet( | 5053 | _ = try fg.wip.callMemSet( |
| 4837 | ptr, | 5054 | ptr, |
| 4838 | ptr_alignment.toLlvm(), | 5055 | ptr_alignment.toLlvm(), |
| ... | @@ -4850,24 +5067,31 @@ fn airStore(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error!Bu | ... | @@ -4850,24 +5067,31 @@ fn airStore(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error!Bu |
| 4850 | const elem = try fg.resolveInst(bin_op.rhs); | 5067 | const elem = try fg.resolveInst(bin_op.rhs); |
| 4851 | 5068 | ||
| 4852 | if (ptr_info.flags.vector_index != .none) { | 5069 | if (ptr_info.flags.vector_index != .none) { |
| 4853 | // Accepted proposal https://github.com/ziglang/zig/issues/24061 will eliminate this usage of `pt`. | 5070 | if (isByRef(elem_ty, zcu)) { |
| 4854 | const vec_ty = try fg.pt.vectorType(.{ | 5071 | const offset = @backingInt(ptr_info.flags.vector_index) * elem_ty.abiSize(zcu); |
| 4855 | .len = ptr_info.packed_offset.host_size, | 5072 | const elem_ptr = try fg.ptraddConst(ptr, offset); |
| 4856 | .child = elem_ty.toIntern(), | 5073 | try fg.store(elem_ptr, ptr_alignment.offset(offset), elem, elem_ty, access_kind); |
| 4857 | }); | 5074 | } else { |
| 5075 | // Accepted proposal https://github.com/ziglang/zig/issues/24061 will eliminate this usage of `pt`. | ||
| 5076 | const vec_ty = try fg.pt.vectorType(.{ | ||
| 5077 | .len = ptr_info.packed_offset.host_size, | ||
| 5078 | .child = elem_ty.toIntern(), | ||
| 5079 | }); | ||
| 5080 | |||
| 5081 | const loaded_vector = try fg.load(ptr, ptr_alignment, vec_ty, access_kind); | ||
| 5082 | const index_val = try o.builder.intValue(.i32, ptr_info.flags.vector_index); | ||
| 5083 | const modified_vector = try fg.wip.insertElement(loaded_vector, elem, index_val, ""); | ||
| 4858 | 5084 | ||
| 4859 | const loaded_vector = try fg.load(ptr, ptr_alignment, vec_ty, access_kind); | 5085 | try fg.store(ptr, ptr_alignment, modified_vector, vec_ty, access_kind); |
| 4860 | const index_val = try o.builder.intValue(.i32, ptr_info.flags.vector_index); | 5086 | } |
| 4861 | const modified_vector = try fg.wip.insertElement(loaded_vector, elem, index_val, ""); | ||
| 4862 | 5087 | ||
| 4863 | try fg.store(ptr, ptr_alignment, modified_vector, vec_ty, access_kind); | ||
| 4864 | return .none; | 5088 | return .none; |
| 4865 | } | 5089 | } |
| 4866 | 5090 | ||
| 4867 | if (ptr_info.packed_offset.host_size != 0) { | 5091 | if (ptr_info.packed_offset.host_size != 0) { |
| 4868 | // Accepted proposal https://github.com/ziglang/zig/issues/24061 will eliminate this usage of `pt`. | 5092 | // Accepted proposal https://github.com/ziglang/zig/issues/24061 will eliminate this usage of `pt`. |
| 4869 | const backing_int_ty = try fg.pt.intType(.unsigned, @intCast(ptr_info.packed_offset.host_size * 8)); | 5093 | const backing_int_ty = try fg.pt.intType(.unsigned, @intCast(ptr_info.packed_offset.host_size * 8)); |
| 4870 | const llvm_backing_int_ty = try o.lowerType(backing_int_ty, .by_value); | 5094 | const llvm_backing_int_ty = try o.lowerType(backing_int_ty, .as_value); |
| 4871 | 5095 | ||
| 4872 | const backing_int_val = try fg.load(ptr, ptr_alignment, backing_int_ty, access_kind); | 5096 | const backing_int_val = try fg.load(ptr, ptr_alignment, backing_int_ty, access_kind); |
| 4873 | 5097 | ||
| ... | @@ -4927,32 +5151,98 @@ fn airLoad(fg: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { | ... | @@ -4927,32 +5151,98 @@ fn airLoad(fg: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 4927 | if (ptr_info.flags.is_volatile) .@"volatile" else .normal; | 5151 | if (ptr_info.flags.is_volatile) .@"volatile" else .normal; |
| 4928 | 5152 | ||
| 4929 | if (ptr_info.flags.vector_index != .none) { | 5153 | if (ptr_info.flags.vector_index != .none) { |
| 4930 | // Accepted proposal https://github.com/ziglang/zig/issues/24061 will eliminate this usage of `pt`. | 5154 | if (isByRef(elem_ty, zcu)) { |
| 4931 | const vec_ty = try fg.pt.vectorType(.{ | 5155 | const elem_size = elem_ty.abiSize(zcu); |
| 4932 | .len = ptr_info.packed_offset.host_size, | 5156 | const offset = @backingInt(ptr_info.flags.vector_index) * elem_size; |
| 4933 | .child = elem_ty.toIntern(), | 5157 | const elem_ptr = try fg.ptraddConst(ptr, offset); |
| 4934 | }); | 5158 | return fg.load(elem_ptr, ptr_align.offset(offset), elem_ty, access_kind); |
| 4935 | const vector_val = try fg.load(ptr, ptr_align, vec_ty, access_kind); | 5159 | } else { |
| 4936 | const index_val = try o.builder.intValue(.i32, ptr_info.flags.vector_index); | 5160 | // Accepted proposal https://github.com/ziglang/zig/issues/24061 will eliminate this usage of `pt`. |
| 4937 | return fg.wip.extractElement(vector_val, index_val, ""); | 5161 | const vec_ty = try fg.pt.vectorType(.{ |
| 5162 | .len = ptr_info.packed_offset.host_size, | ||
| 5163 | .child = elem_ty.toIntern(), | ||
| 5164 | }); | ||
| 5165 | const vector_val = try fg.load(ptr, ptr_align, vec_ty, access_kind); | ||
| 5166 | const index_val = try o.builder.intValue(.i32, ptr_info.flags.vector_index); | ||
| 5167 | return fg.wip.extractElement(vector_val, index_val, ""); | ||
| 5168 | } | ||
| 4938 | } | 5169 | } |
| 4939 | 5170 | ||
| 4940 | if (ptr_info.packed_offset.host_size == 0) { | 5171 | if (ptr_info.packed_offset.host_size == 0) { |
| 4941 | return fg.load(ptr, ptr_align, elem_ty, access_kind); | 5172 | return fg.load(ptr, ptr_align, elem_ty, access_kind); |
| 4942 | } | 5173 | } |
| 4943 | 5174 | ||
| 4944 | assert(!isByRef(elem_ty, zcu)); // all packable types are by-val | ||
| 4945 | |||
| 4946 | // Accepted proposal https://github.com/ziglang/zig/issues/24061 will eliminate this usage of `pt`. | 5175 | // Accepted proposal https://github.com/ziglang/zig/issues/24061 will eliminate this usage of `pt`. |
| 4947 | const backing_int_ty = try fg.pt.intType(.unsigned, @intCast(ptr_info.packed_offset.host_size * 8)); | 5176 | const backing_int_ty = try fg.pt.intType(.unsigned, @intCast(ptr_info.packed_offset.host_size * 8)); |
| 4948 | const llvm_backing_int_ty = try o.lowerType(backing_int_ty, .by_value); | 5177 | const llvm_backing_int_ty = try o.lowerType(backing_int_ty, .as_value); |
| 4949 | 5178 | ||
| 4950 | const backing_int_val = try fg.load(ptr, ptr_align, backing_int_ty, .normal); | 5179 | const backing_int_val = try fg.load(ptr, ptr_align, backing_int_ty, .normal); |
| 4951 | 5180 | ||
| 4952 | const elem_bits = ptr_ty.childType(zcu).bitSize(zcu); | 5181 | const elem_bits = ptr_ty.childType(zcu).bitSize(zcu); |
| 4953 | const shift_amt = try o.builder.intValue(llvm_backing_int_ty, ptr_info.packed_offset.bit_offset); | 5182 | const shift_amt = try o.builder.intValue(llvm_backing_int_ty, ptr_info.packed_offset.bit_offset); |
| 4954 | const shifted_value = try fg.wip.bin(.lshr, backing_int_val, shift_amt, ""); | 5183 | const shifted_value = try fg.wip.bin(.lshr, backing_int_val, shift_amt, ""); |
| 4955 | const elem_llvm_ty = try o.lowerType(elem_ty, .by_value); | 5184 | |
| 5185 | if (isByRef(elem_ty, zcu)) { | ||
| 5186 | const result_ptr = try fg.buildZigAlloca(elem_ty, .none); | ||
| 5187 | switch (elem_ty.floatBits(zcu.getTarget())) { | ||
| 5188 | else => unreachable, | ||
| 5189 | 80 => { | ||
| 5190 | const f80_layout = o.softF80Layout(.{}) catch unreachable; | ||
| 5191 | const mantissa = try fg.wip.cast(.trunc, shifted_value, .i64, "load.mantissa"); | ||
| 5192 | const shifted_exponent = try fg.wip.bin( | ||
| 5193 | .lshr, | ||
| 5194 | backing_int_val, | ||
| 5195 | try o.builder.intValue(llvm_backing_int_ty, ptr_info.packed_offset.bit_offset + 64), | ||
| 5196 | "load.shifted_exponent", | ||
| 5197 | ); | ||
| 5198 | const exponent = try fg.wip.cast(.trunc, shifted_exponent, .i16, "load.exponent"); | ||
| 5199 | |||
| 5200 | try fg.store( | ||
| 5201 | try fg.ptraddConst(result_ptr, f80_layout.mantissa_offset), | ||
| 5202 | f80_layout.alignment.offset(f80_layout.mantissa_offset), | ||
| 5203 | mantissa, | ||
| 5204 | .u64, | ||
| 5205 | .normal, | ||
| 5206 | ); | ||
| 5207 | try fg.store( | ||
| 5208 | try fg.ptraddConst(result_ptr, f80_layout.exponent_offset), | ||
| 5209 | f80_layout.alignment.offset(f80_layout.exponent_offset), | ||
| 5210 | exponent, | ||
| 5211 | .u16, | ||
| 5212 | .normal, | ||
| 5213 | ); | ||
| 5214 | }, | ||
| 5215 | 128 => { | ||
| 5216 | const f128_layout = o.softF128Layout(.{}) catch unreachable; | ||
| 5217 | const lo = try fg.wip.cast(.trunc, shifted_value, .i64, "load.lo"); | ||
| 5218 | const shifted_hi = try fg.wip.bin( | ||
| 5219 | .lshr, | ||
| 5220 | backing_int_val, | ||
| 5221 | try o.builder.intValue(llvm_backing_int_ty, ptr_info.packed_offset.bit_offset + 64), | ||
| 5222 | "load.shifted_hi", | ||
| 5223 | ); | ||
| 5224 | const hi = try fg.wip.cast(.trunc, shifted_hi, .i64, "load.hi"); | ||
| 5225 | |||
| 5226 | try fg.store( | ||
| 5227 | try fg.ptraddConst(result_ptr, f128_layout.lo_offset), | ||
| 5228 | f128_layout.alignment.offset(f128_layout.lo_offset), | ||
| 5229 | lo, | ||
| 5230 | .u64, | ||
| 5231 | .normal, | ||
| 5232 | ); | ||
| 5233 | try fg.store( | ||
| 5234 | try fg.ptraddConst(result_ptr, f128_layout.hi_offset), | ||
| 5235 | f128_layout.alignment.offset(f128_layout.hi_offset), | ||
| 5236 | hi, | ||
| 5237 | .u64, | ||
| 5238 | .normal, | ||
| 5239 | ); | ||
| 5240 | }, | ||
| 5241 | } | ||
| 5242 | return result_ptr; | ||
| 5243 | } | ||
| 5244 | |||
| 5245 | const elem_llvm_ty = try o.lowerType(elem_ty, .as_value); | ||
| 4956 | 5246 | ||
| 4957 | if (elem_ty.zigTypeTag(zcu) == .float or elem_ty.zigTypeTag(zcu) == .vector) { | 5247 | if (elem_ty.zigTypeTag(zcu) == .float or elem_ty.zigTypeTag(zcu) == .vector) { |
| 4958 | const same_size_int = try o.builder.intType(@intCast(elem_bits)); | 5248 | const same_size_int = try o.builder.intType(@intCast(elem_bits)); |
| ... | @@ -5002,7 +5292,7 @@ fn airBreakpoint(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.V | ... | @@ -5002,7 +5292,7 @@ fn airBreakpoint(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.V |
| 5002 | fn airRetAddr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { | 5292 | fn airRetAddr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 5003 | _ = inst; | 5293 | _ = inst; |
| 5004 | const o = self.object; | 5294 | const o = self.object; |
| 5005 | const llvm_usize = try o.lowerType(.usize, .by_value); | 5295 | const llvm_usize = try o.lowerType(.usize, .as_value); |
| 5006 | if (!target_util.supportsReturnAddress(self.object.zcu.getTarget(), self.ownerModule().optimize_mode)) { | 5296 | if (!target_util.supportsReturnAddress(self.object.zcu.getTarget(), self.ownerModule().optimize_mode)) { |
| 5007 | // https://github.com/ziglang/zig/issues/11946 | 5297 | // https://github.com/ziglang/zig/issues/11946 |
| 5008 | return o.builder.intValue(llvm_usize, 0); | 5298 | return o.builder.intValue(llvm_usize, 0); |
| ... | @@ -5014,7 +5304,7 @@ fn airRetAddr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Valu | ... | @@ -5014,7 +5304,7 @@ fn airRetAddr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Valu |
| 5014 | fn airFrameAddress(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { | 5304 | fn airFrameAddress(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 5015 | _ = inst; | 5305 | _ = inst; |
| 5016 | const result = try self.wip.callIntrinsic(.normal, .none, .frameaddress, &.{.ptr}, &.{.@"0"}, ""); | 5306 | const result = try self.wip.callIntrinsic(.normal, .none, .frameaddress, &.{.ptr}, &.{.@"0"}, ""); |
| 5017 | return self.wip.cast(.ptrtoint, result, try self.object.lowerType(.usize, .by_value), ""); | 5307 | return self.wip.cast(.ptrtoint, result, try self.object.lowerType(.usize, .as_value), ""); |
| 5018 | } | 5308 | } |
| 5019 | 5309 | ||
| 5020 | fn airCmpxchg( | 5310 | fn airCmpxchg( |
| ... | @@ -5031,7 +5321,7 @@ fn airCmpxchg( | ... | @@ -5031,7 +5321,7 @@ fn airCmpxchg( |
| 5031 | var expected_value = try self.resolveInst(extra.expected_value); | 5321 | var expected_value = try self.resolveInst(extra.expected_value); |
| 5032 | var new_value = try self.resolveInst(extra.new_value); | 5322 | var new_value = try self.resolveInst(extra.new_value); |
| 5033 | const operand_ty = ptr_ty.childType(zcu); | 5323 | const operand_ty = ptr_ty.childType(zcu); |
| 5034 | const llvm_operand_ty = try o.lowerType(operand_ty, .by_value); | 5324 | const llvm_operand_ty = try o.lowerType(operand_ty, .as_value); |
| 5035 | const llvm_abi_ty = try self.getAtomicAbiType(operand_ty, false); | 5325 | const llvm_abi_ty = try self.getAtomicAbiType(operand_ty, false); |
| 5036 | if (llvm_abi_ty != .none) { | 5326 | if (llvm_abi_ty != .none) { |
| 5037 | // operand needs widening and truncating | 5327 | // operand needs widening and truncating |
| ... | @@ -5101,7 +5391,7 @@ fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Va | ... | @@ -5101,7 +5391,7 @@ fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Va |
| 5101 | const op = toLlvmAtomicRmwBinOp(extra.op(), is_signed_int, is_float); | 5391 | const op = toLlvmAtomicRmwBinOp(extra.op(), is_signed_int, is_float); |
| 5102 | const ordering = toLlvmAtomicOrdering(extra.ordering()); | 5392 | const ordering = toLlvmAtomicOrdering(extra.ordering()); |
| 5103 | const llvm_abi_ty = try self.getAtomicAbiType(operand_ty, op == .xchg); | 5393 | const llvm_abi_ty = try self.getAtomicAbiType(operand_ty, op == .xchg); |
| 5104 | const llvm_operand_ty = try o.lowerType(operand_ty, .by_value); | 5394 | const llvm_operand_ty = try o.lowerType(operand_ty, .as_value); |
| 5105 | 5395 | ||
| 5106 | const access_kind: Builder.MemoryAccessKind = | 5396 | const access_kind: Builder.MemoryAccessKind = |
| 5107 | if (ptr_ty.isVolatilePtr(zcu)) .@"volatile" else .normal; | 5397 | if (ptr_ty.isVolatilePtr(zcu)) .@"volatile" else .normal; |
| ... | @@ -5130,7 +5420,7 @@ fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Va | ... | @@ -5130,7 +5420,7 @@ fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Va |
| 5130 | 5420 | ||
| 5131 | // If we are storing a pointer we need to convert to and from a plain old integer. | 5421 | // If we are storing a pointer we need to convert to and from a plain old integer. |
| 5132 | const non_ptr_operand = switch (operand_ty.zigTypeTag(zcu)) { | 5422 | const non_ptr_operand = switch (operand_ty.zigTypeTag(zcu)) { |
| 5133 | .pointer => try self.wip.cast(.ptrtoint, operand, try o.lowerType(.usize, .by_value), ""), | 5423 | .pointer => try self.wip.cast(.ptrtoint, operand, try o.lowerType(.usize, .as_value), ""), |
| 5134 | else => operand, | 5424 | else => operand, |
| 5135 | }; | 5425 | }; |
| 5136 | 5426 | ||
| ... | @@ -5169,7 +5459,7 @@ fn airAtomicLoad(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.V | ... | @@ -5169,7 +5459,7 @@ fn airAtomicLoad(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.V |
| 5169 | Type.fromInterned(info.child).abiAlignment(zcu)).toLlvm(); | 5459 | Type.fromInterned(info.child).abiAlignment(zcu)).toLlvm(); |
| 5170 | const access_kind: Builder.MemoryAccessKind = | 5460 | const access_kind: Builder.MemoryAccessKind = |
| 5171 | if (info.flags.is_volatile) .@"volatile" else .normal; | 5461 | if (info.flags.is_volatile) .@"volatile" else .normal; |
| 5172 | const elem_llvm_ty = try o.lowerType(elem_ty, .by_value); | 5462 | const elem_llvm_ty = try o.lowerType(elem_ty, .as_value); |
| 5173 | 5463 | ||
| 5174 | self.maybeMarkAllowZeroAccess(info); | 5464 | self.maybeMarkAllowZeroAccess(info); |
| 5175 | 5465 | ||
| ... | @@ -5503,11 +5793,11 @@ fn airClzCtz(self: *FuncGen, inst: Air.Inst.Index, intrinsic: Builder.Intrinsic) | ... | @@ -5503,11 +5793,11 @@ fn airClzCtz(self: *FuncGen, inst: Air.Inst.Index, intrinsic: Builder.Intrinsic) |
| 5503 | .normal, | 5793 | .normal, |
| 5504 | .none, | 5794 | .none, |
| 5505 | intrinsic, | 5795 | intrinsic, |
| 5506 | &.{try o.lowerType(operand_ty, .by_value)}, | 5796 | &.{try o.lowerType(operand_ty, .as_value)}, |
| 5507 | &.{ operand, .false }, | 5797 | &.{ operand, .false }, |
| 5508 | "", | 5798 | "", |
| 5509 | ); | 5799 | ); |
| 5510 | return self.wip.conv(.unsigned, result, try o.lowerType(inst_ty, .by_value), ""); | 5800 | return self.wip.conv(.unsigned, result, try o.lowerType(inst_ty, .as_value), ""); |
| 5511 | } | 5801 | } |
| 5512 | 5802 | ||
| 5513 | fn airBitOp(self: *FuncGen, inst: Air.Inst.Index, intrinsic: Builder.Intrinsic) Allocator.Error!Builder.Value { | 5803 | fn airBitOp(self: *FuncGen, inst: Air.Inst.Index, intrinsic: Builder.Intrinsic) Allocator.Error!Builder.Value { |
| ... | @@ -5521,11 +5811,11 @@ fn airBitOp(self: *FuncGen, inst: Air.Inst.Index, intrinsic: Builder.Intrinsic) | ... | @@ -5521,11 +5811,11 @@ fn airBitOp(self: *FuncGen, inst: Air.Inst.Index, intrinsic: Builder.Intrinsic) |
| 5521 | .normal, | 5811 | .normal, |
| 5522 | .none, | 5812 | .none, |
| 5523 | intrinsic, | 5813 | intrinsic, |
| 5524 | &.{try o.lowerType(operand_ty, .by_value)}, | 5814 | &.{try o.lowerType(operand_ty, .as_value)}, |
| 5525 | &.{operand}, | 5815 | &.{operand}, |
| 5526 | "", | 5816 | "", |
| 5527 | ); | 5817 | ); |
| 5528 | return self.wip.conv(.unsigned, result, try o.lowerType(inst_ty, .by_value), ""); | 5818 | return self.wip.conv(.unsigned, result, try o.lowerType(inst_ty, .as_value), ""); |
| 5529 | } | 5819 | } |
| 5530 | 5820 | ||
| 5531 | fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { | 5821 | fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| ... | @@ -5538,7 +5828,7 @@ fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Val | ... | @@ -5538,7 +5828,7 @@ fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Val |
| 5538 | 5828 | ||
| 5539 | const inst_ty = self.typeOfIndex(inst); | 5829 | const inst_ty = self.typeOfIndex(inst); |
| 5540 | var operand = try self.resolveInst(ty_op.operand); | 5830 | var operand = try self.resolveInst(ty_op.operand); |
| 5541 | var llvm_operand_ty = try o.lowerType(operand_ty, .by_value); | 5831 | var llvm_operand_ty = try o.lowerType(operand_ty, .as_value); |
| 5542 | 5832 | ||
| 5543 | if (bits % 16 == 8) { | 5833 | if (bits % 16 == 8) { |
| 5544 | // If not an even byte-multiple, we need zero-extend + shift-left 1 byte | 5834 | // If not an even byte-multiple, we need zero-extend + shift-left 1 byte |
| ... | @@ -5559,7 +5849,7 @@ fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Val | ... | @@ -5559,7 +5849,7 @@ fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Val |
| 5559 | 5849 | ||
| 5560 | const result = | 5850 | const result = |
| 5561 | try self.wip.callIntrinsic(.normal, .none, .bswap, &.{llvm_operand_ty}, &.{operand}, ""); | 5851 | try self.wip.callIntrinsic(.normal, .none, .bswap, &.{llvm_operand_ty}, &.{operand}, ""); |
| 5562 | return self.wip.conv(.unsigned, result, try o.lowerType(inst_ty, .by_value), ""); | 5852 | return self.wip.conv(.unsigned, result, try o.lowerType(inst_ty, .as_value), ""); |
| 5563 | } | 5853 | } |
| 5564 | 5854 | ||
| 5565 | fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { | 5855 | fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| ... | @@ -5579,7 +5869,7 @@ fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Bui | ... | @@ -5579,7 +5869,7 @@ fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Bui |
| 5579 | 5869 | ||
| 5580 | for (0..names.len) |name_index| { | 5870 | for (0..names.len) |name_index| { |
| 5581 | const err_int = ip.getErrorValueIfExists(names.get(ip)[name_index]).?; | 5871 | const err_int = ip.getErrorValueIfExists(names.get(ip)[name_index]).?; |
| 5582 | const this_tag_int_value = try o.builder.intConst(try o.errorIntType(.by_value), err_int); | 5872 | const this_tag_int_value = try o.builder.intConst(try o.errorIntType(.as_value), err_int); |
| 5583 | try wip_switch.addCase(this_tag_int_value, valid_block, &self.wip); | 5873 | try wip_switch.addCase(this_tag_int_value, valid_block, &self.wip); |
| 5584 | } | 5874 | } |
| 5585 | self.wip.cursor = .{ .block = valid_block }; | 5875 | self.wip.cursor = .{ .block = valid_block }; |
| ... | @@ -5638,7 +5928,7 @@ fn airErrorName(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Va | ... | @@ -5638,7 +5928,7 @@ fn airErrorName(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Va |
| 5638 | const slice_ty = self.typeOfIndex(inst); | 5928 | const slice_ty = self.typeOfIndex(inst); |
| 5639 | 5929 | ||
| 5640 | // If operand is small (e.g. `u8`), then signedness becomes a problem -- GEP always treats the index as signed. | 5930 | // If operand is small (e.g. `u8`), then signedness becomes a problem -- GEP always treats the index as signed. |
| 5641 | const operand_usize = try self.wip.conv(.unsigned, operand, try o.lowerType(.usize, .by_value), ""); | 5931 | const operand_usize = try self.wip.conv(.unsigned, operand, try o.lowerType(.usize, .as_value), ""); |
| 5642 | 5932 | ||
| 5643 | const error_name_table_ptr = try o.getErrorNameTable(); | 5933 | const error_name_table_ptr = try o.getErrorNameTable(); |
| 5644 | const error_name_ptr = try self.ptraddScaled(error_name_table_ptr.toValue(&o.builder), operand_usize, slice_ty.abiSize(zcu)); | 5934 | const error_name_ptr = try self.ptraddScaled(error_name_table_ptr.toValue(&o.builder), operand_usize, slice_ty.abiSize(zcu)); |
| ... | @@ -5649,7 +5939,7 @@ fn airSplat(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value | ... | @@ -5649,7 +5939,7 @@ fn airSplat(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value |
| 5649 | const ty_op = self.air.instructions.items(.data)[@backingInt(inst)].ty_op; | 5939 | const ty_op = self.air.instructions.items(.data)[@backingInt(inst)].ty_op; |
| 5650 | const scalar = try self.resolveInst(ty_op.operand); | 5940 | const scalar = try self.resolveInst(ty_op.operand); |
| 5651 | const vector_ty = self.typeOfIndex(inst); | 5941 | const vector_ty = self.typeOfIndex(inst); |
| 5652 | return self.wip.splatVector(try self.object.lowerType(vector_ty, .by_value), scalar, ""); | 5942 | return self.wip.splatVector(try self.object.lowerType(vector_ty, .as_value), scalar, ""); |
| 5653 | } | 5943 | } |
| 5654 | 5944 | ||
| 5655 | fn airSelect(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { | 5945 | fn airSelect(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| ... | @@ -5672,9 +5962,9 @@ fn airShuffleOne(fg: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Val | ... | @@ -5672,9 +5962,9 @@ fn airShuffleOne(fg: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Val |
| 5672 | const operand = try fg.resolveInst(unwrapped.operand); | 5962 | const operand = try fg.resolveInst(unwrapped.operand); |
| 5673 | const mask = unwrapped.mask; | 5963 | const mask = unwrapped.mask; |
| 5674 | const operand_ty = fg.typeOf(unwrapped.operand); | 5964 | const operand_ty = fg.typeOf(unwrapped.operand); |
| 5675 | const llvm_operand_ty = try o.lowerType(operand_ty, .by_value); | 5965 | const llvm_operand_ty = try o.lowerType(operand_ty, .as_value); |
| 5676 | const llvm_result_ty = try o.lowerType(unwrapped.result_ty, .by_value); | 5966 | const llvm_result_ty = try o.lowerType(unwrapped.result_ty, .as_value); |
| 5677 | const llvm_elem_ty = try o.lowerType(unwrapped.result_ty.childType(zcu), .by_value); | 5967 | const llvm_elem_ty = try o.lowerType(unwrapped.result_ty.childType(zcu), .as_value); |
| 5678 | const llvm_poison_elem = try o.builder.poisonConst(llvm_elem_ty); | 5968 | const llvm_poison_elem = try o.builder.poisonConst(llvm_elem_ty); |
| 5679 | const llvm_poison_mask_elem = try o.builder.poisonConst(.i32); | 5969 | const llvm_poison_mask_elem = try o.builder.poisonConst(.i32); |
| 5680 | const llvm_mask_ty = try o.builder.vectorType(.normal, @intCast(mask.len), .i32); | 5970 | const llvm_mask_ty = try o.builder.vectorType(.normal, @intCast(mask.len), .i32); |
| ... | @@ -5704,7 +5994,7 @@ fn airShuffleOne(fg: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Val | ... | @@ -5704,7 +5994,7 @@ fn airShuffleOne(fg: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Val |
| 5704 | .elem => llvm_poison_elem, | 5994 | .elem => llvm_poison_elem, |
| 5705 | .value => |val| if (!Value.fromInterned(val).isUndef(zcu)) elem: { | 5995 | .value => |val| if (!Value.fromInterned(val).isUndef(zcu)) elem: { |
| 5706 | any_defined_comptime_value = true; | 5996 | any_defined_comptime_value = true; |
| 5707 | break :elem try o.lowerValue(val, .by_value); | 5997 | break :elem try o.lowerValue(val, .as_value); |
| 5708 | } else llvm_poison_elem, | 5998 | } else llvm_poison_elem, |
| 5709 | }; | 5999 | }; |
| 5710 | } | 6000 | } |
| ... | @@ -5776,7 +6066,7 @@ fn airShuffleTwo(fg: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Val | ... | @@ -5776,7 +6066,7 @@ fn airShuffleTwo(fg: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Val |
| 5776 | const unwrapped = fg.air.unwrapShuffleTwo(zcu, inst); | 6066 | const unwrapped = fg.air.unwrapShuffleTwo(zcu, inst); |
| 5777 | 6067 | ||
| 5778 | const mask = unwrapped.mask; | 6068 | const mask = unwrapped.mask; |
| 5779 | const llvm_elem_ty = try o.lowerType(unwrapped.result_ty.childType(zcu), .by_value); | 6069 | const llvm_elem_ty = try o.lowerType(unwrapped.result_ty.childType(zcu), .as_value); |
| 5780 | const llvm_mask_ty = try o.builder.vectorType(.normal, @intCast(mask.len), .i32); | 6070 | const llvm_mask_ty = try o.builder.vectorType(.normal, @intCast(mask.len), .i32); |
| 5781 | const llvm_poison_mask_elem = try o.builder.poisonConst(.i32); | 6071 | const llvm_poison_mask_elem = try o.builder.poisonConst(.i32); |
| 5782 | 6072 | ||
| ... | @@ -5848,95 +6138,25 @@ fn airShuffleTwo(fg: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Val | ... | @@ -5848,95 +6138,25 @@ fn airShuffleTwo(fg: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Val |
| 5848 | ); | 6138 | ); |
| 5849 | } | 6139 | } |
| 5850 | 6140 | ||
| 5851 | /// Reduce a vector by repeatedly applying `llvm_fn` to produce an accumulated result. | 6141 | fn airReduce(fg: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allocator.Error!Builder.Value { |
| 5852 | /// | 6142 | const o = fg.object; |
| 5853 | /// Equivalent to: | ||
| 5854 | /// ``` | ||
| 5855 | /// var accum: T = init; | ||
| 5856 | /// for (0..i) |i| { | ||
| 5857 | /// accum = llvm_fn(accum, vec[i]); | ||
| 5858 | /// } | ||
| 5859 | /// // result is 'accum' | ||
| 5860 | /// ``` | ||
| 5861 | fn buildReducedCall( | ||
| 5862 | self: *FuncGen, | ||
| 5863 | llvm_fn: Builder.Function.Index, | ||
| 5864 | operand_vector: Builder.Value, | ||
| 5865 | vector_len: usize, | ||
| 5866 | accum_init: Builder.Value, | ||
| 5867 | ) Allocator.Error!Builder.Value { | ||
| 5868 | const o = self.object; | ||
| 5869 | const llvm_usize_ty = try o.lowerType(.usize, .by_value); | ||
| 5870 | const llvm_vector_len = try o.builder.intValue(llvm_usize_ty, vector_len); | ||
| 5871 | const llvm_result_ty = accum_init.typeOfWip(&self.wip); | ||
| 5872 | |||
| 5873 | const entry_block = self.wip.cursor.block; | ||
| 5874 | |||
| 5875 | const cond_block = try self.wip.block(2, "ReduceLoopCond"); | ||
| 5876 | const body_block = try self.wip.block(1, "ReduceLoopBody"); | ||
| 5877 | const exit_block = try self.wip.block(1, "ReduceLoopExit"); | ||
| 5878 | |||
| 5879 | _ = try self.wip.br(cond_block); | ||
| 5880 | |||
| 5881 | // ReduceLoopCond: | ||
| 5882 | // %index = phi iN [0, %Entry], [%new_index, %ReduceLoopBody] | ||
| 5883 | // %accum = phi T [%accum_init, %Entry], [%new_accum, %ReduceLoopBody] | ||
| 5884 | // %cond = icmp ult iN %index, %vector_len | ||
| 5885 | // br i1 %cond, label %ReduceLoopBody, label %ReduceLoopExit | ||
| 5886 | self.wip.cursor = .{ .block = cond_block }; | ||
| 5887 | const index = try self.wip.phi(llvm_usize_ty, ""); | ||
| 5888 | const accum = try self.wip.phi(llvm_result_ty, ""); | ||
| 5889 | const cond = try self.wip.icmp(.ult, index.toValue(), llvm_vector_len, ""); | ||
| 5890 | _ = try self.wip.brCond(cond, body_block, exit_block, .none); | ||
| 5891 | |||
| 5892 | // ReduceLoopBody: | ||
| 5893 | // %elem = extractelement <n x T> %operand_vec, iN %index | ||
| 5894 | // %new_accum = call T @llvm_fn(T %accum, T %elem) | ||
| 5895 | // %new_index = add nuw iN %index, 1 | ||
| 5896 | // br label %ReduceLoopCond | ||
| 5897 | self.wip.cursor = .{ .block = body_block }; | ||
| 5898 | const elem = try self.wip.extractElement(operand_vector, index.toValue(), ""); | ||
| 5899 | const new_accum = try self.wip.call( | ||
| 5900 | .normal, | ||
| 5901 | .ccc, | ||
| 5902 | .none, | ||
| 5903 | llvm_fn.typeOf(&o.builder), | ||
| 5904 | llvm_fn.toValue(&o.builder), | ||
| 5905 | &.{ accum.toValue(), elem }, | ||
| 5906 | "", | ||
| 5907 | ); | ||
| 5908 | const new_index = try self.wip.bin(.@"add nuw", index.toValue(), try o.builder.intValue(llvm_usize_ty, 1), ""); | ||
| 5909 | _ = try self.wip.br(cond_block); | ||
| 5910 | |||
| 5911 | const index_init = try o.builder.intValue(llvm_usize_ty, 0); | ||
| 5912 | index.finish(&.{ index_init, new_index }, &.{ entry_block, body_block }, &self.wip); | ||
| 5913 | accum.finish(&.{ accum_init, new_accum }, &.{ entry_block, body_block }, &self.wip); | ||
| 5914 | |||
| 5915 | self.wip.cursor = .{ .block = exit_block }; | ||
| 5916 | return accum.toValue(); | ||
| 5917 | } | ||
| 5918 | |||
| 5919 | fn airReduce(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allocator.Error!Builder.Value { | ||
| 5920 | const o = self.object; | ||
| 5921 | const zcu = o.zcu; | 6143 | const zcu = o.zcu; |
| 5922 | const target = zcu.getTarget(); | 6144 | const target = zcu.getTarget(); |
| 5923 | 6145 | ||
| 5924 | const reduce = self.air.instructions.items(.data)[@backingInt(inst)].reduce; | 6146 | const reduce = fg.air.instructions.items(.data)[@backingInt(inst)].reduce; |
| 5925 | const operand = try self.resolveInst(reduce.operand); | 6147 | const operand = try fg.resolveInst(reduce.operand); |
| 5926 | const operand_ty = self.typeOf(reduce.operand); | 6148 | const operand_ty = fg.typeOf(reduce.operand); |
| 5927 | const llvm_operand_ty = try o.lowerType(operand_ty, .by_value); | 6149 | const scalar_ty = fg.typeOfIndex(inst); |
| 5928 | const scalar_ty = self.typeOfIndex(inst); | ||
| 5929 | const llvm_scalar_ty = try o.lowerType(scalar_ty, .by_value); | ||
| 5930 | 6150 | ||
| 5931 | switch (reduce.operation) { | 6151 | switch (reduce.operation) { |
| 5932 | .And, .Or, .Xor => return self.wip.callIntrinsic(.normal, .none, switch (reduce.operation) { | 6152 | .And, .Or, .Xor => return fg.wip.callIntrinsic(.normal, .none, switch (reduce.operation) { |
| 5933 | .And => .@"vector.reduce.and", | 6153 | .And => .@"vector.reduce.and", |
| 5934 | .Or => .@"vector.reduce.or", | 6154 | .Or => .@"vector.reduce.or", |
| 5935 | .Xor => .@"vector.reduce.xor", | 6155 | .Xor => .@"vector.reduce.xor", |
| 5936 | else => unreachable, | 6156 | else => unreachable, |
| 5937 | }, &.{llvm_operand_ty}, &.{operand}, ""), | 6157 | }, &.{try o.lowerType(operand_ty, .as_value)}, &.{operand}, ""), |
| 5938 | .Min, .Max => switch (scalar_ty.zigTypeTag(zcu)) { | 6158 | .Min, .Max => switch (scalar_ty.zigTypeTag(zcu)) { |
| 5939 | .int => return self.wip.callIntrinsic(.normal, .none, switch (reduce.operation) { | 6159 | .int => return fg.wip.callIntrinsic(.normal, .none, switch (reduce.operation) { |
| 5940 | .Min => if (scalar_ty.isSignedInt(zcu)) | 6160 | .Min => if (scalar_ty.isSignedInt(zcu)) |
| 5941 | .@"vector.reduce.smin" | 6161 | .@"vector.reduce.smin" |
| 5942 | else | 6162 | else |
| ... | @@ -5946,29 +6166,29 @@ fn airReduce(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) A | ... | @@ -5946,29 +6166,29 @@ fn airReduce(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) A |
| 5946 | else | 6166 | else |
| 5947 | .@"vector.reduce.umax", | 6167 | .@"vector.reduce.umax", |
| 5948 | else => unreachable, | 6168 | else => unreachable, |
| 5949 | }, &.{llvm_operand_ty}, &.{operand}, ""), | 6169 | }, &.{try o.lowerType(operand_ty, .as_value)}, &.{operand}, ""), |
| 5950 | .float => if (intrinsicsAllowed(scalar_ty, target)) | 6170 | .float => if (intrinsicsAllowed(.libc, scalar_ty, target)) |
| 5951 | return self.wip.callIntrinsic(fast, .none, switch (reduce.operation) { | 6171 | return fg.wip.callIntrinsic(fast, .none, switch (reduce.operation) { |
| 5952 | .Min => .@"vector.reduce.fmin", | 6172 | .Min => .@"vector.reduce.fmin", |
| 5953 | .Max => .@"vector.reduce.fmax", | 6173 | .Max => .@"vector.reduce.fmax", |
| 5954 | else => unreachable, | 6174 | else => unreachable, |
| 5955 | }, &.{llvm_operand_ty}, &.{operand}, ""), | 6175 | }, &.{try o.lowerType(operand_ty, .as_value)}, &.{operand}, ""), |
| 5956 | else => unreachable, | 6176 | else => unreachable, |
| 5957 | }, | 6177 | }, |
| 5958 | .Add, .Mul => switch (scalar_ty.zigTypeTag(zcu)) { | 6178 | .Add, .Mul => switch (scalar_ty.zigTypeTag(zcu)) { |
| 5959 | .int => return self.wip.callIntrinsic(.normal, .none, switch (reduce.operation) { | 6179 | .int => return fg.wip.callIntrinsic(.normal, .none, switch (reduce.operation) { |
| 5960 | .Add => .@"vector.reduce.add", | 6180 | .Add => .@"vector.reduce.add", |
| 5961 | .Mul => .@"vector.reduce.mul", | 6181 | .Mul => .@"vector.reduce.mul", |
| 5962 | else => unreachable, | 6182 | else => unreachable, |
| 5963 | }, &.{llvm_operand_ty}, &.{operand}, ""), | 6183 | }, &.{try o.lowerType(operand_ty, .as_value)}, &.{operand}, ""), |
| 5964 | .float => if (intrinsicsAllowed(scalar_ty, target)) | 6184 | .float => if (intrinsicsAllowed(.compiler_rt, scalar_ty, target)) |
| 5965 | return self.wip.callIntrinsic(fast, .none, switch (reduce.operation) { | 6185 | return fg.wip.callIntrinsic(fast, .none, switch (reduce.operation) { |
| 5966 | .Add => .@"vector.reduce.fadd", | 6186 | .Add => .@"vector.reduce.fadd", |
| 5967 | .Mul => .@"vector.reduce.fmul", | 6187 | .Mul => .@"vector.reduce.fmul", |
| 5968 | else => unreachable, | 6188 | else => unreachable, |
| 5969 | }, &.{llvm_operand_ty}, &.{ switch (reduce.operation) { | 6189 | }, &.{try o.lowerType(operand_ty, .as_value)}, &.{ switch (reduce.operation) { |
| 5970 | .Add => try o.builder.fpValue(llvm_scalar_ty, -0.0), | 6190 | .Add => try o.builder.fpValue(try o.lowerType(scalar_ty, .as_value), -0.0), |
| 5971 | .Mul => try o.builder.fpValue(llvm_scalar_ty, 1.0), | 6191 | .Mul => try o.builder.fpValue(try o.lowerType(scalar_ty, .as_value), 1.0), |
| 5972 | else => unreachable, | 6192 | else => unreachable, |
| 5973 | }, operand }, ""), | 6193 | }, operand }, ""), |
| 5974 | else => unreachable, | 6194 | else => unreachable, |
| ... | @@ -5986,62 +6206,119 @@ fn airReduce(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) A | ... | @@ -5986,62 +6206,119 @@ fn airReduce(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) A |
| 5986 | libcFloatPrefix(float_bits), libcFloatSuffix(float_bits), | 6206 | libcFloatPrefix(float_bits), libcFloatSuffix(float_bits), |
| 5987 | }), | 6207 | }), |
| 5988 | .Add => try o.builder.strtabStringFmt("__add{s}f3", .{ | 6208 | .Add => try o.builder.strtabStringFmt("__add{s}f3", .{ |
| 5989 | compilerRtFloatAbbrev(float_bits), | 6209 | compilerRtFloatAbbrev(target, float_bits), |
| 5990 | }), | 6210 | }), |
| 5991 | .Mul => try o.builder.strtabStringFmt("__mul{s}f3", .{ | 6211 | .Mul => try o.builder.strtabStringFmt("__mul{s}f3", .{ |
| 5992 | compilerRtFloatAbbrev(float_bits), | 6212 | compilerRtFloatAbbrev(target, float_bits), |
| 5993 | }), | 6213 | }), |
| 5994 | else => unreachable, | 6214 | else => unreachable, |
| 5995 | }; | 6215 | }; |
| 5996 | 6216 | const fn_info: Object.FuncInfo = .{ | |
| 5997 | const libc_fn = try o.getLibcFunction(fn_name, &.{ llvm_scalar_ty, llvm_scalar_ty }, llvm_scalar_ty); | 6217 | .cc = target.cCallingConvention().?, |
| 5998 | const init_val = switch (llvm_scalar_ty) { | 6218 | .param_types = &.{ scalar_ty.toIntern(), scalar_ty.toIntern() }, |
| 5999 | .i16 => try o.builder.intValue(.i16, @as(i16, @bitCast( | 6219 | .return_type = scalar_ty.toIntern(), |
| 6000 | @as(f16, switch (reduce.operation) { | 6220 | }; |
| 6001 | .Min, .Max => std.math.nan(f16), | 6221 | const llvm_fn = try fg.object.getLibcFunction(fg.pt, fn_name, fn_info); |
| 6002 | .Add => -0.0, | 6222 | const init = switch (float_bits) { |
| 6003 | .Mul => 1.0, | ||
| 6004 | else => unreachable, | ||
| 6005 | }), | ||
| 6006 | ))), | ||
| 6007 | .i80 => try o.builder.intValue(.i80, @as(i80, @bitCast( | ||
| 6008 | @as(f80, switch (reduce.operation) { | ||
| 6009 | .Min, .Max => std.math.nan(f80), | ||
| 6010 | .Add => -0.0, | ||
| 6011 | .Mul => 1.0, | ||
| 6012 | else => unreachable, | ||
| 6013 | }), | ||
| 6014 | ))), | ||
| 6015 | .i128 => try o.builder.intValue(.i128, @as(i128, @bitCast( | ||
| 6016 | @as(f128, switch (reduce.operation) { | ||
| 6017 | .Min, .Max => std.math.nan(f128), | ||
| 6018 | .Add => -0.0, | ||
| 6019 | .Mul => 1.0, | ||
| 6020 | else => unreachable, | ||
| 6021 | }), | ||
| 6022 | ))), | ||
| 6023 | else => unreachable, | 6223 | else => unreachable, |
| 6224 | 16 => try o.f16Const(switch (reduce.operation) { | ||
| 6225 | else => unreachable, | ||
| 6226 | .Min, .Max => std.math.nan(f16), | ||
| 6227 | .Add => -0.0, | ||
| 6228 | .Mul => 1.0, | ||
| 6229 | }), | ||
| 6230 | 32 => try o.f32Const(switch (reduce.operation) { | ||
| 6231 | else => unreachable, | ||
| 6232 | .Min, .Max => std.math.nan(f32), | ||
| 6233 | .Add => -0.0, | ||
| 6234 | .Mul => 1.0, | ||
| 6235 | }), | ||
| 6236 | 64 => try o.f64Const(switch (reduce.operation) { | ||
| 6237 | else => unreachable, | ||
| 6238 | .Min, .Max => std.math.nan(f64), | ||
| 6239 | .Add => -0.0, | ||
| 6240 | .Mul => 1.0, | ||
| 6241 | }), | ||
| 6242 | 80 => try o.f80Const(switch (reduce.operation) { | ||
| 6243 | else => unreachable, | ||
| 6244 | .Min, .Max => std.math.nan(f80), | ||
| 6245 | .Add => -0.0, | ||
| 6246 | .Mul => 1.0, | ||
| 6247 | }), | ||
| 6248 | 128 => try o.f128Const(switch (reduce.operation) { | ||
| 6249 | else => unreachable, | ||
| 6250 | .Min, .Max => std.math.nan(f128), | ||
| 6251 | .Add => -0.0, | ||
| 6252 | .Mul => 1.0, | ||
| 6253 | }), | ||
| 6024 | }; | 6254 | }; |
| 6025 | return self.buildReducedCall(libc_fn, operand, operand_ty.vectorLen(zcu), init_val); | 6255 | const iterations = operand_ty.vectorLen(zcu); |
| 6256 | const is_by_ref = isByRef(operand_ty, zcu); | ||
| 6257 | if (iterations > 1 and is_by_ref) { | ||
| 6258 | const init_ref = try o.lowerConstRef(init, scalar_ty.abiAlignment(zcu).toLlvm()); | ||
| 6259 | |||
| 6260 | const entry_block = fg.wip.cursor.block; | ||
| 6261 | const loop_block = try fg.wip.block(2, "reduce.loop"); | ||
| 6262 | const done_block = try fg.wip.block(1, "reduce.loop"); | ||
| 6263 | |||
| 6264 | _ = try fg.wip.br(loop_block); | ||
| 6265 | |||
| 6266 | fg.wip.cursor = .{ .block = loop_block }; | ||
| 6267 | const index = try fg.wip.phi(.i32, "reduce.index"); | ||
| 6268 | const result = try fg.wip.phi(.ptr, "reduce.result"); | ||
| 6269 | |||
| 6270 | const rhs_elem_ptr = try fg.ptraddScaled(operand, index.toValue(), scalar_ty.abiSize(zcu)); | ||
| 6271 | const rhs_elem = try fg.load(rhs_elem_ptr, .none, scalar_ty, .normal); | ||
| 6272 | const next_result = try fg.buildCall(.{}, llvm_fn.typeOf(&o.builder), llvm_fn.toValue(&o.builder), fn_info, fn_info.param_types, &.{ result.toValue(), rhs_elem }); | ||
| 6273 | |||
| 6274 | const next_index = try fg.wip.bin(.@"add nuw", index.toValue(), try o.builder.intValue(.i32, 1), "reduce.next_index"); | ||
| 6275 | index.finish(&.{ try o.builder.intValue(.i32, 0), next_index }, &.{ entry_block, loop_block }, &fg.wip); | ||
| 6276 | result.finish(&.{ init_ref.toValue(), next_result }, &.{ entry_block, loop_block }, &fg.wip); | ||
| 6277 | const is_done = try fg.wip.icmp(.eq, next_index, try o.builder.intValue(.i32, iterations), "reduce.is_done"); | ||
| 6278 | _ = try fg.wip.brCond(is_done, done_block, loop_block, .none); | ||
| 6279 | |||
| 6280 | fg.wip.cursor = .{ .block = done_block }; | ||
| 6281 | return next_result; | ||
| 6282 | } | ||
| 6283 | var result = init.toValue(); | ||
| 6284 | for (0..iterations) |index| { | ||
| 6285 | const index_value = try o.builder.intValue(.i32, index); | ||
| 6286 | const rhs_elem = if (is_by_ref) rhs_elem: { | ||
| 6287 | const rhs_elem_ptr = try fg.ptraddConst(operand, index * scalar_ty.abiSize(zcu)); | ||
| 6288 | break :rhs_elem try fg.load(rhs_elem_ptr, .none, scalar_ty, .normal); | ||
| 6289 | } else try fg.wip.extractElement(operand, index_value, "reduce.rhs_elem"); | ||
| 6290 | result = try fg.buildCall(.{}, llvm_fn.typeOf(&o.builder), llvm_fn.toValue(&o.builder), fn_info, fn_info.param_types, &.{ result, rhs_elem }); | ||
| 6291 | } | ||
| 6292 | return result; | ||
| 6026 | } | 6293 | } |
| 6027 | 6294 | ||
| 6028 | fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { | 6295 | fn airAggregateInit(fg: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 6029 | const o = self.object; | 6296 | const o = fg.object; |
| 6030 | const zcu = o.zcu; | 6297 | const zcu = o.zcu; |
| 6031 | const ip = &zcu.intern_pool; | 6298 | const ip = &zcu.intern_pool; |
| 6032 | const ty_pl = self.air.instructions.items(.data)[@backingInt(inst)].ty_pl; | 6299 | const ty_pl = fg.air.instructions.items(.data)[@backingInt(inst)].ty_pl; |
| 6033 | const result_ty = self.typeOfIndex(inst); | 6300 | const result_ty = fg.typeOfIndex(inst); |
| 6034 | const len: usize = @intCast(result_ty.arrayLen(zcu)); | 6301 | const len: usize = @intCast(result_ty.arrayLen(zcu)); |
| 6035 | const elements: []const Air.Inst.Ref = @ptrCast(self.air.extra.items[ty_pl.payload..][0..len]); | 6302 | const elements: []const Air.Inst.Ref = @ptrCast(fg.air.extra.items[ty_pl.payload..][0..len]); |
| 6036 | 6303 | ||
| 6037 | switch (result_ty.zigTypeTag(zcu)) { | 6304 | switch (result_ty.zigTypeTag(zcu)) { |
| 6038 | .vector => { | 6305 | .vector => if (isByRef(result_ty, zcu)) { |
| 6039 | const llvm_result_ty = try o.lowerType(result_ty, .by_value); | 6306 | const elem_ty = result_ty.childType(zcu); |
| 6307 | const elem_size = elem_ty.abiSize(zcu); | ||
| 6308 | const result_ptr = try fg.buildZigAlloca(result_ty, .none); | ||
| 6309 | for (elements, 0..) |elem, elem_index| { | ||
| 6310 | const elem_ptr = try fg.ptraddConst(result_ptr, elem_index * elem_size); | ||
| 6311 | const llvm_elem = try fg.resolveInst(elem); | ||
| 6312 | try fg.store(elem_ptr, .none, llvm_elem, elem_ty, .normal); | ||
| 6313 | } | ||
| 6314 | return result_ptr; | ||
| 6315 | } else { | ||
| 6316 | const llvm_result_ty = try o.lowerType(result_ty, .as_value); | ||
| 6040 | var vector = try o.builder.poisonValue(llvm_result_ty); | 6317 | var vector = try o.builder.poisonValue(llvm_result_ty); |
| 6041 | for (elements, 0..) |elem, i| { | 6318 | for (elements, 0..) |elem, elem_index| { |
| 6042 | const index_u32 = try o.builder.intValue(.i32, i); | 6319 | const elem_index_val = try o.builder.intValue(.i32, elem_index); |
| 6043 | const llvm_elem = try self.resolveInst(elem); | 6320 | const llvm_elem = try fg.resolveInst(elem); |
| 6044 | vector = try self.wip.insertElement(vector, llvm_elem, index_u32, ""); | 6321 | vector = try fg.wip.insertElement(vector, llvm_elem, elem_index_val, ""); |
| 6045 | } | 6322 | } |
| 6046 | return vector; | 6323 | return vector; |
| 6047 | }, | 6324 | }, |
| ... | @@ -6057,18 +6334,18 @@ fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builde | ... | @@ -6057,18 +6334,18 @@ fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builde |
| 6057 | for (elements, struct_type.field_types.get(ip)) |elem, field_ty| { | 6334 | for (elements, struct_type.field_types.get(ip)) |elem, field_ty| { |
| 6058 | if (!Type.fromInterned(field_ty).hasRuntimeBits(zcu)) continue; | 6335 | if (!Type.fromInterned(field_ty).hasRuntimeBits(zcu)) continue; |
| 6059 | 6336 | ||
| 6060 | const non_int_val = try self.resolveInst(elem); | 6337 | const non_int_val = try fg.resolveInst(elem); |
| 6061 | const ty_bit_size: u16 = @intCast(Type.fromInterned(field_ty).bitSize(zcu)); | 6338 | const ty_bit_size: u16 = @intCast(Type.fromInterned(field_ty).bitSize(zcu)); |
| 6062 | const small_int_ty = try o.builder.intType(ty_bit_size); | 6339 | const small_int_ty = try o.builder.intType(ty_bit_size); |
| 6063 | const small_int_val = if (Type.fromInterned(field_ty).isPtrAtRuntime(zcu)) | 6340 | const small_int_val = if (Type.fromInterned(field_ty).isPtrAtRuntime(zcu)) |
| 6064 | try self.wip.cast(.ptrtoint, non_int_val, small_int_ty, "") | 6341 | try fg.wip.cast(.ptrtoint, non_int_val, small_int_ty, "") |
| 6065 | else | 6342 | else |
| 6066 | try self.wip.cast(.bitcast, non_int_val, small_int_ty, ""); | 6343 | try fg.wip.cast(.bitcast, non_int_val, small_int_ty, ""); |
| 6067 | const shift_rhs = try o.builder.intValue(int_ty, running_bits); | 6344 | const shift_rhs = try o.builder.intValue(int_ty, running_bits); |
| 6068 | const extended_int_val = | 6345 | const extended_int_val = |
| 6069 | try self.wip.conv(.unsigned, small_int_val, int_ty, ""); | 6346 | try fg.wip.conv(.unsigned, small_int_val, int_ty, ""); |
| 6070 | const shifted = try self.wip.bin(.shl, extended_int_val, shift_rhs, ""); | 6347 | const shifted = try fg.wip.bin(.shl, extended_int_val, shift_rhs, ""); |
| 6071 | running_int = try self.wip.bin(.@"or", running_int, shifted, ""); | 6348 | running_int = try fg.wip.bin(.@"or", running_int, shifted, ""); |
| 6072 | running_bits += ty_bit_size; | 6349 | running_bits += ty_bit_size; |
| 6073 | } | 6350 | } |
| 6074 | return running_int; | 6351 | return running_int; |
| ... | @@ -6078,19 +6355,19 @@ fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builde | ... | @@ -6078,19 +6355,19 @@ fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builde |
| 6078 | // TODO in debug builds init to undef so that the padding will be 0xaa | 6355 | // TODO in debug builds init to undef so that the padding will be 0xaa |
| 6079 | // even if we fully populate the fields. | 6356 | // even if we fully populate the fields. |
| 6080 | const struct_align = result_ty.abiAlignment(zcu); | 6357 | const struct_align = result_ty.abiAlignment(zcu); |
| 6081 | const alloca_inst = try self.buildZigAlloca(result_ty, .none); | 6358 | const alloca_inst = try fg.buildZigAlloca(result_ty, .none); |
| 6082 | 6359 | ||
| 6083 | for (elements, 0..) |elem, field_index| { | 6360 | for (elements, 0..) |elem, field_index| { |
| 6084 | if (result_ty.structFieldIsComptime(field_index, zcu)) continue; | 6361 | if (result_ty.structFieldIsComptime(field_index, zcu)) continue; |
| 6085 | const field_ty = result_ty.fieldType(field_index, zcu); | 6362 | const field_ty = result_ty.fieldType(field_index, zcu); |
| 6086 | if (!field_ty.hasRuntimeBits(zcu)) continue; | 6363 | if (!field_ty.hasRuntimeBits(zcu)) continue; |
| 6087 | const offset = result_ty.structFieldOffset(field_index, zcu); | 6364 | const offset = result_ty.structFieldOffset(field_index, zcu); |
| 6088 | const field_ptr = try self.ptraddConst(alloca_inst, offset); | 6365 | const field_ptr = try fg.ptraddConst(alloca_inst, offset); |
| 6089 | const field_ptr_align = struct_align.offset(offset); | 6366 | const field_ptr_align = struct_align.offset(offset); |
| 6090 | 6367 | ||
| 6091 | const llvm_field_val = try self.resolveInst(elem); | 6368 | const llvm_field_val = try fg.resolveInst(elem); |
| 6092 | 6369 | ||
| 6093 | try self.store(field_ptr, field_ptr_align, llvm_field_val, field_ty, .normal); | 6370 | try fg.store(field_ptr, field_ptr_align, llvm_field_val, field_ty, .normal); |
| 6094 | } | 6371 | } |
| 6095 | 6372 | ||
| 6096 | return alloca_inst; | 6373 | return alloca_inst; |
| ... | @@ -6099,21 +6376,21 @@ fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builde | ... | @@ -6099,21 +6376,21 @@ fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builde |
| 6099 | .array => { | 6376 | .array => { |
| 6100 | assert(isByRef(result_ty, zcu)); | 6377 | assert(isByRef(result_ty, zcu)); |
| 6101 | 6378 | ||
| 6102 | const alloca_inst = try self.buildZigAlloca(result_ty, .none); | 6379 | const alloca_inst = try fg.buildZigAlloca(result_ty, .none); |
| 6103 | 6380 | ||
| 6104 | const array_info = result_ty.arrayInfo(zcu); | 6381 | const array_info = result_ty.arrayInfo(zcu); |
| 6105 | 6382 | ||
| 6106 | const elem_size = array_info.elem_type.abiSize(zcu); | 6383 | const elem_size = array_info.elem_type.abiSize(zcu); |
| 6107 | 6384 | ||
| 6108 | for (elements, 0..) |elem, i| { | 6385 | for (elements, 0..) |elem, i| { |
| 6109 | const elem_ptr = try self.ptraddConst(alloca_inst, elem_size * i); | 6386 | const elem_ptr = try fg.ptraddConst(alloca_inst, elem_size * i); |
| 6110 | const llvm_elem = try self.resolveInst(elem); | 6387 | const llvm_elem = try fg.resolveInst(elem); |
| 6111 | try self.store(elem_ptr, .none, llvm_elem, array_info.elem_type, .normal); | 6388 | try fg.store(elem_ptr, .none, llvm_elem, array_info.elem_type, .normal); |
| 6112 | } | 6389 | } |
| 6113 | if (array_info.sentinel) |sent_val| { | 6390 | if (array_info.sentinel) |sent_val| { |
| 6114 | const elem_ptr = try self.ptraddConst(alloca_inst, elem_size * array_info.len); | 6391 | const elem_ptr = try fg.ptraddConst(alloca_inst, elem_size * array_info.len); |
| 6115 | const llvm_elem = try self.resolveValue(sent_val); | 6392 | const llvm_elem = try fg.resolveValue(sent_val); |
| 6116 | try self.store(elem_ptr, .none, llvm_elem.toValue(), array_info.elem_type, .normal); | 6393 | try fg.store(elem_ptr, .none, llvm_elem.toValue(), array_info.elem_type, .normal); |
| 6117 | } | 6394 | } |
| 6118 | 6395 | ||
| 6119 | return alloca_inst; | 6396 | return alloca_inst; |
| ... | @@ -6153,10 +6430,10 @@ fn airUnionInit(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Va | ... | @@ -6153,10 +6430,10 @@ fn airUnionInit(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Va |
| 6153 | const loaded_enum = ip.loadEnumType(tag_ty.toIntern()); | 6430 | const loaded_enum = ip.loadEnumType(tag_ty.toIntern()); |
| 6154 | const llvm_tag_val = switch (loaded_enum.field_values.getOrNone(ip, extra.field_index)) { | 6431 | const llvm_tag_val = switch (loaded_enum.field_values.getOrNone(ip, extra.field_index)) { |
| 6155 | .none => try o.builder.intConst( | 6432 | .none => try o.builder.intConst( |
| 6156 | try o.lowerType(.fromInterned(union_obj.enum_tag_type), .by_value), | 6433 | try o.lowerType(.fromInterned(union_obj.enum_tag_type), .as_value), |
| 6157 | extra.field_index, // auto-numbered | 6434 | extra.field_index, // auto-numbered |
| 6158 | ), | 6435 | ), |
| 6159 | else => |tag_val_ip| try o.lowerValue(tag_val_ip, .by_value), | 6436 | else => |tag_val_ip| try o.lowerValue(tag_val_ip, .as_value), |
| 6160 | }; | 6437 | }; |
| 6161 | const tag_ptr = try self.ptraddConst(result_ptr, layout.tagOffset()); | 6438 | const tag_ptr = try self.ptraddConst(result_ptr, layout.tagOffset()); |
| 6162 | try self.store(tag_ptr, layout.tag_align, llvm_tag_val.toValue(), tag_ty, .normal); | 6439 | try self.store(tag_ptr, layout.tag_align, llvm_tag_val.toValue(), tag_ty, .normal); |
| ... | @@ -6218,7 +6495,7 @@ fn airAddrSpaceCast(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builde | ... | @@ -6218,7 +6495,7 @@ fn airAddrSpaceCast(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builde |
| 6218 | const ty_op = self.air.instructions.items(.data)[@backingInt(inst)].ty_op; | 6495 | const ty_op = self.air.instructions.items(.data)[@backingInt(inst)].ty_op; |
| 6219 | const inst_ty = self.typeOfIndex(inst); | 6496 | const inst_ty = self.typeOfIndex(inst); |
| 6220 | const operand = try self.resolveInst(ty_op.operand); | 6497 | const operand = try self.resolveInst(ty_op.operand); |
| 6221 | return self.wip.cast(.addrspacecast, operand, try self.object.lowerType(inst_ty, .by_value), ""); | 6498 | return self.wip.cast(.addrspacecast, operand, try self.object.lowerType(inst_ty, .as_value), ""); |
| 6222 | } | 6499 | } |
| 6223 | 6500 | ||
| 6224 | fn workIntrinsic( | 6501 | fn workIntrinsic( |
| ... | @@ -6370,7 +6647,7 @@ fn load( | ... | @@ -6370,7 +6647,7 @@ fn load( |
| 6370 | }; | 6647 | }; |
| 6371 | 6648 | ||
| 6372 | if (isByRef(load_ty, zcu)) { | 6649 | if (isByRef(load_ty, zcu)) { |
| 6373 | const llvm_usize_ty = try o.lowerType(.usize, .by_value); | 6650 | const llvm_usize_ty = try o.lowerType(.usize, .as_value); |
| 6374 | const result_ptr = try fg.buildZigAlloca(load_ty, .none); | 6651 | const result_ptr = try fg.buildZigAlloca(load_ty, .none); |
| 6375 | _ = try fg.wip.callMemCpy( | 6652 | _ = try fg.wip.callMemCpy( |
| 6376 | result_ptr, | 6653 | result_ptr, |
| ... | @@ -6384,11 +6661,14 @@ fn load( | ... | @@ -6384,11 +6661,14 @@ fn load( |
| 6384 | return result_ptr; | 6661 | return result_ptr; |
| 6385 | } | 6662 | } |
| 6386 | 6663 | ||
| 6387 | const llvm_memory_ty = try o.lowerType(load_ty, .in_memory); | 6664 | const llvm_access_ty = try o.lowerType(load_ty, .memory_access); |
| 6388 | const llvm_value_ty = try o.lowerType(load_ty, .by_value); | 6665 | const llvm_value_ty = try o.lowerType(load_ty, .as_value); |
| 6389 | 6666 | ||
| 6390 | if (llvm_memory_ty != llvm_value_ty) { | 6667 | if (llvm_access_ty != llvm_value_ty) { |
| 6391 | assert(load_ty.isAbiInt(zcu)); | 6668 | const signedness: std.lang.Signedness = switch (load_ty.toIntern()) { |
| 6669 | .bool_type => .unsigned, | ||
| 6670 | else => load_ty.intInfo(zcu).signedness, | ||
| 6671 | }; | ||
| 6392 | // `load_ty` is an integer type with padding bits. In theory, we shouldn't need any special | 6672 | // `load_ty` is an integer type with padding bits. In theory, we shouldn't need any special |
| 6393 | // handling for these, as LLVM's documented semantics are a valid implementation of Zig's | 6673 | // handling for these, as LLVM's documented semantics are a valid implementation of Zig's |
| 6394 | // semantics. However: | 6674 | // semantics. However: |
| ... | @@ -6401,13 +6681,13 @@ fn load( | ... | @@ -6401,13 +6681,13 @@ fn load( |
| 6401 | // | 6681 | // |
| 6402 | // Therefore, we handle these memory accesses specially: in this case we will actually load | 6682 | // Therefore, we handle these memory accesses specially: in this case we will actually load |
| 6403 | // the next-largest "natural" integer type and then truncate to `load_ty`. | 6683 | // the next-largest "natural" integer type and then truncate to `load_ty`. |
| 6404 | const loaded = try fg.wip.load(access_kind, llvm_memory_ty, ptr, llvm_ptr_align, ""); | 6684 | const loaded = try fg.wip.load(access_kind, llvm_access_ty, ptr, llvm_ptr_align, ""); |
| 6405 | // For packed structs, current Zig semantics don't really allow us to make the padding bits | 6685 | // For packed structs, current Zig semantics don't really allow us to make the padding bits |
| 6406 | // well-defined. This should be solved once https://github.com/ziglang/zig/issues/24061 is | 6686 | // well-defined. This should be solved once https://github.com/ziglang/zig/issues/24061 is |
| 6407 | // implemented, but until then, do a normal trunc for packed types. | 6687 | // implemented, but until then, do a normal trunc for packed types. |
| 6408 | return fg.wip.cast(switch (load_ty.zigTypeTag(zcu)) { | 6688 | return fg.wip.cast(switch (load_ty.zigTypeTag(zcu)) { |
| 6409 | .@"struct", .@"union" => .trunc, | 6689 | .@"struct", .@"union" => .trunc, |
| 6410 | else => switch (load_ty.intInfo(zcu).signedness) { | 6690 | else => switch (signedness) { |
| 6411 | .unsigned => .@"trunc nuw", | 6691 | .unsigned => .@"trunc nuw", |
| 6412 | .signed => .@"trunc nsw", | 6692 | .signed => .@"trunc nsw", |
| 6413 | }, | 6693 | }, |
| ... | @@ -6443,7 +6723,7 @@ fn store( | ... | @@ -6443,7 +6723,7 @@ fn store( |
| 6443 | }; | 6723 | }; |
| 6444 | 6724 | ||
| 6445 | if (isByRef(elem_ty, zcu)) { | 6725 | if (isByRef(elem_ty, zcu)) { |
| 6446 | const llvm_usize_ty = try o.lowerType(.usize, .by_value); | 6726 | const llvm_usize_ty = try o.lowerType(.usize, .as_value); |
| 6447 | _ = try fg.wip.callMemCpy( | 6727 | _ = try fg.wip.callMemCpy( |
| 6448 | ptr, | 6728 | ptr, |
| 6449 | llvm_ptr_align, | 6729 | llvm_ptr_align, |
| ... | @@ -6456,45 +6736,34 @@ fn store( | ... | @@ -6456,45 +6736,34 @@ fn store( |
| 6456 | return; | 6736 | return; |
| 6457 | } | 6737 | } |
| 6458 | 6738 | ||
| 6459 | assert(elem.typeOfWip(&fg.wip) == try o.lowerType(elem_ty, .by_value)); | 6739 | assert(elem.typeOfWip(&fg.wip) == try o.lowerType(elem_ty, .as_value)); |
| 6460 | 6740 | ||
| 6461 | const llvm_memory_ty = try o.lowerType(elem_ty, .in_memory); | 6741 | const llvm_access_ty = try o.lowerType(elem_ty, .memory_access); |
| 6462 | const llvm_value_ty = try o.lowerType(elem_ty, .by_value); | 6742 | const llvm_value_ty = try o.lowerType(elem_ty, .as_value); |
| 6463 | 6743 | ||
| 6464 | if (llvm_memory_ty != llvm_value_ty) { | 6744 | if (llvm_access_ty != llvm_value_ty) { |
| 6465 | assert(elem_ty.isAbiInt(zcu)); | 6745 | const signedness: std.lang.Signedness = switch (elem_ty.toIntern()) { |
| 6746 | .bool_type => .unsigned, | ||
| 6747 | else => elem_ty.intInfo(zcu).signedness, | ||
| 6748 | }; | ||
| 6466 | // `elem_ty` is an integer type with padding bits, so we need to handle it specially---see | 6749 | // `elem_ty` is an integer type with padding bits, so we need to handle it specially---see |
| 6467 | // the corresponding comment in `FuncGen.load` for more details. | 6750 | // the corresponding comment in `FuncGen.load` for more details. |
| 6468 | const extended = try fg.wip.cast(switch (elem_ty.intInfo(zcu).signedness) { | 6751 | const extended = try fg.wip.cast(switch (signedness) { |
| 6469 | .unsigned => .zext, | 6752 | .unsigned => .zext, |
| 6470 | .signed => .sext, | 6753 | .signed => .sext, |
| 6471 | }, elem, llvm_memory_ty, ""); | 6754 | }, elem, llvm_access_ty, ""); |
| 6472 | _ = try fg.wip.storeAtomic( | 6755 | _ = try fg.wip.store(access_kind, extended, ptr, llvm_ptr_align); |
| 6473 | access_kind, | ||
| 6474 | extended, | ||
| 6475 | ptr, | ||
| 6476 | fg.sync_scope, | ||
| 6477 | .none, | ||
| 6478 | llvm_ptr_align, | ||
| 6479 | ); | ||
| 6480 | return; | 6756 | return; |
| 6481 | } | 6757 | } |
| 6482 | 6758 | ||
| 6483 | // `elem_ty` is a simple by-val type which requires no special handling. | 6759 | // `elem_ty` is a simple by-val type which requires no special handling. |
| 6484 | _ = try fg.wip.storeAtomic( | 6760 | _ = try fg.wip.store(access_kind, elem, ptr, llvm_ptr_align); |
| 6485 | access_kind, | ||
| 6486 | elem, | ||
| 6487 | ptr, | ||
| 6488 | fg.sync_scope, | ||
| 6489 | .none, | ||
| 6490 | llvm_ptr_align, | ||
| 6491 | ); | ||
| 6492 | } | 6761 | } |
| 6493 | 6762 | ||
| 6494 | fn valgrindMarkUndef(fg: *FuncGen, ptr: Builder.Value, len: Builder.Value) Allocator.Error!void { | 6763 | fn valgrindMarkUndef(fg: *FuncGen, ptr: Builder.Value, len: Builder.Value) Allocator.Error!void { |
| 6495 | const VG_USERREQ__MAKE_MEM_UNDEFINED = 1296236545; | 6764 | const VG_USERREQ__MAKE_MEM_UNDEFINED = 1296236545; |
| 6496 | const o = fg.object; | 6765 | const o = fg.object; |
| 6497 | const usize_ty = try o.lowerType(.usize, .by_value); | 6766 | const usize_ty = try o.lowerType(.usize, .as_value); |
| 6498 | const zero = try o.builder.intValue(usize_ty, 0); | 6767 | const zero = try o.builder.intValue(usize_ty, 0); |
| 6499 | const req = try o.builder.intValue(usize_ty, VG_USERREQ__MAKE_MEM_UNDEFINED); | 6768 | const req = try o.builder.intValue(usize_ty, VG_USERREQ__MAKE_MEM_UNDEFINED); |
| 6500 | const ptr_as_usize = try fg.wip.cast(.ptrtoint, ptr, usize_ty, ""); | 6769 | const ptr_as_usize = try fg.wip.cast(.ptrtoint, ptr, usize_ty, ""); |
| ... | @@ -6516,7 +6785,7 @@ fn valgrindClientRequest( | ... | @@ -6516,7 +6785,7 @@ fn valgrindClientRequest( |
| 6516 | const target = zcu.getTarget(); | 6785 | const target = zcu.getTarget(); |
| 6517 | if (!target_util.hasValgrindSupport(target, .stage2_llvm)) return default_value; | 6786 | if (!target_util.hasValgrindSupport(target, .stage2_llvm)) return default_value; |
| 6518 | 6787 | ||
| 6519 | const llvm_usize = try o.lowerType(.usize, .by_value); | 6788 | const llvm_usize = try o.lowerType(.usize, .as_value); |
| 6520 | const usize_align = Type.usize.abiAlignment(zcu).toLlvm(); | 6789 | const usize_align = Type.usize.abiAlignment(zcu).toLlvm(); |
| 6521 | 6790 | ||
| 6522 | const array_llvm_ty = try o.builder.arrayType(6, llvm_usize); | 6791 | const array_llvm_ty = try o.builder.arrayType(6, llvm_usize); |
| ... | @@ -6650,13 +6919,14 @@ fn typeOfIndex(fg: *FuncGen, inst: Air.Inst.Index) Type { | ... | @@ -6650,13 +6919,14 @@ fn typeOfIndex(fg: *FuncGen, inst: Air.Inst.Index) Type { |
| 6650 | 6919 | ||
| 6651 | const ParamTypeIterator = struct { | 6920 | const ParamTypeIterator = struct { |
| 6652 | object: *Object, | 6921 | object: *Object, |
| 6653 | fn_info: InternPool.Key.FuncType, | 6922 | cc: std.lang.CallingConvention, |
| 6923 | param_types: []const InternPool.Index, | ||
| 6654 | zig_index: u32, | 6924 | zig_index: u32, |
| 6655 | llvm_index: u32, | 6925 | llvm_index: u32, |
| 6656 | types_len: u32, | 6926 | types_len: u32, |
| 6657 | types_buffer: [8]Builder.Type, | 6927 | types_buffer: [8]Builder.Type, |
| 6658 | offsets_buffer: [9]u64, | 6928 | offsets_buffer: [9]u64, |
| 6659 | byval_attr: bool, | 6929 | byval_attr: ?Object.Byval, |
| 6660 | 6930 | ||
| 6661 | const Lowering = union(enum) { | 6931 | const Lowering = union(enum) { |
| 6662 | no_bits, | 6932 | no_bits, |
| ... | @@ -6672,88 +6942,78 @@ const ParamTypeIterator = struct { | ... | @@ -6672,88 +6942,78 @@ const ParamTypeIterator = struct { |
| 6672 | }; | 6942 | }; |
| 6673 | 6943 | ||
| 6674 | pub fn next(it: *ParamTypeIterator) Allocator.Error!?Lowering { | 6944 | pub fn next(it: *ParamTypeIterator) Allocator.Error!?Lowering { |
| 6675 | if (it.zig_index >= it.fn_info.param_types.len) return null; | 6945 | if (it.zig_index >= it.param_types.len) return null; |
| 6676 | const ip = &it.object.zcu.intern_pool; | 6946 | const ty = it.param_types[it.zig_index]; |
| 6677 | const ty = it.fn_info.param_types.get(ip)[it.zig_index]; | 6947 | it.byval_attr = null; |
| 6678 | it.byval_attr = false; | ||
| 6679 | return nextInner(it, Type.fromInterned(ty)); | 6948 | return nextInner(it, Type.fromInterned(ty)); |
| 6680 | } | 6949 | } |
| 6681 | 6950 | ||
| 6682 | /// `airCall` uses this instead of `next` so that it can take into account variadic functions. | 6951 | /// `airCall` uses this instead of `next` so that it can take into account variadic functions. |
| 6683 | fn nextCall(it: *ParamTypeIterator, fg: *FuncGen, args: []const Air.Inst.Ref) Allocator.Error!?Lowering { | 6952 | fn nextCall(it: *ParamTypeIterator, arg_types: []const InternPool.Index) Allocator.Error!?Lowering { |
| 6684 | const ip = &it.object.zcu.intern_pool; | 6953 | if (it.zig_index >= it.param_types.len) { |
| 6685 | if (it.zig_index >= it.fn_info.param_types.len) { | 6954 | if (it.zig_index >= arg_types.len) { |
| 6686 | if (it.zig_index >= args.len) { | ||
| 6687 | return null; | 6955 | return null; |
| 6688 | } else { | 6956 | } else { |
| 6689 | return nextInner(it, fg.typeOf(args[it.zig_index])); | 6957 | return nextInner(it, .fromInterned(arg_types[it.zig_index])); |
| 6690 | } | 6958 | } |
| 6691 | } else { | 6959 | } else { |
| 6692 | return nextInner(it, Type.fromInterned(it.fn_info.param_types.get(ip)[it.zig_index])); | 6960 | return nextInner(it, .fromInterned(it.param_types[it.zig_index])); |
| 6693 | } | 6961 | } |
| 6694 | } | 6962 | } |
| 6695 | 6963 | ||
| 6696 | fn nextInner(it: *ParamTypeIterator, ty: Type) Allocator.Error!?Lowering { | 6964 | fn nextInner(it: *ParamTypeIterator, ty: Type) Allocator.Error!?Lowering { |
| 6697 | const zcu = it.object.zcu; | 6965 | const zcu = it.object.zcu; |
| 6698 | const target = zcu.getTarget(); | 6966 | ty.assertHasLayout(zcu); |
| 6699 | |||
| 6700 | if (!ty.hasRuntimeBits(zcu)) { | 6967 | if (!ty.hasRuntimeBits(zcu)) { |
| 6701 | it.zig_index += 1; | 6968 | it.zig_index += 1; |
| 6702 | return .no_bits; | 6969 | return .no_bits; |
| 6703 | } | 6970 | } |
| 6704 | switch (it.fn_info.cc) { | 6971 | switch (it.cc) { |
| 6705 | .@"inline" => unreachable, | 6972 | .@"inline" => unreachable, |
| 6706 | .auto => { | 6973 | .auto => { |
| 6707 | it.zig_index += 1; | 6974 | it.zig_index += 1; |
| 6708 | it.llvm_index += 1; | 6975 | it.llvm_index += 1; |
| 6976 | |||
| 6977 | // Match the c calling convention in some cases to avoid llvm bugs. | ||
| 6978 | const target = zcu.getTarget(); | ||
| 6979 | if (target.cpu.arch == .x86_64 and ty.isVector(zcu) and ty.childType(zcu).toIntern() == .bool_type) return switch (ty.vectorLen(zcu)) { | ||
| 6980 | 0 => .no_bits, | ||
| 6981 | 1...32 => .abi_sized_int, | ||
| 6982 | 33...64 => { | ||
| 6983 | it.types_buffer[0..1].* = .{.double}; | ||
| 6984 | it.offsets_buffer[0..2].* = .{ 0, 8 }; | ||
| 6985 | it.types_len = 1; | ||
| 6986 | return .multiple_llvm_types; | ||
| 6987 | }, | ||
| 6988 | else => .byval, | ||
| 6989 | }; | ||
| 6990 | |||
| 6709 | if (ty.isSlice(zcu) or | 6991 | if (ty.isSlice(zcu) or |
| 6710 | (ty.zigTypeTag(zcu) == .optional and ty.optionalChild(zcu).isSlice(zcu) and !ty.ptrAllowsZero(zcu))) | 6992 | (ty.zigTypeTag(zcu) == .optional and ty.optionalChild(zcu).isSlice(zcu) and !ty.ptrAllowsZero(zcu))) |
| 6711 | { | 6993 | { |
| 6712 | it.llvm_index += 1; | 6994 | it.llvm_index += 1; |
| 6713 | return .slice; | 6995 | return .slice; |
| 6714 | } else if (isByRef(ty, zcu)) { | ||
| 6715 | return .byref; | ||
| 6716 | } else if (target.cpu.arch.isX86() and | ||
| 6717 | !target.cpu.has(.x86, .avx512f) and | ||
| 6718 | ty.totalVectorBits(zcu) >= 512) | ||
| 6719 | { | ||
| 6720 | // As of LLVM 18, passing a vector byval with fastcc that is 512 bits or more returns | ||
| 6721 | // "512-bit vector arguments require 'avx512f' for AVX512" | ||
| 6722 | return .byref; | ||
| 6723 | } else { | ||
| 6724 | return .byval; | ||
| 6725 | } | 6996 | } |
| 6997 | if (isByRef(ty, zcu)) return .byref; | ||
| 6998 | return .byval; | ||
| 6726 | }, | 6999 | }, |
| 6727 | .async => { | 7000 | .async => { |
| 6728 | @panic("TODO implement async function lowering in the LLVM backend"); | 7001 | @panic("TODO implement async function lowering in the LLVM backend"); |
| 6729 | }, | 7002 | }, |
| 6730 | .x86_64_sysv, .x86_64_x32 => return it.nextSystemV(ty), | ||
| 6731 | .x86_64_win => return it.nextWin64(ty), | ||
| 6732 | .x86_stdcall => { | ||
| 6733 | it.zig_index += 1; | ||
| 6734 | it.llvm_index += 1; | ||
| 6735 | |||
| 6736 | if (isScalar(zcu, ty)) { | ||
| 6737 | return .byval; | ||
| 6738 | } else { | ||
| 6739 | it.byval_attr = true; | ||
| 6740 | return .byref; | ||
| 6741 | } | ||
| 6742 | }, | ||
| 6743 | .aarch64_aapcs, .aarch64_aapcs_darwin, .aarch64_aapcs_win => { | 7003 | .aarch64_aapcs, .aarch64_aapcs_darwin, .aarch64_aapcs_win => { |
| 6744 | it.zig_index += 1; | 7004 | it.zig_index += 1; |
| 6745 | it.llvm_index += 1; | 7005 | it.llvm_index += 1; |
| 6746 | switch (aarch64_c_abi.classifyType(ty, zcu)) { | 7006 | switch (aarch64_c_abi.classifyType(ty, zcu)) { |
| 6747 | .memory => return .byref_mut, | 7007 | .memory => return .byref_mut, |
| 6748 | .float_array => |len| return Lowering{ .float_array = len }, | 7008 | .float_array => |len| return .{ .float_array = len }, |
| 6749 | .byval => return .byval, | 7009 | .byval => return .byval, |
| 6750 | .integer => { | 7010 | .integer => { |
| 6751 | it.types_len = 1; | ||
| 6752 | it.types_buffer[0..1].* = .{.i64}; | 7011 | it.types_buffer[0..1].* = .{.i64}; |
| 6753 | it.offsets_buffer[0..2].* = .{ 0, 8 }; | 7012 | it.offsets_buffer[0..2].* = .{ 0, 8 }; |
| 7013 | it.types_len = 1; | ||
| 6754 | return .multiple_llvm_types; | 7014 | return .multiple_llvm_types; |
| 6755 | }, | 7015 | }, |
| 6756 | .double_integer => return Lowering{ .i64_array = 2 }, | 7016 | .double_integer => return .{ .i64_array = 2 }, |
| 6757 | } | 7017 | } |
| 6758 | }, | 7018 | }, |
| 6759 | .arm_aapcs, .arm_aapcs_vfp => { | 7019 | .arm_aapcs, .arm_aapcs_vfp => { |
| ... | @@ -6761,26 +7021,101 @@ const ParamTypeIterator = struct { | ... | @@ -6761,26 +7021,101 @@ const ParamTypeIterator = struct { |
| 6761 | it.llvm_index += 1; | 7021 | it.llvm_index += 1; |
| 6762 | switch (arm_c_abi.classifyType(ty, zcu, .arg)) { | 7022 | switch (arm_c_abi.classifyType(ty, zcu, .arg)) { |
| 6763 | .memory => { | 7023 | .memory => { |
| 6764 | it.byval_attr = true; | 7024 | it.byval_attr = .{}; |
| 6765 | return .byref; | 7025 | return .byref; |
| 6766 | }, | 7026 | }, |
| 6767 | .byval => return .byval, | 7027 | .byval => return .byval, |
| 6768 | .i32_array => |size| return Lowering{ .i32_array = size }, | 7028 | .i32_array => |size| return .{ .i32_array = size }, |
| 6769 | .i64_array => |size| return Lowering{ .i64_array = size }, | 7029 | .i64_array => |size| return .{ .i64_array = size }, |
| 6770 | } | 7030 | } |
| 6771 | }, | 7031 | }, |
| 7032 | .loongarch32_ilp32, .loongarch64_lp64 => switch (loongarch_c_abi.classifyType(ty, zcu)) { | ||
| 7033 | .ignored => { | ||
| 7034 | it.zig_index += 1; | ||
| 7035 | return .no_bits; | ||
| 7036 | }, | ||
| 7037 | .gar, .far => { | ||
| 7038 | it.zig_index += 1; | ||
| 7039 | it.llvm_index += 1; | ||
| 7040 | return .byval; | ||
| 7041 | }, | ||
| 7042 | .member => |member_ty| { | ||
| 7043 | it.types_buffer[0..1].* = .{ | ||
| 7044 | try it.object.lowerType(member_ty, .as_value), | ||
| 7045 | }; | ||
| 7046 | it.offsets_buffer[0..2].* = .{ 0, member_ty.abiSize(zcu) }; | ||
| 7047 | it.types_len = 1; | ||
| 7048 | it.zig_index += 1; | ||
| 7049 | it.llvm_index += 1; | ||
| 7050 | return .multiple_llvm_types; | ||
| 7051 | }, | ||
| 7052 | .member_pair => |member_tys| { | ||
| 7053 | it.types_buffer[0..2].* = .{ | ||
| 7054 | try it.object.lowerType(member_tys[0], .as_value), | ||
| 7055 | try it.object.lowerType(member_tys[1], .as_value), | ||
| 7056 | }; | ||
| 7057 | const first_size = member_tys[0].abiSize(zcu); | ||
| 7058 | const second_size = member_tys[0].abiSize(zcu); | ||
| 7059 | it.offsets_buffer[0..3].* = .{ 0, first_size, first_size + second_size }; | ||
| 7060 | it.types_len = 2; | ||
| 7061 | it.zig_index += 1; | ||
| 7062 | it.llvm_index += 2; | ||
| 7063 | return .multiple_llvm_types; | ||
| 7064 | }, | ||
| 7065 | .memory_gar => { | ||
| 7066 | switch (it.cc) { | ||
| 7067 | else => unreachable, | ||
| 7068 | .loongarch32_ilp32 => { | ||
| 7069 | it.types_buffer[0..1].* = .{.i32}; | ||
| 7070 | it.offsets_buffer[0..2].* = .{ 0, 4 }; | ||
| 7071 | }, | ||
| 7072 | .loongarch64_lp64 => { | ||
| 7073 | it.types_buffer[0..1].* = .{.i64}; | ||
| 7074 | it.offsets_buffer[0..2].* = .{ 0, 8 }; | ||
| 7075 | }, | ||
| 7076 | } | ||
| 7077 | it.types_len = 1; | ||
| 7078 | it.zig_index += 1; | ||
| 7079 | it.llvm_index += 1; | ||
| 7080 | return .multiple_llvm_types; | ||
| 7081 | }, | ||
| 7082 | .memory_gar_pair => { | ||
| 7083 | it.zig_index += 1; | ||
| 7084 | it.llvm_index += 1; | ||
| 7085 | return switch (it.cc) { | ||
| 7086 | else => unreachable, | ||
| 7087 | .loongarch32_ilp32 => .{ .i32_array = 2 }, | ||
| 7088 | .loongarch64_lp64 => .{ .i64_array = 2 }, | ||
| 7089 | }; | ||
| 7090 | }, | ||
| 7091 | .address => { | ||
| 7092 | it.zig_index += 1; | ||
| 7093 | it.llvm_index += 1; | ||
| 7094 | return .byref; | ||
| 7095 | }, | ||
| 7096 | }, | ||
| 6772 | .mips_o32 => { | 7097 | .mips_o32 => { |
| 6773 | it.zig_index += 1; | 7098 | it.zig_index += 1; |
| 6774 | it.llvm_index += 1; | 7099 | it.llvm_index += 1; |
| 6775 | switch (mips_c_abi.classifyType(ty, zcu, .arg)) { | 7100 | switch (mips_c_abi.classifyType(ty, zcu, .arg)) { |
| 6776 | .memory => { | 7101 | .memory => { |
| 6777 | it.byval_attr = true; | 7102 | it.byval_attr = .{}; |
| 6778 | return .byref; | 7103 | return .byref; |
| 6779 | }, | 7104 | }, |
| 6780 | .byval => return .byval, | 7105 | .byval => return .byval, |
| 6781 | .i32_array => |size| return Lowering{ .i32_array = size }, | 7106 | .i32_array => |size| return .{ .i32_array = size }, |
| 6782 | } | 7107 | } |
| 6783 | }, | 7108 | }, |
| 7109 | .powerpc64_elf_v2 => { | ||
| 7110 | it.zig_index += 1; | ||
| 7111 | it.llvm_index += 1; | ||
| 7112 | if (isByRef(ty, zcu)) return switch (ty.abiSize(zcu)) { | ||
| 7113 | 1...8 => .abi_sized_int, | ||
| 7114 | 9...64 => |abi_size| .{ .i64_array = @intCast(@divCeil(abi_size, 8)) }, | ||
| 7115 | else => .byref, | ||
| 7116 | }; | ||
| 7117 | return .byval; // TODO | ||
| 7118 | }, | ||
| 6784 | .riscv64_lp64, .riscv32_ilp32 => { | 7119 | .riscv64_lp64, .riscv32_ilp32 => { |
| 6785 | it.zig_index += 1; | 7120 | it.zig_index += 1; |
| 6786 | it.llvm_index += 1; | 7121 | it.llvm_index += 1; |
| ... | @@ -6788,7 +7123,7 @@ const ParamTypeIterator = struct { | ... | @@ -6788,7 +7123,7 @@ const ParamTypeIterator = struct { |
| 6788 | .memory => return .byref_mut, | 7123 | .memory => return .byref_mut, |
| 6789 | .byval => return .byval, | 7124 | .byval => return .byval, |
| 6790 | .integer => return .abi_sized_int, | 7125 | .integer => return .abi_sized_int, |
| 6791 | .double_integer => return Lowering{ .i64_array = 2 }, | 7126 | .double_integer => return .{ .i64_array = 2 }, |
| 6792 | .fields => { | 7127 | .fields => { |
| 6793 | it.types_len = 0; | 7128 | it.types_len = 0; |
| 6794 | var field_it: InternPool.LoadedStructType.RuntimeOrderIterator = if (zcu.typeToStruct(ty)) |loaded_struct| | 7129 | var field_it: InternPool.LoadedStructType.RuntimeOrderIterator = if (zcu.typeToStruct(ty)) |loaded_struct| |
| ... | @@ -6798,7 +7133,7 @@ const ParamTypeIterator = struct { | ... | @@ -6798,7 +7133,7 @@ const ParamTypeIterator = struct { |
| 6798 | while (field_it.next()) |field_index| { | 7133 | while (field_it.next()) |field_index| { |
| 6799 | const field_ty = ty.fieldType(field_index, zcu); | 7134 | const field_ty = ty.fieldType(field_index, zcu); |
| 6800 | if (!field_ty.hasRuntimeBits(zcu)) continue; | 7135 | if (!field_ty.hasRuntimeBits(zcu)) continue; |
| 6801 | it.types_buffer[it.types_len] = try it.object.lowerType(field_ty, .by_value); | 7136 | it.types_buffer[it.types_len] = try it.object.lowerType(field_ty, .as_value); |
| 6802 | it.offsets_buffer[it.types_len] = ty.structFieldOffset(field_index, zcu); | 7137 | it.offsets_buffer[it.types_len] = ty.structFieldOffset(field_index, zcu); |
| 6803 | it.types_len += 1; | 7138 | it.types_len += 1; |
| 6804 | } | 7139 | } |
| ... | @@ -6808,28 +7143,105 @@ const ParamTypeIterator = struct { | ... | @@ -6808,28 +7143,105 @@ const ParamTypeIterator = struct { |
| 6808 | }, | 7143 | }, |
| 6809 | } | 7144 | } |
| 6810 | }, | 7145 | }, |
| 6811 | .wasm_mvp => switch (wasm_c_abi.classifyType(ty, zcu)) { | 7146 | .s390x_sysv, .s390x_sysv_vx => { |
| 7147 | it.zig_index += 1; | ||
| 7148 | switch (s390x_c_abi.classifyType(ty, .arg, zcu)) { | ||
| 7149 | .none => return .no_bits, | ||
| 7150 | .double_or_float, .vector, .simple => { | ||
| 7151 | it.llvm_index += 1; | ||
| 7152 | return .byval; | ||
| 7153 | }, | ||
| 7154 | .simple_aggregate => { | ||
| 7155 | it.llvm_index += 1; | ||
| 7156 | return .abi_sized_int; | ||
| 7157 | }, | ||
| 7158 | .pointer => { | ||
| 7159 | it.llvm_index += 1; | ||
| 7160 | return .byref_mut; | ||
| 7161 | }, | ||
| 7162 | } | ||
| 7163 | }, | ||
| 7164 | .wasm_mvp => switch (wasm_c_abi.classifyTypeForLlvm(ty, zcu)) { | ||
| 6812 | .direct => |scalar_ty| { | 7165 | .direct => |scalar_ty| { |
| 6813 | if (isScalar(zcu, ty)) { | 7166 | if (isScalar(zcu, ty)) { |
| 6814 | it.zig_index += 1; | 7167 | it.zig_index += 1; |
| 6815 | it.llvm_index += 1; | 7168 | it.llvm_index += 1; |
| 6816 | return .byval; | 7169 | return .byval; |
| 6817 | } else { | 7170 | } else { |
| 6818 | it.types_buffer[0..1].* = .{try it.object.lowerType(scalar_ty, .by_value)}; | 7171 | it.types_buffer[0..1].* = .{try it.object.lowerType(scalar_ty, .as_value)}; |
| 6819 | it.offsets_buffer[0..2].* = .{ 0, scalar_ty.abiSize(zcu) }; | 7172 | it.offsets_buffer[0..2].* = .{ 0, scalar_ty.abiSize(zcu) }; |
| 6820 | it.types_len = 1; | 7173 | it.types_len = 1; |
| 6821 | it.llvm_index += 1; | ||
| 6822 | it.zig_index += 1; | 7174 | it.zig_index += 1; |
| 7175 | it.llvm_index += 1; | ||
| 6823 | return .multiple_llvm_types; | 7176 | return .multiple_llvm_types; |
| 6824 | } | 7177 | } |
| 6825 | }, | 7178 | }, |
| 6826 | .indirect => { | 7179 | .indirect => { |
| 6827 | it.zig_index += 1; | 7180 | it.zig_index += 1; |
| 6828 | it.llvm_index += 1; | 7181 | it.llvm_index += 1; |
| 6829 | it.byval_attr = true; | 7182 | it.byval_attr = .{}; |
| 6830 | return .byref; | 7183 | return .byref; |
| 6831 | }, | 7184 | }, |
| 6832 | }, | 7185 | }, |
| 7186 | .x86_stdcall => { | ||
| 7187 | it.zig_index += 1; | ||
| 7188 | it.llvm_index += 1; | ||
| 7189 | |||
| 7190 | if (isScalar(zcu, ty)) { | ||
| 7191 | return .byval; | ||
| 7192 | } else { | ||
| 7193 | it.byval_attr = .{}; | ||
| 7194 | return .byref; | ||
| 7195 | } | ||
| 7196 | }, | ||
| 7197 | .x86_sysv, .x86_win, .x86_mingw => { | ||
| 7198 | if (isByRef(ty, zcu)) { | ||
| 7199 | var items_buf: [1]codegen.FlattenedItem = undefined; | ||
| 7200 | if (codegen.flattenType(&items_buf, ty, zcu, .{ | ||
| 7201 | .allow_arrays = false, | ||
| 7202 | })) |items| one_float: { | ||
| 7203 | if (items.len != 1 or items[0].offset != 0) break :one_float; | ||
| 7204 | const item_ty = items[0].type orelse break :one_float; | ||
| 7205 | if (!item_ty.isRuntimeFloat()) break :one_float; | ||
| 7206 | it.types_buffer[0..1].*, it.offsets_buffer[0..2].* = | ||
| 7207 | switch (item_ty.floatBits(zcu.getTarget())) { | ||
| 7208 | else => unreachable, | ||
| 7209 | 32 => .{ .{.float}, .{ 0, 4 } }, | ||
| 7210 | 64 => .{ .{.double}, .{ 0, 8 } }, | ||
| 7211 | 16, 80, 128 => break :one_float, | ||
| 7212 | }; | ||
| 7213 | it.types_len = 1; | ||
| 7214 | it.zig_index += 1; | ||
| 7215 | it.llvm_index += 1; | ||
| 7216 | return .multiple_llvm_types; | ||
| 7217 | } | ||
| 7218 | it.zig_index += 1; | ||
| 7219 | it.llvm_index += 1; | ||
| 7220 | it.byval_attr = .{ .alignment = .@"4" }; | ||
| 7221 | return .byref; | ||
| 7222 | } | ||
| 7223 | if (ty.isAbiInt(zcu)) switch (ty.intInfo(zcu).bits) { | ||
| 7224 | else => unreachable, | ||
| 7225 | 8, 16, 32, 64 => { | ||
| 7226 | it.zig_index += 1; | ||
| 7227 | it.llvm_index += 1; | ||
| 7228 | return .byval; | ||
| 7229 | }, | ||
| 7230 | 128 => { | ||
| 7231 | it.types_buffer[0..2].* = .{ .i64, .i64 }; | ||
| 7232 | it.offsets_buffer[0..3].* = .{ 0, 8, 16 }; | ||
| 7233 | it.types_len = 2; | ||
| 7234 | it.zig_index += 1; | ||
| 7235 | it.llvm_index += 2; | ||
| 7236 | return .multiple_llvm_types; | ||
| 7237 | }, | ||
| 7238 | }; | ||
| 7239 | it.zig_index += 1; | ||
| 7240 | it.llvm_index += 1; | ||
| 7241 | return .byval; | ||
| 7242 | }, | ||
| 7243 | .x86_64_sysv, .x86_64_x32 => return try it.next_x86_64_sysv(ty), | ||
| 7244 | .x86_64_win => return it.next_x86_64_win(ty), | ||
| 6833 | // TODO investigate other callconvs | 7245 | // TODO investigate other callconvs |
| 6834 | else => { | 7246 | else => { |
| 6835 | it.zig_index += 1; | 7247 | it.zig_index += 1; |
| ... | @@ -6839,7 +7251,7 @@ const ParamTypeIterator = struct { | ... | @@ -6839,7 +7251,7 @@ const ParamTypeIterator = struct { |
| 6839 | } | 7251 | } |
| 6840 | } | 7252 | } |
| 6841 | 7253 | ||
| 6842 | fn nextWin64(it: *ParamTypeIterator, ty: Type) ?Lowering { | 7254 | fn next_x86_64_win(it: *ParamTypeIterator, ty: Type) Lowering { |
| 6843 | const zcu = it.object.zcu; | 7255 | const zcu = it.object.zcu; |
| 6844 | switch (x86_64_abi.classifyWindows(ty, zcu, zcu.getTarget(), .arg)) { | 7256 | switch (x86_64_abi.classifyWindows(ty, zcu, zcu.getTarget(), .arg)) { |
| 6845 | .integer => { | 7257 | .integer => { |
| ... | @@ -6880,119 +7292,114 @@ const ParamTypeIterator = struct { | ... | @@ -6880,119 +7292,114 @@ const ParamTypeIterator = struct { |
| 6880 | } | 7292 | } |
| 6881 | } | 7293 | } |
| 6882 | 7294 | ||
| 6883 | fn nextSystemV(it: *ParamTypeIterator, ty: Type) Allocator.Error!?Lowering { | 7295 | fn next_x86_64_sysv(it: *ParamTypeIterator, ty: Type) Allocator.Error!Lowering { |
| 6884 | const zcu = it.object.zcu; | 7296 | const o = it.object; |
| 6885 | const ip = &zcu.intern_pool; | 7297 | const zcu = o.zcu; |
| 6886 | ty.assertHasLayout(zcu); | 7298 | const target = zcu.getTarget(); |
| 6887 | const classes = x86_64_abi.classifySystemV(ty, zcu, zcu.getTarget(), .arg); | 7299 | const classes = x86_64_abi.classifySystemV(ty, zcu, target, .arg); |
| 6888 | if (classes[0] == .memory) { | 7300 | var types_len: u32 = 0; |
| 6889 | it.zig_index += 1; | 7301 | const classes_len = for (classes, 0..) |class, class_index| switch (class) { |
| 6890 | it.llvm_index += 1; | 7302 | .integer => { |
| 6891 | it.byval_attr = true; | 7303 | it.types_buffer[types_len] = try o.builder.intType(@min(8 * ty.abiSize(zcu) - 64 * class_index, 64)); |
| 6892 | return .byref; | 7304 | it.offsets_buffer[types_len] = 8 * class_index; |
| 6893 | } | 7305 | types_len += 1; |
| 6894 | if (isScalar(zcu, ty)) { | 7306 | }, |
| 6895 | it.zig_index += 1; | 7307 | .sse => { |
| 6896 | it.llvm_index += 1; | 7308 | it.types_buffer[types_len] = .double; |
| 6897 | return .byval; | 7309 | it.offsets_buffer[types_len] = 8 * class_index; |
| 6898 | } | 7310 | types_len += 1; |
| 6899 | var types_index: u32 = 0; | 7311 | }, |
| 6900 | var offset: u64 = 0; | 7312 | .sseup => { |
| 6901 | for (classes) |class| { | 7313 | if (it.types_buffer[types_len - 1] == .double) { |
| 6902 | switch (class) { | 7314 | if (ty.isVector(zcu)) { |
| 6903 | .integer => { | 7315 | it.zig_index += 1; |
| 6904 | it.types_buffer[types_index] = .i64; | 7316 | it.llvm_index += 1; |
| 6905 | it.offsets_buffer[types_index] = offset; | 7317 | return .byval; |
| 6906 | types_index += 1; | ||
| 6907 | }, | ||
| 6908 | .sse => { | ||
| 6909 | it.types_buffer[types_index] = .double; | ||
| 6910 | it.offsets_buffer[types_index] = offset; | ||
| 6911 | types_index += 1; | ||
| 6912 | }, | ||
| 6913 | .sseup => { | ||
| 6914 | if (it.types_buffer[types_index - 1] == .double) { | ||
| 6915 | it.types_buffer[types_index - 1] = .fp128; | ||
| 6916 | } else { | ||
| 6917 | it.types_buffer[types_index] = .double; | ||
| 6918 | it.offsets_buffer[types_index] = offset; | ||
| 6919 | types_index += 1; | ||
| 6920 | } | 7318 | } |
| 6921 | }, | 7319 | it.types_buffer[types_len - 1] = .fp128; |
| 6922 | .float => { | 7320 | } else { |
| 6923 | it.types_buffer[types_index] = .float; | 7321 | it.types_buffer[types_len] = .double; |
| 6924 | it.offsets_buffer[types_index] = offset; | 7322 | it.offsets_buffer[types_len] = 8 * class_index; |
| 6925 | types_index += 1; | 7323 | types_len += 1; |
| 6926 | }, | 7324 | } |
| 6927 | .float_combine => { | 7325 | }, |
| 6928 | it.types_buffer[types_index] = try it.object.builder.vectorType(.normal, 2, .float); | 7326 | .float => { |
| 6929 | it.offsets_buffer[types_index] = offset; | 7327 | it.types_buffer[types_len] = .float; |
| 6930 | types_index += 1; | 7328 | it.offsets_buffer[types_len] = 8 * class_index; |
| 6931 | }, | 7329 | types_len += 1; |
| 6932 | .x87 => { | 7330 | }, |
| 6933 | it.zig_index += 1; | 7331 | .float_combine => { |
| 6934 | it.llvm_index += 1; | 7332 | it.types_buffer[types_len] = try it.object.builder.vectorType(.normal, 2, .float); |
| 6935 | it.byval_attr = true; | 7333 | it.offsets_buffer[types_len] = 8 * class_index; |
| 6936 | return .byref; | 7334 | types_len += 1; |
| 6937 | }, | 7335 | }, |
| 6938 | .x87up => unreachable, | 7336 | .x87 => { |
| 6939 | .none => break, | ||
| 6940 | .memory => unreachable, // handled above | ||
| 6941 | .win_i128 => unreachable, // windows only | ||
| 6942 | .bool_vector_mask, | ||
| 6943 | .integer_per_element, | ||
| 6944 | .sse_per_element, | ||
| 6945 | .sse_sse_x87_per_qword, | ||
| 6946 | .sse_per_xword, | ||
| 6947 | .sse_per_yword, | ||
| 6948 | .sse_per_zword, | ||
| 6949 | => unreachable, // vectors already handled by `isScalar` above | ||
| 6950 | } | ||
| 6951 | offset += 8; | ||
| 6952 | } | ||
| 6953 | const first_non_integer = std.mem.indexOfNone(x86_64_abi.Class, &classes, &.{.integer}); | ||
| 6954 | if (first_non_integer == null or classes[first_non_integer.?] == .none) { | ||
| 6955 | assert(first_non_integer orelse classes.len == types_index); | ||
| 6956 | if (types_index == 1) { | ||
| 6957 | it.zig_index += 1; | 7337 | it.zig_index += 1; |
| 6958 | it.llvm_index += 1; | 7338 | it.llvm_index += 1; |
| 6959 | return .abi_sized_int; | 7339 | it.byval_attr = .{}; |
| 6960 | } | 7340 | return .byref; |
| 6961 | if (it.llvm_index + types_index > 6) { | 7341 | }, |
| 7342 | .x87up => unreachable, | ||
| 7343 | .none => break class_index, | ||
| 7344 | .memory => { | ||
| 7345 | it.zig_index += 1; | ||
| 7346 | it.llvm_index += 1; | ||
| 7347 | it.byval_attr = .{}; | ||
| 7348 | return .byref; | ||
| 7349 | }, | ||
| 7350 | .win_i128 => unreachable, // windows only | ||
| 7351 | .bool_vector_mask, | ||
| 7352 | .integer_per_element, | ||
| 7353 | .sse_per_element, | ||
| 7354 | .sse_sse_x87_per_qword, | ||
| 7355 | .sse_per_xword, | ||
| 7356 | .sse_per_yword, | ||
| 7357 | .sse_per_zword, | ||
| 7358 | => { | ||
| 7359 | it.zig_index += 1; | ||
| 7360 | it.llvm_index += 1; | ||
| 7361 | return .byval; | ||
| 7362 | }, | ||
| 7363 | } else classes.len; | ||
| 7364 | if (types_len > 1) { | ||
| 7365 | if (it.llvm_index + classes_len > 6) { | ||
| 6962 | it.zig_index += 1; | 7366 | it.zig_index += 1; |
| 6963 | it.llvm_index += 1; | 7367 | it.llvm_index += 1; |
| 6964 | it.byval_attr = true; | 7368 | it.byval_attr = .{}; |
| 6965 | return .byref; | 7369 | return .byref; |
| 6966 | } | 7370 | } |
| 6967 | switch (ip.indexToKey(ty.toIntern())) { | 7371 | } else if (!isByRef(ty, zcu)) { |
| 6968 | .struct_type => { | 7372 | const llvm_ty = try o.lowerType(ty, .as_value); |
| 6969 | const size = ty.abiSize(zcu); | 7373 | if (it.types_buffer[0] == llvm_ty or |
| 6970 | assert(@divCeil(size, 8) == types_index); | 7374 | (it.types_buffer[0] == .i64 and llvm_ty.isPointer(&o.builder))) |
| 6971 | if (size % 8 > 0) { | 7375 | { |
| 6972 | it.types_buffer[types_index - 1] = | 7376 | it.zig_index += 1; |
| 6973 | try it.object.builder.intType(@intCast(size % 8 * 8)); | 7377 | it.llvm_index += 1; |
| 6974 | } | 7378 | return .byval; |
| 6975 | }, | ||
| 6976 | else => {}, | ||
| 6977 | } | 7379 | } |
| 6978 | } | 7380 | } |
| 6979 | it.offsets_buffer[types_index] = offset; | 7381 | it.offsets_buffer[types_len] = 8 * classes_len; |
| 6980 | it.types_len = types_index; | 7382 | it.types_len = types_len; |
| 6981 | it.llvm_index += types_index; | 7383 | it.llvm_index += types_len; |
| 6982 | it.zig_index += 1; | 7384 | it.zig_index += 1; |
| 6983 | return .multiple_llvm_types; | 7385 | return .multiple_llvm_types; |
| 6984 | } | 7386 | } |
| 6985 | }; | 7387 | }; |
| 6986 | pub fn iterateParamTypes(object: *Object, fn_info: InternPool.Key.FuncType) ParamTypeIterator { | 7388 | pub fn iterateParamTypes( |
| 7389 | object: *Object, | ||
| 7390 | cc: std.lang.CallingConvention, | ||
| 7391 | param_types: []const InternPool.Index, | ||
| 7392 | ) ParamTypeIterator { | ||
| 6987 | return .{ | 7393 | return .{ |
| 6988 | .object = object, | 7394 | .object = object, |
| 6989 | .fn_info = fn_info, | 7395 | .cc = cc, |
| 7396 | .param_types = param_types, | ||
| 6990 | .zig_index = 0, | 7397 | .zig_index = 0, |
| 6991 | .llvm_index = 0, | 7398 | .llvm_index = 0, |
| 6992 | .types_len = undefined, | 7399 | .types_len = undefined, |
| 6993 | .types_buffer = undefined, | 7400 | .types_buffer = undefined, |
| 6994 | .offsets_buffer = undefined, | 7401 | .offsets_buffer = undefined, |
| 6995 | .byval_attr = false, | 7402 | .byval_attr = null, |
| 6996 | }; | 7403 | }; |
| 6997 | } | 7404 | } |
| 6998 | 7405 | ||
| ... | @@ -7017,54 +7424,68 @@ pub const FnReturnStrat = union(enum) { | ... | @@ -7017,54 +7424,68 @@ pub const FnReturnStrat = union(enum) { |
| 7017 | /// In order to support the C calling convention, some return types need to be lowered | 7424 | /// In order to support the C calling convention, some return types need to be lowered |
| 7018 | /// completely differently in the function prototype to honor the C ABI, and then | 7425 | /// completely differently in the function prototype to honor the C ABI, and then |
| 7019 | /// be effectively bitcasted to the actual return type. | 7426 | /// be effectively bitcasted to the actual return type. |
| 7020 | pub fn fnReturnStrat(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!FnReturnStrat { | 7427 | pub fn fnReturnStrat(o: *Object, cc: std.lang.CallingConvention, ret_ty: Type) Allocator.Error!FnReturnStrat { |
| 7021 | const zcu = o.zcu; | 7428 | const zcu = o.zcu; |
| 7022 | const ret_ty: Type = .fromInterned(fn_info.return_type); | ||
| 7023 | ret_ty.assertHasLayout(zcu); | 7429 | ret_ty.assertHasLayout(zcu); |
| 7024 | if (!ret_ty.hasRuntimeBits(zcu)) return .void; | 7430 | if (!ret_ty.hasRuntimeBits(zcu)) return .void; |
| 7025 | switch (fn_info.cc) { | 7431 | return switch (cc) { |
| 7026 | .@"inline" => unreachable, | 7432 | .@"inline" => unreachable, |
| 7027 | .auto => { | 7433 | .auto => { |
| 7028 | if (isByRef(ret_ty, zcu)) return .sret; | 7434 | // Match the c calling convention in some cases to avoid llvm bugs. |
| 7029 | |||
| 7030 | const target = zcu.getTarget(); | 7435 | const target = zcu.getTarget(); |
| 7031 | if (target.cpu.arch.isX86() and | 7436 | if (target.cpu.arch == .x86_64 and ret_ty.isVector(zcu) and ret_ty.childType(zcu).toIntern() == .bool_type) return switch (ret_ty.vectorLen(zcu)) { |
| 7032 | !target.cpu.has(.x86, .avx512f) and | 7437 | 0 => .void, |
| 7033 | ret_ty.totalVectorBits(zcu) >= 512) | 7438 | 1...8 => .{ .mem_cast = .i8 }, |
| 7034 | { | 7439 | 9...16 => .{ .mem_cast = .i16 }, |
| 7035 | // As of LLVM 18, passing a vector byval with fastcc that is 512 bits or more returns | 7440 | 17...32 => .{ .mem_cast = .i32 }, |
| 7036 | // "512-bit vector arguments require 'avx512f' for AVX512" | 7441 | 33...64 => .{ .mem_cast = .double }, |
| 7037 | return .sret; | 7442 | else => .by_val, |
| 7038 | } | 7443 | }; |
| 7039 | 7444 | return if (isByRef(ret_ty, zcu)) .sret else .by_val; | |
| 7040 | return .by_val; | ||
| 7041 | }, | 7445 | }, |
| 7042 | .x86_64_sysv, .x86_64_x32 => return lowerSystemVFnRetTy(o, fn_info), | ||
| 7043 | .x86_64_win => return lowerWin64FnRetTy(o, fn_info), | ||
| 7044 | .x86_stdcall => if (isScalar(zcu, ret_ty)) { | ||
| 7045 | assert(!isByRef(ret_ty, zcu)); | ||
| 7046 | return .by_val; | ||
| 7047 | } else return .sret, | ||
| 7048 | .x86_fastcall => return lowerX86FastcallFnRetTy(o, zcu, ret_ty), | ||
| 7049 | .x86_sysv, .x86_win => return if (isByRef(ret_ty, zcu)) .sret else .by_val, | ||
| 7050 | .aarch64_aapcs, .aarch64_aapcs_darwin, .aarch64_aapcs_win => switch (aarch64_c_abi.classifyType(ret_ty, zcu)) { | 7446 | .aarch64_aapcs, .aarch64_aapcs_darwin, .aarch64_aapcs_win => switch (aarch64_c_abi.classifyType(ret_ty, zcu)) { |
| 7051 | .memory => return .sret, | 7447 | .memory => .sret, |
| 7052 | .float_array, .byval => return .forceByVal(o, ret_ty), | 7448 | .float_array, .byval => .forceByVal(o, ret_ty), |
| 7053 | .integer => return .{ .mem_cast = .i64 }, | 7449 | .integer => .{ .mem_cast = .i64 }, |
| 7054 | .double_integer => return .{ .mem_cast = try o.builder.arrayType(2, .i64) }, | 7450 | .double_integer => .{ .mem_cast = try o.builder.arrayType(2, .i64) }, |
| 7055 | }, | 7451 | }, |
| 7056 | .arm_aapcs, .arm_aapcs_vfp => switch (arm_c_abi.classifyType(ret_ty, zcu, .ret)) { | 7452 | .arm_aapcs, .arm_aapcs_vfp => switch (arm_c_abi.classifyType(ret_ty, zcu, .ret)) { |
| 7057 | .memory, .i64_array => return .sret, | 7453 | .memory, .i64_array => .sret, |
| 7058 | .i32_array => |len| return if (len == 1) .{ .mem_cast = .i32 } else .sret, | 7454 | .i32_array => |len| if (len == 1) .{ .mem_cast = .i32 } else .sret, |
| 7059 | .byval => return .forceByVal(o, ret_ty), | 7455 | .byval => .forceByVal(o, ret_ty), |
| 7456 | }, | ||
| 7457 | .loongarch32_ilp32, .loongarch64_lp64 => switch (loongarch_c_abi.classifyType(ret_ty, zcu)) { | ||
| 7458 | .ignored => .void, | ||
| 7459 | .gar, .far => .by_val, | ||
| 7460 | .member => |member_ty| .{ .mem_cast = try o.lowerType(member_ty, .as_value) }, | ||
| 7461 | .member_pair => |member_tys| .{ .mem_cast = try o.builder.structType(.normal, &.{ | ||
| 7462 | try o.lowerType(member_tys[0], .as_value), | ||
| 7463 | try o.lowerType(member_tys[1], .as_value), | ||
| 7464 | }) }, | ||
| 7465 | .memory_gar => .{ .mem_cast = switch (cc) { | ||
| 7466 | else => unreachable, | ||
| 7467 | .loongarch32_ilp32 => .i32, | ||
| 7468 | .loongarch64_lp64 => .i64, | ||
| 7469 | } }, | ||
| 7470 | .memory_gar_pair => .{ .mem_cast = try o.builder.arrayType(2, switch (cc) { | ||
| 7471 | else => unreachable, | ||
| 7472 | .loongarch32_ilp32 => .i32, | ||
| 7473 | .loongarch64_lp64 => .i64, | ||
| 7474 | }) }, | ||
| 7475 | .address => .sret, | ||
| 7060 | }, | 7476 | }, |
| 7061 | .mips_o32 => switch (mips_c_abi.classifyType(ret_ty, zcu, .ret)) { | 7477 | .mips_o32 => switch (mips_c_abi.classifyType(ret_ty, zcu, .ret)) { |
| 7062 | .memory, .i32_array => return .sret, | 7478 | .memory, .i32_array => .sret, |
| 7063 | .byval => return .forceByVal(o, ret_ty), | 7479 | .byval => .forceByVal(o, ret_ty), |
| 7064 | }, | 7480 | }, |
| 7481 | .powerpc64_elf_v2 => if (isByRef(ret_ty, zcu)) switch (ret_ty.abiSize(zcu)) { | ||
| 7482 | 1...8 => .{ .mem_cast = try o.builder.intType(@intCast(ret_ty.abiSize(zcu) * 8)) }, | ||
| 7483 | 9...16 => .{ .mem_cast = try o.builder.structType(.normal, &.{ .i64, .i64 }) }, | ||
| 7484 | else => .sret, | ||
| 7485 | } else .by_val, // TODO | ||
| 7065 | .riscv64_lp64, .riscv32_ilp32 => switch (riscv_c_abi.classifyType(ret_ty, zcu)) { | 7486 | .riscv64_lp64, .riscv32_ilp32 => switch (riscv_c_abi.classifyType(ret_ty, zcu)) { |
| 7066 | .memory => return .sret, | 7487 | .memory => .sret, |
| 7067 | .integer => return .{ .mem_cast = try o.builder.intType(@intCast(ret_ty.abiSize(zcu) * 8)) }, | 7488 | .integer => .{ .mem_cast = try o.builder.intType(@intCast(ret_ty.abiSize(zcu) * 8)) }, |
| 7068 | .double_integer => { | 7489 | .double_integer => { |
| 7069 | const integer: Builder.Type = switch (zcu.getTarget().cpu.arch) { | 7490 | const integer: Builder.Type = switch (zcu.getTarget().cpu.arch) { |
| 7070 | .riscv64, .riscv64be => .i64, | 7491 | .riscv64, .riscv64be => .i64, |
| ... | @@ -7073,34 +7494,78 @@ pub fn fnReturnStrat(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Err | ... | @@ -7073,34 +7494,78 @@ pub fn fnReturnStrat(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Err |
| 7073 | }; | 7494 | }; |
| 7074 | return .{ .mem_cast = try o.builder.structType(.normal, &.{ integer, integer }) }; | 7495 | return .{ .mem_cast = try o.builder.structType(.normal, &.{ integer, integer }) }; |
| 7075 | }, | 7496 | }, |
| 7076 | .byval => return .forceByVal(o, ret_ty), | 7497 | .byval => .forceByVal(o, ret_ty), |
| 7077 | .fields => { | 7498 | .fields => { |
| 7078 | var types_len: usize = 0; | 7499 | var types_len: usize = 0; |
| 7079 | var types: [8]Builder.Type = undefined; | 7500 | var types: [8]Builder.Type = undefined; |
| 7080 | for (0..ret_ty.structFieldCount(zcu)) |field_index| { | 7501 | for (0..ret_ty.structFieldCount(zcu)) |field_index| { |
| 7081 | const field_ty = ret_ty.fieldType(field_index, zcu); | 7502 | const field_ty = ret_ty.fieldType(field_index, zcu); |
| 7082 | if (!field_ty.hasRuntimeBits(zcu)) continue; | 7503 | if (!field_ty.hasRuntimeBits(zcu)) continue; |
| 7083 | types[types_len] = try o.lowerType(field_ty, .by_value); | 7504 | types[types_len] = try o.lowerType(field_ty, .as_value); |
| 7084 | types_len += 1; | 7505 | types_len += 1; |
| 7085 | } | 7506 | } |
| 7086 | return .{ .mem_cast = try o.builder.structType(.normal, types[0..types_len]) }; | 7507 | return .{ .mem_cast = try o.builder.structType(.normal, types[0..types_len]) }; |
| 7087 | }, | 7508 | }, |
| 7088 | }, | 7509 | }, |
| 7089 | .wasm_mvp => switch (wasm_c_abi.classifyType(ret_ty, zcu)) { | 7510 | .s390x_sysv, .s390x_sysv_vx => switch (s390x_c_abi.classifyType(ret_ty, .ret, zcu)) { |
| 7511 | .none => .void, | ||
| 7512 | .double_or_float, .vector, .simple => .by_val, | ||
| 7513 | .simple_aggregate => unreachable, | ||
| 7514 | .pointer => .sret, | ||
| 7515 | }, | ||
| 7516 | .wasm_mvp => switch (wasm_c_abi.classifyTypeForLlvm(ret_ty, zcu)) { | ||
| 7090 | .direct => |scalar_ty| if (scalar_ty.toIntern() == ret_ty.toIntern()) { | 7517 | .direct => |scalar_ty| if (scalar_ty.toIntern() == ret_ty.toIntern()) { |
| 7091 | assert(!isByRef(ret_ty, zcu)); | 7518 | assert(!isByRef(ret_ty, zcu)); |
| 7092 | return .by_val; | 7519 | return .by_val; |
| 7093 | } else { | 7520 | } else .{ .mem_cast = try o.lowerType(scalar_ty, .as_value) }, |
| 7094 | return .{ .mem_cast = try o.lowerType(scalar_ty, .by_value) }; | 7521 | .indirect => .sret, |
| 7095 | }, | ||
| 7096 | .indirect => return .sret, | ||
| 7097 | }, | 7522 | }, |
| 7523 | .x86_stdcall => if (isScalar(zcu, ret_ty)) { | ||
| 7524 | assert(!isByRef(ret_ty, zcu)); | ||
| 7525 | return .by_val; | ||
| 7526 | } else .sret, | ||
| 7527 | .x86_fastcall => fnReturnStrat_x86_fastcall(o, zcu, ret_ty), | ||
| 7528 | .x86_sysv, .x86_win, .x86_mingw => if (isByRef(ret_ty, zcu)) { | ||
| 7529 | switch (cc) { | ||
| 7530 | else => unreachable, | ||
| 7531 | .x86_sysv => return .sret, | ||
| 7532 | .x86_win => {}, | ||
| 7533 | .x86_mingw => { | ||
| 7534 | var items_buf: [1]codegen.FlattenedItem = undefined; | ||
| 7535 | if (codegen.flattenType(&items_buf, ret_ty, zcu, .{})) |items| one_float: { | ||
| 7536 | if (items.len != 1 or items[0].offset != 0) break :one_float; | ||
| 7537 | const item_ty = items[0].type orelse break :one_float; | ||
| 7538 | if (!item_ty.isRuntimeFloat()) break :one_float; | ||
| 7539 | return .{ .mem_cast = switch (item_ty.floatBits(zcu.getTarget())) { | ||
| 7540 | else => unreachable, | ||
| 7541 | 16 => .half, | ||
| 7542 | 32 => .float, | ||
| 7543 | 64 => .double, | ||
| 7544 | 80, 128 => break :one_float, | ||
| 7545 | } }; | ||
| 7546 | } | ||
| 7547 | }, | ||
| 7548 | } | ||
| 7549 | return switch (ret_ty.abiSize(zcu)) { | ||
| 7550 | 0 => .void, | ||
| 7551 | 1 => .{ .mem_cast = .i8 }, | ||
| 7552 | 2 => .{ .mem_cast = .i16 }, | ||
| 7553 | 4 => .{ .mem_cast = .i32 }, | ||
| 7554 | 8 => .{ .mem_cast = .i64 }, | ||
| 7555 | else => .sret, | ||
| 7556 | }; | ||
| 7557 | } else if (ret_ty.isAbiInt(zcu) and ret_ty.intInfo(zcu).bits > 64) | ||
| 7558 | .sret | ||
| 7559 | else | ||
| 7560 | .by_val, | ||
| 7561 | .x86_64_sysv, .x86_64_x32 => fnReturnStrat_x86_64_sysv(o, ret_ty), | ||
| 7562 | .x86_64_win => fnReturnStrat_x86_64_win(o, ret_ty), | ||
| 7098 | // TODO investigate other callconvs | 7563 | // TODO investigate other callconvs |
| 7099 | else => return .forceByVal(o, ret_ty), | 7564 | else => .forceByVal(o, ret_ty), |
| 7100 | } | 7565 | }; |
| 7101 | } | 7566 | } |
| 7102 | 7567 | ||
| 7103 | fn lowerX86FastcallFnRetTy(o: *Object, zcu: *Zcu, ty: Type) Allocator.Error!FnReturnStrat { | 7568 | fn fnReturnStrat_x86_fastcall(o: *Object, zcu: *Zcu, ty: Type) Allocator.Error!FnReturnStrat { |
| 7104 | if (isScalar(zcu, ty)) { | 7569 | if (isScalar(zcu, ty)) { |
| 7105 | assert(!isByRef(ty, zcu)); | 7570 | assert(!isByRef(ty, zcu)); |
| 7106 | return .by_val; | 7571 | return .by_val; |
| ... | @@ -7115,9 +7580,8 @@ fn lowerX86FastcallFnRetTy(o: *Object, zcu: *Zcu, ty: Type) Allocator.Error!FnRe | ... | @@ -7115,9 +7580,8 @@ fn lowerX86FastcallFnRetTy(o: *Object, zcu: *Zcu, ty: Type) Allocator.Error!FnRe |
| 7115 | return .sret; | 7580 | return .sret; |
| 7116 | } | 7581 | } |
| 7117 | 7582 | ||
| 7118 | fn lowerWin64FnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!FnReturnStrat { | 7583 | fn fnReturnStrat_x86_64_win(o: *Object, ret_ty: Type) Allocator.Error!FnReturnStrat { |
| 7119 | const zcu = o.zcu; | 7584 | const zcu = o.zcu; |
| 7120 | const ret_ty = Type.fromInterned(fn_info.return_type); | ||
| 7121 | switch (x86_64_abi.classifyWindows(ret_ty, zcu, zcu.getTarget(), .ret)) { | 7585 | switch (x86_64_abi.classifyWindows(ret_ty, zcu, zcu.getTarget(), .ret)) { |
| 7122 | .integer => if (isScalar(zcu, ret_ty)) { | 7586 | .integer => if (isScalar(zcu, ret_ty)) { |
| 7123 | assert(!isByRef(ret_ty, zcu)); | 7587 | assert(!isByRef(ret_ty, zcu)); |
| ... | @@ -7150,78 +7614,65 @@ fn lowerWin64FnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Err | ... | @@ -7150,78 +7614,65 @@ fn lowerWin64FnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Err |
| 7150 | } | 7614 | } |
| 7151 | } | 7615 | } |
| 7152 | 7616 | ||
| 7153 | fn lowerSystemVFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!FnReturnStrat { | 7617 | fn fnReturnStrat_x86_64_sysv(o: *Object, ret_ty: Type) Allocator.Error!FnReturnStrat { |
| 7154 | const zcu = o.zcu; | 7618 | const zcu = o.zcu; |
| 7155 | const ip = &zcu.intern_pool; | ||
| 7156 | const ret_ty = Type.fromInterned(fn_info.return_type); | ||
| 7157 | if (isScalar(zcu, ret_ty)) { | ||
| 7158 | assert(!isByRef(ret_ty, zcu)); | ||
| 7159 | return .by_val; | ||
| 7160 | } | ||
| 7161 | const classes = x86_64_abi.classifySystemV(ret_ty, zcu, zcu.getTarget(), .ret); | 7619 | const classes = x86_64_abi.classifySystemV(ret_ty, zcu, zcu.getTarget(), .ret); |
| 7162 | var types_index: u32 = 0; | ||
| 7163 | var types_buffer: [8]Builder.Type = undefined; | 7620 | var types_buffer: [8]Builder.Type = undefined; |
| 7164 | for (classes) |class| { | 7621 | var types_len: u32 = 0; |
| 7165 | switch (class) { | 7622 | for (classes, 0..) |class, class_index| switch (class) { |
| 7166 | .integer => { | 7623 | .integer => { |
| 7167 | types_buffer[types_index] = .i64; | 7624 | types_buffer[types_len] = try o.builder.intType(@min(8 * ret_ty.abiSize(zcu) - 64 * class_index, 64)); |
| 7168 | types_index += 1; | 7625 | types_len += 1; |
| 7169 | }, | 7626 | }, |
| 7170 | .sse => { | 7627 | .sse => { |
| 7171 | types_buffer[types_index] = .double; | 7628 | types_buffer[types_len] = .double; |
| 7172 | types_index += 1; | 7629 | types_len += 1; |
| 7173 | }, | 7630 | }, |
| 7174 | .sseup => { | 7631 | .sseup => { |
| 7175 | if (types_buffer[types_index - 1] == .double) { | 7632 | if (types_buffer[types_len - 1] == .double) { |
| 7176 | types_buffer[types_index - 1] = .fp128; | 7633 | if (ret_ty.isVector(zcu)) return .by_val; |
| 7177 | } else { | 7634 | types_buffer[types_len - 1] = .fp128; |
| 7178 | types_buffer[types_index] = .double; | 7635 | } else { |
| 7179 | types_index += 1; | 7636 | types_buffer[types_len] = .double; |
| 7180 | } | 7637 | types_len += 1; |
| 7181 | }, | 7638 | } |
| 7182 | .float => { | 7639 | }, |
| 7183 | types_buffer[types_index] = .float; | 7640 | .float => { |
| 7184 | types_index += 1; | 7641 | types_buffer[types_len] = .float; |
| 7185 | }, | 7642 | types_len += 1; |
| 7186 | .float_combine => { | 7643 | }, |
| 7187 | types_buffer[types_index] = try o.builder.vectorType(.normal, 2, .float); | 7644 | .float_combine => { |
| 7188 | types_index += 1; | 7645 | types_buffer[types_len] = try o.builder.vectorType(.normal, 2, .float); |
| 7189 | }, | 7646 | types_len += 1; |
| 7190 | .x87 => { | 7647 | }, |
| 7191 | if (types_index != 0 or classes[2] != .none) return .sret; | 7648 | .x87 => { |
| 7192 | types_buffer[types_index] = .x86_fp80; | 7649 | if (types_len > 0 or classes[2] != .none) return .sret; |
| 7193 | types_index += 1; | 7650 | types_buffer[types_len] = .x86_fp80; |
| 7194 | }, | 7651 | types_len += 1; |
| 7195 | .x87up => continue, | 7652 | }, |
| 7196 | .none => break, | 7653 | .x87up => continue, |
| 7197 | .memory => return .sret, | 7654 | .none => break, |
| 7198 | .win_i128 => unreachable, // windows only | 7655 | .memory => return if (ret_ty.isVector(zcu)) .by_val else .sret, |
| 7199 | .bool_vector_mask, | 7656 | .win_i128 => unreachable, // windows only |
| 7200 | .integer_per_element, | 7657 | .bool_vector_mask, |
| 7201 | .sse_per_element, | 7658 | .integer_per_element, |
| 7202 | .sse_sse_x87_per_qword, | 7659 | .sse_per_element, |
| 7203 | .sse_per_xword, | 7660 | .sse_sse_x87_per_qword, |
| 7204 | .sse_per_yword, | 7661 | .sse_per_xword, |
| 7205 | .sse_per_zword, | 7662 | .sse_per_yword, |
| 7206 | => unreachable, // vectors already handled by `isScalar` above | 7663 | .sse_per_zword, |
| 7207 | } | 7664 | => return .by_val, |
| 7208 | } | 7665 | }; |
| 7209 | const first_non_integer = std.mem.indexOfNone(x86_64_abi.Class, &classes, &.{.integer}); | 7666 | if (types_len > 1) return .{ .mem_cast = try o.builder.structType(.normal, types_buffer[0..types_len]) }; |
| 7210 | if (first_non_integer == null or classes[first_non_integer.?] == .none) { | 7667 | if (!isByRef(ret_ty, zcu)) { |
| 7211 | assert(first_non_integer orelse classes.len == types_index); | 7668 | const llvm_ty = try o.lowerType(ret_ty, .as_value); |
| 7212 | switch (ip.indexToKey(ret_ty.toIntern())) { | 7669 | if (types_buffer[0] == llvm_ty) return .by_val; |
| 7213 | .struct_type => { | 7670 | if (types_buffer[0] == .i64 and llvm_ty.isPointer(&o.builder)) return .by_val; |
| 7214 | const size = ret_ty.abiSize(zcu); | 7671 | if (types_buffer[0] == .double and llvm_ty.isVector(&o.builder) and |
| 7215 | assert(@divCeil(size, 8) == types_index); | 7672 | llvm_ty.vectorLen(&o.builder) == 1 and |
| 7216 | if (size % 8 > 0) { | 7673 | llvm_ty.scalarType(&o.builder) == .double) return .by_val; |
| 7217 | types_buffer[types_index - 1] = try o.builder.intType(@intCast(size % 8 * 8)); | ||
| 7218 | } | ||
| 7219 | }, | ||
| 7220 | else => {}, | ||
| 7221 | } | ||
| 7222 | if (types_index == 1) return .{ .mem_cast = types_buffer[0] }; | ||
| 7223 | } | 7674 | } |
| 7224 | return .{ .mem_cast = try o.builder.structType(.normal, types_buffer[0..types_index]) }; | 7675 | return .{ .mem_cast = types_buffer[0] }; |
| 7225 | } | 7676 | } |
| 7226 | 7677 | ||
| 7227 | /// This function deliberately does not handle `_BitInt` because it typically | 7678 | /// This function deliberately does not handle `_BitInt` because it typically |
| ... | @@ -7234,15 +7685,22 @@ pub fn ccAbiPromoteInt(cc: std.lang.CallingConvention, zcu: *Zcu, ty: Type) ?std | ... | @@ -7234,15 +7685,22 @@ pub fn ccAbiPromoteInt(cc: std.lang.CallingConvention, zcu: *Zcu, ty: Type) ?std |
| 7234 | else => {}, | 7685 | else => {}, |
| 7235 | } | 7686 | } |
| 7236 | 7687 | ||
| 7237 | const ty_tag = ty.zigTypeTag(zcu); | 7688 | const target = zcu.getTarget(); |
| 7238 | const int_info = switch (ty_tag) { | 7689 | const int_info: std.lang.Type.Int = if (ty.toIntern() == .bool_type) |
| 7239 | .bool => Type.u1.intInfo(zcu), | 7690 | .{ .signedness = .unsigned, .bits = 1 } |
| 7240 | else => if (ty.isAbiInt(zcu)) ty.intInfo(zcu) else return null, | 7691 | else if (ty.isAbiInt(zcu)) |
| 7241 | }; | 7692 | ty.intInfo(zcu) |
| 7693 | else if (ty.isRuntimeFloat()) switch (ty.floatBits(target)) { | ||
| 7694 | else => unreachable, | ||
| 7695 | 16, 32, 64 => |bits| switch (std.zig.target.compilerRtFloatAbi(target, bits)) { | ||
| 7696 | .hard => return null, | ||
| 7697 | .soft => .{ .signedness = .unsigned, .bits = bits }, | ||
| 7698 | }, | ||
| 7699 | 80, 128 => return null, | ||
| 7700 | } else return null; | ||
| 7242 | 7701 | ||
| 7243 | assert(int_info.bits == 0 or (int_info.bits == 1 and ty_tag == .bool) or std.math.isPowerOfTwo(int_info.bits)); | 7702 | assert(int_info.bits == 0 or (int_info.bits == 1 and ty.toIntern() == .bool_type) or std.math.isPowerOfTwo(int_info.bits)); |
| 7244 | 7703 | ||
| 7245 | const target = zcu.getTarget(); | ||
| 7246 | return switch (target.cpu.arch) { | 7704 | return switch (target.cpu.arch) { |
| 7247 | .aarch64, | 7705 | .aarch64, |
| 7248 | .aarch64_be, | 7706 | .aarch64_be, |
| ... | @@ -7338,15 +7796,26 @@ pub fn isByRef(ty: Type, zcu: *const Zcu) bool { | ... | @@ -7338,15 +7796,26 @@ pub fn isByRef(ty: Type, zcu: *const Zcu) bool { |
| 7338 | .void, | 7796 | .void, |
| 7339 | .bool, | 7797 | .bool, |
| 7340 | .int, | 7798 | .int, |
| 7341 | .float, | ||
| 7342 | .pointer, | 7799 | .pointer, |
| 7343 | .error_set, | 7800 | .error_set, |
| 7344 | .@"fn", | 7801 | .@"fn", |
| 7345 | .@"enum", | 7802 | .@"enum", |
| 7346 | .vector, | ||
| 7347 | .@"anyframe", | 7803 | .@"anyframe", |
| 7348 | => false, | 7804 | => false, |
| 7349 | 7805 | ||
| 7806 | .float, .vector => { | ||
| 7807 | const target = zcu.getTarget(); | ||
| 7808 | const scalar_ty = ty.scalarType(zcu); | ||
| 7809 | return if (scalar_ty.isRuntimeFloat()) switch (scalar_ty.floatBits(target)) { | ||
| 7810 | else => unreachable, | ||
| 7811 | 16, 32, 64 => false, | ||
| 7812 | 80, 128 => |bits| switch (std.zig.target.compilerRtFloatAbi(target, bits)) { | ||
| 7813 | .hard => false, | ||
| 7814 | .soft => true, | ||
| 7815 | }, | ||
| 7816 | } else false; | ||
| 7817 | }, | ||
| 7818 | |||
| 7350 | .array, | 7819 | .array, |
| 7351 | .frame, | 7820 | .frame, |
| 7352 | => ty.hasRuntimeBits(zcu), | 7821 | => ty.hasRuntimeBits(zcu), |
| ... | @@ -7392,7 +7861,7 @@ fn getAtomicAbiType(fg: *const FuncGen, ty: Type, is_rmw_xchg: bool) Allocator.E | ... | @@ -7392,7 +7861,7 @@ fn getAtomicAbiType(fg: *const FuncGen, ty: Type, is_rmw_xchg: bool) Allocator.E |
| 7392 | fn ptraddConst(fg: *FuncGen, ptr: Builder.Value, offset: u64) Allocator.Error!Builder.Value { | 7861 | fn ptraddConst(fg: *FuncGen, ptr: Builder.Value, offset: u64) Allocator.Error!Builder.Value { |
| 7393 | if (offset == 0) return ptr; | 7862 | if (offset == 0) return ptr; |
| 7394 | const o = fg.object; | 7863 | const o = fg.object; |
| 7395 | const llvm_usize_ty = try o.lowerType(.usize, .by_value); | 7864 | const llvm_usize_ty = try o.lowerType(.usize, .as_value); |
| 7396 | const offset_val = try o.builder.intValue(llvm_usize_ty, offset); | 7865 | const offset_val = try o.builder.intValue(llvm_usize_ty, offset); |
| 7397 | return fg.wip.gep(.inbounds, .i8, ptr, &.{offset_val}, ""); | 7866 | return fg.wip.gep(.inbounds, .i8, ptr, &.{offset_val}, ""); |
| 7398 | } | 7867 | } |
| ... | @@ -7407,12 +7876,19 @@ fn ptraddScaled(fg: *FuncGen, ptr: Builder.Value, index: Builder.Value, scale: u | ... | @@ -7407,12 +7876,19 @@ fn ptraddScaled(fg: *FuncGen, ptr: Builder.Value, index: Builder.Value, scale: u |
| 7407 | return fg.wip.gep(.inbounds, llvm_scale_ty, ptr, &.{index}, ""); | 7876 | return fg.wip.gep(.inbounds, llvm_scale_ty, ptr, &.{index}, ""); |
| 7408 | } | 7877 | } |
| 7409 | 7878 | ||
| 7410 | fn compilerRtIntBits(bits: u16) ?u16 { | 7879 | fn compilerRtPromoteInt(int_info: InternPool.Key.IntType) ?Type { |
| 7411 | inline for (.{ 32, 64, 128 }) |b| { | 7880 | if (int_info.bits <= 32) return switch (int_info.signedness) { |
| 7412 | if (bits <= b) { | 7881 | .signed => .i32, |
| 7413 | return b; | 7882 | .unsigned => .u32, |
| 7414 | } | 7883 | }; |
| 7415 | } | 7884 | if (int_info.bits <= 64) return switch (int_info.signedness) { |
| 7885 | .signed => .i64, | ||
| 7886 | .unsigned => .u64, | ||
| 7887 | }; | ||
| 7888 | if (int_info.bits <= 128) return switch (int_info.signedness) { | ||
| 7889 | .signed => .i128, | ||
| 7890 | .unsigned => .u128, | ||
| 7891 | }; | ||
| 7416 | return null; | 7892 | return null; |
| 7417 | } | 7893 | } |
| 7418 | 7894 | ||
| ... | @@ -7471,13 +7947,21 @@ fn appendConstraints( | ... | @@ -7471,13 +7947,21 @@ fn appendConstraints( |
| 7471 | } | 7947 | } |
| 7472 | 7948 | ||
| 7473 | /// LLVM does not support all relevant intrinsics for all targets, so we | 7949 | /// LLVM does not support all relevant intrinsics for all targets, so we |
| 7474 | /// may need to manually generate a compiler-rt call. | 7950 | /// may need to manually generate a compiler-rt call using a soft type. |
| 7475 | fn intrinsicsAllowed(scalar_ty: Type, target: *const std.Target) bool { | 7951 | fn intrinsicsAllowed(kind: enum { compiler_rt, libc }, scalar_ty: Type, target: *const std.Target) bool { |
| 7476 | return switch (scalar_ty.toIntern()) { | 7952 | if (!scalar_ty.isRuntimeFloat()) return true; |
| 7477 | .f16_type => llvm.backendSupportsF16(target), | 7953 | const bits = scalar_ty.floatBits(target); |
| 7478 | .f80_type => (target.cTypeBitSize(.longdouble) == 80) and llvm.backendSupportsF80(target), | 7954 | // Since upstream musl/msvc do not actually define the *f128 functions, llvm decides |
| 7479 | .f128_type => (target.cTypeBitSize(.longdouble) == 128) and llvm.backendSupportsF128(target), | 7955 | // that it is a much better idea to just emit a call to the entirely wrong function as |
| 7480 | else => true, | 7956 | // a fallback. We wouldn't want any linker errors when trying to perform an operation |
| 7957 | // that isn't actually implemented anywhere, now would we! | ||
| 7958 | if (bits == 128 and target.cpu.arch.isX86() and !target.abi.isGnu()) return switch (kind) { | ||
| 7959 | .compiler_rt => true, | ||
| 7960 | .libc => false, | ||
| 7961 | }; | ||
| 7962 | return switch (std.zig.target.compilerRtFloatAbi(target, bits)) { | ||
| 7963 | .hard => true, | ||
| 7964 | .soft => false, | ||
| 7481 | }; | 7965 | }; |
| 7482 | } | 7966 | } |
| 7483 | 7967 | ||
| ... | @@ -7823,12 +8307,14 @@ const Builder = std.zig.llvm.Builder; | ... | @@ -7823,12 +8307,14 @@ const Builder = std.zig.llvm.Builder; |
| 7823 | const assert = std.debug.assert; | 8307 | const assert = std.debug.assert; |
| 7824 | const math = std.math; | 8308 | const math = std.math; |
| 7825 | 8309 | ||
| 7826 | const x86_64_abi = @import("../x86_64/abi.zig"); | ||
| 7827 | const wasm_c_abi = @import("../wasm/abi.zig"); | ||
| 7828 | const aarch64_c_abi = @import("../aarch64/abi.zig"); | 8310 | const aarch64_c_abi = @import("../aarch64/abi.zig"); |
| 7829 | const arm_c_abi = @import("../arm/abi.zig"); | 8311 | const arm_c_abi = @import("../arm/abi.zig"); |
| 7830 | const riscv_c_abi = @import("../riscv64/abi.zig"); | 8312 | const loongarch_c_abi = @import("../loongarch/abi.zig"); |
| 7831 | const mips_c_abi = @import("../mips/abi.zig"); | 8313 | const mips_c_abi = @import("../mips/abi.zig"); |
| 8314 | const riscv_c_abi = @import("../riscv64/abi.zig"); | ||
| 8315 | const s390x_c_abi = @import("../s390x/abi.zig"); | ||
| 8316 | const wasm_c_abi = @import("../wasm/abi.zig"); | ||
| 8317 | const x86_64_abi = @import("../x86_64/abi.zig"); | ||
| 7832 | 8318 | ||
| 7833 | const Zcu = @import("../../Zcu.zig"); | 8319 | const Zcu = @import("../../Zcu.zig"); |
| 7834 | const Air = @import("../../Air.zig"); | 8320 | const Air = @import("../../Air.zig"); |
src/codegen/llvm/bindings.zig+2| ... | @@ -331,6 +331,8 @@ extern fn ZigLLVMWriteArchive( | ... | @@ -331,6 +331,8 @@ extern fn ZigLLVMWriteArchive( |
| 331 | file_names_ptr: [*]const [*:0]const u8, | 331 | file_names_ptr: [*]const [*:0]const u8, |
| 332 | file_names_len: usize, | 332 | file_names_len: usize, |
| 333 | archive_kind: ArchiveKind, | 333 | archive_kind: ArchiveKind, |
| 334 | err_file_index_out: *usize, | ||
| 335 | err_msg_out: *[*:0]u8, | ||
| 334 | ) bool; | 336 | ) bool; |
| 335 | 337 | ||
| 336 | pub const ParseCommandLineOptions = ZigLLVMParseCommandLineOptions; | 338 | pub const ParseCommandLineOptions = ZigLLVMParseCommandLineOptions; |
src/codegen/loongarch/abi.zig created+133| ... | @@ -0,0 +1,133 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const InternPool = @import("../../InternPool.zig"); | ||
| 3 | const Type = @import("../../Type.zig"); | ||
| 4 | const Zcu = @import("../../Zcu.zig"); | ||
| 5 | |||
| 6 | pub const Class = union(enum) { | ||
| 7 | ignored, | ||
| 8 | gar, | ||
| 9 | far, | ||
| 10 | member: Type, | ||
| 11 | member_pair: [2]Type, | ||
| 12 | memory_gar, | ||
| 13 | memory_gar_pair, | ||
| 14 | address, | ||
| 15 | |||
| 16 | fn combineMember(container_class: Class, member_class: Class, member_ty: Type) Class { | ||
| 17 | const second_member_ty = switch (member_class) { | ||
| 18 | .ignored => return container_class, | ||
| 19 | .gar, .far => member_ty, | ||
| 20 | .member => |second_member_ty| second_member_ty, | ||
| 21 | .member_pair, .memory_gar, .memory_gar_pair, .address => return .address, | ||
| 22 | }; | ||
| 23 | return switch (container_class) { | ||
| 24 | .ignored => .{ .member = second_member_ty }, | ||
| 25 | .gar, .far, .memory_gar, .memory_gar_pair => unreachable, | ||
| 26 | .member => |first_member_ty| .{ .member_pair = .{ first_member_ty, second_member_ty } }, | ||
| 27 | .member_pair, .address => .address, | ||
| 28 | }; | ||
| 29 | } | ||
| 30 | }; | ||
| 31 | |||
| 32 | pub fn classifyType(ty: Type, zcu: *Zcu) Class { | ||
| 33 | return Classifier.init(zcu).classifyType(ty); | ||
| 34 | } | ||
| 35 | |||
| 36 | const Classifier = struct { | ||
| 37 | zcu: *Zcu, | ||
| 38 | target: *const std.Target, | ||
| 39 | grlen: u8, | ||
| 40 | frlen: u8, | ||
| 41 | |||
| 42 | fn init(zcu: *Zcu) Classifier { | ||
| 43 | const target = zcu.getTarget(); | ||
| 44 | return .{ | ||
| 45 | .zcu = zcu, | ||
| 46 | .target = target, | ||
| 47 | .grlen = switch (target.cpu.arch) { | ||
| 48 | else => unreachable, | ||
| 49 | .loongarch32 => 32, | ||
| 50 | .loongarch64 => 64, | ||
| 51 | }, | ||
| 52 | .frlen = if (target.cpu.has(.loongarch, .d)) | ||
| 53 | 64 | ||
| 54 | else if (target.cpu.has(.loongarch, .f)) | ||
| 55 | 32 | ||
| 56 | else | ||
| 57 | 0, | ||
| 58 | }; | ||
| 59 | } | ||
| 60 | |||
| 61 | fn classifyType(c: Classifier, ty: Type) Class { | ||
| 62 | switch (ty.zigTypeTag(c.zcu)) { | ||
| 63 | .type, | ||
| 64 | .comptime_float, | ||
| 65 | .comptime_int, | ||
| 66 | .undefined, | ||
| 67 | .null, | ||
| 68 | .error_union, | ||
| 69 | .error_set, | ||
| 70 | .@"fn", | ||
| 71 | .@"opaque", | ||
| 72 | .frame, | ||
| 73 | .@"anyframe", | ||
| 74 | .enum_literal, | ||
| 75 | .spirv, | ||
| 76 | => unreachable, | ||
| 77 | .void, .noreturn => return .ignored, | ||
| 78 | .bool => return .gar, | ||
| 79 | .int, .@"enum" => { | ||
| 80 | const bits = ty.intInfo(c.zcu).bits; | ||
| 81 | if (bits == 0) return .ignored; | ||
| 82 | if (bits <= c.grlen) return .gar; | ||
| 83 | if (bits <= 2 * c.grlen) return .memory_gar_pair; | ||
| 84 | return .address; | ||
| 85 | }, | ||
| 86 | .float => { | ||
| 87 | const bits = ty.floatBits(c.target); | ||
| 88 | if (bits <= c.frlen) return .far; | ||
| 89 | if (bits <= c.grlen) return .gar; | ||
| 90 | if (bits <= 2 * c.grlen) return .memory_gar_pair; | ||
| 91 | return .address; | ||
| 92 | }, | ||
| 93 | .pointer, .optional => return .gar, | ||
| 94 | .array => { | ||
| 95 | var class: Class = .ignored; | ||
| 96 | const elem_ty = ty.childType(c.zcu); | ||
| 97 | const elem_class = c.classifyType(elem_ty); | ||
| 98 | for (0..std.math.lossyCast(usize, ty.arrayLenIncludingSentinel(c.zcu))) |_| { | ||
| 99 | class = class.combineMember(elem_class, elem_ty); | ||
| 100 | if (class == .address) break; | ||
| 101 | } | ||
| 102 | if (class != .address) return class; | ||
| 103 | }, | ||
| 104 | .@"struct" => switch (ty.containerLayout(c.zcu)) { | ||
| 105 | .auto => unreachable, | ||
| 106 | .@"extern" => { | ||
| 107 | var class: Class = .ignored; | ||
| 108 | var field_it: InternPool.LoadedStructType.RuntimeOrderIterator = if (c.zcu.typeToStruct(ty)) |loaded_struct| | ||
| 109 | loaded_struct.iterateRuntimeOrder(&c.zcu.intern_pool) | ||
| 110 | else | ||
| 111 | .{ .runtime_order = null, .fields_len = ty.structFieldCount(c.zcu), .next_index = 0 }; | ||
| 112 | while (field_it.next()) |field_index| { | ||
| 113 | const field_ty = ty.fieldType(field_index, c.zcu); | ||
| 114 | class = class.combineMember(c.classifyType(field_ty), field_ty); | ||
| 115 | if (class == .address) break; | ||
| 116 | } | ||
| 117 | if (class != .address) return class; | ||
| 118 | }, | ||
| 119 | .@"packed" => return c.classifyType(ty.backingIntType(c.zcu)), | ||
| 120 | }, | ||
| 121 | .@"union" => switch (ty.containerLayout(c.zcu)) { | ||
| 122 | .auto => unreachable, | ||
| 123 | .@"extern" => {}, | ||
| 124 | .@"packed" => return c.classifyType(ty.backingIntType(c.zcu)), | ||
| 125 | }, | ||
| 126 | .vector => {}, | ||
| 127 | } | ||
| 128 | const size = ty.abiSize(c.zcu); | ||
| 129 | if (size <= @divExact(c.grlen, 8)) return .memory_gar; | ||
| 130 | if (size <= @divExact(2 * c.grlen, 8)) return .memory_gar_pair; | ||
| 131 | return .address; | ||
| 132 | } | ||
| 133 | }; | ||
src/codegen/mips/abi.zig+8-1| ... | @@ -38,7 +38,14 @@ pub fn classifyType(ty: Type, zcu: *Zcu, ctx: Context) Class { | ... | @@ -38,7 +38,14 @@ pub fn classifyType(ty: Type, zcu: *Zcu, ctx: Context) Class { |
| 38 | return .byval; | 38 | return .byval; |
| 39 | }, | 39 | }, |
| 40 | .bool => return .byval, | 40 | .bool => return .byval, |
| 41 | .float => return .byval, | 41 | .float => return switch (ty.floatBits(target)) { |
| 42 | else => unreachable, | ||
| 43 | 16, 32, 64 => .byval, | ||
| 44 | 80, 128 => switch (max_direct_size) { | ||
| 45 | else => unreachable, | ||
| 46 | 64 => .memory, | ||
| 47 | }, | ||
| 48 | }, | ||
| 42 | .int, .@"enum", .error_set => { | 49 | .int, .@"enum", .error_set => { |
| 43 | return .byval; | 50 | return .byval; |
| 44 | }, | 51 | }, |
src/codegen/riscv64/CodeGen.zig+8-8| ... | @@ -5036,7 +5036,7 @@ fn airRet(func: *Func, inst: Air.Inst.Index, safety: bool) !void { | ... | @@ -5036,7 +5036,7 @@ fn airRet(func: *Func, inst: Air.Inst.Index, safety: bool) !void { |
| 5036 | .register_pair, | 5036 | .register_pair, |
| 5037 | => { | 5037 | => { |
| 5038 | if (ret_ty.isVector(zcu)) { | 5038 | if (ret_ty.isVector(zcu)) { |
| 5039 | const bit_size = ret_ty.totalVectorBits(zcu); | 5039 | const bit_size = ret_ty.bitSize(zcu); |
| 5040 | 5040 | ||
| 5041 | // set the vtype to hold the entire vector's contents in a single element | 5041 | // set the vtype to hold the entire vector's contents in a single element |
| 5042 | try func.setVl(.zero, 0, .{ | 5042 | try func.setVl(.zero, 0, .{ |
| ... | @@ -6235,8 +6235,8 @@ fn airAsm(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -6235,8 +6235,8 @@ fn airAsm(func: *Func, inst: Air.Inst.Index) !void { |
| 6235 | next_op: for (&ops) |*op| { | 6235 | next_op: for (&ops) |*op| { |
| 6236 | const op_str = while (!last_op) { | 6236 | const op_str = while (!last_op) { |
| 6237 | const full_str = op_it.next() orelse break :next_op; | 6237 | const full_str = op_it.next() orelse break :next_op; |
| 6238 | const code_str = if (mem.indexOfScalar(u8, full_str, '#') orelse | 6238 | const code_str = if (mem.findScalar(u8, full_str, '#') orelse |
| 6239 | mem.indexOf(u8, full_str, "//")) |comment| | 6239 | mem.find(u8, full_str, "//")) |comment| |
| 6240 | code: { | 6240 | code: { |
| 6241 | last_op = true; | 6241 | last_op = true; |
| 6242 | break :code full_str[0..comment]; | 6242 | break :code full_str[0..comment]; |
| ... | @@ -6250,7 +6250,7 @@ fn airAsm(func: *Func, inst: Air.Inst.Index) !void { | ... | @@ -6250,7 +6250,7 @@ fn airAsm(func: *Func, inst: Air.Inst.Index) !void { |
| 6250 | } else if (std.fmt.parseInt(i12, op_str, 10)) |int| { | 6250 | } else if (std.fmt.parseInt(i12, op_str, 10)) |int| { |
| 6251 | op.* = .{ .imm = Immediate.s(int) }; | 6251 | op.* = .{ .imm = Immediate.s(int) }; |
| 6252 | } else |_| if (mem.startsWith(u8, op_str, "%[")) { | 6252 | } else |_| if (mem.startsWith(u8, op_str, "%[")) { |
| 6253 | const mod_index = mem.indexOf(u8, op_str, "]@"); | 6253 | const mod_index = mem.find(u8, op_str, "]@"); |
| 6254 | const modifier = if (mod_index) |index| | 6254 | const modifier = if (mod_index) |index| |
| 6255 | op_str[index + "]@".len ..] | 6255 | op_str[index + "]@".len ..] |
| 6256 | else | 6256 | else |
| ... | @@ -6871,7 +6871,7 @@ fn genSetReg(func: *Func, ty: Type, reg: Register, src_mcv: MCValue) InnerError! | ... | @@ -6871,7 +6871,7 @@ fn genSetReg(func: *Func, ty: Type, reg: Register, src_mcv: MCValue) InnerError! |
| 6871 | // size to the total size of the vector, and vmv.x.s will work then | 6871 | // size to the total size of the vector, and vmv.x.s will work then |
| 6872 | if (src_reg.class() == .vector) { | 6872 | if (src_reg.class() == .vector) { |
| 6873 | try func.setVl(.zero, 0, .{ | 6873 | try func.setVl(.zero, 0, .{ |
| 6874 | .vsew = switch (ty.totalVectorBits(zcu)) { | 6874 | .vsew = switch (ty.bitSize(zcu)) { |
| 6875 | 8 => .@"8", | 6875 | 8 => .@"8", |
| 6876 | 16 => .@"16", | 6876 | 16 => .@"16", |
| 6877 | 32 => .@"32", | 6877 | 32 => .@"32", |
| ... | @@ -8339,9 +8339,9 @@ fn resolveCallingConventionValues( | ... | @@ -8339,9 +8339,9 @@ fn resolveCallingConventionValues( |
| 8339 | fn wantSafety(func: *Func) bool { | 8339 | fn wantSafety(func: *Func) bool { |
| 8340 | return switch (func.mod.optimize_mode) { | 8340 | return switch (func.mod.optimize_mode) { |
| 8341 | .Debug => true, | 8341 | .Debug => true, |
| 8342 | .ReleaseSafe => true, | 8342 | .safe => true, |
| 8343 | .ReleaseFast => false, | 8343 | .fast => false, |
| 8344 | .ReleaseSmall => false, | 8344 | .small => false, |
| 8345 | }; | 8345 | }; |
| 8346 | } | 8346 | } |
| 8347 | 8347 |
src/codegen/riscv64/abi.zig+10-2| ... | @@ -56,12 +56,20 @@ pub fn classifyType(ty: Type, zcu: *Zcu) Class { | ... | @@ -56,12 +56,20 @@ pub fn classifyType(ty: Type, zcu: *Zcu) Class { |
| 56 | return .integer; | 56 | return .integer; |
| 57 | }, | 57 | }, |
| 58 | .bool => return .integer, | 58 | .bool => return .integer, |
| 59 | .float => return .byval, | ||
| 60 | .int, .@"enum", .error_set => { | 59 | .int, .@"enum", .error_set => { |
| 61 | const bit_size = ty.bitSize(zcu); | 60 | const bit_size = ty.bitSize(zcu); |
| 62 | if (bit_size > max_byval_size) return .memory; | 61 | if (bit_size > max_byval_size) return .memory; |
| 63 | return .byval; | 62 | return .byval; |
| 64 | }, | 63 | }, |
| 64 | .float => return switch (ty.floatBits(target)) { | ||
| 65 | else => unreachable, | ||
| 66 | 16, 32, 64, 128 => .byval, | ||
| 67 | 80 => switch (max_byval_size) { | ||
| 68 | else => unreachable, | ||
| 69 | 64 => .memory, | ||
| 70 | 128 => .double_integer, | ||
| 71 | }, | ||
| 72 | }, | ||
| 65 | .vector => { | 73 | .vector => { |
| 66 | const bit_size = ty.bitSize(zcu); | 74 | const bit_size = ty.bitSize(zcu); |
| 67 | if (bit_size > max_byval_size) return .memory; | 75 | if (bit_size > max_byval_size) return .memory; |
| ... | @@ -190,7 +198,7 @@ pub fn classifySystem(ty: Type, zcu: *Zcu) [8]SystemClass { | ... | @@ -190,7 +198,7 @@ pub fn classifySystem(ty: Type, zcu: *Zcu) [8]SystemClass { |
| 190 | }, | 198 | }, |
| 191 | .vector => { | 199 | .vector => { |
| 192 | // we pass vectors through integer registers if they are small enough to fit. | 200 | // we pass vectors through integer registers if they are small enough to fit. |
| 193 | const vec_bits = ty.totalVectorBits(zcu); | 201 | const vec_bits = ty.bitSize(zcu); |
| 194 | if (vec_bits <= 64) { | 202 | if (vec_bits <= 64) { |
| 195 | result[0] = .integer; | 203 | result[0] = .integer; |
| 196 | return result; | 204 | return result; |
src/codegen/riscv64/encoding.zig+1-1| ... | @@ -498,7 +498,7 @@ pub const Instruction = union(Lir.Format) { | ... | @@ -498,7 +498,7 @@ pub const Instruction = union(Lir.Format) { |
| 498 | extra: u32, | 498 | extra: u32, |
| 499 | 499 | ||
| 500 | comptime { | 500 | comptime { |
| 501 | for (std.meta.fieldTypes(Instruction)) |field_type| { | 501 | for (@typeInfo(Instruction).@"union".field_types) |field_type| { |
| 502 | assert(@bitSizeOf(field_type) == 32); | 502 | assert(@bitSizeOf(field_type) == 32); |
| 503 | } | 503 | } |
| 504 | } | 504 | } |
src/codegen/s390x/abi.zig created+85| ... | @@ -0,0 +1,85 @@ | ||
| 1 | const assert = std.debug.assert; | ||
| 2 | const std = @import("std"); | ||
| 3 | const InternPool = @import("../../InternPool.zig"); | ||
| 4 | const Type = @import("../../Type.zig"); | ||
| 5 | const Zcu = @import("../../Zcu.zig"); | ||
| 6 | |||
| 7 | pub const Context = enum { ret, arg }; | ||
| 8 | |||
| 9 | pub const Class = enum { | ||
| 10 | none, | ||
| 11 | double_or_float, | ||
| 12 | vector, | ||
| 13 | simple, | ||
| 14 | simple_aggregate, | ||
| 15 | pointer, | ||
| 16 | }; | ||
| 17 | |||
| 18 | pub fn classifyType(ty: Type, context: Context, zcu: *Zcu) Class { | ||
| 19 | tag: switch (ty.zigTypeTag(zcu)) { | ||
| 20 | .type, | ||
| 21 | .comptime_float, | ||
| 22 | .comptime_int, | ||
| 23 | .undefined, | ||
| 24 | .null, | ||
| 25 | .error_union, | ||
| 26 | .error_set, | ||
| 27 | .@"fn", | ||
| 28 | .@"opaque", | ||
| 29 | .frame, | ||
| 30 | .@"anyframe", | ||
| 31 | .enum_literal, | ||
| 32 | .spirv, | ||
| 33 | => unreachable, | ||
| 34 | .void, .noreturn => return .none, | ||
| 35 | .bool => return .simple, | ||
| 36 | .int, .@"enum" => return switch (ty.intInfo(zcu).bits) { | ||
| 37 | 0 => .none, | ||
| 38 | 1...64 => .simple, | ||
| 39 | else => .pointer, | ||
| 40 | }, | ||
| 41 | .float => switch (ty.floatBits(zcu.getTarget())) { | ||
| 42 | else => unreachable, | ||
| 43 | 16, 32, 64 => return .double_or_float, | ||
| 44 | 80 => {}, | ||
| 45 | 128 => return .pointer, | ||
| 46 | }, | ||
| 47 | .pointer, .optional => return .simple, | ||
| 48 | .array => {}, | ||
| 49 | .@"struct", .@"union" => |tag| switch (ty.containerLayout(zcu)) { | ||
| 50 | .auto => unreachable, | ||
| 51 | .@"extern" => switch (context) { | ||
| 52 | .ret => {}, | ||
| 53 | .arg => { | ||
| 54 | var class: Class = .none; | ||
| 55 | for (0..switch (tag) { | ||
| 56 | else => unreachable, | ||
| 57 | .@"struct" => ty.structFieldCount(zcu), | ||
| 58 | .@"union" => ty.unionTagTypeHypothetical(zcu).enumFieldCount(zcu), | ||
| 59 | }) |field_index| { | ||
| 60 | switch (tag) { | ||
| 61 | else => unreachable, | ||
| 62 | .@"struct" => if (ty.structFieldIsComptime(field_index, zcu)) continue, | ||
| 63 | .@"union" => {}, | ||
| 64 | } | ||
| 65 | const field_class = classifyType(ty.fieldType(field_index, zcu), context, zcu); | ||
| 66 | if (field_class == .none) continue; | ||
| 67 | if (class != .none) break :tag; | ||
| 68 | class = field_class; | ||
| 69 | } | ||
| 70 | return class; | ||
| 71 | }, | ||
| 72 | }, | ||
| 73 | .@"packed" => return classifyType(ty.backingIntType(zcu), context, zcu), | ||
| 74 | }, | ||
| 75 | .vector => return if (ty.abiSize(zcu) <= 16) .vector else .pointer, | ||
| 76 | } | ||
| 77 | return switch (ty.abiSize(zcu)) { | ||
| 78 | 0 => .none, | ||
| 79 | 1, 2, 4, 8 => switch (context) { | ||
| 80 | .ret => .pointer, | ||
| 81 | .arg => .simple_aggregate, | ||
| 82 | }, | ||
| 83 | else => .pointer, | ||
| 84 | }; | ||
| 85 | } | ||
src/codegen/sparc64/CodeGen.zig+3-3| ... | @@ -4764,9 +4764,9 @@ fn truncRegister( | ... | @@ -4764,9 +4764,9 @@ fn truncRegister( |
| 4764 | fn wantSafety(self: *Self) bool { | 4764 | fn wantSafety(self: *Self) bool { |
| 4765 | return switch (self.bin_file.comp.root_mod.optimize_mode) { | 4765 | return switch (self.bin_file.comp.root_mod.optimize_mode) { |
| 4766 | .Debug => true, | 4766 | .Debug => true, |
| 4767 | .ReleaseSafe => true, | 4767 | .safe => true, |
| 4768 | .ReleaseFast => false, | 4768 | .fast => false, |
| 4769 | .ReleaseSmall => false, | 4769 | .small => false, |
| 4770 | }; | 4770 | }; |
| 4771 | } | 4771 | } |
| 4772 | 4772 |
src/codegen/spirv/Assembler.zig+39-38| ... | @@ -24,8 +24,9 @@ inst: struct { | ... | @@ -24,8 +24,9 @@ inst: struct { |
| 24 | opcode: Opcode = undefined, | 24 | opcode: Opcode = undefined, |
| 25 | operands: std.ArrayList(Operand) = .empty, | 25 | operands: std.ArrayList(Operand) = .empty, |
| 26 | string_bytes: std.ArrayList(u8) = .empty, | 26 | string_bytes: std.ArrayList(u8) = .empty, |
| 27 | inst_offset: u32 = 0, | ||
| 27 | 28 | ||
| 28 | fn result(ass: @This()) ?AsmValue.Ref { | 29 | fn result(ass: *const @This()) ?AsmValue.Ref { |
| 29 | for (ass.operands.items[0..@min(ass.operands.items.len, 2)]) |op| { | 30 | for (ass.operands.items[0..@min(ass.operands.items.len, 2)]) |op| { |
| 30 | switch (op) { | 31 | switch (op) { |
| 31 | .result_id => |index| return index, | 32 | .result_id => |index| return index, |
| ... | @@ -35,7 +36,7 @@ inst: struct { | ... | @@ -35,7 +36,7 @@ inst: struct { |
| 35 | return null; | 36 | return null; |
| 36 | } | 37 | } |
| 37 | } = .{}, | 38 | } = .{}, |
| 38 | value_map: std.array_hash_map.String(AsmValue) = .{}, | 39 | value_map: std.array_hash_map.String(AsmValue) = .empty, |
| 39 | inst_map: std.array_hash_map.String(void) = .empty, | 40 | inst_map: std.array_hash_map.String(void) = .empty, |
| 40 | 41 | ||
| 41 | const Operand = union(enum) { | 42 | const Operand = union(enum) { |
| ... | @@ -82,7 +83,7 @@ pub fn assemble(ass: *Assembler, src: []const u8) Error!void { | ... | @@ -82,7 +83,7 @@ pub fn assemble(ass: *Assembler, src: []const u8) Error!void { |
| 82 | if (ass.inst_map.count() == 0) { | 83 | if (ass.inst_map.count() == 0) { |
| 83 | const instructions = spec.InstructionSet.core.instructions(); | 84 | const instructions = spec.InstructionSet.core.instructions(); |
| 84 | try ass.inst_map.ensureUnusedCapacity(gpa, @intCast(instructions.len)); | 85 | try ass.inst_map.ensureUnusedCapacity(gpa, @intCast(instructions.len)); |
| 85 | for (spec.InstructionSet.core.instructions(), 0..) |inst, i| { | 86 | for (instructions, 0..) |inst, i| { |
| 86 | const entry = try ass.inst_map.getOrPut(gpa, inst.name); | 87 | const entry = try ass.inst_map.getOrPut(gpa, inst.name); |
| 87 | assert(entry.index == i); | 88 | assert(entry.index == i); |
| 88 | } | 89 | } |
| ... | @@ -114,12 +115,13 @@ fn addError(ass: *Assembler, offset: u32, comptime fmt: []const u8, args: anytyp | ... | @@ -114,12 +115,13 @@ fn addError(ass: *Assembler, offset: u32, comptime fmt: []const u8, args: anytyp |
| 114 | } | 115 | } |
| 115 | 116 | ||
| 116 | fn fail(ass: *Assembler, offset: u32, comptime fmt: []const u8, args: anytype) Error { | 117 | fn fail(ass: *Assembler, offset: u32, comptime fmt: []const u8, args: anytype) Error { |
| 118 | @branchHint(.cold); | ||
| 117 | try ass.addError(offset, fmt, args); | 119 | try ass.addError(offset, fmt, args); |
| 118 | return error.AssembleFail; | 120 | return error.AssembleFail; |
| 119 | } | 121 | } |
| 120 | 122 | ||
| 121 | fn todo(ass: *Assembler, comptime fmt: []const u8, args: anytype) Error { | 123 | fn todo(ass: *Assembler, comptime fmt: []const u8, args: anytype) Error { |
| 122 | return ass.fail(0, "todo: " ++ fmt, args); | 124 | return ass.fail(ass.inst.inst_offset, "todo: " ++ fmt, args); |
| 123 | } | 125 | } |
| 124 | 126 | ||
| 125 | const AsmValue = union(enum) { | 127 | const AsmValue = union(enum) { |
| ... | @@ -177,19 +179,19 @@ fn processInstruction(ass: *Assembler) !void { | ... | @@ -177,19 +179,19 @@ fn processInstruction(ass: *Assembler) !void { |
| 177 | const cg = ass.cg; | 179 | const cg = ass.cg; |
| 178 | const result: AsmValue = switch (ass.inst.opcode) { | 180 | const result: AsmValue = switch (ass.inst.opcode) { |
| 179 | .OpEntryPoint => { | 181 | .OpEntryPoint => { |
| 180 | return ass.fail(ass.currentToken().start, "cannot export entry points in assembly", .{}); | 182 | return ass.fail(ass.inst.inst_offset, "cannot export entry points in assembly", .{}); |
| 181 | }, | 183 | }, |
| 182 | .OpExecutionMode, .OpExecutionModeId => { | 184 | .OpExecutionMode, .OpExecutionModeId => { |
| 183 | return ass.fail(ass.currentToken().start, "cannot set execution mode in assembly", .{}); | 185 | return ass.fail(ass.inst.inst_offset, "cannot set execution mode in assembly", .{}); |
| 184 | }, | 186 | }, |
| 185 | .OpCapability, .OpExtension => { | 187 | .OpCapability, .OpExtension => { |
| 186 | return ass.fail(ass.currentToken().start, "cannot declare capabilities or extensions in assembly; use -mcpu instead", .{}); | 188 | return ass.fail(ass.inst.inst_offset, "cannot declare capabilities or extensions in assembly; use -mcpu instead", .{}); |
| 187 | }, | 189 | }, |
| 188 | .OpExtInstImport => blk: { | 190 | .OpExtInstImport => blk: { |
| 189 | const set_name_offset = ass.inst.operands.items[1].string; | 191 | const set_name_offset = ass.inst.operands.items[1].string; |
| 190 | const set_name = std.mem.sliceTo(ass.inst.string_bytes.items[set_name_offset..], 0); | 192 | const set_name = std.mem.sliceTo(ass.inst.string_bytes.items[set_name_offset..], 0); |
| 191 | const set_tag = std.meta.stringToEnum(spec.InstructionSet, set_name) orelse { | 193 | const set_tag = std.meta.stringToEnum(spec.InstructionSet, set_name) orelse { |
| 192 | return ass.fail(set_name_offset, "unknown instruction set: {s}", .{set_name}); | 194 | return ass.fail(ass.inst.inst_offset, "unknown instruction set: {s}", .{set_name}); |
| 193 | }; | 195 | }; |
| 194 | break :blk .{ .value = try cg.importInstructionSet(set_tag) }; | 196 | break :blk .{ .value = try cg.importInstructionSet(set_tag) }; |
| 195 | }, | 197 | }, |
| ... | @@ -209,9 +211,8 @@ fn processInstruction(ass: *Assembler) !void { | ... | @@ -209,9 +211,8 @@ fn processInstruction(ass: *Assembler) !void { |
| 209 | switch (ass.value_map.values()[result_ref]) { | 211 | switch (ass.value_map.values()[result_ref]) { |
| 210 | .just_declared => ass.value_map.values()[result_ref] = result, | 212 | .just_declared => ass.value_map.values()[result_ref] = result, |
| 211 | else => { | 213 | else => { |
| 212 | // TODO: Improve source location. | ||
| 213 | const name = ass.value_map.keys()[result_ref]; | 214 | const name = ass.value_map.keys()[result_ref]; |
| 214 | return ass.fail(0, "duplicate definition of %{s}", .{name}); | 215 | return ass.fail(ass.inst.inst_offset, "duplicate definition of %{s}", .{name}); |
| 215 | }, | 216 | }, |
| 216 | } | 217 | } |
| 217 | } | 218 | } |
| ... | @@ -229,12 +230,11 @@ fn processTypeInstruction(ass: *Assembler) !AsmValue { | ... | @@ -229,12 +230,11 @@ fn processTypeInstruction(ass: *Assembler) !AsmValue { |
| 229 | 0 => .unsigned, | 230 | 0 => .unsigned, |
| 230 | 1 => .signed, | 231 | 1 => .signed, |
| 231 | else => { | 232 | else => { |
| 232 | // TODO: Improve source location. | 233 | return ass.fail(ass.inst.inst_offset, "{} is not a valid signedness (expected 0 or 1)", .{operands[2].literal32}); |
| 233 | return ass.fail(0, "{} is not a valid signedness (expected 0 or 1)", .{operands[2].literal32}); | ||
| 234 | }, | 234 | }, |
| 235 | }; | 235 | }; |
| 236 | const width = std.math.cast(u16, operands[1].literal32) orelse { | 236 | const width = std.math.cast(u16, operands[1].literal32) orelse { |
| 237 | return ass.fail(0, "int type of {} bits is too large", .{operands[1].literal32}); | 237 | return ass.fail(ass.inst.inst_offset, "int type of {} bits is too large", .{operands[1].literal32}); |
| 238 | }; | 238 | }; |
| 239 | break :blk try cg.intType(signedness, width); | 239 | break :blk try cg.intType(signedness, width); |
| 240 | }, | 240 | }, |
| ... | @@ -243,7 +243,7 @@ fn processTypeInstruction(ass: *Assembler) !AsmValue { | ... | @@ -243,7 +243,7 @@ fn processTypeInstruction(ass: *Assembler) !AsmValue { |
| 243 | switch (bits) { | 243 | switch (bits) { |
| 244 | 16, 32, 64 => {}, | 244 | 16, 32, 64 => {}, |
| 245 | else => { | 245 | else => { |
| 246 | return ass.fail(0, "{} is not a valid bit count for floats (expected 16, 32 or 64)", .{bits}); | 246 | return ass.fail(ass.inst.inst_offset, "{} is not a valid bit count for floats (expected 16, 32 or 64)", .{bits}); |
| 247 | }, | 247 | }, |
| 248 | } | 248 | } |
| 249 | break :blk try cg.floatType(@intCast(bits)); | 249 | break :blk try cg.floatType(@intCast(bits)); |
| ... | @@ -366,38 +366,40 @@ fn processGenericInstruction(ass: *Assembler) !?AsmValue { | ... | @@ -366,38 +366,40 @@ fn processGenericInstruction(ass: *Assembler) !?AsmValue { |
| 366 | 366 | ||
| 367 | var maybe_result_id: ?Id = null; | 367 | var maybe_result_id: ?Id = null; |
| 368 | const first_word = section.instructions.items.len; | 368 | const first_word = section.instructions.items.len; |
| 369 | // At this point we're not quite sure how many operands this instruction is | 369 | |
| 370 | // going to have, so insert 0 and patch up the actual opcode word later. | 370 | // Pre-calculate exact instruction size to avoid per-operand capacity checks. |
| 371 | try section.ensureUnusedCapacity(cg.gpa, 1); | 371 | var total_words: usize = 1; // 1 word for the opcode itself |
| 372 | for (operands) |operand| { | ||
| 373 | total_words += switch (operand) { | ||
| 374 | .value, .literal32, .result_id, .ref_id => 1, | ||
| 375 | .literal64 => 2, | ||
| 376 | .string => |offset| blk: { | ||
| 377 | const text = std.mem.sliceTo(ass.inst.string_bytes.items[offset..], 0); | ||
| 378 | break :blk @divCeil(text.len + 1, @sizeOf(Word)); | ||
| 379 | }, | ||
| 380 | }; | ||
| 381 | } | ||
| 382 | |||
| 383 | try section.ensureUnusedCapacity(cg.gpa, total_words); | ||
| 372 | section.writeWord(0); | 384 | section.writeWord(0); |
| 373 | 385 | ||
| 374 | for (operands) |operand| { | 386 | for (operands) |operand| { |
| 375 | switch (operand) { | 387 | switch (operand) { |
| 376 | .value, .literal32 => |word| { | 388 | .value, .literal32 => |word| section.writeWord(word), |
| 377 | try section.ensureUnusedCapacity(cg.gpa, 1); | 389 | .literal64 => |dword| section.writeDoubleWord(dword), |
| 378 | section.writeWord(word); | ||
| 379 | }, | ||
| 380 | .literal64 => |dword| { | ||
| 381 | try section.ensureUnusedCapacity(cg.gpa, 2); | ||
| 382 | section.writeDoubleWord(dword); | ||
| 383 | }, | ||
| 384 | .result_id => { | 390 | .result_id => { |
| 385 | maybe_result_id = if (maybe_spv_decl_index) |spv_decl_index| | 391 | maybe_result_id = if (maybe_spv_decl_index) |spv_decl_index| |
| 386 | cg.declPtr(spv_decl_index).result_id | 392 | cg.declPtr(spv_decl_index).result_id |
| 387 | else | 393 | else |
| 388 | cg.allocId(); | 394 | cg.allocId(); |
| 389 | try section.ensureUnusedCapacity(cg.gpa, 1); | ||
| 390 | section.writeOperand(Id, maybe_result_id.?); | 395 | section.writeOperand(Id, maybe_result_id.?); |
| 391 | }, | 396 | }, |
| 392 | .ref_id => |index| { | 397 | .ref_id => |index| { |
| 393 | const result = try ass.resolveRef(index); | 398 | const result = try ass.resolveRef(index); |
| 394 | try section.ensureUnusedCapacity(cg.gpa, 1); | ||
| 395 | section.writeOperand(spec.Id, result.resultId()); | 399 | section.writeOperand(spec.Id, result.resultId()); |
| 396 | }, | 400 | }, |
| 397 | .string => |offset| { | 401 | .string => |offset| { |
| 398 | const text = std.mem.sliceTo(ass.inst.string_bytes.items[offset..], 0); | 402 | const text = std.mem.sliceTo(ass.inst.string_bytes.items[offset..], 0); |
| 399 | const size = @divCeil(text.len + 1, @sizeOf(Word)); | ||
| 400 | try section.ensureUnusedCapacity(cg.gpa, size); | ||
| 401 | section.writeOperand(spec.LiteralString, text); | 403 | section.writeOperand(spec.LiteralString, text); |
| 402 | }, | 404 | }, |
| 403 | } | 405 | } |
| ... | @@ -445,11 +447,11 @@ fn processSpecConstVector(ass: *Assembler) !?AsmValue { | ... | @@ -445,11 +447,11 @@ fn processSpecConstVector(ass: *Assembler) !?AsmValue { |
| 445 | const gpa = cg.gpa; | 447 | const gpa = cg.gpa; |
| 446 | const ty_ref = switch (ass.inst.operands.items[0]) { | 448 | const ty_ref = switch (ass.inst.operands.items[0]) { |
| 447 | .ref_id => |i| i, | 449 | .ref_id => |i| i, |
| 448 | else => return ass.fail(0, "missing result type", .{}), | 450 | else => return ass.fail(ass.inst.inst_offset, "missing result type", .{}), |
| 449 | }; | 451 | }; |
| 450 | const composite_ty_id = switch (try ass.resolveRef(ty_ref)) { | 452 | const composite_ty_id = switch (try ass.resolveRef(ty_ref)) { |
| 451 | .ty => |id| id, | 453 | .ty => |id| id, |
| 452 | else => return ass.fail(0, "%ty must be a type", .{}), | 454 | else => return ass.fail(ass.inst.inst_offset, "%ty must be a type", .{}), |
| 453 | }; | 455 | }; |
| 454 | 456 | ||
| 455 | const globals = &cg.sections.globals; | 457 | const globals = &cg.sections.globals; |
| ... | @@ -483,7 +485,7 @@ fn processSpecConstVector(ass: *Assembler) !?AsmValue { | ... | @@ -483,7 +485,7 @@ fn processSpecConstVector(ass: *Assembler) !?AsmValue { |
| 483 | } | 485 | } |
| 484 | 486 | ||
| 485 | const spec_id_word = std.math.cast(u32, spec_id_base + i) orelse { | 487 | const spec_id_word = std.math.cast(u32, spec_id_base + i) orelse { |
| 486 | return ass.fail(0, "SpecId {} does not fit in 32 bits", .{spec_id_base + i}); | 488 | return ass.fail(ass.inst.inst_offset, "SpecId {} does not fit in 32 bits", .{spec_id_base + i}); |
| 487 | }; | 489 | }; |
| 488 | try annotations.emitRaw(gpa, .OpDecorate, 3); | 490 | try annotations.emitRaw(gpa, .OpDecorate, 3); |
| 489 | annotations.writeOperand(Id, elem_id); | 491 | annotations.writeOperand(Id, elem_id); |
| ... | @@ -505,8 +507,7 @@ fn resolveMaybeForwardRef(ass: *Assembler, ref: AsmValue.Ref) !AsmValue { | ... | @@ -505,8 +507,7 @@ fn resolveMaybeForwardRef(ass: *Assembler, ref: AsmValue.Ref) !AsmValue { |
| 505 | switch (value) { | 507 | switch (value) { |
| 506 | .just_declared => { | 508 | .just_declared => { |
| 507 | const name = ass.value_map.keys()[ref]; | 509 | const name = ass.value_map.keys()[ref]; |
| 508 | // TODO: Improve source location. | 510 | return ass.fail(ass.inst.inst_offset, "self-referential parameter %{s}", .{name}); |
| 509 | return ass.fail(0, "ass-referential parameter %{s}", .{name}); | ||
| 510 | }, | 511 | }, |
| 511 | else => return value, | 512 | else => return value, |
| 512 | } | 513 | } |
| ... | @@ -518,8 +519,7 @@ fn resolveRef(ass: *Assembler, ref: AsmValue.Ref) !AsmValue { | ... | @@ -518,8 +519,7 @@ fn resolveRef(ass: *Assembler, ref: AsmValue.Ref) !AsmValue { |
| 518 | .just_declared => unreachable, | 519 | .just_declared => unreachable, |
| 519 | .unresolved_forward_reference => { | 520 | .unresolved_forward_reference => { |
| 520 | const name = ass.value_map.keys()[ref]; | 521 | const name = ass.value_map.keys()[ref]; |
| 521 | // TODO: Improve source location. | 522 | return ass.fail(ass.inst.inst_offset, "reference to undeclared result-id %{s}", .{name}); |
| 522 | return ass.fail(0, "reference to undeclared result-id %{s}", .{name}); | ||
| 523 | }, | 523 | }, |
| 524 | else => return value, | 524 | else => return value, |
| 525 | } | 525 | } |
| ... | @@ -536,6 +536,7 @@ fn parseInstruction(ass: *Assembler) !void { | ... | @@ -536,6 +536,7 @@ fn parseInstruction(ass: *Assembler) !void { |
| 536 | ass.inst.opcode = undefined; | 536 | ass.inst.opcode = undefined; |
| 537 | ass.inst.operands.clearRetainingCapacity(); | 537 | ass.inst.operands.clearRetainingCapacity(); |
| 538 | ass.inst.string_bytes.clearRetainingCapacity(); | 538 | ass.inst.string_bytes.clearRetainingCapacity(); |
| 539 | ass.inst.inst_offset = ass.currentToken().start; | ||
| 539 | 540 | ||
| 540 | const lhs_result_tok = ass.currentToken(); | 541 | const lhs_result_tok = ass.currentToken(); |
| 541 | const maybe_lhs_result: ?AsmValue.Ref = if (ass.eatToken(.result_id_assign)) blk: { | 542 | const maybe_lhs_result: ?AsmValue.Ref = if (ass.eatToken(.result_id_assign)) blk: { |
| ... | @@ -589,8 +590,8 @@ fn parseInstruction(ass: *Assembler) !void { | ... | @@ -589,8 +590,8 @@ fn parseInstruction(ass: *Assembler) !void { |
| 589 | .required => if (ass.isAtInstructionBoundary()) { | 590 | .required => if (ass.isAtInstructionBoundary()) { |
| 590 | return ass.fail( | 591 | return ass.fail( |
| 591 | ass.currentToken().start, | 592 | ass.currentToken().start, |
| 592 | "missing required operand", // TODO: Operand name? | 593 | "missing required operand '{s}'", |
| 593 | .{}, | 594 | .{@tagName(operand.kind)}, |
| 594 | ); | 595 | ); |
| 595 | } else { | 596 | } else { |
| 596 | try ass.parseOperand(operand.kind); | 597 | try ass.parseOperand(operand.kind); |
src/codegen/spirv/CodeGen.zig+2-2| ... | @@ -7280,7 +7280,7 @@ fn structuredBreak(cg: *CodeGen, target_block: Id) !void { | ... | @@ -7280,7 +7280,7 @@ fn structuredBreak(cg: *CodeGen, target_block: Id) !void { |
| 7280 | if (cg.block_terminated) return; | 7280 | if (cg.block_terminated) return; |
| 7281 | 7281 | ||
| 7282 | const gpa = cg.gpa; | 7282 | const gpa = cg.gpa; |
| 7283 | const sblock = cg.block_stack.getLast().?; | 7283 | const sblock = cg.block_stack.last().?; |
| 7284 | const merge_block = switch (sblock.*) { | 7284 | const merge_block = switch (sblock.*) { |
| 7285 | .selection => |*merge| blk: { | 7285 | .selection => |*merge| blk: { |
| 7286 | const merge_label = cg.allocId(); | 7286 | const merge_label = cg.allocId(); |
| ... | @@ -7447,7 +7447,7 @@ fn lowerBlock(cg: *CodeGen, inst: Air.Inst.Index, body: []const Air.Inst.Index) | ... | @@ -7447,7 +7447,7 @@ fn lowerBlock(cg: *CodeGen, inst: Air.Inst.Index, body: []const Air.Inst.Index) |
| 7447 | .operand_2 = this_block, | 7447 | .operand_2 = this_block, |
| 7448 | }); | 7448 | }); |
| 7449 | 7449 | ||
| 7450 | const sblock = cg.block_stack.getLast().?; | 7450 | const sblock = cg.block_stack.last().?; |
| 7451 | 7451 | ||
| 7452 | if (ty.isNoReturn(zcu)) { | 7452 | if (ty.isNoReturn(zcu)) { |
| 7453 | // If this block is noreturn, this instruction is the last of a block, | 7453 | // If this block is noreturn, this instruction is the last of a block, |
src/codegen/spirv/Section.zig+6-3| ... | @@ -49,8 +49,9 @@ pub fn emitRaw( | ... | @@ -49,8 +49,9 @@ pub fn emitRaw( |
| 49 | operand_words: usize, | 49 | operand_words: usize, |
| 50 | ) !void { | 50 | ) !void { |
| 51 | const word_count = 1 + operand_words; | 51 | const word_count = 1 + operand_words; |
| 52 | if (word_count > std.math.maxInt(u16)) return error.OutOfMemory; | ||
| 52 | try section.instructions.ensureUnusedCapacity(allocator, word_count); | 53 | try section.instructions.ensureUnusedCapacity(allocator, word_count); |
| 53 | section.writeWord((@as(Word, @intCast(word_count << 16))) | @backingInt(opcode)); | 54 | section.writeWord((@as(Word, @intCast(word_count)) << 16) | @backingInt(opcode)); |
| 54 | } | 55 | } |
| 55 | 56 | ||
| 56 | /// Write an entire instruction, including all operands | 57 | /// Write an entire instruction, including all operands |
| ... | @@ -70,7 +71,8 @@ pub fn emitAssumeCapacity( | ... | @@ -70,7 +71,8 @@ pub fn emitAssumeCapacity( |
| 70 | operands: opcode.Operands(), | 71 | operands: opcode.Operands(), |
| 71 | ) !void { | 72 | ) !void { |
| 72 | const word_count = instructionSize(opcode, operands); | 73 | const word_count = instructionSize(opcode, operands); |
| 73 | section.writeWord(@as(Word, @intCast(word_count << 16)) | @backingInt(opcode)); | 74 | if (word_count > std.math.maxInt(u16)) return error.OutOfMemory; |
| 75 | section.writeWord((@as(Word, @intCast(word_count)) << 16) | @backingInt(opcode)); | ||
| 74 | section.writeOperands(opcode.Operands(), operands); | 76 | section.writeOperands(opcode.Operands(), operands); |
| 75 | } | 77 | } |
| 76 | 78 | ||
| ... | @@ -81,8 +83,9 @@ pub fn emit( | ... | @@ -81,8 +83,9 @@ pub fn emit( |
| 81 | operands: opcode.Operands(), | 83 | operands: opcode.Operands(), |
| 82 | ) !void { | 84 | ) !void { |
| 83 | const word_count = instructionSize(opcode, operands); | 85 | const word_count = instructionSize(opcode, operands); |
| 86 | if (word_count > std.math.maxInt(u16)) return error.OutOfMemory; | ||
| 84 | try section.instructions.ensureUnusedCapacity(allocator, word_count); | 87 | try section.instructions.ensureUnusedCapacity(allocator, word_count); |
| 85 | section.writeWord(@as(Word, @intCast(word_count << 16)) | @backingInt(opcode)); | 88 | section.writeWord((@as(Word, @intCast(word_count)) << 16) | @backingInt(opcode)); |
| 86 | section.writeOperands(opcode.Operands(), operands); | 89 | section.writeOperands(opcode.Operands(), operands); |
| 87 | } | 90 | } |
| 88 | 91 |
src/codegen/wasm/CodeGen.zig+111-65| ... | @@ -24,12 +24,6 @@ const Alignment = InternPool.Alignment; | ... | @@ -24,12 +24,6 @@ const Alignment = InternPool.Alignment; |
| 24 | const errUnionPayloadOffset = codegen.errUnionPayloadOffset; | 24 | const errUnionPayloadOffset = codegen.errUnionPayloadOffset; |
| 25 | const errUnionErrorOffset = codegen.errUnionErrorOffset; | 25 | const errUnionErrorOffset = codegen.errUnionErrorOffset; |
| 26 | 26 | ||
| 27 | const target_util = @import("../../target.zig"); | ||
| 28 | const libcFloatPrefix = target_util.libcFloatPrefix; | ||
| 29 | const libcFloatSuffix = target_util.libcFloatSuffix; | ||
| 30 | const compilerRtFloatAbbrev = target_util.compilerRtFloatAbbrev; | ||
| 31 | const compilerRtIntAbbrev = target_util.compilerRtIntAbbrev; | ||
| 32 | |||
| 33 | pub fn legalizeFeatures(_: *const std.Target) *const Air.Legalize.Features { | 27 | pub fn legalizeFeatures(_: *const std.Target) *const Air.Legalize.Features { |
| 34 | return comptime &.initMany(&.{ | 28 | return comptime &.initMany(&.{ |
| 35 | .expand_bit_cast_safe, | 29 | .expand_bit_cast_safe, |
| ... | @@ -573,7 +567,7 @@ fn addCallIntrinsic(cg: *CodeGen, intrinsic: Mir.Intrinsic) error{OutOfMemory}!v | ... | @@ -573,7 +567,7 @@ fn addCallIntrinsic(cg: *CodeGen, intrinsic: Mir.Intrinsic) error{OutOfMemory}!v |
| 573 | /// Appends entries to `mir_extra` based on the type of `extra`. | 567 | /// Appends entries to `mir_extra` based on the type of `extra`. |
| 574 | /// Returns the index into `mir_extra` | 568 | /// Returns the index into `mir_extra` |
| 575 | fn addExtra(cg: *CodeGen, extra: anytype) error{OutOfMemory}!u32 { | 569 | fn addExtra(cg: *CodeGen, extra: anytype) error{OutOfMemory}!u32 { |
| 576 | const field_count = std.meta.fieldNames(@TypeOf(extra)).len; | 570 | const field_count = @typeInfo(@TypeOf(extra)).@"struct".field_names.len; |
| 577 | try cg.mir_extra.ensureUnusedCapacity(cg.gpa, field_count); | 571 | try cg.mir_extra.ensureUnusedCapacity(cg.gpa, field_count); |
| 578 | return cg.addExtraAssumeCapacity(extra); | 572 | return cg.addExtraAssumeCapacity(extra); |
| 579 | } | 573 | } |
| ... | @@ -933,21 +927,26 @@ fn resolveCallingConventionValues( | ... | @@ -933,21 +927,26 @@ fn resolveCallingConventionValues( |
| 933 | }, | 927 | }, |
| 934 | .wasm_mvp => { | 928 | .wasm_mvp => { |
| 935 | for (fn_info.param_types.get(ip)) |ty| { | 929 | for (fn_info.param_types.get(ip)) |ty| { |
| 936 | if (!Type.fromInterned(ty).hasRuntimeBits(zcu)) { | 930 | const param_ty: Type = .fromInterned(ty); |
| 931 | if (!param_ty.hasRuntimeBits(zcu)) { | ||
| 937 | continue; | 932 | continue; |
| 938 | } | 933 | } |
| 939 | switch (abi.classifyType(.fromInterned(ty), zcu)) { | 934 | |
| 940 | .direct => |scalar_ty| if (!abi.lowerAsDoubleI64(scalar_ty, zcu)) { | 935 | switch (abi.classifyType(param_ty, zcu, target)) { |
| 936 | .direct, .indirect => { | ||
| 941 | try args.append(.{ .local = .{ .value = result.local_index, .references = 1 } }); | 937 | try args.append(.{ .local = .{ .value = result.local_index, .references = 1 } }); |
| 942 | result.local_index += 1; | 938 | result.local_index += 1; |
| 943 | } else { | 939 | }, |
| 940 | .double_i64 => { | ||
| 944 | try args.append(.{ .local = .{ .value = result.local_index, .references = 1 } }); | 941 | try args.append(.{ .local = .{ .value = result.local_index, .references = 1 } }); |
| 945 | try args.append(.{ .local = .{ .value = result.local_index + 1, .references = 1 } }); | 942 | try args.append(.{ .local = .{ .value = result.local_index + 1, .references = 1 } }); |
| 946 | result.local_index += 2; | 943 | result.local_index += 2; |
| 947 | }, | 944 | }, |
| 948 | .indirect => { | 945 | .unrolled => |vector| { |
| 949 | try args.append(.{ .local = .{ .value = result.local_index, .references = 1 } }); | 946 | for (0..vector.len) |_| { |
| 950 | result.local_index += 1; | 947 | try args.append(.{ .local = .{ .value = result.local_index, .references = 1 } }); |
| 948 | result.local_index += 1; | ||
| 949 | } | ||
| 951 | }, | 950 | }, |
| 952 | } | 951 | } |
| 953 | } | 952 | } |
| ... | @@ -974,9 +973,10 @@ pub fn firstParamSRet( | ... | @@ -974,9 +973,10 @@ pub fn firstParamSRet( |
| 974 | switch (cc) { | 973 | switch (cc) { |
| 975 | .@"inline" => unreachable, | 974 | .@"inline" => unreachable, |
| 976 | .auto => return isByRef(return_type, zcu, target), | 975 | .auto => return isByRef(return_type, zcu, target), |
| 977 | .wasm_mvp => switch (abi.classifyType(return_type, zcu)) { | 976 | .wasm_mvp => switch (abi.classifyType(return_type, zcu, target)) { |
| 978 | .direct => |scalar_ty| return abi.lowerAsDoubleI64(scalar_ty, zcu), | 977 | .direct => return false, |
| 979 | .indirect => return true, | 978 | .double_i64, .indirect => return true, |
| 979 | .unrolled => |vector| return vector.len > 1, | ||
| 980 | }, | 980 | }, |
| 981 | else => return false, | 981 | else => return false, |
| 982 | } | 982 | } |
| ... | @@ -991,18 +991,15 @@ fn lowerArg(cg: *CodeGen, cc: std.lang.CallingConvention, ty: Type, value: WValu | ... | @@ -991,18 +991,15 @@ fn lowerArg(cg: *CodeGen, cc: std.lang.CallingConvention, ty: Type, value: WValu |
| 991 | 991 | ||
| 992 | const zcu = cg.pt.zcu; | 992 | const zcu = cg.pt.zcu; |
| 993 | 993 | ||
| 994 | switch (abi.classifyType(ty, zcu)) { | 994 | switch (abi.classifyType(ty, zcu, cg.target)) { |
| 995 | .direct => |scalar_type| if (!abi.lowerAsDoubleI64(scalar_type, zcu)) { | 995 | .direct => |scalar_ty| { |
| 996 | if (!isByRef(ty, zcu, cg.target)) { | 996 | if (!isByRef(ty, zcu, cg.target)) { |
| 997 | return cg.lowerToStack(value); | 997 | return cg.lowerToStack(value); |
| 998 | } else { | 998 | } else { |
| 999 | switch (value) { | 999 | _ = try cg.load(value, scalar_ty, 0); |
| 1000 | .nav_ref, .stack_offset => _ = try cg.load(value, scalar_type, 0), | ||
| 1001 | .dead => unreachable, | ||
| 1002 | else => try cg.emitWValue(value), | ||
| 1003 | } | ||
| 1004 | } | 1000 | } |
| 1005 | } else { | 1001 | }, |
| 1002 | .double_i64 => { | ||
| 1006 | assert(ty.abiSize(zcu) == 16); | 1003 | assert(ty.abiSize(zcu) == 16); |
| 1007 | // in this case we have an integer or float that must be lowered as 2 i64's. | 1004 | // in this case we have an integer or float that must be lowered as 2 i64's. |
| 1008 | try cg.emitWValue(value); | 1005 | try cg.emitWValue(value); |
| ... | @@ -1010,7 +1007,17 @@ fn lowerArg(cg: *CodeGen, cc: std.lang.CallingConvention, ty: Type, value: WValu | ... | @@ -1010,7 +1007,17 @@ fn lowerArg(cg: *CodeGen, cc: std.lang.CallingConvention, ty: Type, value: WValu |
| 1010 | try cg.emitWValue(value); | 1007 | try cg.emitWValue(value); |
| 1011 | try cg.addMemArg(.i64_load, .{ .offset = value.offset() + 8, .alignment = 8 }); | 1008 | try cg.addMemArg(.i64_load, .{ .offset = value.offset() + 8, .alignment = 8 }); |
| 1012 | }, | 1009 | }, |
| 1013 | .indirect => return cg.lowerToStack(value), | 1010 | .indirect => { |
| 1011 | const stack_copy = try cg.allocStack(ty); | ||
| 1012 | try cg.store(stack_copy, value, ty, 0); | ||
| 1013 | return cg.lowerToStack(stack_copy); | ||
| 1014 | }, | ||
| 1015 | .unrolled => |vector| { | ||
| 1016 | const elem_size: u32 = @intCast(vector.elem_type.abiSize(zcu)); | ||
| 1017 | for (0..vector.len) |index| { | ||
| 1018 | _ = try cg.load(value, vector.elem_type, @intCast(index * elem_size)); | ||
| 1019 | } | ||
| 1020 | }, | ||
| 1014 | } | 1021 | } |
| 1015 | } | 1022 | } |
| 1016 | 1023 | ||
| ... | @@ -1953,16 +1960,19 @@ fn airRet(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -1953,16 +1960,19 @@ fn airRet(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 1953 | if (cg.return_value != .none) { | 1960 | if (cg.return_value != .none) { |
| 1954 | try cg.store(cg.return_value, operand, ret_ty, 0); | 1961 | try cg.store(cg.return_value, operand, ret_ty, 0); |
| 1955 | } else if (fn_info.cc == .wasm_mvp and ret_ty.hasRuntimeBits(zcu)) { | 1962 | } else if (fn_info.cc == .wasm_mvp and ret_ty.hasRuntimeBits(zcu)) { |
| 1956 | switch (abi.classifyType(ret_ty, zcu)) { | 1963 | switch (abi.classifyType(ret_ty, zcu, cg.target)) { |
| 1957 | .direct => |scalar_type| { | 1964 | .direct => |scalar_type| { |
| 1958 | assert(!abi.lowerAsDoubleI64(scalar_type, zcu)); | ||
| 1959 | if (!isByRef(ret_ty, zcu, cg.target)) { | 1965 | if (!isByRef(ret_ty, zcu, cg.target)) { |
| 1960 | try cg.emitWValue(operand); | 1966 | try cg.emitWValue(operand); |
| 1961 | } else { | 1967 | } else { |
| 1962 | _ = try cg.load(operand, scalar_type, 0); | 1968 | _ = try cg.load(operand, scalar_type, 0); |
| 1963 | } | 1969 | } |
| 1964 | }, | 1970 | }, |
| 1965 | .indirect => unreachable, | 1971 | .double_i64, .indirect => unreachable, |
| 1972 | .unrolled => |vector| { | ||
| 1973 | assert(vector.len == 1); | ||
| 1974 | _ = try cg.load(operand, vector.elem_type, 0); | ||
| 1975 | }, | ||
| 1966 | } | 1976 | } |
| 1967 | } else { | 1977 | } else { |
| 1968 | if (!ret_ty.hasRuntimeBits(zcu) and ret_ty.isError(zcu)) { | 1978 | if (!ret_ty.hasRuntimeBits(zcu) and ret_ty.isError(zcu)) { |
| ... | @@ -2009,8 +2019,18 @@ fn airRetLoad(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -2009,8 +2019,18 @@ fn airRetLoad(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2009 | try cg.addImm32(0); | 2019 | try cg.addImm32(0); |
| 2010 | } | 2020 | } |
| 2011 | } else if (!firstParamSRet(fn_info.cc, Type.fromInterned(fn_info.return_type), zcu, cg.target)) { | 2021 | } else if (!firstParamSRet(fn_info.cc, Type.fromInterned(fn_info.return_type), zcu, cg.target)) { |
| 2012 | // leave on the stack | 2022 | if (fn_info.cc == .wasm_mvp) { |
| 2013 | _ = try cg.load(operand, ret_ty, 0); | 2023 | switch (abi.classifyType(ret_ty, zcu, cg.target)) { |
| 2024 | .direct => |scalar_type| _ = try cg.load(operand, scalar_type, 0), | ||
| 2025 | .double_i64, .indirect => unreachable, | ||
| 2026 | .unrolled => |vector| { | ||
| 2027 | assert(vector.len == 1); | ||
| 2028 | _ = try cg.load(operand, vector.elem_type, 0); | ||
| 2029 | }, | ||
| 2030 | } | ||
| 2031 | } else { | ||
| 2032 | _ = try cg.load(operand, ret_ty, 0); | ||
| 2033 | } | ||
| 2014 | } | 2034 | } |
| 2015 | 2035 | ||
| 2016 | try cg.restoreStackPointer(); | 2036 | try cg.restoreStackPointer(); |
| ... | @@ -2138,22 +2158,30 @@ fn airCall(cg: *CodeGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier) | ... | @@ -2138,22 +2158,30 @@ fn airCall(cg: *CodeGen, inst: Air.Inst.Index, modifier: std.lang.CallModifier) |
| 2138 | } else if (first_param_sret) { | 2158 | } else if (first_param_sret) { |
| 2139 | break :result_value sret; | 2159 | break :result_value sret; |
| 2140 | } else if (zcu.typeToFunc(fn_ty).?.cc == .wasm_mvp) { | 2160 | } else if (zcu.typeToFunc(fn_ty).?.cc == .wasm_mvp) { |
| 2141 | switch (abi.classifyType(ret_ty, zcu)) { | 2161 | switch (abi.classifyType(ret_ty, zcu, cg.target)) { |
| 2142 | .direct => |scalar_type| { | 2162 | .direct => |scalar_type| { |
| 2143 | assert(!abi.lowerAsDoubleI64(scalar_type, zcu)); | ||
| 2144 | if (!isByRef(ret_ty, zcu, cg.target)) { | 2163 | if (!isByRef(ret_ty, zcu, cg.target)) { |
| 2145 | const result_local = try cg.allocLocal(ret_ty); | 2164 | const result_local = try cg.allocLocal(ret_ty); |
| 2146 | try cg.addLocal(.local_set, result_local.local.value); | 2165 | try cg.addLocal(.local_set, result_local.local.value); |
| 2147 | break :result_value result_local; | 2166 | break :result_value result_local; |
| 2148 | } else { | 2167 | } else { |
| 2149 | const result_local = try cg.allocLocal(ret_ty); | 2168 | const result_local = try cg.allocLocal(scalar_type); |
| 2150 | try cg.addLocal(.local_set, result_local.local.value); | 2169 | try cg.addLocal(.local_set, result_local.local.value); |
| 2151 | const result = try cg.allocStack(ret_ty); | 2170 | const result = try cg.allocStack(ret_ty); |
| 2152 | try cg.store(result, result_local, scalar_type, 0); | 2171 | try cg.store(result, result_local, scalar_type, 0); |
| 2153 | break :result_value result; | 2172 | break :result_value result; |
| 2154 | } | 2173 | } |
| 2155 | }, | 2174 | }, |
| 2156 | .indirect => unreachable, | 2175 | .double_i64, .indirect => unreachable, |
| 2176 | .unrolled => |vector| { | ||
| 2177 | assert(vector.len == 1); | ||
| 2178 | const result_local = try cg.allocLocal(vector.elem_type); | ||
| 2179 | // save call result from operand stack | ||
| 2180 | try cg.addLocal(.local_set, result_local.local.value); | ||
| 2181 | const result = try cg.allocStack(ret_ty); | ||
| 2182 | try cg.store(result, result_local, vector.elem_type, 0); | ||
| 2183 | break :result_value result; | ||
| 2184 | }, | ||
| 2157 | } | 2185 | } |
| 2158 | } else { | 2186 | } else { |
| 2159 | const result_local = try cg.allocLocal(ret_ty); | 2187 | const result_local = try cg.allocLocal(ret_ty); |
| ... | @@ -2456,17 +2484,32 @@ fn airArg(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -2456,17 +2484,32 @@ fn airArg(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2456 | const cc = zcu.typeToFunc(zcu.navValue(cg.owner_nav).typeOf(zcu)).?.cc; | 2484 | const cc = zcu.typeToFunc(zcu.navValue(cg.owner_nav).typeOf(zcu)).?.cc; |
| 2457 | const arg_ty = cg.typeOfIndex(inst); | 2485 | const arg_ty = cg.typeOfIndex(inst); |
| 2458 | if (cc == .wasm_mvp) { | 2486 | if (cc == .wasm_mvp) { |
| 2459 | switch (abi.classifyType(arg_ty, zcu)) { | 2487 | switch (abi.classifyType(arg_ty, zcu, cg.target)) { |
| 2460 | .direct => |scalar_ty| if (!abi.lowerAsDoubleI64(scalar_ty, zcu)) { | 2488 | .direct => |scalar_type| { |
| 2461 | cg.arg_index += 1; | 2489 | cg.arg_index += 1; |
| 2462 | } else { | 2490 | if (isByRef(arg_ty, zcu, cg.target)) { |
| 2491 | const result = try cg.allocStack(arg_ty); | ||
| 2492 | try cg.store(result, arg, scalar_type, 0); | ||
| 2493 | return cg.finishAir(inst, result, &.{}); | ||
| 2494 | } | ||
| 2495 | }, | ||
| 2496 | .indirect => cg.arg_index += 1, | ||
| 2497 | .double_i64 => { | ||
| 2463 | cg.arg_index += 2; | 2498 | cg.arg_index += 2; |
| 2464 | const result = try cg.allocStack(arg_ty); | 2499 | const result = try cg.allocStack(arg_ty); |
| 2465 | try cg.store(result, arg, Type.u64, 0); | 2500 | try cg.store(result, arg, Type.u64, 0); |
| 2466 | try cg.store(result, cg.args[arg_index + 1], Type.u64, 8); | 2501 | try cg.store(result, cg.args[arg_index + 1], Type.u64, 8); |
| 2467 | return cg.finishAir(inst, result, &.{}); | 2502 | return cg.finishAir(inst, result, &.{}); |
| 2468 | }, | 2503 | }, |
| 2469 | .indirect => cg.arg_index += 1, | 2504 | .unrolled => |vector| { |
| 2505 | const result = try cg.allocStack(arg_ty); | ||
| 2506 | const elem_size: u32 = @intCast(vector.elem_type.abiSize(zcu)); | ||
| 2507 | for (0..vector.len) |index| { | ||
| 2508 | try cg.store(result, cg.args[cg.arg_index], vector.elem_type, @intCast(index * elem_size)); | ||
| 2509 | cg.arg_index += 1; | ||
| 2510 | } | ||
| 2511 | return cg.finishAir(inst, result, &.{}); | ||
| 2512 | }, | ||
| 2470 | } | 2513 | } |
| 2471 | } else { | 2514 | } else { |
| 2472 | cg.arg_index += 1; | 2515 | cg.arg_index += 1; |
| ... | @@ -2515,15 +2558,15 @@ const IntType = struct { | ... | @@ -2515,15 +2558,15 @@ const IntType = struct { |
| 2515 | .anyerror, .adhoc_inferred_error_set => .{ .is_signed = false, .bits = zcu.errorSetBits() }, | 2558 | .anyerror, .adhoc_inferred_error_set => .{ .is_signed = false, .bits = zcu.errorSetBits() }, |
| 2516 | .isize => .{ .is_signed = true, .bits = cg.target.ptrBitWidth() }, | 2559 | .isize => .{ .is_signed = true, .bits = cg.target.ptrBitWidth() }, |
| 2517 | .usize => .{ .is_signed = false, .bits = cg.target.ptrBitWidth() }, | 2560 | .usize => .{ .is_signed = false, .bits = cg.target.ptrBitWidth() }, |
| 2518 | .c_char => .{ .is_signed = cg.target.cCharSignedness() == .signed, .bits = cg.target.cTypeBitSize(.char) }, | 2561 | .c_char => .{ .is_signed = cg.target.cCharSignedness().? == .signed, .bits = cg.target.cTypeBitSize(.char).? }, |
| 2519 | .c_short => .{ .is_signed = true, .bits = cg.target.cTypeBitSize(.short) }, | 2562 | .c_short => .{ .is_signed = true, .bits = cg.target.cTypeBitSize(.short).? }, |
| 2520 | .c_ushort => .{ .is_signed = false, .bits = cg.target.cTypeBitSize(.short) }, | 2563 | .c_ushort => .{ .is_signed = false, .bits = cg.target.cTypeBitSize(.short).? }, |
| 2521 | .c_int => .{ .is_signed = true, .bits = cg.target.cTypeBitSize(.int) }, | 2564 | .c_int => .{ .is_signed = true, .bits = cg.target.cTypeBitSize(.int).? }, |
| 2522 | .c_uint => .{ .is_signed = false, .bits = cg.target.cTypeBitSize(.int) }, | 2565 | .c_uint => .{ .is_signed = false, .bits = cg.target.cTypeBitSize(.int).? }, |
| 2523 | .c_long => .{ .is_signed = true, .bits = cg.target.cTypeBitSize(.long) }, | 2566 | .c_long => .{ .is_signed = true, .bits = cg.target.cTypeBitSize(.long).? }, |
| 2524 | .c_ulong => .{ .is_signed = false, .bits = cg.target.cTypeBitSize(.long) }, | 2567 | .c_ulong => .{ .is_signed = false, .bits = cg.target.cTypeBitSize(.long).? }, |
| 2525 | .c_longlong => .{ .is_signed = true, .bits = cg.target.cTypeBitSize(.longlong) }, | 2568 | .c_longlong => .{ .is_signed = true, .bits = cg.target.cTypeBitSize(.longlong).? }, |
| 2526 | .c_ulonglong => .{ .is_signed = false, .bits = cg.target.cTypeBitSize(.longlong) }, | 2569 | .c_ulonglong => .{ .is_signed = false, .bits = cg.target.cTypeBitSize(.longlong).? }, |
| 2527 | .f16, .f32, .f64, .f80, .f128, .c_longdouble => unreachable, | 2570 | .f16, .f32, .f64, .f80, .f128, .c_longdouble => unreachable, |
| 2528 | .anyopaque, .void, .type, .comptime_int, .comptime_float, .noreturn, .null, .undefined, .enum_literal, .generic_poison => unreachable, | 2571 | .anyopaque, .void, .type, .comptime_int, .comptime_float, .noreturn, .null, .undefined, .enum_literal, .generic_poison => unreachable, |
| 2529 | }, | 2572 | }, |
| ... | @@ -4340,7 +4383,7 @@ fn floatRem(cg: *CodeGen, ty: FloatType, lhs: WValue, rhs: WValue) InnerError!WV | ... | @@ -4340,7 +4383,7 @@ fn floatRem(cg: *CodeGen, ty: FloatType, lhs: WValue, rhs: WValue) InnerError!WV |
| 4340 | .f32 => return cg.callIntrinsic(.fmodf, &.{ .f32_type, .f32_type }, Type.f32, &.{ lhs, rhs }), | 4383 | .f32 => return cg.callIntrinsic(.fmodf, &.{ .f32_type, .f32_type }, Type.f32, &.{ lhs, rhs }), |
| 4341 | .f64 => return cg.callIntrinsic(.fmod, &.{ .f64_type, .f64_type }, Type.f64, &.{ lhs, rhs }), | 4384 | .f64 => return cg.callIntrinsic(.fmod, &.{ .f64_type, .f64_type }, Type.f64, &.{ lhs, rhs }), |
| 4342 | .f80 => return cg.callIntrinsic(.__fmodx, &.{ .f80_type, .f80_type }, Type.f80, &.{ lhs, rhs }), | 4385 | .f80 => return cg.callIntrinsic(.__fmodx, &.{ .f80_type, .f80_type }, Type.f80, &.{ lhs, rhs }), |
| 4343 | .f128 => return cg.callIntrinsic(.fmodq, &.{ .f128_type, .f128_type }, Type.f128, &.{ lhs, rhs }), | 4386 | .f128 => return cg.callIntrinsic(.fmodf128, &.{ .f128_type, .f128_type }, Type.f128, &.{ lhs, rhs }), |
| 4344 | } | 4387 | } |
| 4345 | } | 4388 | } |
| 4346 | 4389 | ||
| ... | @@ -4376,7 +4419,7 @@ fn floatMax(cg: *CodeGen, ty: FloatType, lhs: WValue, rhs: WValue) InnerError!WV | ... | @@ -4376,7 +4419,7 @@ fn floatMax(cg: *CodeGen, ty: FloatType, lhs: WValue, rhs: WValue) InnerError!WV |
| 4376 | .f32 => return cg.callIntrinsic(.fmaxf, &.{ .f32_type, .f32_type }, Type.f32, &.{ lhs, rhs }), | 4419 | .f32 => return cg.callIntrinsic(.fmaxf, &.{ .f32_type, .f32_type }, Type.f32, &.{ lhs, rhs }), |
| 4377 | .f64 => return cg.callIntrinsic(.fmax, &.{ .f64_type, .f64_type }, Type.f64, &.{ lhs, rhs }), | 4420 | .f64 => return cg.callIntrinsic(.fmax, &.{ .f64_type, .f64_type }, Type.f64, &.{ lhs, rhs }), |
| 4378 | .f80 => return cg.callIntrinsic(.__fmaxx, &.{ .f80_type, .f80_type }, Type.f80, &.{ lhs, rhs }), | 4421 | .f80 => return cg.callIntrinsic(.__fmaxx, &.{ .f80_type, .f80_type }, Type.f80, &.{ lhs, rhs }), |
| 4379 | .f128 => return cg.callIntrinsic(.fmaxq, &.{ .f128_type, .f128_type }, Type.f128, &.{ lhs, rhs }), | 4422 | .f128 => return cg.callIntrinsic(.fmaxf128, &.{ .f128_type, .f128_type }, Type.f128, &.{ lhs, rhs }), |
| 4380 | } | 4423 | } |
| 4381 | } | 4424 | } |
| 4382 | 4425 | ||
| ... | @@ -4387,7 +4430,7 @@ fn floatMin(cg: *CodeGen, ty: FloatType, lhs: WValue, rhs: WValue) InnerError!WV | ... | @@ -4387,7 +4430,7 @@ fn floatMin(cg: *CodeGen, ty: FloatType, lhs: WValue, rhs: WValue) InnerError!WV |
| 4387 | .f32 => return cg.callIntrinsic(.fminf, &.{ .f32_type, .f32_type }, Type.f32, &.{ lhs, rhs }), | 4430 | .f32 => return cg.callIntrinsic(.fminf, &.{ .f32_type, .f32_type }, Type.f32, &.{ lhs, rhs }), |
| 4388 | .f64 => return cg.callIntrinsic(.fmin, &.{ .f64_type, .f64_type }, Type.f64, &.{ lhs, rhs }), | 4431 | .f64 => return cg.callIntrinsic(.fmin, &.{ .f64_type, .f64_type }, Type.f64, &.{ lhs, rhs }), |
| 4389 | .f80 => return cg.callIntrinsic(.__fminx, &.{ .f80_type, .f80_type }, Type.f80, &.{ lhs, rhs }), | 4432 | .f80 => return cg.callIntrinsic(.__fminx, &.{ .f80_type, .f80_type }, Type.f80, &.{ lhs, rhs }), |
| 4390 | .f128 => return cg.callIntrinsic(.fminq, &.{ .f128_type, .f128_type }, Type.f128, &.{ lhs, rhs }), | 4433 | .f128 => return cg.callIntrinsic(.fminf128, &.{ .f128_type, .f128_type }, Type.f128, &.{ lhs, rhs }), |
| 4391 | } | 4434 | } |
| 4392 | } | 4435 | } |
| 4393 | 4436 | ||
| ... | @@ -4405,7 +4448,7 @@ fn floatSqrt(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue { | ... | @@ -4405,7 +4448,7 @@ fn floatSqrt(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue { |
| 4405 | return .stack; | 4448 | return .stack; |
| 4406 | }, | 4449 | }, |
| 4407 | .f80 => return cg.callIntrinsic(.__sqrtx, &.{.f80_type}, Type.f80, &.{arg}), | 4450 | .f80 => return cg.callIntrinsic(.__sqrtx, &.{.f80_type}, Type.f80, &.{arg}), |
| 4408 | .f128 => return cg.callIntrinsic(.sqrtq, &.{.f128_type}, Type.f128, &.{arg}), | 4451 | .f128 => return cg.callIntrinsic(.sqrtf128, &.{.f128_type}, Type.f128, &.{arg}), |
| 4409 | } | 4452 | } |
| 4410 | } | 4453 | } |
| 4411 | 4454 | ||
| ... | @@ -4415,7 +4458,7 @@ fn floatSin(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue { | ... | @@ -4415,7 +4458,7 @@ fn floatSin(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue { |
| 4415 | .f32 => return cg.callIntrinsic(.sinf, &.{.f32_type}, Type.f32, &.{arg}), | 4458 | .f32 => return cg.callIntrinsic(.sinf, &.{.f32_type}, Type.f32, &.{arg}), |
| 4416 | .f64 => return cg.callIntrinsic(.sin, &.{.f64_type}, Type.f64, &.{arg}), | 4459 | .f64 => return cg.callIntrinsic(.sin, &.{.f64_type}, Type.f64, &.{arg}), |
| 4417 | .f80 => return cg.callIntrinsic(.__sinx, &.{.f80_type}, Type.f80, &.{arg}), | 4460 | .f80 => return cg.callIntrinsic(.__sinx, &.{.f80_type}, Type.f80, &.{arg}), |
| 4418 | .f128 => return cg.callIntrinsic(.sinq, &.{.f128_type}, Type.f128, &.{arg}), | 4461 | .f128 => return cg.callIntrinsic(.sinf128, &.{.f128_type}, Type.f128, &.{arg}), |
| 4419 | } | 4462 | } |
| 4420 | } | 4463 | } |
| 4421 | 4464 | ||
| ... | @@ -4425,7 +4468,7 @@ fn floatCos(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue { | ... | @@ -4425,7 +4468,7 @@ fn floatCos(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue { |
| 4425 | .f32 => return cg.callIntrinsic(.cosf, &.{.f32_type}, Type.f32, &.{arg}), | 4468 | .f32 => return cg.callIntrinsic(.cosf, &.{.f32_type}, Type.f32, &.{arg}), |
| 4426 | .f64 => return cg.callIntrinsic(.cos, &.{.f64_type}, Type.f64, &.{arg}), | 4469 | .f64 => return cg.callIntrinsic(.cos, &.{.f64_type}, Type.f64, &.{arg}), |
| 4427 | .f80 => return cg.callIntrinsic(.__cosx, &.{.f80_type}, Type.f80, &.{arg}), | 4470 | .f80 => return cg.callIntrinsic(.__cosx, &.{.f80_type}, Type.f80, &.{arg}), |
| 4428 | .f128 => return cg.callIntrinsic(.cosq, &.{.f128_type}, Type.f128, &.{arg}), | 4471 | .f128 => return cg.callIntrinsic(.cosf128, &.{.f128_type}, Type.f128, &.{arg}), |
| 4429 | } | 4472 | } |
| 4430 | } | 4473 | } |
| 4431 | 4474 | ||
| ... | @@ -4435,7 +4478,7 @@ fn floatTan(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue { | ... | @@ -4435,7 +4478,7 @@ fn floatTan(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue { |
| 4435 | .f32 => return cg.callIntrinsic(.tanf, &.{.f32_type}, Type.f32, &.{arg}), | 4478 | .f32 => return cg.callIntrinsic(.tanf, &.{.f32_type}, Type.f32, &.{arg}), |
| 4436 | .f64 => return cg.callIntrinsic(.tan, &.{.f64_type}, Type.f64, &.{arg}), | 4479 | .f64 => return cg.callIntrinsic(.tan, &.{.f64_type}, Type.f64, &.{arg}), |
| 4437 | .f80 => return cg.callIntrinsic(.__tanx, &.{.f80_type}, Type.f80, &.{arg}), | 4480 | .f80 => return cg.callIntrinsic(.__tanx, &.{.f80_type}, Type.f80, &.{arg}), |
| 4438 | .f128 => return cg.callIntrinsic(.tanq, &.{.f128_type}, Type.f128, &.{arg}), | 4481 | .f128 => return cg.callIntrinsic(.tanf128, &.{.f128_type}, Type.f128, &.{arg}), |
| 4439 | } | 4482 | } |
| 4440 | } | 4483 | } |
| 4441 | 4484 | ||
| ... | @@ -4445,7 +4488,7 @@ fn floatExp(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue { | ... | @@ -4445,7 +4488,7 @@ fn floatExp(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue { |
| 4445 | .f32 => return cg.callIntrinsic(.expf, &.{.f32_type}, Type.f32, &.{arg}), | 4488 | .f32 => return cg.callIntrinsic(.expf, &.{.f32_type}, Type.f32, &.{arg}), |
| 4446 | .f64 => return cg.callIntrinsic(.exp, &.{.f64_type}, Type.f64, &.{arg}), | 4489 | .f64 => return cg.callIntrinsic(.exp, &.{.f64_type}, Type.f64, &.{arg}), |
| 4447 | .f80 => return cg.callIntrinsic(.__expx, &.{.f80_type}, Type.f80, &.{arg}), | 4490 | .f80 => return cg.callIntrinsic(.__expx, &.{.f80_type}, Type.f80, &.{arg}), |
| 4448 | .f128 => return cg.callIntrinsic(.expq, &.{.f128_type}, Type.f128, &.{arg}), | 4491 | .f128 => return cg.callIntrinsic(.expf128, &.{.f128_type}, Type.f128, &.{arg}), |
| 4449 | } | 4492 | } |
| 4450 | } | 4493 | } |
| 4451 | 4494 | ||
| ... | @@ -4455,7 +4498,7 @@ fn floatExp2(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue { | ... | @@ -4455,7 +4498,7 @@ fn floatExp2(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue { |
| 4455 | .f32 => return cg.callIntrinsic(.exp2f, &.{.f32_type}, Type.f32, &.{arg}), | 4498 | .f32 => return cg.callIntrinsic(.exp2f, &.{.f32_type}, Type.f32, &.{arg}), |
| 4456 | .f64 => return cg.callIntrinsic(.exp2, &.{.f64_type}, Type.f64, &.{arg}), | 4499 | .f64 => return cg.callIntrinsic(.exp2, &.{.f64_type}, Type.f64, &.{arg}), |
| 4457 | .f80 => return cg.callIntrinsic(.__exp2x, &.{.f80_type}, Type.f80, &.{arg}), | 4500 | .f80 => return cg.callIntrinsic(.__exp2x, &.{.f80_type}, Type.f80, &.{arg}), |
| 4458 | .f128 => return cg.callIntrinsic(.exp2q, &.{.f128_type}, Type.f128, &.{arg}), | 4501 | .f128 => return cg.callIntrinsic(.exp2f128, &.{.f128_type}, Type.f128, &.{arg}), |
| 4459 | } | 4502 | } |
| 4460 | } | 4503 | } |
| 4461 | 4504 | ||
| ... | @@ -4465,7 +4508,7 @@ fn floatLog(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue { | ... | @@ -4465,7 +4508,7 @@ fn floatLog(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue { |
| 4465 | .f32 => return cg.callIntrinsic(.logf, &.{.f32_type}, Type.f32, &.{arg}), | 4508 | .f32 => return cg.callIntrinsic(.logf, &.{.f32_type}, Type.f32, &.{arg}), |
| 4466 | .f64 => return cg.callIntrinsic(.log, &.{.f64_type}, Type.f64, &.{arg}), | 4509 | .f64 => return cg.callIntrinsic(.log, &.{.f64_type}, Type.f64, &.{arg}), |
| 4467 | .f80 => return cg.callIntrinsic(.__logx, &.{.f80_type}, Type.f80, &.{arg}), | 4510 | .f80 => return cg.callIntrinsic(.__logx, &.{.f80_type}, Type.f80, &.{arg}), |
| 4468 | .f128 => return cg.callIntrinsic(.logq, &.{.f128_type}, Type.f128, &.{arg}), | 4511 | .f128 => return cg.callIntrinsic(.logf128, &.{.f128_type}, Type.f128, &.{arg}), |
| 4469 | } | 4512 | } |
| 4470 | } | 4513 | } |
| 4471 | 4514 | ||
| ... | @@ -4475,7 +4518,7 @@ fn floatLog2(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue { | ... | @@ -4475,7 +4518,7 @@ fn floatLog2(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue { |
| 4475 | .f32 => return cg.callIntrinsic(.log2f, &.{.f32_type}, Type.f32, &.{arg}), | 4518 | .f32 => return cg.callIntrinsic(.log2f, &.{.f32_type}, Type.f32, &.{arg}), |
| 4476 | .f64 => return cg.callIntrinsic(.log2, &.{.f64_type}, Type.f64, &.{arg}), | 4519 | .f64 => return cg.callIntrinsic(.log2, &.{.f64_type}, Type.f64, &.{arg}), |
| 4477 | .f80 => return cg.callIntrinsic(.__log2x, &.{.f80_type}, Type.f80, &.{arg}), | 4520 | .f80 => return cg.callIntrinsic(.__log2x, &.{.f80_type}, Type.f80, &.{arg}), |
| 4478 | .f128 => return cg.callIntrinsic(.log2q, &.{.f128_type}, Type.f128, &.{arg}), | 4521 | .f128 => return cg.callIntrinsic(.log2f128, &.{.f128_type}, Type.f128, &.{arg}), |
| 4479 | } | 4522 | } |
| 4480 | } | 4523 | } |
| 4481 | 4524 | ||
| ... | @@ -4485,7 +4528,7 @@ fn floatLog10(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue { | ... | @@ -4485,7 +4528,7 @@ fn floatLog10(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue { |
| 4485 | .f32 => return cg.callIntrinsic(.log10f, &.{.f32_type}, Type.f32, &.{arg}), | 4528 | .f32 => return cg.callIntrinsic(.log10f, &.{.f32_type}, Type.f32, &.{arg}), |
| 4486 | .f64 => return cg.callIntrinsic(.log10, &.{.f64_type}, Type.f64, &.{arg}), | 4529 | .f64 => return cg.callIntrinsic(.log10, &.{.f64_type}, Type.f64, &.{arg}), |
| 4487 | .f80 => return cg.callIntrinsic(.__log10x, &.{.f80_type}, Type.f80, &.{arg}), | 4530 | .f80 => return cg.callIntrinsic(.__log10x, &.{.f80_type}, Type.f80, &.{arg}), |
| 4488 | .f128 => return cg.callIntrinsic(.log10q, &.{.f128_type}, Type.f128, &.{arg}), | 4531 | .f128 => return cg.callIntrinsic(.log10f128, &.{.f128_type}, Type.f128, &.{arg}), |
| 4489 | } | 4532 | } |
| 4490 | } | 4533 | } |
| 4491 | 4534 | ||
| ... | @@ -4503,7 +4546,7 @@ fn floatFloor(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue { | ... | @@ -4503,7 +4546,7 @@ fn floatFloor(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue { |
| 4503 | return .stack; | 4546 | return .stack; |
| 4504 | }, | 4547 | }, |
| 4505 | .f80 => return cg.callIntrinsic(.__floorx, &.{.f80_type}, Type.f80, &.{arg}), | 4548 | .f80 => return cg.callIntrinsic(.__floorx, &.{.f80_type}, Type.f80, &.{arg}), |
| 4506 | .f128 => return cg.callIntrinsic(.floorq, &.{.f128_type}, Type.f128, &.{arg}), | 4549 | .f128 => return cg.callIntrinsic(.floorf128, &.{.f128_type}, Type.f128, &.{arg}), |
| 4507 | } | 4550 | } |
| 4508 | } | 4551 | } |
| 4509 | 4552 | ||
| ... | @@ -4521,7 +4564,7 @@ fn floatCeil(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue { | ... | @@ -4521,7 +4564,7 @@ fn floatCeil(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue { |
| 4521 | return .stack; | 4564 | return .stack; |
| 4522 | }, | 4565 | }, |
| 4523 | .f80 => return cg.callIntrinsic(.__ceilx, &.{.f80_type}, Type.f80, &.{arg}), | 4566 | .f80 => return cg.callIntrinsic(.__ceilx, &.{.f80_type}, Type.f80, &.{arg}), |
| 4524 | .f128 => return cg.callIntrinsic(.ceilq, &.{.f128_type}, Type.f128, &.{arg}), | 4567 | .f128 => return cg.callIntrinsic(.ceilf128, &.{.f128_type}, Type.f128, &.{arg}), |
| 4525 | } | 4568 | } |
| 4526 | } | 4569 | } |
| 4527 | 4570 | ||
| ... | @@ -4539,7 +4582,7 @@ fn floatRound(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue { | ... | @@ -4539,7 +4582,7 @@ fn floatRound(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue { |
| 4539 | return .stack; | 4582 | return .stack; |
| 4540 | }, | 4583 | }, |
| 4541 | .f80 => return cg.callIntrinsic(.__roundx, &.{.f80_type}, Type.f80, &.{arg}), | 4584 | .f80 => return cg.callIntrinsic(.__roundx, &.{.f80_type}, Type.f80, &.{arg}), |
| 4542 | .f128 => return cg.callIntrinsic(.roundq, &.{.f128_type}, Type.f128, &.{arg}), | 4585 | .f128 => return cg.callIntrinsic(.roundf128, &.{.f128_type}, Type.f128, &.{arg}), |
| 4543 | } | 4586 | } |
| 4544 | } | 4587 | } |
| 4545 | 4588 | ||
| ... | @@ -4557,7 +4600,7 @@ fn floatTrunc(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue { | ... | @@ -4557,7 +4600,7 @@ fn floatTrunc(cg: *CodeGen, ty: FloatType, arg: WValue) InnerError!WValue { |
| 4557 | return .stack; | 4600 | return .stack; |
| 4558 | }, | 4601 | }, |
| 4559 | .f80 => return cg.callIntrinsic(.__truncx, &.{.f80_type}, Type.f80, &.{arg}), | 4602 | .f80 => return cg.callIntrinsic(.__truncx, &.{.f80_type}, Type.f80, &.{arg}), |
| 4560 | .f128 => return cg.callIntrinsic(.truncq, &.{.f128_type}, Type.f128, &.{arg}), | 4603 | .f128 => return cg.callIntrinsic(.truncf128, &.{.f128_type}, Type.f128, &.{arg}), |
| 4561 | } | 4604 | } |
| 4562 | } | 4605 | } |
| 4563 | 4606 | ||
| ... | @@ -4929,7 +4972,8 @@ fn lowerPtr(cg: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerErro | ... | @@ -4929,7 +4972,8 @@ fn lowerPtr(cg: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerErro |
| 4929 | const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr; | 4972 | const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr; |
| 4930 | const offset: u64 = prev_offset + ptr.byte_offset; | 4973 | const offset: u64 = prev_offset + ptr.byte_offset; |
| 4931 | return switch (ptr.base_addr) { | 4974 | return switch (ptr.base_addr) { |
| 4932 | .nav => |nav| return if (Type.fromInterned(ip.getNav(nav).resolved.?.type).isRuntimeFnOrHasRuntimeBits(zcu)) | 4975 | .nav => |nav| return if (ip.getNav(nav).getExtern(ip) != null or |
| 4976 | Type.fromInterned(ip.getNav(nav).resolved.?.type).isRuntimeFnOrHasRuntimeBits(zcu)) | ||
| 4933 | .{ .nav_ref = .{ .nav_index = nav, .offset = @intCast(offset) } } | 4977 | .{ .nav_ref = .{ .nav_index = nav, .offset = @intCast(offset) } } |
| 4934 | else | 4978 | else |
| 4935 | .{ .imm32 = @intCast(zcu.navAlignment(nav).forward(@as(u32, 0xaaaaaaaa))) }, | 4979 | .{ .imm32 = @intCast(zcu.navAlignment(nav).forward(@as(u32, 0xaaaaaaaa))) }, |
| ... | @@ -5613,6 +5657,8 @@ fn bitcastClass(cg: *CodeGen, ty: Type) BitcastClass { | ... | @@ -5613,6 +5657,8 @@ fn bitcastClass(cg: *CodeGen, ty: Type) BitcastClass { |
| 5613 | } | 5657 | } |
| 5614 | 5658 | ||
| 5615 | fn bitcast(cg: *CodeGen, dest_ty: Type, src_ty: Type, operand: WValue) InnerError!?WValue { | 5659 | fn bitcast(cg: *CodeGen, dest_ty: Type, src_ty: Type, operand: WValue) InnerError!?WValue { |
| 5660 | if (dest_ty.eql(src_ty)) return null; | ||
| 5661 | |||
| 5616 | const zcu = cg.pt.zcu; | 5662 | const zcu = cg.pt.zcu; |
| 5617 | const src_class = cg.bitcastClass(src_ty); | 5663 | const src_class = cg.bitcastClass(src_ty); |
| 5618 | const dest_class = cg.bitcastClass(dest_ty); | 5664 | const dest_class = cg.bitcastClass(dest_ty); |
src/codegen/wasm/Emit.zig+125-49| ... | @@ -21,7 +21,7 @@ pub const Error = error{ | ... | @@ -21,7 +21,7 @@ pub const Error = error{ |
| 21 | OutOfMemory, | 21 | OutOfMemory, |
| 22 | }; | 22 | }; |
| 23 | 23 | ||
| 24 | pub fn lowerToCode(emit: *Emit) Error!void { | 24 | pub fn lower(emit: *Emit) Error!void { |
| 25 | const mir = &emit.mir; | 25 | const mir = &emit.mir; |
| 26 | const code = emit.code; | 26 | const code = emit.code; |
| 27 | const wasm = emit.wasm; | 27 | const wasm = emit.wasm; |
| ... | @@ -31,6 +31,47 @@ pub fn lowerToCode(emit: *Emit) Error!void { | ... | @@ -31,6 +31,47 @@ pub fn lowerToCode(emit: *Emit) Error!void { |
| 31 | const target = &comp.root_mod.resolved_target.result; | 31 | const target = &comp.root_mod.resolved_target.result; |
| 32 | const is_wasm32 = target.cpu.arch == .wasm32; | 32 | const is_wasm32 = target.cpu.arch == .wasm32; |
| 33 | 33 | ||
| 34 | // Write the locals in the prologue of the function body. | ||
| 35 | try code.ensureUnusedCapacity(gpa, 5 + mir.locals.len * 6 + 38); | ||
| 36 | |||
| 37 | writeUleb128(code, @as(u32, @intCast(mir.locals.len))); | ||
| 38 | |||
| 39 | for (mir.locals) |local| { | ||
| 40 | writeUleb128(code, @as(u32, 1)); | ||
| 41 | code.appendAssumeCapacity(@backingInt(local)); | ||
| 42 | } | ||
| 43 | |||
| 44 | // Stack management section of function prologue. | ||
| 45 | const stack_alignment = mir.prologue.flags.stack_alignment; | ||
| 46 | if (stack_alignment.toByteUnits()) |align_bytes| { | ||
| 47 | // load stack pointer | ||
| 48 | code.appendAssumeCapacity(@backingInt(std.wasm.Opcode.global_get)); | ||
| 49 | try appendStackPointerGlobalIndex(wasm, code, is_obj); | ||
| 50 | // store stack pointer so we can restore it when we return from the function | ||
| 51 | code.appendAssumeCapacity(@backingInt(std.wasm.Opcode.local_tee)); | ||
| 52 | writeUleb128(code, mir.prologue.sp_local); | ||
| 53 | // get the total stack size | ||
| 54 | const aligned_stack: i32 = @intCast(stack_alignment.forward(mir.prologue.stack_size)); | ||
| 55 | code.appendAssumeCapacity(@backingInt(std.wasm.Opcode.i32_const)); | ||
| 56 | writeSleb128(code, aligned_stack); | ||
| 57 | // subtract it from the current stack pointer | ||
| 58 | code.appendAssumeCapacity(@backingInt(std.wasm.Opcode.i32_sub)); | ||
| 59 | // Get negative stack alignment | ||
| 60 | const neg_stack_align = @as(i32, @intCast(align_bytes)) * -1; | ||
| 61 | code.appendAssumeCapacity(@backingInt(std.wasm.Opcode.i32_const)); | ||
| 62 | writeSleb128(code, neg_stack_align); | ||
| 63 | // Bitwise-and the value to get the new stack pointer to ensure the | ||
| 64 | // pointers are aligned with the abi alignment. | ||
| 65 | code.appendAssumeCapacity(@backingInt(std.wasm.Opcode.i32_and)); | ||
| 66 | // The bottom will be used to calculate all stack pointer offsets. | ||
| 67 | code.appendAssumeCapacity(@backingInt(std.wasm.Opcode.local_tee)); | ||
| 68 | writeUleb128(code, mir.prologue.bottom_stack_local); | ||
| 69 | // Store the current stack pointer value into the global stack pointer so other function calls will | ||
| 70 | // start from this value instead and not overwrite the current stack. | ||
| 71 | code.appendAssumeCapacity(@backingInt(std.wasm.Opcode.global_set)); | ||
| 72 | try appendStackPointerGlobalIndex(wasm, code, is_obj); | ||
| 73 | } | ||
| 74 | |||
| 34 | const tags = mir.instructions.items(.tag); | 75 | const tags = mir.instructions.items(.tag); |
| 35 | const datas = mir.instructions.items(.data); | 76 | const datas = mir.instructions.items(.data); |
| 36 | var inst: u32 = 0; | 77 | var inst: u32 = 0; |
| ... | @@ -78,14 +119,21 @@ pub fn lowerToCode(emit: *Emit) Error!void { | ... | @@ -78,14 +119,21 @@ pub fn lowerToCode(emit: *Emit) Error!void { |
| 78 | continue :loop tags[inst]; | 119 | continue :loop tags[inst]; |
| 79 | }, | 120 | }, |
| 80 | .func_ref => { | 121 | .func_ref => { |
| 81 | const indirect_func_idx: Wasm.ZcuIndirectFunctionSetIndex = @fromBackingInt(@intCast( | 122 | try code.ensureUnusedCapacity(gpa, 11); |
| 82 | wasm.zcu_indirect_function_set.getIndex(datas[inst].nav_index).?, | 123 | const opcode: std.wasm.Opcode = if (is_wasm32) .i32_const else .i64_const; |
| 83 | )); | 124 | code.appendAssumeCapacity(@backingInt(opcode)); |
| 84 | code.appendAssumeCapacity(@backingInt(std.wasm.Opcode.i32_const)); | ||
| 85 | if (is_obj) { | 125 | if (is_obj) { |
| 86 | @panic("TODO"); | 126 | try wasm.zcu_relocations.append(gpa, .{ |
| 127 | .offset = @intCast(code.items.len), | ||
| 128 | .pointee = .{ .function_nav = datas[inst].nav_index }, | ||
| 129 | .tag = if (is_wasm32) .table_index_sleb else .table_index_sleb64, | ||
| 130 | .addend = 0, | ||
| 131 | }); | ||
| 132 | appendSlebRelocPlaceholder(code, is_wasm32); | ||
| 87 | } else { | 133 | } else { |
| 88 | writeSleb128(code, 1 + @backingInt(indirect_func_idx)); | 134 | const function_index = Wasm.OutputFunctionIndex.fromIpNav(wasm, datas[inst].nav_index); |
| 135 | const table_index = wasm.flush_buffer.indirect_function_table.getIndex(function_index).? + 1; | ||
| 136 | writeSleb128(code, table_index); | ||
| 89 | } | 137 | } |
| 90 | inst += 1; | 138 | inst += 1; |
| 91 | continue :loop tags[inst]; | 139 | continue :loop tags[inst]; |
| ... | @@ -105,18 +153,17 @@ pub fn lowerToCode(emit: *Emit) Error!void { | ... | @@ -105,18 +153,17 @@ pub fn lowerToCode(emit: *Emit) Error!void { |
| 105 | continue :loop tags[inst]; | 153 | continue :loop tags[inst]; |
| 106 | }, | 154 | }, |
| 107 | .error_name_table_ref => { | 155 | .error_name_table_ref => { |
| 108 | wasm.error_name_table_ref_count += 1; | ||
| 109 | try code.ensureUnusedCapacity(gpa, 11); | 156 | try code.ensureUnusedCapacity(gpa, 11); |
| 110 | const opcode: std.wasm.Opcode = if (is_wasm32) .i32_const else .i64_const; | 157 | const opcode: std.wasm.Opcode = if (is_wasm32) .i32_const else .i64_const; |
| 111 | code.appendAssumeCapacity(@backingInt(opcode)); | 158 | code.appendAssumeCapacity(@backingInt(opcode)); |
| 112 | if (is_obj) { | 159 | if (is_obj) { |
| 113 | try wasm.out_relocs.append(gpa, .{ | 160 | try wasm.zcu_relocations.append(gpa, .{ |
| 114 | .offset = @intCast(code.items.len), | 161 | .offset = @intCast(code.items.len), |
| 115 | .pointee = .{ .symbol_index = try wasm.errorNameTableSymbolIndex() }, | 162 | .pointee = .{ .data_resolution = .__zig_error_name_table }, |
| 116 | .tag = if (is_wasm32) .memory_addr_leb else .memory_addr_leb64, | 163 | .tag = if (is_wasm32) .memory_addr_sleb else .memory_addr_sleb64, |
| 117 | .addend = 0, | 164 | .addend = 0, |
| 118 | }); | 165 | }); |
| 119 | code.appendNTimesAssumeCapacity(0, if (is_wasm32) 5 else 10); | 166 | appendSlebRelocPlaceholder(code, is_wasm32); |
| 120 | 167 | ||
| 121 | inst += 1; | 168 | inst += 1; |
| 122 | continue :loop tags[inst]; | 169 | continue :loop tags[inst]; |
| ... | @@ -164,13 +211,13 @@ pub fn lowerToCode(emit: *Emit) Error!void { | ... | @@ -164,13 +211,13 @@ pub fn lowerToCode(emit: *Emit) Error!void { |
| 164 | try code.ensureUnusedCapacity(gpa, 6); | 211 | try code.ensureUnusedCapacity(gpa, 6); |
| 165 | code.appendAssumeCapacity(@backingInt(std.wasm.Opcode.call)); | 212 | code.appendAssumeCapacity(@backingInt(std.wasm.Opcode.call)); |
| 166 | if (is_obj) { | 213 | if (is_obj) { |
| 167 | try wasm.out_relocs.append(gpa, .{ | 214 | try wasm.zcu_relocations.append(gpa, .{ |
| 168 | .offset = @intCast(code.items.len), | 215 | .offset = @intCast(code.items.len), |
| 169 | .pointee = .{ .symbol_index = try wasm.navSymbolIndex(datas[inst].nav_index) }, | 216 | .pointee = .{ .function_nav = datas[inst].nav_index }, |
| 170 | .tag = .function_index_leb, | 217 | .tag = .function_index_leb, |
| 171 | .addend = 0, | 218 | .addend = 0, |
| 172 | }); | 219 | }); |
| 173 | code.appendNTimesAssumeCapacity(0, 5); | 220 | appendUlebRelocPlaceholder(code); |
| 174 | } else { | 221 | } else { |
| 175 | appendOutputFunctionIndex(code, .fromIpNav(wasm, datas[inst].nav_index)); | 222 | appendOutputFunctionIndex(code, .fromIpNav(wasm, datas[inst].nav_index)); |
| 176 | } | 223 | } |
| ... | @@ -191,13 +238,13 @@ pub fn lowerToCode(emit: *Emit) Error!void { | ... | @@ -191,13 +238,13 @@ pub fn lowerToCode(emit: *Emit) Error!void { |
| 191 | ).?; | 238 | ).?; |
| 192 | if (is_obj) { | 239 | if (is_obj) { |
| 193 | code.appendAssumeCapacity(@backingInt(std.wasm.Opcode.call_indirect)); | 240 | code.appendAssumeCapacity(@backingInt(std.wasm.Opcode.call_indirect)); |
| 194 | try wasm.out_relocs.append(gpa, .{ | 241 | try wasm.zcu_relocations.append(gpa, .{ |
| 195 | .offset = @intCast(code.items.len), | 242 | .offset = @intCast(code.items.len), |
| 196 | .pointee = .{ .type_index = func_ty_index }, | 243 | .pointee = .{ .type_index = func_ty_index }, |
| 197 | .tag = .type_index_leb, | 244 | .tag = .type_index_leb, |
| 198 | .addend = 0, | 245 | .addend = 0, |
| 199 | }); | 246 | }); |
| 200 | code.appendNTimesAssumeCapacity(0, 5); | 247 | appendUlebRelocPlaceholder(code); |
| 201 | } else { | 248 | } else { |
| 202 | const index: Wasm.Flush.FuncTypeIndex = @fromBackingInt(@intCast(wasm.flush_buffer.func_types.getIndex(func_ty_index) orelse { | 249 | const index: Wasm.Flush.FuncTypeIndex = @fromBackingInt(@intCast(wasm.flush_buffer.func_types.getIndex(func_ty_index) orelse { |
| 203 | // In this case we tried to call a function pointer for | 250 | // In this case we tried to call a function pointer for |
| ... | @@ -224,13 +271,13 @@ pub fn lowerToCode(emit: *Emit) Error!void { | ... | @@ -224,13 +271,13 @@ pub fn lowerToCode(emit: *Emit) Error!void { |
| 224 | try code.ensureUnusedCapacity(gpa, 6); | 271 | try code.ensureUnusedCapacity(gpa, 6); |
| 225 | code.appendAssumeCapacity(@backingInt(std.wasm.Opcode.call)); | 272 | code.appendAssumeCapacity(@backingInt(std.wasm.Opcode.call)); |
| 226 | if (is_obj) { | 273 | if (is_obj) { |
| 227 | try wasm.out_relocs.append(gpa, .{ | 274 | try wasm.zcu_relocations.append(gpa, .{ |
| 228 | .offset = @intCast(code.items.len), | 275 | .offset = @intCast(code.items.len), |
| 229 | .pointee = .{ .symbol_index = try wasm.tagTableIndexSymbolIndex(datas[inst].ip_index) }, | 276 | .pointee = .{ .tag_function = datas[inst].ip_index }, |
| 230 | .tag = .function_index_leb, | 277 | .tag = .function_index_leb, |
| 231 | .addend = 0, | 278 | .addend = 0, |
| 232 | }); | 279 | }); |
| 233 | code.appendNTimesAssumeCapacity(0, 5); | 280 | appendUlebRelocPlaceholder(code); |
| 234 | } else { | 281 | } else { |
| 235 | appendOutputFunctionIndex(code, .fromTagIndexType(wasm, datas[inst].ip_index)); | 282 | appendOutputFunctionIndex(code, .fromTagIndexType(wasm, datas[inst].ip_index)); |
| 236 | } | 283 | } |
| ... | @@ -244,14 +291,20 @@ pub fn lowerToCode(emit: *Emit) Error!void { | ... | @@ -244,14 +291,20 @@ pub fn lowerToCode(emit: *Emit) Error!void { |
| 244 | const opcode: std.wasm.Opcode = if (is_wasm32) .i32_const else .i64_const; | 291 | const opcode: std.wasm.Opcode = if (is_wasm32) .i32_const else .i64_const; |
| 245 | code.appendAssumeCapacity(@backingInt(opcode)); | 292 | code.appendAssumeCapacity(@backingInt(opcode)); |
| 246 | if (is_obj) { | 293 | if (is_obj) { |
| 247 | @panic("TODO"); | 294 | try wasm.zcu_relocations.append(gpa, .{ |
| 295 | .offset = @intCast(code.items.len), | ||
| 296 | .pointee = .{ .data_resolution = .__zig_tag_name_table }, | ||
| 297 | .tag = if (is_wasm32) .memory_addr_sleb else .memory_addr_sleb64, | ||
| 298 | .addend = @intCast(wasm.tagIndexTableOffset(datas[inst].ip_index)), | ||
| 299 | }); | ||
| 300 | appendSlebRelocPlaceholder(code, is_wasm32); | ||
| 248 | } else { | 301 | } else { |
| 249 | const addr: u32 = wasm.tagIndexTableAddr(datas[inst].ip_index); | 302 | const addr: u32 = wasm.tagIndexTableAddr(datas[inst].ip_index); |
| 250 | writeSleb128(code, addr); | 303 | writeSleb128(code, addr); |
| 251 | |||
| 252 | inst += 1; | ||
| 253 | continue :loop tags[inst]; | ||
| 254 | } | 304 | } |
| 305 | |||
| 306 | inst += 1; | ||
| 307 | continue :loop tags[inst]; | ||
| 255 | }, | 308 | }, |
| 256 | 309 | ||
| 257 | .call_intrinsic => { | 310 | .call_intrinsic => { |
| ... | @@ -263,13 +316,13 @@ pub fn lowerToCode(emit: *Emit) Error!void { | ... | @@ -263,13 +316,13 @@ pub fn lowerToCode(emit: *Emit) Error!void { |
| 263 | try code.ensureUnusedCapacity(gpa, 6); | 316 | try code.ensureUnusedCapacity(gpa, 6); |
| 264 | code.appendAssumeCapacity(@backingInt(std.wasm.Opcode.call)); | 317 | code.appendAssumeCapacity(@backingInt(std.wasm.Opcode.call)); |
| 265 | if (is_obj) { | 318 | if (is_obj) { |
| 266 | try wasm.out_relocs.append(gpa, .{ | 319 | try wasm.zcu_relocations.append(gpa, .{ |
| 267 | .offset = @intCast(code.items.len), | 320 | .offset = @intCast(code.items.len), |
| 268 | .pointee = .{ .symbol_index = try wasm.symbolNameIndex(symbol_name) }, | 321 | .pointee = .{ .function_name = symbol_name }, |
| 269 | .tag = .function_index_leb, | 322 | .tag = .function_index_leb, |
| 270 | .addend = 0, | 323 | .addend = 0, |
| 271 | }); | 324 | }); |
| 272 | code.appendNTimesAssumeCapacity(0, 5); | 325 | appendUlebRelocPlaceholder(code); |
| 273 | } else { | 326 | } else { |
| 274 | appendOutputFunctionIndex(code, .fromSymbolName(wasm, symbol_name)); | 327 | appendOutputFunctionIndex(code, .fromSymbolName(wasm, symbol_name)); |
| 275 | } | 328 | } |
| ... | @@ -281,18 +334,7 @@ pub fn lowerToCode(emit: *Emit) Error!void { | ... | @@ -281,18 +334,7 @@ pub fn lowerToCode(emit: *Emit) Error!void { |
| 281 | .global_set_sp => { | 334 | .global_set_sp => { |
| 282 | try code.ensureUnusedCapacity(gpa, 6); | 335 | try code.ensureUnusedCapacity(gpa, 6); |
| 283 | code.appendAssumeCapacity(@backingInt(std.wasm.Opcode.global_set)); | 336 | code.appendAssumeCapacity(@backingInt(std.wasm.Opcode.global_set)); |
| 284 | if (is_obj) { | 337 | try appendStackPointerGlobalIndex(wasm, code, is_obj); |
| 285 | try wasm.out_relocs.append(gpa, .{ | ||
| 286 | .offset = @intCast(code.items.len), | ||
| 287 | .pointee = .{ .symbol_index = try wasm.stackPointerSymbolIndex() }, | ||
| 288 | .tag = .global_index_leb, | ||
| 289 | .addend = 0, | ||
| 290 | }); | ||
| 291 | code.appendNTimesAssumeCapacity(0, 5); | ||
| 292 | } else { | ||
| 293 | const sp_global: Wasm.GlobalIndex = .stack_pointer; | ||
| 294 | writeUleb128(code, @backingInt(sp_global)); | ||
| 295 | } | ||
| 296 | 338 | ||
| 297 | inst += 1; | 339 | inst += 1; |
| 298 | continue :loop tags[inst]; | 340 | continue :loop tags[inst]; |
| ... | @@ -960,13 +1002,13 @@ fn uavRefObj(wasm: *Wasm, code: *ArrayList(u8), value: InternPool.Index, offset: | ... | @@ -960,13 +1002,13 @@ fn uavRefObj(wasm: *Wasm, code: *ArrayList(u8), value: InternPool.Index, offset: |
| 960 | try code.ensureUnusedCapacity(gpa, 11); | 1002 | try code.ensureUnusedCapacity(gpa, 11); |
| 961 | code.appendAssumeCapacity(@backingInt(opcode)); | 1003 | code.appendAssumeCapacity(@backingInt(opcode)); |
| 962 | 1004 | ||
| 963 | try wasm.out_relocs.append(gpa, .{ | 1005 | try wasm.zcu_relocations.append(gpa, .{ |
| 964 | .offset = @intCast(code.items.len), | 1006 | .offset = @intCast(code.items.len), |
| 965 | .pointee = .{ .symbol_index = try wasm.uavSymbolIndex(value) }, | 1007 | .pointee = .{ .data_uav = value }, |
| 966 | .tag = if (is_wasm32) .memory_addr_leb else .memory_addr_leb64, | 1008 | .tag = if (is_wasm32) .memory_addr_sleb else .memory_addr_sleb64, |
| 967 | .addend = offset, | 1009 | .addend = offset, |
| 968 | }); | 1010 | }); |
| 969 | code.appendNTimesAssumeCapacity(0, if (is_wasm32) 5 else 10); | 1011 | appendSlebRelocPlaceholder(code, is_wasm32); |
| 970 | } | 1012 | } |
| 971 | 1013 | ||
| 972 | fn uavRefExe(wasm: *Wasm, code: *ArrayList(u8), value: InternPool.Index, offset: i32, is_wasm32: bool) !void { | 1014 | fn uavRefExe(wasm: *Wasm, code: *ArrayList(u8), value: InternPool.Index, offset: i32, is_wasm32: bool) !void { |
| ... | @@ -978,7 +1020,7 @@ fn uavRefExe(wasm: *Wasm, code: *ArrayList(u8), value: InternPool.Index, offset: | ... | @@ -978,7 +1020,7 @@ fn uavRefExe(wasm: *Wasm, code: *ArrayList(u8), value: InternPool.Index, offset: |
| 978 | code.appendAssumeCapacity(@backingInt(opcode)); | 1020 | code.appendAssumeCapacity(@backingInt(opcode)); |
| 979 | 1021 | ||
| 980 | const addr = wasm.uavAddr(value); | 1022 | const addr = wasm.uavAddr(value); |
| 981 | writeUleb128(code, @as(u32, @intCast(@as(i64, addr) + offset))); | 1023 | writeSleb128(code, @as(u32, @intCast(@as(i64, addr) + offset))); |
| 982 | } | 1024 | } |
| 983 | 1025 | ||
| 984 | fn navRefOff(wasm: *Wasm, code: *ArrayList(u8), data: Mir.NavRefOff, is_wasm32: bool) !void { | 1026 | fn navRefOff(wasm: *Wasm, code: *ArrayList(u8), data: Mir.NavRefOff, is_wasm32: bool) !void { |
| ... | @@ -995,16 +1037,16 @@ fn navRefOff(wasm: *Wasm, code: *ArrayList(u8), data: Mir.NavRefOff, is_wasm32: | ... | @@ -995,16 +1037,16 @@ fn navRefOff(wasm: *Wasm, code: *ArrayList(u8), data: Mir.NavRefOff, is_wasm32: |
| 995 | const opcode: std.wasm.Opcode = if (is_wasm32) .i32_const else .i64_const; | 1037 | const opcode: std.wasm.Opcode = if (is_wasm32) .i32_const else .i64_const; |
| 996 | code.appendAssumeCapacity(@backingInt(opcode)); | 1038 | code.appendAssumeCapacity(@backingInt(opcode)); |
| 997 | if (is_obj) { | 1039 | if (is_obj) { |
| 998 | try wasm.out_relocs.append(gpa, .{ | 1040 | try wasm.zcu_relocations.append(gpa, .{ |
| 999 | .offset = @intCast(code.items.len), | 1041 | .offset = @intCast(code.items.len), |
| 1000 | .pointee = .{ .symbol_index = try wasm.navSymbolIndex(data.nav_index) }, | 1042 | .pointee = .{ .data_nav = data.nav_index }, |
| 1001 | .tag = if (is_wasm32) .memory_addr_leb else .memory_addr_leb64, | 1043 | .tag = if (is_wasm32) .memory_addr_sleb else .memory_addr_sleb64, |
| 1002 | .addend = data.offset, | 1044 | .addend = data.offset, |
| 1003 | }); | 1045 | }); |
| 1004 | code.appendNTimesAssumeCapacity(0, if (is_wasm32) 5 else 10); | 1046 | appendSlebRelocPlaceholder(code, is_wasm32); |
| 1005 | } else { | 1047 | } else { |
| 1006 | const addr = wasm.navAddr(data.nav_index); | 1048 | const addr = wasm.navAddr(data.nav_index); |
| 1007 | writeUleb128(code, @as(u32, @intCast(@as(i64, addr) + data.offset))); | 1049 | writeSleb128(code, @as(u32, @intCast(@as(i64, addr) + data.offset))); |
| 1008 | } | 1050 | } |
| 1009 | } | 1051 | } |
| 1010 | 1052 | ||
| ... | @@ -1012,6 +1054,40 @@ fn appendOutputFunctionIndex(code: *ArrayList(u8), i: Wasm.OutputFunctionIndex) | ... | @@ -1012,6 +1054,40 @@ fn appendOutputFunctionIndex(code: *ArrayList(u8), i: Wasm.OutputFunctionIndex) |
| 1012 | writeUleb128(code, @backingInt(i)); | 1054 | writeUleb128(code, @backingInt(i)); |
| 1013 | } | 1055 | } |
| 1014 | 1056 | ||
| 1057 | fn appendStackPointerGlobalIndex( | ||
| 1058 | wasm: *Wasm, | ||
| 1059 | code: *ArrayList(u8), | ||
| 1060 | is_obj: bool, | ||
| 1061 | ) Error!void { | ||
| 1062 | if (is_obj) { | ||
| 1063 | try wasm.zcu_relocations.append(wasm.base.comp.gpa, .{ | ||
| 1064 | .offset = @intCast(code.items.len), | ||
| 1065 | .pointee = .stack_pointer, | ||
| 1066 | .tag = .global_index_leb, | ||
| 1067 | .addend = 0, | ||
| 1068 | }); | ||
| 1069 | appendUlebRelocPlaceholder(code); | ||
| 1070 | } else { | ||
| 1071 | const sp_global: Wasm.GlobalIndex = .stack_pointer; | ||
| 1072 | writeUleb128(code, @backingInt(sp_global)); | ||
| 1073 | } | ||
| 1074 | } | ||
| 1075 | |||
| 1076 | fn appendUlebRelocPlaceholder(code: *ArrayList(u8)) void { | ||
| 1077 | code.appendSliceAssumeCapacity(&.{ 0x80, 0x80, 0x80, 0x80, 0x00 }); | ||
| 1078 | } | ||
| 1079 | |||
| 1080 | fn appendSlebRelocPlaceholder(code: *ArrayList(u8), is_wasm32: bool) void { | ||
| 1081 | if (is_wasm32) { | ||
| 1082 | code.appendSliceAssumeCapacity(&.{ 0x80, 0x80, 0x80, 0x80, 0x00 }); | ||
| 1083 | } else { | ||
| 1084 | code.appendSliceAssumeCapacity(&.{ | ||
| 1085 | 0x80, 0x80, 0x80, 0x80, 0x80, | ||
| 1086 | 0x80, 0x80, 0x80, 0x80, 0x00, | ||
| 1087 | }); | ||
| 1088 | } | ||
| 1089 | } | ||
| 1090 | |||
| 1015 | fn writeUleb128(code: *ArrayList(u8), arg: anytype) void { | 1091 | fn writeUleb128(code: *ArrayList(u8), arg: anytype) void { |
| 1016 | var w: std.Io.Writer = .fixed(code.unusedCapacitySlice()); | 1092 | var w: std.Io.Writer = .fixed(code.unusedCapacitySlice()); |
| 1017 | w.writeUleb128(arg) catch unreachable; | 1093 | w.writeUleb128(arg) catch unreachable; |
src/codegen/wasm/Mir.zig+22-70| ... | @@ -114,7 +114,7 @@ pub const Inst = struct { | ... | @@ -114,7 +114,7 @@ pub const Inst = struct { |
| 114 | /// | 114 | /// |
| 115 | /// Uses `payload` pointing to a `NavRefOff`. | 115 | /// Uses `payload` pointing to a `NavRefOff`. |
| 116 | nav_ref_off, | 116 | nav_ref_off, |
| 117 | /// Lowers to an i32_const which is the index of the function in the | 117 | /// Lowers to an iNN_const which is the index of the function in the |
| 118 | /// table section. | 118 | /// table section. |
| 119 | /// | 119 | /// |
| 120 | /// Uses `nav_index`. | 120 | /// Uses `nav_index`. |
| ... | @@ -661,8 +661,8 @@ pub const Inst = struct { | ... | @@ -661,8 +661,8 @@ pub const Inst = struct { |
| 661 | 661 | ||
| 662 | comptime { | 662 | comptime { |
| 663 | switch (builtin.mode) { | 663 | switch (builtin.mode) { |
| 664 | .Debug, .ReleaseSafe => {}, | 664 | .debug, .safe => {}, |
| 665 | .ReleaseFast, .ReleaseSmall => assert(@sizeOf(Data) == 4), | 665 | .fast, .small => assert(@sizeOf(Data) == 4), |
| 666 | } | 666 | } |
| 667 | } | 667 | } |
| 668 | }; | 668 | }; |
| ... | @@ -679,60 +679,12 @@ pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void { | ... | @@ -679,60 +679,12 @@ pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void { |
| 679 | } | 679 | } |
| 680 | 680 | ||
| 681 | pub fn lower(mir: *const Mir, wasm: *Wasm, code: *std.ArrayList(u8)) std.mem.Allocator.Error!void { | 681 | pub fn lower(mir: *const Mir, wasm: *Wasm, code: *std.ArrayList(u8)) std.mem.Allocator.Error!void { |
| 682 | const gpa = wasm.base.comp.gpa; | ||
| 683 | |||
| 684 | // Write the locals in the prologue of the function body. | ||
| 685 | try code.ensureUnusedCapacity(gpa, 5 + mir.locals.len * 6 + 38); | ||
| 686 | |||
| 687 | var w: std.Io.Writer = .fixed(code.unusedCapacitySlice()); | ||
| 688 | |||
| 689 | w.writeLeb128(@as(u32, @intCast(mir.locals.len))) catch unreachable; | ||
| 690 | |||
| 691 | for (mir.locals) |local| { | ||
| 692 | w.writeLeb128(@as(u32, 1)) catch unreachable; | ||
| 693 | w.writeByte(@backingInt(local)) catch unreachable; | ||
| 694 | } | ||
| 695 | |||
| 696 | // Stack management section of function prologue. | ||
| 697 | const stack_alignment = mir.prologue.flags.stack_alignment; | ||
| 698 | if (stack_alignment.toByteUnits()) |align_bytes| { | ||
| 699 | const sp_global: Wasm.GlobalIndex = .stack_pointer; | ||
| 700 | // load stack pointer | ||
| 701 | w.writeByte(@backingInt(std.wasm.Opcode.global_get)) catch unreachable; | ||
| 702 | w.writeUleb128(@backingInt(sp_global)) catch unreachable; | ||
| 703 | // store stack pointer so we can restore it when we return from the function | ||
| 704 | w.writeByte(@backingInt(std.wasm.Opcode.local_tee)) catch unreachable; | ||
| 705 | w.writeUleb128(mir.prologue.sp_local) catch unreachable; | ||
| 706 | // get the total stack size | ||
| 707 | const aligned_stack: i32 = @intCast(stack_alignment.forward(mir.prologue.stack_size)); | ||
| 708 | w.writeByte(@backingInt(std.wasm.Opcode.i32_const)) catch unreachable; | ||
| 709 | w.writeSleb128(aligned_stack) catch unreachable; | ||
| 710 | // subtract it from the current stack pointer | ||
| 711 | w.writeByte(@backingInt(std.wasm.Opcode.i32_sub)) catch unreachable; | ||
| 712 | // Get negative stack alignment | ||
| 713 | const neg_stack_align = @as(i32, @intCast(align_bytes)) * -1; | ||
| 714 | w.writeByte(@backingInt(std.wasm.Opcode.i32_const)) catch unreachable; | ||
| 715 | w.writeSleb128(neg_stack_align) catch unreachable; | ||
| 716 | // Bitwise-and the value to get the new stack pointer to ensure the | ||
| 717 | // pointers are aligned with the abi alignment. | ||
| 718 | w.writeByte(@backingInt(std.wasm.Opcode.i32_and)) catch unreachable; | ||
| 719 | // The bottom will be used to calculate all stack pointer offsets. | ||
| 720 | w.writeByte(@backingInt(std.wasm.Opcode.local_tee)) catch unreachable; | ||
| 721 | w.writeUleb128(mir.prologue.bottom_stack_local) catch unreachable; | ||
| 722 | // Store the current stack pointer value into the global stack pointer so other function calls will | ||
| 723 | // start from this value instead and not overwrite the current stack. | ||
| 724 | w.writeByte(@backingInt(std.wasm.Opcode.global_set)) catch unreachable; | ||
| 725 | w.writeUleb128(@backingInt(sp_global)) catch unreachable; | ||
| 726 | } | ||
| 727 | |||
| 728 | code.items.len += w.end; | ||
| 729 | |||
| 730 | var emit: Emit = .{ | 682 | var emit: Emit = .{ |
| 731 | .mir = mir.*, | 683 | .mir = mir.*, |
| 732 | .wasm = wasm, | 684 | .wasm = wasm, |
| 733 | .code = code, | 685 | .code = code, |
| 734 | }; | 686 | }; |
| 735 | try emit.lowerToCode(); | 687 | try emit.lower(); |
| 736 | } | 688 | } |
| 737 | 689 | ||
| 738 | pub fn extraData(self: *const Mir, comptime T: type, index: usize) struct { data: T, end: usize } { | 690 | pub fn extraData(self: *const Mir, comptime T: type, index: usize) struct { data: T, end: usize } { |
| ... | @@ -991,48 +943,48 @@ pub const Intrinsic = enum(u32) { | ... | @@ -991,48 +943,48 @@ pub const Intrinsic = enum(u32) { |
| 991 | __udivti3, | 943 | __udivti3, |
| 992 | __umodei5, | 944 | __umodei5, |
| 993 | __umodti3, | 945 | __umodti3, |
| 994 | ceilq, | 946 | ceilf128, |
| 995 | cos, | 947 | cos, |
| 996 | cosf, | 948 | cosf, |
| 997 | cosq, | 949 | cosf128, |
| 998 | exp, | 950 | exp, |
| 999 | exp2, | 951 | exp2, |
| 1000 | exp2f, | 952 | exp2f, |
| 1001 | exp2q, | 953 | exp2f128, |
| 1002 | expf, | 954 | expf, |
| 1003 | expq, | 955 | expf128, |
| 1004 | fabsq, | 956 | fabsf128, |
| 1005 | floorq, | 957 | floorf128, |
| 1006 | fma, | 958 | fma, |
| 1007 | fmaf, | 959 | fmaf, |
| 1008 | fmaq, | 960 | fmaf128, |
| 1009 | fmax, | 961 | fmax, |
| 1010 | fmaxf, | 962 | fmaxf, |
| 1011 | fmaxq, | 963 | fmaxf128, |
| 1012 | fmin, | 964 | fmin, |
| 1013 | fminf, | 965 | fminf, |
| 1014 | fminq, | 966 | fminf128, |
| 1015 | fmod, | 967 | fmod, |
| 1016 | fmodf, | 968 | fmodf, |
| 1017 | fmodq, | 969 | fmodf128, |
| 1018 | log, | 970 | log, |
| 1019 | log10, | 971 | log10, |
| 1020 | log10f, | 972 | log10f, |
| 1021 | log10q, | 973 | log10f128, |
| 1022 | log2, | 974 | log2, |
| 1023 | log2f, | 975 | log2f, |
| 1024 | log2q, | 976 | log2f128, |
| 1025 | logf, | 977 | logf, |
| 1026 | logq, | 978 | logf128, |
| 1027 | roundq, | 979 | roundf128, |
| 1028 | sin, | 980 | sin, |
| 1029 | sinf, | 981 | sinf, |
| 1030 | sinq, | 982 | sinf128, |
| 1031 | sqrtq, | 983 | sqrtf128, |
| 1032 | tan, | 984 | tan, |
| 1033 | tanf, | 985 | tanf, |
| 1034 | tanq, | 986 | tanf128, |
| 1035 | truncq, | 987 | truncf128, |
| 1036 | memcpy, | 988 | memcpy, |
| 1037 | memmove, | 989 | memmove, |
| 1038 | memset, | 990 | memset, |
src/codegen/wasm/abi.zig+72-22| ... | @@ -11,21 +11,53 @@ const assert = std.debug.assert; | ... | @@ -11,21 +11,53 @@ const assert = std.debug.assert; |
| 11 | const Type = @import("../../Type.zig"); | 11 | const Type = @import("../../Type.zig"); |
| 12 | const Zcu = @import("../../Zcu.zig"); | 12 | const Zcu = @import("../../Zcu.zig"); |
| 13 | 13 | ||
| 14 | /// Defines how to pass a type as part of a function signature, | 14 | /// Describes how the Wasm backend represents a C ABI value. |
| 15 | /// both for parameters as well as return values. | ||
| 16 | pub const Class = union(enum) { | 15 | pub const Class = union(enum) { |
| 17 | direct: Type, | 16 | direct: Type, |
| 17 | double_i64, | ||
| 18 | indirect, | 18 | indirect, |
| 19 | unrolled: struct { | ||
| 20 | elem_type: Type, | ||
| 21 | len: u32, | ||
| 22 | }, | ||
| 19 | }; | 23 | }; |
| 20 | 24 | ||
| 21 | /// Classifies a given Zig type to determine how they must be passed | 25 | pub const LlvmClass = union(enum) { |
| 22 | /// or returned as value within a wasm function. | 26 | direct: Type, |
| 23 | pub fn classifyType(ty: Type, zcu: *const Zcu) Class { | 27 | indirect, |
| 28 | }; | ||
| 29 | |||
| 30 | pub fn classifyType(ty: Type, zcu: *const Zcu, target: *const Target) Class { | ||
| 31 | if (ty.zigTypeTag(zcu) == .vector) { | ||
| 32 | if (!(ty.bitSize(zcu) == 128 and target.cpu.has(.wasm, .simd128))) { | ||
| 33 | const elem_type = ty.childType(zcu); | ||
| 34 | return .{ .unrolled = .{ | ||
| 35 | .elem_type = elem_type, | ||
| 36 | .len = ty.vectorLen(zcu), | ||
| 37 | } }; | ||
| 38 | } | ||
| 39 | return .{ .direct = ty }; | ||
| 40 | } | ||
| 41 | |||
| 42 | return switch (classifyTypeForLlvm(ty, zcu)) { | ||
| 43 | .direct => |scalar_ty| if (scalar_ty.bitSize(zcu) > 64) | ||
| 44 | .double_i64 | ||
| 45 | else | ||
| 46 | .{ .direct = scalar_ty }, | ||
| 47 | .indirect => .indirect, | ||
| 48 | }; | ||
| 49 | } | ||
| 50 | |||
| 51 | pub fn classifyTypeForLlvm(ty: Type, zcu: *const Zcu) LlvmClass { | ||
| 24 | const ip = &zcu.intern_pool; | 52 | const ip = &zcu.intern_pool; |
| 25 | assert(ty.hasRuntimeBits(zcu)); | 53 | assert(ty.hasRuntimeBits(zcu)); |
| 26 | switch (ty.zigTypeTag(zcu)) { | 54 | switch (ty.zigTypeTag(zcu)) { |
| 27 | .int, .@"enum", .error_set => return .{ .direct = ty }, | 55 | .int, .@"enum", .error_set => return .{ .direct = ty }, |
| 28 | .float => return .{ .direct = ty }, | 56 | .float => return switch (ty.floatBits(zcu.getTarget())) { |
| 57 | else => unreachable, | ||
| 58 | 16, 32, 64, 128 => .{ .direct = ty }, | ||
| 59 | 80 => .indirect, | ||
| 60 | }, | ||
| 29 | .bool => return .{ .direct = ty }, | 61 | .bool => return .{ .direct = ty }, |
| 30 | .vector => return .{ .direct = ty }, | 62 | .vector => return .{ .direct = ty }, |
| 31 | .array => return .indirect, | 63 | .array => return .indirect, |
| ... | @@ -39,20 +71,35 @@ pub fn classifyType(ty: Type, zcu: *const Zcu) Class { | ... | @@ -39,20 +71,35 @@ pub fn classifyType(ty: Type, zcu: *const Zcu) Class { |
| 39 | }, | 71 | }, |
| 40 | .@"struct" => { | 72 | .@"struct" => { |
| 41 | const struct_type = zcu.typeToStruct(ty).?; | 73 | const struct_type = zcu.typeToStruct(ty).?; |
| 42 | if (struct_type.layout == .@"packed") { | 74 | switch (struct_type.layout) { |
| 43 | return .{ .direct = ty }; | 75 | .auto => unreachable, |
| 44 | } | 76 | .@"packed" => return .{ .direct = ty }, |
| 45 | if (struct_type.field_types.len > 1) { | 77 | .@"extern" => {}, |
| 46 | // The struct type is non-scalar. | ||
| 47 | return .indirect; | ||
| 48 | } | 78 | } |
| 49 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[0]); | 79 | var opt_single_field_ty: ?Type = null; |
| 50 | const explicit_align = struct_type.field_aligns.getOrNone(ip, 0); | 80 | for (struct_type.field_types.get(ip), 0..) |field_ty_index, field_index| { |
| 51 | if (explicit_align != .none) { | 81 | const field_ty: Type = .fromInterned(field_ty_index); |
| 52 | if (explicit_align.compareStrict(.gt, field_ty.abiAlignment(zcu))) | 82 | if (!field_ty.hasRuntimeBits(zcu)) continue; |
| 83 | |||
| 84 | if (opt_single_field_ty != null) { | ||
| 85 | return .indirect; | ||
| 86 | } | ||
| 87 | |||
| 88 | const field_align = struct_type.field_aligns.getOrNone(ip, field_index); | ||
| 89 | if (field_align != .none and field_align.compareStrict(.gt, field_ty.abiAlignment(zcu))) { | ||
| 53 | return .indirect; | 90 | return .indirect; |
| 91 | } | ||
| 92 | opt_single_field_ty = field_ty; | ||
| 54 | } | 93 | } |
| 55 | return classifyType(field_ty, zcu); | 94 | const single_field_ty = opt_single_field_ty.?; |
| 95 | if (single_field_ty.zigTypeTag(zcu) == .array) { | ||
| 96 | switch (single_field_ty.arrayLenIncludingSentinel(zcu)) { | ||
| 97 | 0 => unreachable, | ||
| 98 | 1 => return classifyTypeForLlvm(single_field_ty.childType(zcu), zcu), | ||
| 99 | else => {}, | ||
| 100 | } | ||
| 101 | } | ||
| 102 | return classifyTypeForLlvm(single_field_ty, zcu); | ||
| 56 | }, | 103 | }, |
| 57 | .@"union" => { | 104 | .@"union" => { |
| 58 | const union_obj = zcu.typeToUnion(ty).?; | 105 | const union_obj = zcu.typeToUnion(ty).?; |
| ... | @@ -63,7 +110,14 @@ pub fn classifyType(ty: Type, zcu: *const Zcu) Class { | ... | @@ -63,7 +110,14 @@ pub fn classifyType(ty: Type, zcu: *const Zcu) Class { |
| 63 | assert(layout.tag_size == 0); | 110 | assert(layout.tag_size == 0); |
| 64 | if (union_obj.field_types.len > 1) return .indirect; | 111 | if (union_obj.field_types.len > 1) return .indirect; |
| 65 | const first_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[0]); | 112 | const first_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[0]); |
| 66 | return classifyType(first_field_ty, zcu); | 113 | if (first_field_ty.zigTypeTag(zcu) == .array) { |
| 114 | switch (first_field_ty.arrayLenIncludingSentinel(zcu)) { | ||
| 115 | 0 => unreachable, | ||
| 116 | 1 => return classifyTypeForLlvm(first_field_ty.childType(zcu), zcu), | ||
| 117 | else => {}, | ||
| 118 | } | ||
| 119 | } | ||
| 120 | return classifyTypeForLlvm(first_field_ty, zcu); | ||
| 67 | }, | 121 | }, |
| 68 | .error_union, | 122 | .error_union, |
| 69 | .frame, | 123 | .frame, |
| ... | @@ -82,7 +136,3 @@ pub fn classifyType(ty: Type, zcu: *const Zcu) Class { | ... | @@ -82,7 +136,3 @@ pub fn classifyType(ty: Type, zcu: *const Zcu) Class { |
| 82 | => unreachable, | 136 | => unreachable, |
| 83 | } | 137 | } |
| 84 | } | 138 | } |
| 85 | |||
| 86 | pub fn lowerAsDoubleI64(scalar_ty: Type, zcu: *const Zcu) bool { | ||
| 87 | return scalar_ty.bitSize(zcu) > 64; | ||
| 88 | } |
src/codegen/x86_64/CodeGen.zig+194-312| ... | @@ -1301,7 +1301,7 @@ fn addInst(self: *CodeGen, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index { | ... | @@ -1301,7 +1301,7 @@ fn addInst(self: *CodeGen, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index { |
| 1301 | } | 1301 | } |
| 1302 | 1302 | ||
| 1303 | fn addExtra(self: *CodeGen, extra: anytype) Allocator.Error!u32 { | 1303 | fn addExtra(self: *CodeGen, extra: anytype) Allocator.Error!u32 { |
| 1304 | const field_count = std.meta.fieldNames(@TypeOf(extra)).len; | 1304 | const field_count = @typeInfo(@TypeOf(extra)).@"struct".field_names.len; |
| 1305 | try self.mir_extra.ensureUnusedCapacity(self.gpa, field_count); | 1305 | try self.mir_extra.ensureUnusedCapacity(self.gpa, field_count); |
| 1306 | return self.addExtraAssumeCapacity(extra); | 1306 | return self.addExtraAssumeCapacity(extra); |
| 1307 | } | 1307 | } |
| ... | @@ -2152,7 +2152,7 @@ fn gen( | ... | @@ -2152,7 +2152,7 @@ fn gen( |
| 2152 | 2152 | ||
| 2153 | const epilogue = if (self.epilogue_relocs.items.len > 0) epilogue: { | 2153 | const epilogue = if (self.epilogue_relocs.items.len > 0) epilogue: { |
| 2154 | var last_inst: Mir.Inst.Index = @intCast(self.mir_instructions.len - 1); | 2154 | var last_inst: Mir.Inst.Index = @intCast(self.mir_instructions.len - 1); |
| 2155 | while (self.epilogue_relocs.getLast() == last_inst) { | 2155 | while (self.epilogue_relocs.last() == last_inst) { |
| 2156 | self.epilogue_relocs.items.len -= 1; | 2156 | self.epilogue_relocs.items.len -= 1; |
| 2157 | self.mir_instructions.set(last_inst, .{ | 2157 | self.mir_instructions.set(last_inst, .{ |
| 2158 | .tag = .pseudo, | 2158 | .tag = .pseudo, |
| ... | @@ -34436,7 +34436,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -34436,7 +34436,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 34436 | .call_frame = .{ .alignment = .@"16" }, | 34436 | .call_frame = .{ .alignment = .@"16" }, |
| 34437 | .extra_temps = .{ | 34437 | .extra_temps = .{ |
| 34438 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, | 34438 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, |
| 34439 | .{ .type = .usize, .kind = .{ .extern_func = "truncq" } }, | 34439 | .{ .type = .usize, .kind = .{ .extern_func = "truncf128" } }, |
| 34440 | .unused, | 34440 | .unused, |
| 34441 | .unused, | 34441 | .unused, |
| 34442 | .unused, | 34442 | .unused, |
| ... | @@ -34470,7 +34470,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -34470,7 +34470,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 34470 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 34470 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 34471 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, | 34471 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, |
| 34472 | .{ .type = .f128, .kind = .mem }, | 34472 | .{ .type = .f128, .kind = .mem }, |
| 34473 | .{ .type = .usize, .kind = .{ .extern_func = "truncq" } }, | 34473 | .{ .type = .usize, .kind = .{ .extern_func = "truncf128" } }, |
| 34474 | .unused, | 34474 | .unused, |
| 34475 | .unused, | 34475 | .unused, |
| 34476 | .unused, | 34476 | .unused, |
| ... | @@ -34505,7 +34505,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -34505,7 +34505,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 34505 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 34505 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 34506 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, | 34506 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, |
| 34507 | .{ .type = .f128, .kind = .mem }, | 34507 | .{ .type = .f128, .kind = .mem }, |
| 34508 | .{ .type = .usize, .kind = .{ .extern_func = "truncq" } }, | 34508 | .{ .type = .usize, .kind = .{ .extern_func = "truncf128" } }, |
| 34509 | .unused, | 34509 | .unused, |
| 34510 | .unused, | 34510 | .unused, |
| 34511 | .unused, | 34511 | .unused, |
| ... | @@ -34540,7 +34540,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -34540,7 +34540,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 34540 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 34540 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 34541 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, | 34541 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, |
| 34542 | .{ .type = .f128, .kind = .mem }, | 34542 | .{ .type = .f128, .kind = .mem }, |
| 34543 | .{ .type = .usize, .kind = .{ .extern_func = "truncq" } }, | 34543 | .{ .type = .usize, .kind = .{ .extern_func = "truncf128" } }, |
| 34544 | .unused, | 34544 | .unused, |
| 34545 | .unused, | 34545 | .unused, |
| 34546 | .unused, | 34546 | .unused, |
| ... | @@ -34575,7 +34575,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -34575,7 +34575,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 34575 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 34575 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 34576 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 34576 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 34577 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, | 34577 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, |
| 34578 | .{ .type = .usize, .kind = .{ .extern_func = "truncq" } }, | 34578 | .{ .type = .usize, .kind = .{ .extern_func = "truncf128" } }, |
| 34579 | .unused, | 34579 | .unused, |
| 34580 | .unused, | 34580 | .unused, |
| 34581 | .unused, | 34581 | .unused, |
| ... | @@ -34612,7 +34612,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -34612,7 +34612,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 34612 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 34612 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 34613 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 34613 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 34614 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, | 34614 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, |
| 34615 | .{ .type = .usize, .kind = .{ .extern_func = "truncq" } }, | 34615 | .{ .type = .usize, .kind = .{ .extern_func = "truncf128" } }, |
| 34616 | .unused, | 34616 | .unused, |
| 34617 | .unused, | 34617 | .unused, |
| 34618 | .unused, | 34618 | .unused, |
| ... | @@ -34649,7 +34649,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -34649,7 +34649,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 34649 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 34649 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 34650 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 34650 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 34651 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, | 34651 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, |
| 34652 | .{ .type = .usize, .kind = .{ .extern_func = "truncq" } }, | 34652 | .{ .type = .usize, .kind = .{ .extern_func = "truncf128" } }, |
| 34653 | .unused, | 34653 | .unused, |
| 34654 | .unused, | 34654 | .unused, |
| 34655 | .unused, | 34655 | .unused, |
| ... | @@ -34688,7 +34688,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -34688,7 +34688,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 34688 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, | 34688 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, |
| 34689 | .{ .type = .f128, .kind = .mem }, | 34689 | .{ .type = .f128, .kind = .mem }, |
| 34690 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 34690 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 34691 | .{ .type = .usize, .kind = .{ .extern_func = "truncq" } }, | 34691 | .{ .type = .usize, .kind = .{ .extern_func = "truncf128" } }, |
| 34692 | .unused, | 34692 | .unused, |
| 34693 | .unused, | 34693 | .unused, |
| 34694 | .unused, | 34694 | .unused, |
| ... | @@ -34727,7 +34727,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -34727,7 +34727,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 34727 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, | 34727 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, |
| 34728 | .{ .type = .f128, .kind = .mem }, | 34728 | .{ .type = .f128, .kind = .mem }, |
| 34729 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 34729 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 34730 | .{ .type = .usize, .kind = .{ .extern_func = "truncq" } }, | 34730 | .{ .type = .usize, .kind = .{ .extern_func = "truncf128" } }, |
| 34731 | .unused, | 34731 | .unused, |
| 34732 | .unused, | 34732 | .unused, |
| 34733 | .unused, | 34733 | .unused, |
| ... | @@ -34766,7 +34766,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -34766,7 +34766,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 34766 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, | 34766 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, |
| 34767 | .{ .type = .f128, .kind = .mem }, | 34767 | .{ .type = .f128, .kind = .mem }, |
| 34768 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 34768 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 34769 | .{ .type = .usize, .kind = .{ .extern_func = "truncq" } }, | 34769 | .{ .type = .usize, .kind = .{ .extern_func = "truncf128" } }, |
| 34770 | .unused, | 34770 | .unused, |
| 34771 | .unused, | 34771 | .unused, |
| 34772 | .unused, | 34772 | .unused, |
| ... | @@ -35960,8 +35960,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -35960,8 +35960,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 35960 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, | 35960 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, |
| 35961 | .{ .type = .usize, .kind = .{ .extern_func = switch (direction) { | 35961 | .{ .type = .usize, .kind = .{ .extern_func = switch (direction) { |
| 35962 | else => unreachable, | 35962 | else => unreachable, |
| 35963 | .zero => "truncq", | 35963 | .zero => "truncf128", |
| 35964 | .down => "floorq", | 35964 | .down => "floorf128", |
| 35965 | } } }, | 35965 | } } }, |
| 35966 | .unused, | 35966 | .unused, |
| 35967 | .unused, | 35967 | .unused, |
| ... | @@ -35998,8 +35998,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -35998,8 +35998,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 35998 | .{ .type = .f128, .kind = .mem }, | 35998 | .{ .type = .f128, .kind = .mem }, |
| 35999 | .{ .type = .usize, .kind = .{ .extern_func = switch (direction) { | 35999 | .{ .type = .usize, .kind = .{ .extern_func = switch (direction) { |
| 36000 | else => unreachable, | 36000 | else => unreachable, |
| 36001 | .zero => "truncq", | 36001 | .zero => "truncf128", |
| 36002 | .down => "floorq", | 36002 | .down => "floorf128", |
| 36003 | } } }, | 36003 | } } }, |
| 36004 | .unused, | 36004 | .unused, |
| 36005 | .unused, | 36005 | .unused, |
| ... | @@ -36037,8 +36037,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -36037,8 +36037,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 36037 | .{ .type = .f128, .kind = .mem }, | 36037 | .{ .type = .f128, .kind = .mem }, |
| 36038 | .{ .type = .usize, .kind = .{ .extern_func = switch (direction) { | 36038 | .{ .type = .usize, .kind = .{ .extern_func = switch (direction) { |
| 36039 | else => unreachable, | 36039 | else => unreachable, |
| 36040 | .zero => "truncq", | 36040 | .zero => "truncf128", |
| 36041 | .down => "floorq", | 36041 | .down => "floorf128", |
| 36042 | } } }, | 36042 | } } }, |
| 36043 | .unused, | 36043 | .unused, |
| 36044 | .unused, | 36044 | .unused, |
| ... | @@ -36076,8 +36076,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -36076,8 +36076,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 36076 | .{ .type = .f128, .kind = .mem }, | 36076 | .{ .type = .f128, .kind = .mem }, |
| 36077 | .{ .type = .usize, .kind = .{ .extern_func = switch (direction) { | 36077 | .{ .type = .usize, .kind = .{ .extern_func = switch (direction) { |
| 36078 | else => unreachable, | 36078 | else => unreachable, |
| 36079 | .zero => "truncq", | 36079 | .zero => "truncf128", |
| 36080 | .down => "floorq", | 36080 | .down => "floorf128", |
| 36081 | } } }, | 36081 | } } }, |
| 36082 | .unused, | 36082 | .unused, |
| 36083 | .unused, | 36083 | .unused, |
| ... | @@ -36115,8 +36115,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -36115,8 +36115,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 36115 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, | 36115 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, |
| 36116 | .{ .type = .usize, .kind = .{ .extern_func = switch (direction) { | 36116 | .{ .type = .usize, .kind = .{ .extern_func = switch (direction) { |
| 36117 | else => unreachable, | 36117 | else => unreachable, |
| 36118 | .zero => "truncq", | 36118 | .zero => "truncf128", |
| 36119 | .down => "floorq", | 36119 | .down => "floorf128", |
| 36120 | } } }, | 36120 | } } }, |
| 36121 | .unused, | 36121 | .unused, |
| 36122 | .unused, | 36122 | .unused, |
| ... | @@ -36156,8 +36156,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -36156,8 +36156,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 36156 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, | 36156 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, |
| 36157 | .{ .type = .usize, .kind = .{ .extern_func = switch (direction) { | 36157 | .{ .type = .usize, .kind = .{ .extern_func = switch (direction) { |
| 36158 | else => unreachable, | 36158 | else => unreachable, |
| 36159 | .zero => "truncq", | 36159 | .zero => "truncf128", |
| 36160 | .down => "floorq", | 36160 | .down => "floorf128", |
| 36161 | } } }, | 36161 | } } }, |
| 36162 | .unused, | 36162 | .unused, |
| 36163 | .unused, | 36163 | .unused, |
| ... | @@ -36197,8 +36197,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -36197,8 +36197,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 36197 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, | 36197 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, |
| 36198 | .{ .type = .usize, .kind = .{ .extern_func = switch (direction) { | 36198 | .{ .type = .usize, .kind = .{ .extern_func = switch (direction) { |
| 36199 | else => unreachable, | 36199 | else => unreachable, |
| 36200 | .zero => "truncq", | 36200 | .zero => "truncf128", |
| 36201 | .down => "floorq", | 36201 | .down => "floorf128", |
| 36202 | } } }, | 36202 | } } }, |
| 36203 | .unused, | 36203 | .unused, |
| 36204 | .unused, | 36204 | .unused, |
| ... | @@ -36240,8 +36240,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -36240,8 +36240,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 36240 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 36240 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 36241 | .{ .type = .usize, .kind = .{ .extern_func = switch (direction) { | 36241 | .{ .type = .usize, .kind = .{ .extern_func = switch (direction) { |
| 36242 | else => unreachable, | 36242 | else => unreachable, |
| 36243 | .zero => "truncq", | 36243 | .zero => "truncf128", |
| 36244 | .down => "floorq", | 36244 | .down => "floorf128", |
| 36245 | } } }, | 36245 | } } }, |
| 36246 | .unused, | 36246 | .unused, |
| 36247 | .unused, | 36247 | .unused, |
| ... | @@ -36283,8 +36283,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -36283,8 +36283,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 36283 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 36283 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 36284 | .{ .type = .usize, .kind = .{ .extern_func = switch (direction) { | 36284 | .{ .type = .usize, .kind = .{ .extern_func = switch (direction) { |
| 36285 | else => unreachable, | 36285 | else => unreachable, |
| 36286 | .zero => "truncq", | 36286 | .zero => "truncf128", |
| 36287 | .down => "floorq", | 36287 | .down => "floorf128", |
| 36288 | } } }, | 36288 | } } }, |
| 36289 | .unused, | 36289 | .unused, |
| 36290 | .unused, | 36290 | .unused, |
| ... | @@ -36326,8 +36326,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -36326,8 +36326,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 36326 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 36326 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 36327 | .{ .type = .usize, .kind = .{ .extern_func = switch (direction) { | 36327 | .{ .type = .usize, .kind = .{ .extern_func = switch (direction) { |
| 36328 | else => unreachable, | 36328 | else => unreachable, |
| 36329 | .zero => "truncq", | 36329 | .zero => "truncf128", |
| 36330 | .down => "floorq", | 36330 | .down => "floorf128", |
| 36331 | } } }, | 36331 | } } }, |
| 36332 | .unused, | 36332 | .unused, |
| 36333 | .unused, | 36333 | .unused, |
| ... | @@ -37691,7 +37691,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -37691,7 +37691,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 37691 | .call_frame = .{ .alignment = .@"16" }, | 37691 | .call_frame = .{ .alignment = .@"16" }, |
| 37692 | .extra_temps = .{ | 37692 | .extra_temps = .{ |
| 37693 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, | 37693 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, |
| 37694 | .{ .type = .usize, .kind = .{ .extern_func = "floorq" } }, | 37694 | .{ .type = .usize, .kind = .{ .extern_func = "floorf128" } }, |
| 37695 | .unused, | 37695 | .unused, |
| 37696 | .unused, | 37696 | .unused, |
| 37697 | .unused, | 37697 | .unused, |
| ... | @@ -37725,7 +37725,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -37725,7 +37725,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 37725 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 37725 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 37726 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, | 37726 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, |
| 37727 | .{ .type = .f128, .kind = .mem }, | 37727 | .{ .type = .f128, .kind = .mem }, |
| 37728 | .{ .type = .usize, .kind = .{ .extern_func = "floorq" } }, | 37728 | .{ .type = .usize, .kind = .{ .extern_func = "floorf128" } }, |
| 37729 | .unused, | 37729 | .unused, |
| 37730 | .unused, | 37730 | .unused, |
| 37731 | .unused, | 37731 | .unused, |
| ... | @@ -37760,7 +37760,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -37760,7 +37760,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 37760 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 37760 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 37761 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, | 37761 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, |
| 37762 | .{ .type = .f128, .kind = .mem }, | 37762 | .{ .type = .f128, .kind = .mem }, |
| 37763 | .{ .type = .usize, .kind = .{ .extern_func = "floorq" } }, | 37763 | .{ .type = .usize, .kind = .{ .extern_func = "floorf128" } }, |
| 37764 | .unused, | 37764 | .unused, |
| 37765 | .unused, | 37765 | .unused, |
| 37766 | .unused, | 37766 | .unused, |
| ... | @@ -37795,7 +37795,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -37795,7 +37795,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 37795 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 37795 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 37796 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, | 37796 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, |
| 37797 | .{ .type = .f128, .kind = .mem }, | 37797 | .{ .type = .f128, .kind = .mem }, |
| 37798 | .{ .type = .usize, .kind = .{ .extern_func = "floorq" } }, | 37798 | .{ .type = .usize, .kind = .{ .extern_func = "floorf128" } }, |
| 37799 | .unused, | 37799 | .unused, |
| 37800 | .unused, | 37800 | .unused, |
| 37801 | .unused, | 37801 | .unused, |
| ... | @@ -37830,7 +37830,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -37830,7 +37830,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 37830 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 37830 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 37831 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 37831 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 37832 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, | 37832 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, |
| 37833 | .{ .type = .usize, .kind = .{ .extern_func = "floorq" } }, | 37833 | .{ .type = .usize, .kind = .{ .extern_func = "floorf128" } }, |
| 37834 | .unused, | 37834 | .unused, |
| 37835 | .unused, | 37835 | .unused, |
| 37836 | .unused, | 37836 | .unused, |
| ... | @@ -37867,7 +37867,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -37867,7 +37867,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 37867 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 37867 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 37868 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 37868 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 37869 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, | 37869 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, |
| 37870 | .{ .type = .usize, .kind = .{ .extern_func = "floorq" } }, | 37870 | .{ .type = .usize, .kind = .{ .extern_func = "floorf128" } }, |
| 37871 | .unused, | 37871 | .unused, |
| 37872 | .unused, | 37872 | .unused, |
| 37873 | .unused, | 37873 | .unused, |
| ... | @@ -37904,7 +37904,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -37904,7 +37904,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 37904 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 37904 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 37905 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 37905 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 37906 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, | 37906 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, |
| 37907 | .{ .type = .usize, .kind = .{ .extern_func = "floorq" } }, | 37907 | .{ .type = .usize, .kind = .{ .extern_func = "floorf128" } }, |
| 37908 | .unused, | 37908 | .unused, |
| 37909 | .unused, | 37909 | .unused, |
| 37910 | .unused, | 37910 | .unused, |
| ... | @@ -37943,7 +37943,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -37943,7 +37943,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 37943 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, | 37943 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, |
| 37944 | .{ .type = .f128, .kind = .mem }, | 37944 | .{ .type = .f128, .kind = .mem }, |
| 37945 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 37945 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 37946 | .{ .type = .usize, .kind = .{ .extern_func = "floorq" } }, | 37946 | .{ .type = .usize, .kind = .{ .extern_func = "floorf128" } }, |
| 37947 | .unused, | 37947 | .unused, |
| 37948 | .unused, | 37948 | .unused, |
| 37949 | .unused, | 37949 | .unused, |
| ... | @@ -37982,7 +37982,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -37982,7 +37982,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 37982 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, | 37982 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, |
| 37983 | .{ .type = .f128, .kind = .mem }, | 37983 | .{ .type = .f128, .kind = .mem }, |
| 37984 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 37984 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 37985 | .{ .type = .usize, .kind = .{ .extern_func = "floorq" } }, | 37985 | .{ .type = .usize, .kind = .{ .extern_func = "floorf128" } }, |
| 37986 | .unused, | 37986 | .unused, |
| 37987 | .unused, | 37987 | .unused, |
| 37988 | .unused, | 37988 | .unused, |
| ... | @@ -38021,7 +38021,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -38021,7 +38021,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 38021 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, | 38021 | .{ .type = .usize, .kind = .{ .extern_func = "__divtf3" } }, |
| 38022 | .{ .type = .f128, .kind = .mem }, | 38022 | .{ .type = .f128, .kind = .mem }, |
| 38023 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 38023 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 38024 | .{ .type = .usize, .kind = .{ .extern_func = "floorq" } }, | 38024 | .{ .type = .usize, .kind = .{ .extern_func = "floorf128" } }, |
| 38025 | .unused, | 38025 | .unused, |
| 38026 | .unused, | 38026 | .unused, |
| 38027 | .unused, | 38027 | .unused, |
| ... | @@ -39558,7 +39558,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -39558,7 +39558,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 39558 | }, | 39558 | }, |
| 39559 | .call_frame = .{ .alignment = .@"16" }, | 39559 | .call_frame = .{ .alignment = .@"16" }, |
| 39560 | .extra_temps = .{ | 39560 | .extra_temps = .{ |
| 39561 | .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } }, | 39561 | .{ .type = .usize, .kind = .{ .extern_func = "fmodf128" } }, |
| 39562 | .unused, | 39562 | .unused, |
| 39563 | .unused, | 39563 | .unused, |
| 39564 | .unused, | 39564 | .unused, |
| ... | @@ -39590,7 +39590,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -39590,7 +39590,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 39590 | .extra_temps = .{ | 39590 | .extra_temps = .{ |
| 39591 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 39591 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 39592 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 39592 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 39593 | .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } }, | 39593 | .{ .type = .usize, .kind = .{ .extern_func = "fmodf128" } }, |
| 39594 | .unused, | 39594 | .unused, |
| 39595 | .unused, | 39595 | .unused, |
| 39596 | .unused, | 39596 | .unused, |
| ... | @@ -39623,7 +39623,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -39623,7 +39623,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 39623 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 39623 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 39624 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 39624 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 39625 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 39625 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 39626 | .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } }, | 39626 | .{ .type = .usize, .kind = .{ .extern_func = "fmodf128" } }, |
| 39627 | .unused, | 39627 | .unused, |
| 39628 | .unused, | 39628 | .unused, |
| 39629 | .unused, | 39629 | .unused, |
| ... | @@ -39659,7 +39659,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -39659,7 +39659,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 39659 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 39659 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 39660 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 39660 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 39661 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 39661 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 39662 | .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } }, | 39662 | .{ .type = .usize, .kind = .{ .extern_func = "fmodf128" } }, |
| 39663 | .unused, | 39663 | .unused, |
| 39664 | .unused, | 39664 | .unused, |
| 39665 | .unused, | 39665 | .unused, |
| ... | @@ -39695,7 +39695,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -39695,7 +39695,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 39695 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 39695 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 39696 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 39696 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 39697 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 39697 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 39698 | .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } }, | 39698 | .{ .type = .usize, .kind = .{ .extern_func = "fmodf128" } }, |
| 39699 | .unused, | 39699 | .unused, |
| 39700 | .unused, | 39700 | .unused, |
| 39701 | .unused, | 39701 | .unused, |
| ... | @@ -39731,7 +39731,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -39731,7 +39731,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 39731 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 39731 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 39732 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 39732 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 39733 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 39733 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 39734 | .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } }, | 39734 | .{ .type = .usize, .kind = .{ .extern_func = "fmodf128" } }, |
| 39735 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 39735 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 39736 | .unused, | 39736 | .unused, |
| 39737 | .unused, | 39737 | .unused, |
| ... | @@ -39767,7 +39767,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -39767,7 +39767,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 39767 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 39767 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 39768 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 39768 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 39769 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 39769 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 39770 | .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } }, | 39770 | .{ .type = .usize, .kind = .{ .extern_func = "fmodf128" } }, |
| 39771 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 39771 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 39772 | .unused, | 39772 | .unused, |
| 39773 | .unused, | 39773 | .unused, |
| ... | @@ -39803,7 +39803,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -39803,7 +39803,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 39803 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 39803 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 39804 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 39804 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 39805 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 39805 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 39806 | .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } }, | 39806 | .{ .type = .usize, .kind = .{ .extern_func = "fmodf128" } }, |
| 39807 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 39807 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 39808 | .unused, | 39808 | .unused, |
| 39809 | .unused, | 39809 | .unused, |
| ... | @@ -42803,7 +42803,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -42803,7 +42803,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 42803 | .call_frame = .{ .alignment = .@"16" }, | 42803 | .call_frame = .{ .alignment = .@"16" }, |
| 42804 | .extra_temps = .{ | 42804 | .extra_temps = .{ |
| 42805 | .{ .type = .f128, .kind = .mem }, | 42805 | .{ .type = .f128, .kind = .mem }, |
| 42806 | .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } }, | 42806 | .{ .type = .usize, .kind = .{ .extern_func = "fmodf128" } }, |
| 42807 | .{ .type = .u64, .kind = .{ .reg = .rcx } }, | 42807 | .{ .type = .u64, .kind = .{ .reg = .rcx } }, |
| 42808 | .{ .type = .u64, .kind = .{ .reg = .rdx } }, | 42808 | .{ .type = .u64, .kind = .{ .reg = .rdx } }, |
| 42809 | .{ .type = .u64, .kind = .{ .reg = .rax } }, | 42809 | .{ .type = .u64, .kind = .{ .reg = .rax } }, |
| ... | @@ -42849,7 +42849,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -42849,7 +42849,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 42849 | .call_frame = .{ .alignment = .@"16" }, | 42849 | .call_frame = .{ .alignment = .@"16" }, |
| 42850 | .extra_temps = .{ | 42850 | .extra_temps = .{ |
| 42851 | .{ .type = .f128, .kind = .mem }, | 42851 | .{ .type = .f128, .kind = .mem }, |
| 42852 | .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } }, | 42852 | .{ .type = .usize, .kind = .{ .extern_func = "fmodf128" } }, |
| 42853 | .{ .type = .u64, .kind = .{ .reg = .rcx } }, | 42853 | .{ .type = .u64, .kind = .{ .reg = .rcx } }, |
| 42854 | .{ .type = .u64, .kind = .{ .reg = .rdx } }, | 42854 | .{ .type = .u64, .kind = .{ .reg = .rdx } }, |
| 42855 | .{ .type = .u64, .kind = .{ .reg = .rax } }, | 42855 | .{ .type = .u64, .kind = .{ .reg = .rax } }, |
| ... | @@ -42895,7 +42895,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -42895,7 +42895,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 42895 | .call_frame = .{ .alignment = .@"16" }, | 42895 | .call_frame = .{ .alignment = .@"16" }, |
| 42896 | .extra_temps = .{ | 42896 | .extra_temps = .{ |
| 42897 | .{ .type = .f128, .kind = .mem }, | 42897 | .{ .type = .f128, .kind = .mem }, |
| 42898 | .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } }, | 42898 | .{ .type = .usize, .kind = .{ .extern_func = "fmodf128" } }, |
| 42899 | .{ .type = .u64, .kind = .{ .reg = .rcx } }, | 42899 | .{ .type = .u64, .kind = .{ .reg = .rcx } }, |
| 42900 | .{ .type = .u64, .kind = .{ .reg = .rdx } }, | 42900 | .{ .type = .u64, .kind = .{ .reg = .rdx } }, |
| 42901 | .{ .type = .u64, .kind = .{ .reg = .rax } }, | 42901 | .{ .type = .u64, .kind = .{ .reg = .rax } }, |
| ... | @@ -42942,7 +42942,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -42942,7 +42942,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 42942 | .call_frame = .{ .alignment = .@"16" }, | 42942 | .call_frame = .{ .alignment = .@"16" }, |
| 42943 | .extra_temps = .{ | 42943 | .extra_temps = .{ |
| 42944 | .{ .type = .f128, .kind = .mem }, | 42944 | .{ .type = .f128, .kind = .mem }, |
| 42945 | .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } }, | 42945 | .{ .type = .usize, .kind = .{ .extern_func = "fmodf128" } }, |
| 42946 | .{ .type = .u64, .kind = .{ .reg = .rdx } }, | 42946 | .{ .type = .u64, .kind = .{ .reg = .rdx } }, |
| 42947 | .{ .type = .f128, .kind = .mem }, | 42947 | .{ .type = .f128, .kind = .mem }, |
| 42948 | .{ .type = .u64, .kind = .{ .reg = .rax } }, | 42948 | .{ .type = .u64, .kind = .{ .reg = .rax } }, |
| ... | @@ -42984,7 +42984,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -42984,7 +42984,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 42984 | .extra_temps = .{ | 42984 | .extra_temps = .{ |
| 42985 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 42985 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 42986 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 42986 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 42987 | .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } }, | 42987 | .{ .type = .usize, .kind = .{ .extern_func = "fmodf128" } }, |
| 42988 | .{ .type = .f128, .kind = .mem }, | 42988 | .{ .type = .f128, .kind = .mem }, |
| 42989 | .{ .type = .f128, .kind = .{ .reg = .xmm1 } }, | 42989 | .{ .type = .f128, .kind = .{ .reg = .xmm1 } }, |
| 42990 | .{ .type = .u64, .kind = .{ .reg = .rax } }, | 42990 | .{ .type = .u64, .kind = .{ .reg = .rax } }, |
| ... | @@ -43029,7 +43029,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -43029,7 +43029,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 43029 | .extra_temps = .{ | 43029 | .extra_temps = .{ |
| 43030 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 43030 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 43031 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 43031 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 43032 | .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } }, | 43032 | .{ .type = .usize, .kind = .{ .extern_func = "fmodf128" } }, |
| 43033 | .{ .type = .f128, .kind = .mem }, | 43033 | .{ .type = .f128, .kind = .mem }, |
| 43034 | .{ .type = .f128, .kind = .{ .reg = .xmm1 } }, | 43034 | .{ .type = .f128, .kind = .{ .reg = .xmm1 } }, |
| 43035 | .{ .type = .u64, .kind = .{ .reg = .rax } }, | 43035 | .{ .type = .u64, .kind = .{ .reg = .rax } }, |
| ... | @@ -43074,7 +43074,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -43074,7 +43074,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 43074 | .extra_temps = .{ | 43074 | .extra_temps = .{ |
| 43075 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 43075 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 43076 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 43076 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 43077 | .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } }, | 43077 | .{ .type = .usize, .kind = .{ .extern_func = "fmodf128" } }, |
| 43078 | .{ .type = .f128, .kind = .mem }, | 43078 | .{ .type = .f128, .kind = .mem }, |
| 43079 | .{ .type = .f128, .kind = .{ .reg = .xmm1 } }, | 43079 | .{ .type = .f128, .kind = .{ .reg = .xmm1 } }, |
| 43080 | .{ .type = .u64, .kind = .{ .reg = .rax } }, | 43080 | .{ .type = .u64, .kind = .{ .reg = .rax } }, |
| ... | @@ -43120,7 +43120,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -43120,7 +43120,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 43120 | .extra_temps = .{ | 43120 | .extra_temps = .{ |
| 43121 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 43121 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 43122 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 43122 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 43123 | .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } }, | 43123 | .{ .type = .usize, .kind = .{ .extern_func = "fmodf128" } }, |
| 43124 | .{ .type = .f128, .kind = .mem }, | 43124 | .{ .type = .f128, .kind = .mem }, |
| 43125 | .{ .type = .usize, .kind = .{ .reg = .rax } }, | 43125 | .{ .type = .usize, .kind = .{ .reg = .rax } }, |
| 43126 | .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } }, | 43126 | .{ .type = .usize, .kind = .{ .extern_func = "__addtf3" } }, |
| ... | @@ -43164,7 +43164,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -43164,7 +43164,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 43164 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, | 43164 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, |
| 43165 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 43165 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 43166 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 43166 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 43167 | .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } }, | 43167 | .{ .type = .usize, .kind = .{ .extern_func = "fmodf128" } }, |
| 43168 | .{ .type = .f128, .kind = .{ .reg = .rcx } }, | 43168 | .{ .type = .f128, .kind = .{ .reg = .rcx } }, |
| 43169 | .{ .type = .f128, .kind = .{ .reg = .rdx } }, | 43169 | .{ .type = .f128, .kind = .{ .reg = .rdx } }, |
| 43170 | .{ .type = .f128, .kind = .{ .reg = .rax } }, | 43170 | .{ .type = .f128, .kind = .{ .reg = .rax } }, |
| ... | @@ -43211,7 +43211,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -43211,7 +43211,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 43211 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, | 43211 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, |
| 43212 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 43212 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 43213 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 43213 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 43214 | .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } }, | 43214 | .{ .type = .usize, .kind = .{ .extern_func = "fmodf128" } }, |
| 43215 | .{ .type = .f128, .kind = .{ .reg = .rcx } }, | 43215 | .{ .type = .f128, .kind = .{ .reg = .rcx } }, |
| 43216 | .{ .type = .f128, .kind = .{ .reg = .rdx } }, | 43216 | .{ .type = .f128, .kind = .{ .reg = .rdx } }, |
| 43217 | .{ .type = .f128, .kind = .{ .reg = .rax } }, | 43217 | .{ .type = .f128, .kind = .{ .reg = .rax } }, |
| ... | @@ -43258,7 +43258,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -43258,7 +43258,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 43258 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, | 43258 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, |
| 43259 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 43259 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 43260 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 43260 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 43261 | .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } }, | 43261 | .{ .type = .usize, .kind = .{ .extern_func = "fmodf128" } }, |
| 43262 | .{ .type = .f128, .kind = .{ .reg = .rcx } }, | 43262 | .{ .type = .f128, .kind = .{ .reg = .rcx } }, |
| 43263 | .{ .type = .f128, .kind = .{ .reg = .rdx } }, | 43263 | .{ .type = .f128, .kind = .{ .reg = .rdx } }, |
| 43264 | .{ .type = .f128, .kind = .{ .reg = .rax } }, | 43264 | .{ .type = .f128, .kind = .{ .reg = .rax } }, |
| ... | @@ -43306,7 +43306,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -43306,7 +43306,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 43306 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, | 43306 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, |
| 43307 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 43307 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 43308 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 43308 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 43309 | .{ .type = .usize, .kind = .{ .extern_func = "fmodq" } }, | 43309 | .{ .type = .usize, .kind = .{ .extern_func = "fmodf128" } }, |
| 43310 | .{ .type = .f128, .kind = .{ .reg = .rdx } }, | 43310 | .{ .type = .f128, .kind = .{ .reg = .rdx } }, |
| 43311 | .{ .type = .f128, .kind = .mem }, | 43311 | .{ .type = .f128, .kind = .mem }, |
| 43312 | .{ .type = .f128, .kind = .{ .reg = .rax } }, | 43312 | .{ .type = .f128, .kind = .{ .reg = .rax } }, |
| ... | @@ -47623,7 +47623,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -47623,7 +47623,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 47623 | }, | 47623 | }, |
| 47624 | .call_frame = .{ .alignment = .@"16" }, | 47624 | .call_frame = .{ .alignment = .@"16" }, |
| 47625 | .extra_temps = .{ | 47625 | .extra_temps = .{ |
| 47626 | .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } }, | 47626 | .{ .type = .usize, .kind = .{ .extern_func = "fmaxf128" } }, |
| 47627 | .unused, | 47627 | .unused, |
| 47628 | .unused, | 47628 | .unused, |
| 47629 | .unused, | 47629 | .unused, |
| ... | @@ -47655,7 +47655,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -47655,7 +47655,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 47655 | .extra_temps = .{ | 47655 | .extra_temps = .{ |
| 47656 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 47656 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 47657 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 47657 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 47658 | .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } }, | 47658 | .{ .type = .usize, .kind = .{ .extern_func = "fmaxf128" } }, |
| 47659 | .unused, | 47659 | .unused, |
| 47660 | .unused, | 47660 | .unused, |
| 47661 | .unused, | 47661 | .unused, |
| ... | @@ -47688,7 +47688,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -47688,7 +47688,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 47688 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 47688 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 47689 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 47689 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 47690 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 47690 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 47691 | .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } }, | 47691 | .{ .type = .usize, .kind = .{ .extern_func = "fmaxf128" } }, |
| 47692 | .unused, | 47692 | .unused, |
| 47693 | .unused, | 47693 | .unused, |
| 47694 | .unused, | 47694 | .unused, |
| ... | @@ -47724,7 +47724,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -47724,7 +47724,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 47724 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 47724 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 47725 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 47725 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 47726 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 47726 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 47727 | .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } }, | 47727 | .{ .type = .usize, .kind = .{ .extern_func = "fmaxf128" } }, |
| 47728 | .unused, | 47728 | .unused, |
| 47729 | .unused, | 47729 | .unused, |
| 47730 | .unused, | 47730 | .unused, |
| ... | @@ -47760,7 +47760,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -47760,7 +47760,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 47760 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 47760 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 47761 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 47761 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 47762 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 47762 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 47763 | .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } }, | 47763 | .{ .type = .usize, .kind = .{ .extern_func = "fmaxf128" } }, |
| 47764 | .unused, | 47764 | .unused, |
| 47765 | .unused, | 47765 | .unused, |
| 47766 | .unused, | 47766 | .unused, |
| ... | @@ -47796,7 +47796,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -47796,7 +47796,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 47796 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 47796 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 47797 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 47797 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 47798 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 47798 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 47799 | .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } }, | 47799 | .{ .type = .usize, .kind = .{ .extern_func = "fmaxf128" } }, |
| 47800 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 47800 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 47801 | .unused, | 47801 | .unused, |
| 47802 | .unused, | 47802 | .unused, |
| ... | @@ -47832,7 +47832,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -47832,7 +47832,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 47832 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 47832 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 47833 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 47833 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 47834 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 47834 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 47835 | .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } }, | 47835 | .{ .type = .usize, .kind = .{ .extern_func = "fmaxf128" } }, |
| 47836 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 47836 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 47837 | .unused, | 47837 | .unused, |
| 47838 | .unused, | 47838 | .unused, |
| ... | @@ -47868,7 +47868,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -47868,7 +47868,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 47868 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 47868 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 47869 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 47869 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 47870 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 47870 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 47871 | .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } }, | 47871 | .{ .type = .usize, .kind = .{ .extern_func = "fmaxf128" } }, |
| 47872 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 47872 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 47873 | .unused, | 47873 | .unused, |
| 47874 | .unused, | 47874 | .unused, |
| ... | @@ -51926,7 +51926,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -51926,7 +51926,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 51926 | }, | 51926 | }, |
| 51927 | .call_frame = .{ .alignment = .@"16" }, | 51927 | .call_frame = .{ .alignment = .@"16" }, |
| 51928 | .extra_temps = .{ | 51928 | .extra_temps = .{ |
| 51929 | .{ .type = .usize, .kind = .{ .extern_func = "fminq" } }, | 51929 | .{ .type = .usize, .kind = .{ .extern_func = "fminf128" } }, |
| 51930 | .unused, | 51930 | .unused, |
| 51931 | .unused, | 51931 | .unused, |
| 51932 | .unused, | 51932 | .unused, |
| ... | @@ -51958,7 +51958,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -51958,7 +51958,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 51958 | .extra_temps = .{ | 51958 | .extra_temps = .{ |
| 51959 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 51959 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 51960 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 51960 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 51961 | .{ .type = .usize, .kind = .{ .extern_func = "fminq" } }, | 51961 | .{ .type = .usize, .kind = .{ .extern_func = "fminf128" } }, |
| 51962 | .unused, | 51962 | .unused, |
| 51963 | .unused, | 51963 | .unused, |
| 51964 | .unused, | 51964 | .unused, |
| ... | @@ -51991,7 +51991,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -51991,7 +51991,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 51991 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, | 51991 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, |
| 51992 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 51992 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 51993 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 51993 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 51994 | .{ .type = .usize, .kind = .{ .extern_func = "fminq" } }, | 51994 | .{ .type = .usize, .kind = .{ .extern_func = "fminf128" } }, |
| 51995 | .unused, | 51995 | .unused, |
| 51996 | .unused, | 51996 | .unused, |
| 51997 | .unused, | 51997 | .unused, |
| ... | @@ -52027,7 +52027,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -52027,7 +52027,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 52027 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, | 52027 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, |
| 52028 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 52028 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 52029 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 52029 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 52030 | .{ .type = .usize, .kind = .{ .extern_func = "fminq" } }, | 52030 | .{ .type = .usize, .kind = .{ .extern_func = "fminf128" } }, |
| 52031 | .unused, | 52031 | .unused, |
| 52032 | .unused, | 52032 | .unused, |
| 52033 | .unused, | 52033 | .unused, |
| ... | @@ -52063,7 +52063,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -52063,7 +52063,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 52063 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, | 52063 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, |
| 52064 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 52064 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 52065 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 52065 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 52066 | .{ .type = .usize, .kind = .{ .extern_func = "fminq" } }, | 52066 | .{ .type = .usize, .kind = .{ .extern_func = "fminf128" } }, |
| 52067 | .unused, | 52067 | .unused, |
| 52068 | .unused, | 52068 | .unused, |
| 52069 | .unused, | 52069 | .unused, |
| ... | @@ -52099,7 +52099,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -52099,7 +52099,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 52099 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 52099 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 52100 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 52100 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 52101 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 52101 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 52102 | .{ .type = .usize, .kind = .{ .extern_func = "fminq" } }, | 52102 | .{ .type = .usize, .kind = .{ .extern_func = "fminf128" } }, |
| 52103 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 52103 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 52104 | .unused, | 52104 | .unused, |
| 52105 | .unused, | 52105 | .unused, |
| ... | @@ -52135,7 +52135,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -52135,7 +52135,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 52135 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 52135 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 52136 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 52136 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 52137 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 52137 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 52138 | .{ .type = .usize, .kind = .{ .extern_func = "fminq" } }, | 52138 | .{ .type = .usize, .kind = .{ .extern_func = "fminf128" } }, |
| 52139 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 52139 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 52140 | .unused, | 52140 | .unused, |
| 52141 | .unused, | 52141 | .unused, |
| ... | @@ -52171,7 +52171,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -52171,7 +52171,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 52171 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 52171 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 52172 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 52172 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 52173 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 52173 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 52174 | .{ .type = .usize, .kind = .{ .extern_func = "fminq" } }, | 52174 | .{ .type = .usize, .kind = .{ .extern_func = "fminf128" } }, |
| 52175 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 52175 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 52176 | .unused, | 52176 | .unused, |
| 52177 | .unused, | 52177 | .unused, |
| ... | @@ -76457,7 +76457,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -76457,7 +76457,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 76457 | }, | 76457 | }, |
| 76458 | .call_frame = .{ .alignment = .@"16" }, | 76458 | .call_frame = .{ .alignment = .@"16" }, |
| 76459 | .extra_temps = .{ | 76459 | .extra_temps = .{ |
| 76460 | .{ .type = .usize, .kind = .{ .extern_func = "sqrtq" } }, | 76460 | .{ .type = .usize, .kind = .{ .extern_func = "sqrtf128" } }, |
| 76461 | .unused, | 76461 | .unused, |
| 76462 | .unused, | 76462 | .unused, |
| 76463 | .unused, | 76463 | .unused, |
| ... | @@ -76484,7 +76484,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -76484,7 +76484,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 76484 | .call_frame = .{ .alignment = .@"16" }, | 76484 | .call_frame = .{ .alignment = .@"16" }, |
| 76485 | .extra_temps = .{ | 76485 | .extra_temps = .{ |
| 76486 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 76486 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 76487 | .{ .type = .usize, .kind = .{ .extern_func = "sqrtq" } }, | 76487 | .{ .type = .usize, .kind = .{ .extern_func = "sqrtf128" } }, |
| 76488 | .unused, | 76488 | .unused, |
| 76489 | .unused, | 76489 | .unused, |
| 76490 | .unused, | 76490 | .unused, |
| ... | @@ -76512,7 +76512,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -76512,7 +76512,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 76512 | .extra_temps = .{ | 76512 | .extra_temps = .{ |
| 76513 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 76513 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 76514 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 76514 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 76515 | .{ .type = .usize, .kind = .{ .extern_func = "sqrtq" } }, | 76515 | .{ .type = .usize, .kind = .{ .extern_func = "sqrtf128" } }, |
| 76516 | .unused, | 76516 | .unused, |
| 76517 | .unused, | 76517 | .unused, |
| 76518 | .unused, | 76518 | .unused, |
| ... | @@ -76543,7 +76543,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -76543,7 +76543,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 76543 | .extra_temps = .{ | 76543 | .extra_temps = .{ |
| 76544 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 76544 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 76545 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 76545 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 76546 | .{ .type = .usize, .kind = .{ .extern_func = "sqrtq" } }, | 76546 | .{ .type = .usize, .kind = .{ .extern_func = "sqrtf128" } }, |
| 76547 | .unused, | 76547 | .unused, |
| 76548 | .unused, | 76548 | .unused, |
| 76549 | .unused, | 76549 | .unused, |
| ... | @@ -76574,7 +76574,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -76574,7 +76574,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 76574 | .extra_temps = .{ | 76574 | .extra_temps = .{ |
| 76575 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 76575 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 76576 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 76576 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 76577 | .{ .type = .usize, .kind = .{ .extern_func = "sqrtq" } }, | 76577 | .{ .type = .usize, .kind = .{ .extern_func = "sqrtf128" } }, |
| 76578 | .unused, | 76578 | .unused, |
| 76579 | .unused, | 76579 | .unused, |
| 76580 | .unused, | 76580 | .unused, |
| ... | @@ -76605,7 +76605,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -76605,7 +76605,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 76605 | .extra_temps = .{ | 76605 | .extra_temps = .{ |
| 76606 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 76606 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 76607 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 76607 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 76608 | .{ .type = .usize, .kind = .{ .extern_func = "sqrtq" } }, | 76608 | .{ .type = .usize, .kind = .{ .extern_func = "sqrtf128" } }, |
| 76609 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 76609 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 76610 | .unused, | 76610 | .unused, |
| 76611 | .unused, | 76611 | .unused, |
| ... | @@ -76636,7 +76636,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -76636,7 +76636,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 76636 | .extra_temps = .{ | 76636 | .extra_temps = .{ |
| 76637 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 76637 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 76638 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 76638 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 76639 | .{ .type = .usize, .kind = .{ .extern_func = "sqrtq" } }, | 76639 | .{ .type = .usize, .kind = .{ .extern_func = "sqrtf128" } }, |
| 76640 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 76640 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 76641 | .unused, | 76641 | .unused, |
| 76642 | .unused, | 76642 | .unused, |
| ... | @@ -76667,7 +76667,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -76667,7 +76667,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 76667 | .extra_temps = .{ | 76667 | .extra_temps = .{ |
| 76668 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 76668 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 76669 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 76669 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 76670 | .{ .type = .usize, .kind = .{ .extern_func = "sqrtq" } }, | 76670 | .{ .type = .usize, .kind = .{ .extern_func = "sqrtf128" } }, |
| 76671 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 76671 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 76672 | .unused, | 76672 | .unused, |
| 76673 | .unused, | 76673 | .unused, |
| ... | @@ -77306,7 +77306,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -77306,7 +77306,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 77306 | }, | 77306 | }, |
| 77307 | .call_frame = .{ .alignment = .@"16" }, | 77307 | .call_frame = .{ .alignment = .@"16" }, |
| 77308 | .extra_temps = .{ | 77308 | .extra_temps = .{ |
| 77309 | .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "q" } }, | 77309 | .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "f128" } }, |
| 77310 | .unused, | 77310 | .unused, |
| 77311 | .unused, | 77311 | .unused, |
| 77312 | .unused, | 77312 | .unused, |
| ... | @@ -77333,7 +77333,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -77333,7 +77333,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 77333 | .call_frame = .{ .alignment = .@"16" }, | 77333 | .call_frame = .{ .alignment = .@"16" }, |
| 77334 | .extra_temps = .{ | 77334 | .extra_temps = .{ |
| 77335 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 77335 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 77336 | .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "q" } }, | 77336 | .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "f128" } }, |
| 77337 | .unused, | 77337 | .unused, |
| 77338 | .unused, | 77338 | .unused, |
| 77339 | .unused, | 77339 | .unused, |
| ... | @@ -77361,7 +77361,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -77361,7 +77361,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 77361 | .extra_temps = .{ | 77361 | .extra_temps = .{ |
| 77362 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 77362 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 77363 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 77363 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 77364 | .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "q" } }, | 77364 | .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "f128" } }, |
| 77365 | .unused, | 77365 | .unused, |
| 77366 | .unused, | 77366 | .unused, |
| 77367 | .unused, | 77367 | .unused, |
| ... | @@ -77392,7 +77392,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -77392,7 +77392,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 77392 | .extra_temps = .{ | 77392 | .extra_temps = .{ |
| 77393 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 77393 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 77394 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 77394 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 77395 | .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "q" } }, | 77395 | .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "f128" } }, |
| 77396 | .unused, | 77396 | .unused, |
| 77397 | .unused, | 77397 | .unused, |
| 77398 | .unused, | 77398 | .unused, |
| ... | @@ -77423,7 +77423,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -77423,7 +77423,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 77423 | .extra_temps = .{ | 77423 | .extra_temps = .{ |
| 77424 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 77424 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 77425 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 77425 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 77426 | .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "q" } }, | 77426 | .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "f128" } }, |
| 77427 | .unused, | 77427 | .unused, |
| 77428 | .unused, | 77428 | .unused, |
| 77429 | .unused, | 77429 | .unused, |
| ... | @@ -77454,7 +77454,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -77454,7 +77454,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 77454 | .extra_temps = .{ | 77454 | .extra_temps = .{ |
| 77455 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 77455 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 77456 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 77456 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 77457 | .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "q" } }, | 77457 | .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "f128" } }, |
| 77458 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 77458 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 77459 | .unused, | 77459 | .unused, |
| 77460 | .unused, | 77460 | .unused, |
| ... | @@ -77485,7 +77485,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -77485,7 +77485,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 77485 | .extra_temps = .{ | 77485 | .extra_temps = .{ |
| 77486 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 77486 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 77487 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 77487 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 77488 | .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "q" } }, | 77488 | .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "f128" } }, |
| 77489 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 77489 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 77490 | .unused, | 77490 | .unused, |
| 77491 | .unused, | 77491 | .unused, |
| ... | @@ -77516,7 +77516,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -77516,7 +77516,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 77516 | .extra_temps = .{ | 77516 | .extra_temps = .{ |
| 77517 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 77517 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 77518 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 77518 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 77519 | .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "q" } }, | 77519 | .{ .type = .usize, .kind = .{ .extern_func = @tagName(name) ++ "f128" } }, |
| 77520 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 77520 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 77521 | .unused, | 77521 | .unused, |
| 77522 | .unused, | 77522 | .unused, |
| ... | @@ -80155,9 +80155,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -80155,9 +80155,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 80155 | .extra_temps = .{ | 80155 | .extra_temps = .{ |
| 80156 | .{ .type = .usize, .kind = .{ .extern_func = switch (direction) { | 80156 | .{ .type = .usize, .kind = .{ .extern_func = switch (direction) { |
| 80157 | else => unreachable, | 80157 | else => unreachable, |
| 80158 | .down => "floorq", | 80158 | .down => "floorf128", |
| 80159 | .up => "ceilq", | 80159 | .up => "ceilf128", |
| 80160 | .zero => "truncq", | 80160 | .zero => "truncf128", |
| 80161 | } } }, | 80161 | } } }, |
| 80162 | .unused, | 80162 | .unused, |
| 80163 | .unused, | 80163 | .unused, |
| ... | @@ -80187,9 +80187,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -80187,9 +80187,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 80187 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 80187 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 80188 | .{ .type = .usize, .kind = .{ .extern_func = switch (direction) { | 80188 | .{ .type = .usize, .kind = .{ .extern_func = switch (direction) { |
| 80189 | else => unreachable, | 80189 | else => unreachable, |
| 80190 | .down => "floorq", | 80190 | .down => "floorf128", |
| 80191 | .up => "ceilq", | 80191 | .up => "ceilf128", |
| 80192 | .zero => "truncq", | 80192 | .zero => "truncf128", |
| 80193 | } } }, | 80193 | } } }, |
| 80194 | .unused, | 80194 | .unused, |
| 80195 | .unused, | 80195 | .unused, |
| ... | @@ -80220,9 +80220,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -80220,9 +80220,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 80220 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 80220 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 80221 | .{ .type = .usize, .kind = .{ .extern_func = switch (direction) { | 80221 | .{ .type = .usize, .kind = .{ .extern_func = switch (direction) { |
| 80222 | else => unreachable, | 80222 | else => unreachable, |
| 80223 | .down => "floorq", | 80223 | .down => "floorf128", |
| 80224 | .up => "ceilq", | 80224 | .up => "ceilf128", |
| 80225 | .zero => "truncq", | 80225 | .zero => "truncf128", |
| 80226 | } } }, | 80226 | } } }, |
| 80227 | .unused, | 80227 | .unused, |
| 80228 | .unused, | 80228 | .unused, |
| ... | @@ -80256,9 +80256,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -80256,9 +80256,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 80256 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 80256 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 80257 | .{ .type = .usize, .kind = .{ .extern_func = switch (direction) { | 80257 | .{ .type = .usize, .kind = .{ .extern_func = switch (direction) { |
| 80258 | else => unreachable, | 80258 | else => unreachable, |
| 80259 | .down => "floorq", | 80259 | .down => "floorf128", |
| 80260 | .up => "ceilq", | 80260 | .up => "ceilf128", |
| 80261 | .zero => "truncq", | 80261 | .zero => "truncf128", |
| 80262 | } } }, | 80262 | } } }, |
| 80263 | .unused, | 80263 | .unused, |
| 80264 | .unused, | 80264 | .unused, |
| ... | @@ -80292,9 +80292,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -80292,9 +80292,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 80292 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 80292 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 80293 | .{ .type = .usize, .kind = .{ .extern_func = switch (direction) { | 80293 | .{ .type = .usize, .kind = .{ .extern_func = switch (direction) { |
| 80294 | else => unreachable, | 80294 | else => unreachable, |
| 80295 | .down => "floorq", | 80295 | .down => "floorf128", |
| 80296 | .up => "ceilq", | 80296 | .up => "ceilf128", |
| 80297 | .zero => "truncq", | 80297 | .zero => "truncf128", |
| 80298 | } } }, | 80298 | } } }, |
| 80299 | .unused, | 80299 | .unused, |
| 80300 | .unused, | 80300 | .unused, |
| ... | @@ -80328,9 +80328,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -80328,9 +80328,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 80328 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 80328 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 80329 | .{ .type = .usize, .kind = .{ .extern_func = switch (direction) { | 80329 | .{ .type = .usize, .kind = .{ .extern_func = switch (direction) { |
| 80330 | else => unreachable, | 80330 | else => unreachable, |
| 80331 | .down => "floorq", | 80331 | .down => "floorf128", |
| 80332 | .up => "ceilq", | 80332 | .up => "ceilf128", |
| 80333 | .zero => "truncq", | 80333 | .zero => "truncf128", |
| 80334 | } } }, | 80334 | } } }, |
| 80335 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 80335 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 80336 | .unused, | 80336 | .unused, |
| ... | @@ -80364,9 +80364,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -80364,9 +80364,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 80364 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 80364 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 80365 | .{ .type = .usize, .kind = .{ .extern_func = switch (direction) { | 80365 | .{ .type = .usize, .kind = .{ .extern_func = switch (direction) { |
| 80366 | else => unreachable, | 80366 | else => unreachable, |
| 80367 | .down => "floorq", | 80367 | .down => "floorf128", |
| 80368 | .up => "ceilq", | 80368 | .up => "ceilf128", |
| 80369 | .zero => "truncq", | 80369 | .zero => "truncf128", |
| 80370 | } } }, | 80370 | } } }, |
| 80371 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 80371 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 80372 | .unused, | 80372 | .unused, |
| ... | @@ -80400,9 +80400,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -80400,9 +80400,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 80400 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 80400 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 80401 | .{ .type = .usize, .kind = .{ .extern_func = switch (direction) { | 80401 | .{ .type = .usize, .kind = .{ .extern_func = switch (direction) { |
| 80402 | else => unreachable, | 80402 | else => unreachable, |
| 80403 | .down => "floorq", | 80403 | .down => "floorf128", |
| 80404 | .up => "ceilq", | 80404 | .up => "ceilf128", |
| 80405 | .zero => "truncq", | 80405 | .zero => "truncf128", |
| 80406 | } } }, | 80406 | } } }, |
| 80407 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 80407 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 80408 | .unused, | 80408 | .unused, |
| ... | @@ -125531,7 +125531,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -125531,7 +125531,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 125531 | .{ ._, ._, .call, .tmp1d, ._, ._, ._ }, | 125531 | .{ ._, ._, .call, .tmp1d, ._, ._, ._ }, |
| 125532 | } }, | 125532 | } }, |
| 125533 | }, .{ | 125533 | }, .{ |
| 125534 | .required_cc_abi = .sysv64, | ||
| 125535 | .required_features = .{ .sse, null, null, null }, | 125534 | .required_features = .{ .sse, null, null, null }, |
| 125536 | .src_constraints = .{ .{ .unsigned_int = .xword }, .any, .any }, | 125535 | .src_constraints = .{ .{ .unsigned_int = .xword }, .any, .any }, |
| 125537 | .dst_constraints = .{ .{ .float = .xword }, .any }, | 125536 | .dst_constraints = .{ .{ .float = .xword }, .any }, |
| ... | @@ -125557,34 +125556,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -125557,34 +125556,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 125557 | .each = .{ .once = &.{ | 125556 | .each = .{ .once = &.{ |
| 125558 | .{ ._, ._, .call, .tmp0d, ._, ._, ._ }, | 125557 | .{ ._, ._, .call, .tmp0d, ._, ._, ._ }, |
| 125559 | } }, | 125558 | } }, |
| 125560 | }, .{ | ||
| 125561 | .required_cc_abi = .win64, | ||
| 125562 | .required_features = .{ .sse, null, null, null }, | ||
| 125563 | .src_constraints = .{ .{ .unsigned_int = .xword }, .any, .any }, | ||
| 125564 | .dst_constraints = .{ .{ .float = .xword }, .any }, | ||
| 125565 | .patterns = &.{ | ||
| 125566 | .{ .src = .{ .to_mem, .none, .none } }, | ||
| 125567 | }, | ||
| 125568 | .call_frame = .{ .alignment = .@"16" }, | ||
| 125569 | .extra_temps = .{ | ||
| 125570 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | ||
| 125571 | .{ .type = .usize, .kind = .{ .extern_func = "__floatuntitf" } }, | ||
| 125572 | .unused, | ||
| 125573 | .unused, | ||
| 125574 | .unused, | ||
| 125575 | .unused, | ||
| 125576 | .unused, | ||
| 125577 | .unused, | ||
| 125578 | .unused, | ||
| 125579 | .unused, | ||
| 125580 | .unused, | ||
| 125581 | }, | ||
| 125582 | .dst_temps = .{ .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } }, .unused }, | ||
| 125583 | .clobbers = .{ .eflags = true, .caller_preserved = .ccc }, | ||
| 125584 | .each = .{ .once = &.{ | ||
| 125585 | .{ ._, ._, .lea, .tmp0p, .mem(.src0), ._, ._ }, | ||
| 125586 | .{ ._, ._, .call, .tmp1d, ._, ._, ._ }, | ||
| 125587 | } }, | ||
| 125588 | }, .{ | 125559 | }, .{ |
| 125589 | .required_features = .{ .@"64bit", .sse, null, null }, | 125560 | .required_features = .{ .@"64bit", .sse, null, null }, |
| 125590 | .src_constraints = .{ .{ .remainder_signed_int = .{ .of = .dword, .is = .dword } }, .any, .any }, | 125561 | .src_constraints = .{ .{ .remainder_signed_int = .{ .of = .dword, .is = .dword } }, .any, .any }, |
| ... | @@ -126791,7 +126762,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -126791,7 +126762,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 126791 | .{ ._, ._ae, .j, .@"0b", ._, ._, ._ }, | 126762 | .{ ._, ._ae, .j, .@"0b", ._, ._, ._ }, |
| 126792 | } }, | 126763 | } }, |
| 126793 | }, .{ | 126764 | }, .{ |
| 126794 | .required_cc_abi = .sysv64, | ||
| 126795 | .required_features = .{ .avx, null, null, null }, | 126765 | .required_features = .{ .avx, null, null, null }, |
| 126796 | .src_constraints = .{ .{ .multiple_scalar_unsigned_int = .{ .of = .xword, .is = .xword } }, .any, .any }, | 126766 | .src_constraints = .{ .{ .multiple_scalar_unsigned_int = .{ .of = .xword, .is = .xword } }, .any, .any }, |
| 126797 | .dst_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any }, | 126767 | .dst_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any }, |
| ... | @@ -126824,39 +126794,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -126824,39 +126794,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 126824 | .{ ._, ._ae, .j, .@"0b", ._, ._, ._ }, | 126794 | .{ ._, ._ae, .j, .@"0b", ._, ._, ._ }, |
| 126825 | } }, | 126795 | } }, |
| 126826 | }, .{ | 126796 | }, .{ |
| 126827 | .required_cc_abi = .win64, | ||
| 126828 | .required_features = .{ .avx, null, null, null }, | ||
| 126829 | .src_constraints = .{ .{ .multiple_scalar_unsigned_int = .{ .of = .xword, .is = .xword } }, .any, .any }, | ||
| 126830 | .dst_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any }, | ||
| 126831 | .patterns = &.{ | ||
| 126832 | .{ .src = .{ .to_mem, .none, .none } }, | ||
| 126833 | }, | ||
| 126834 | .call_frame = .{ .alignment = .@"16" }, | ||
| 126835 | .extra_temps = .{ | ||
| 126836 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | ||
| 126837 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | ||
| 126838 | .{ .type = .usize, .kind = .{ .extern_func = "__floatuntitf" } }, | ||
| 126839 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | ||
| 126840 | .unused, | ||
| 126841 | .unused, | ||
| 126842 | .unused, | ||
| 126843 | .unused, | ||
| 126844 | .unused, | ||
| 126845 | .unused, | ||
| 126846 | .unused, | ||
| 126847 | }, | ||
| 126848 | .dst_temps = .{ .mem, .unused }, | ||
| 126849 | .clobbers = .{ .eflags = true, .caller_preserved = .ccc }, | ||
| 126850 | .each = .{ .once = &.{ | ||
| 126851 | .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ }, | ||
| 126852 | .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ }, | ||
| 126853 | .{ ._, ._, .call, .tmp2d, ._, ._, ._ }, | ||
| 126854 | .{ ._, .v_dqa, .mov, .memi(.dst0x, .tmp0), .tmp3x, ._, ._ }, | ||
| 126855 | .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ }, | ||
| 126856 | .{ ._, ._ae, .j, .@"0b", ._, ._, ._ }, | ||
| 126857 | } }, | ||
| 126858 | }, .{ | ||
| 126859 | .required_cc_abi = .sysv64, | ||
| 126860 | .required_features = .{ .sse2, null, null, null }, | 126797 | .required_features = .{ .sse2, null, null, null }, |
| 126861 | .src_constraints = .{ .{ .multiple_scalar_unsigned_int = .{ .of = .xword, .is = .xword } }, .any, .any }, | 126798 | .src_constraints = .{ .{ .multiple_scalar_unsigned_int = .{ .of = .xword, .is = .xword } }, .any, .any }, |
| 126862 | .dst_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any }, | 126799 | .dst_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any }, |
| ... | @@ -126889,39 +126826,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -126889,39 +126826,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 126889 | .{ ._, ._ae, .j, .@"0b", ._, ._, ._ }, | 126826 | .{ ._, ._ae, .j, .@"0b", ._, ._, ._ }, |
| 126890 | } }, | 126827 | } }, |
| 126891 | }, .{ | 126828 | }, .{ |
| 126892 | .required_cc_abi = .win64, | ||
| 126893 | .required_features = .{ .sse2, null, null, null }, | ||
| 126894 | .src_constraints = .{ .{ .multiple_scalar_unsigned_int = .{ .of = .xword, .is = .xword } }, .any, .any }, | ||
| 126895 | .dst_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any }, | ||
| 126896 | .patterns = &.{ | ||
| 126897 | .{ .src = .{ .to_mem, .none, .none } }, | ||
| 126898 | }, | ||
| 126899 | .call_frame = .{ .alignment = .@"16" }, | ||
| 126900 | .extra_temps = .{ | ||
| 126901 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | ||
| 126902 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | ||
| 126903 | .{ .type = .usize, .kind = .{ .extern_func = "__floatuntitf" } }, | ||
| 126904 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | ||
| 126905 | .unused, | ||
| 126906 | .unused, | ||
| 126907 | .unused, | ||
| 126908 | .unused, | ||
| 126909 | .unused, | ||
| 126910 | .unused, | ||
| 126911 | .unused, | ||
| 126912 | }, | ||
| 126913 | .dst_temps = .{ .mem, .unused }, | ||
| 126914 | .clobbers = .{ .eflags = true, .caller_preserved = .ccc }, | ||
| 126915 | .each = .{ .once = &.{ | ||
| 126916 | .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ }, | ||
| 126917 | .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ }, | ||
| 126918 | .{ ._, ._, .call, .tmp2d, ._, ._, ._ }, | ||
| 126919 | .{ ._, ._dqa, .mov, .memi(.dst0x, .tmp0), .tmp3x, ._, ._ }, | ||
| 126920 | .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ }, | ||
| 126921 | .{ ._, ._ae, .j, .@"0b", ._, ._, ._ }, | ||
| 126922 | } }, | ||
| 126923 | }, .{ | ||
| 126924 | .required_cc_abi = .sysv64, | ||
| 126925 | .required_features = .{ .sse, null, null, null }, | 126829 | .required_features = .{ .sse, null, null, null }, |
| 126926 | .src_constraints = .{ .{ .multiple_scalar_unsigned_int = .{ .of = .xword, .is = .xword } }, .any, .any }, | 126830 | .src_constraints = .{ .{ .multiple_scalar_unsigned_int = .{ .of = .xword, .is = .xword } }, .any, .any }, |
| 126927 | .dst_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any }, | 126831 | .dst_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any }, |
| ... | @@ -126953,38 +126857,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -126953,38 +126857,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 126953 | .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ }, | 126857 | .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ }, |
| 126954 | .{ ._, ._ae, .j, .@"0b", ._, ._, ._ }, | 126858 | .{ ._, ._ae, .j, .@"0b", ._, ._, ._ }, |
| 126955 | } }, | 126859 | } }, |
| 126956 | }, .{ | ||
| 126957 | .required_cc_abi = .win64, | ||
| 126958 | .required_features = .{ .sse, null, null, null }, | ||
| 126959 | .src_constraints = .{ .{ .multiple_scalar_unsigned_int = .{ .of = .xword, .is = .xword } }, .any, .any }, | ||
| 126960 | .dst_constraints = .{ .{ .multiple_scalar_float = .{ .of = .xword, .is = .xword } }, .any }, | ||
| 126961 | .patterns = &.{ | ||
| 126962 | .{ .src = .{ .to_mem, .none, .none } }, | ||
| 126963 | }, | ||
| 126964 | .call_frame = .{ .alignment = .@"16" }, | ||
| 126965 | .extra_temps = .{ | ||
| 126966 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | ||
| 126967 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | ||
| 126968 | .{ .type = .usize, .kind = .{ .extern_func = "__floatuntitf" } }, | ||
| 126969 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | ||
| 126970 | .unused, | ||
| 126971 | .unused, | ||
| 126972 | .unused, | ||
| 126973 | .unused, | ||
| 126974 | .unused, | ||
| 126975 | .unused, | ||
| 126976 | .unused, | ||
| 126977 | }, | ||
| 126978 | .dst_temps = .{ .mem, .unused }, | ||
| 126979 | .clobbers = .{ .eflags = true, .caller_preserved = .ccc }, | ||
| 126980 | .each = .{ .once = &.{ | ||
| 126981 | .{ ._, ._, .mov, .tmp0d, .sia(-16, .src0, .add_unaligned_size), ._, ._ }, | ||
| 126982 | .{ .@"0:", ._, .lea, .tmp1p, .memi(.src0, .tmp0), ._, ._ }, | ||
| 126983 | .{ ._, ._, .call, .tmp2d, ._, ._, ._ }, | ||
| 126984 | .{ ._, ._ps, .mova, .memi(.dst0x, .tmp0), .tmp3x, ._, ._ }, | ||
| 126985 | .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ }, | ||
| 126986 | .{ ._, ._ae, .j, .@"0b", ._, ._, ._ }, | ||
| 126987 | } }, | ||
| 126988 | }, .{ | 126860 | }, .{ |
| 126989 | .required_features = .{ .@"64bit", .avx, null, null }, | 126861 | .required_features = .{ .@"64bit", .avx, null, null }, |
| 126990 | .src_constraints = .{ .{ .scalar_remainder_signed_int = .{ .of = .dword, .is = .dword } }, .any, .any }, | 126862 | .src_constraints = .{ .{ .scalar_remainder_signed_int = .{ .of = .dword, .is = .dword } }, .any, .any }, |
| ... | @@ -142552,7 +142424,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -142552,7 +142424,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 142552 | .extra_temps = .{ | 142424 | .extra_temps = .{ |
| 142553 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 142425 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 142554 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 142426 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 142555 | .{ .type = .usize, .kind = .{ .extern_func = "fminq" } }, | 142427 | .{ .type = .usize, .kind = .{ .extern_func = "fminf128" } }, |
| 142556 | .unused, | 142428 | .unused, |
| 142557 | .unused, | 142429 | .unused, |
| 142558 | .unused, | 142430 | .unused, |
| ... | @@ -142584,7 +142456,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -142584,7 +142456,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 142584 | .extra_temps = .{ | 142456 | .extra_temps = .{ |
| 142585 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 142457 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 142586 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 142458 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 142587 | .{ .type = .usize, .kind = .{ .extern_func = "fminq" } }, | 142459 | .{ .type = .usize, .kind = .{ .extern_func = "fminf128" } }, |
| 142588 | .unused, | 142460 | .unused, |
| 142589 | .unused, | 142461 | .unused, |
| 142590 | .unused, | 142462 | .unused, |
| ... | @@ -142616,7 +142488,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -142616,7 +142488,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 142616 | .extra_temps = .{ | 142488 | .extra_temps = .{ |
| 142617 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 142489 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 142618 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 142490 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 142619 | .{ .type = .usize, .kind = .{ .extern_func = "fminq" } }, | 142491 | .{ .type = .usize, .kind = .{ .extern_func = "fminf128" } }, |
| 142620 | .unused, | 142492 | .unused, |
| 142621 | .unused, | 142493 | .unused, |
| 142622 | .unused, | 142494 | .unused, |
| ... | @@ -142649,7 +142521,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -142649,7 +142521,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 142649 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 142521 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 142650 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 142522 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 142651 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 142523 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 142652 | .{ .type = .usize, .kind = .{ .extern_func = "fminq" } }, | 142524 | .{ .type = .usize, .kind = .{ .extern_func = "fminf128" } }, |
| 142653 | .{ .type = .f128, .kind = .mem }, | 142525 | .{ .type = .f128, .kind = .mem }, |
| 142654 | .unused, | 142526 | .unused, |
| 142655 | .unused, | 142527 | .unused, |
| ... | @@ -142683,7 +142555,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -142683,7 +142555,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 142683 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 142555 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 142684 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 142556 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 142685 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 142557 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 142686 | .{ .type = .usize, .kind = .{ .extern_func = "fminq" } }, | 142558 | .{ .type = .usize, .kind = .{ .extern_func = "fminf128" } }, |
| 142687 | .{ .type = .f128, .kind = .mem }, | 142559 | .{ .type = .f128, .kind = .mem }, |
| 142688 | .unused, | 142560 | .unused, |
| 142689 | .unused, | 142561 | .unused, |
| ... | @@ -142717,7 +142589,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -142717,7 +142589,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 142717 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 142589 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 142718 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 142590 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 142719 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 142591 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 142720 | .{ .type = .usize, .kind = .{ .extern_func = "fminq" } }, | 142592 | .{ .type = .usize, .kind = .{ .extern_func = "fminf128" } }, |
| 142721 | .{ .type = .f128, .kind = .mem }, | 142593 | .{ .type = .f128, .kind = .mem }, |
| 142722 | .unused, | 142594 | .unused, |
| 142723 | .unused, | 142595 | .unused, |
| ... | @@ -152785,7 +152657,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -152785,7 +152657,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 152785 | .extra_temps = .{ | 152657 | .extra_temps = .{ |
| 152786 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 152658 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 152787 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 152659 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 152788 | .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } }, | 152660 | .{ .type = .usize, .kind = .{ .extern_func = "fmaxf128" } }, |
| 152789 | .unused, | 152661 | .unused, |
| 152790 | .unused, | 152662 | .unused, |
| 152791 | .unused, | 152663 | .unused, |
| ... | @@ -152817,7 +152689,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -152817,7 +152689,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 152817 | .extra_temps = .{ | 152689 | .extra_temps = .{ |
| 152818 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 152690 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 152819 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 152691 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 152820 | .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } }, | 152692 | .{ .type = .usize, .kind = .{ .extern_func = "fmaxf128" } }, |
| 152821 | .unused, | 152693 | .unused, |
| 152822 | .unused, | 152694 | .unused, |
| 152823 | .unused, | 152695 | .unused, |
| ... | @@ -152849,7 +152721,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -152849,7 +152721,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 152849 | .extra_temps = .{ | 152721 | .extra_temps = .{ |
| 152850 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 152722 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 152851 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 152723 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 152852 | .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } }, | 152724 | .{ .type = .usize, .kind = .{ .extern_func = "fmaxf128" } }, |
| 152853 | .unused, | 152725 | .unused, |
| 152854 | .unused, | 152726 | .unused, |
| 152855 | .unused, | 152727 | .unused, |
| ... | @@ -152882,7 +152754,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -152882,7 +152754,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 152882 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 152754 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 152883 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 152755 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 152884 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 152756 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 152885 | .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } }, | 152757 | .{ .type = .usize, .kind = .{ .extern_func = "fmaxf128" } }, |
| 152886 | .{ .type = .f128, .kind = .mem }, | 152758 | .{ .type = .f128, .kind = .mem }, |
| 152887 | .unused, | 152759 | .unused, |
| 152888 | .unused, | 152760 | .unused, |
| ... | @@ -152916,7 +152788,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -152916,7 +152788,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 152916 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 152788 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 152917 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 152789 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 152918 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 152790 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 152919 | .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } }, | 152791 | .{ .type = .usize, .kind = .{ .extern_func = "fmaxf128" } }, |
| 152920 | .{ .type = .f128, .kind = .mem }, | 152792 | .{ .type = .f128, .kind = .mem }, |
| 152921 | .unused, | 152793 | .unused, |
| 152922 | .unused, | 152794 | .unused, |
| ... | @@ -152950,7 +152822,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -152950,7 +152822,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 152950 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 152822 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 152951 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 152823 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 152952 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 152824 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 152953 | .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } }, | 152825 | .{ .type = .usize, .kind = .{ .extern_func = "fmaxf128" } }, |
| 152954 | .{ .type = .f128, .kind = .mem }, | 152826 | .{ .type = .f128, .kind = .mem }, |
| 152955 | .unused, | 152827 | .unused, |
| 152956 | .unused, | 152828 | .unused, |
| ... | @@ -163019,7 +162891,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -163019,7 +162891,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 163019 | .extra_temps = .{ | 162891 | .extra_temps = .{ |
| 163020 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 162892 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 163021 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 162893 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 163022 | .{ .type = .usize, .kind = .{ .extern_func = "fminq" } }, | 162894 | .{ .type = .usize, .kind = .{ .extern_func = "fminf128" } }, |
| 163023 | .unused, | 162895 | .unused, |
| 163024 | .unused, | 162896 | .unused, |
| 163025 | .unused, | 162897 | .unused, |
| ... | @@ -163051,7 +162923,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -163051,7 +162923,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 163051 | .extra_temps = .{ | 162923 | .extra_temps = .{ |
| 163052 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 162924 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 163053 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 162925 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 163054 | .{ .type = .usize, .kind = .{ .extern_func = "fminq" } }, | 162926 | .{ .type = .usize, .kind = .{ .extern_func = "fminf128" } }, |
| 163055 | .unused, | 162927 | .unused, |
| 163056 | .unused, | 162928 | .unused, |
| 163057 | .unused, | 162929 | .unused, |
| ... | @@ -163083,7 +162955,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -163083,7 +162955,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 163083 | .extra_temps = .{ | 162955 | .extra_temps = .{ |
| 163084 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 162956 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 163085 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 162957 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 163086 | .{ .type = .usize, .kind = .{ .extern_func = "fminq" } }, | 162958 | .{ .type = .usize, .kind = .{ .extern_func = "fminf128" } }, |
| 163087 | .unused, | 162959 | .unused, |
| 163088 | .unused, | 162960 | .unused, |
| 163089 | .unused, | 162961 | .unused, |
| ... | @@ -163116,7 +162988,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -163116,7 +162988,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 163116 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 162988 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 163117 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 162989 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 163118 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 162990 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 163119 | .{ .type = .usize, .kind = .{ .extern_func = "fminq" } }, | 162991 | .{ .type = .usize, .kind = .{ .extern_func = "fminf128" } }, |
| 163120 | .{ .type = .f128, .kind = .mem }, | 162992 | .{ .type = .f128, .kind = .mem }, |
| 163121 | .unused, | 162993 | .unused, |
| 163122 | .unused, | 162994 | .unused, |
| ... | @@ -163150,7 +163022,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -163150,7 +163022,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 163150 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 163022 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 163151 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 163023 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 163152 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 163024 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 163153 | .{ .type = .usize, .kind = .{ .extern_func = "fminq" } }, | 163025 | .{ .type = .usize, .kind = .{ .extern_func = "fminf128" } }, |
| 163154 | .{ .type = .f128, .kind = .mem }, | 163026 | .{ .type = .f128, .kind = .mem }, |
| 163155 | .unused, | 163027 | .unused, |
| 163156 | .unused, | 163028 | .unused, |
| ... | @@ -163184,7 +163056,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -163184,7 +163056,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 163184 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 163056 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 163185 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 163057 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 163186 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 163058 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 163187 | .{ .type = .usize, .kind = .{ .extern_func = "fminq" } }, | 163059 | .{ .type = .usize, .kind = .{ .extern_func = "fminf128" } }, |
| 163188 | .{ .type = .f128, .kind = .mem }, | 163060 | .{ .type = .f128, .kind = .mem }, |
| 163189 | .unused, | 163061 | .unused, |
| 163190 | .unused, | 163062 | .unused, |
| ... | @@ -164816,7 +164688,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -164816,7 +164688,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 164816 | .extra_temps = .{ | 164688 | .extra_temps = .{ |
| 164817 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 164689 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 164818 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 164690 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 164819 | .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } }, | 164691 | .{ .type = .usize, .kind = .{ .extern_func = "fmaxf128" } }, |
| 164820 | .unused, | 164692 | .unused, |
| 164821 | .unused, | 164693 | .unused, |
| 164822 | .unused, | 164694 | .unused, |
| ... | @@ -164848,7 +164720,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -164848,7 +164720,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 164848 | .extra_temps = .{ | 164720 | .extra_temps = .{ |
| 164849 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 164721 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 164850 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 164722 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 164851 | .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } }, | 164723 | .{ .type = .usize, .kind = .{ .extern_func = "fmaxf128" } }, |
| 164852 | .unused, | 164724 | .unused, |
| 164853 | .unused, | 164725 | .unused, |
| 164854 | .unused, | 164726 | .unused, |
| ... | @@ -164880,7 +164752,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -164880,7 +164752,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 164880 | .extra_temps = .{ | 164752 | .extra_temps = .{ |
| 164881 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 164753 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 164882 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 164754 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 164883 | .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } }, | 164755 | .{ .type = .usize, .kind = .{ .extern_func = "fmaxf128" } }, |
| 164884 | .unused, | 164756 | .unused, |
| 164885 | .unused, | 164757 | .unused, |
| 164886 | .unused, | 164758 | .unused, |
| ... | @@ -164913,7 +164785,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -164913,7 +164785,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 164913 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 164785 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 164914 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 164786 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 164915 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 164787 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 164916 | .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } }, | 164788 | .{ .type = .usize, .kind = .{ .extern_func = "fmaxf128" } }, |
| 164917 | .{ .type = .f128, .kind = .mem }, | 164789 | .{ .type = .f128, .kind = .mem }, |
| 164918 | .unused, | 164790 | .unused, |
| 164919 | .unused, | 164791 | .unused, |
| ... | @@ -164947,7 +164819,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -164947,7 +164819,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 164947 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 164819 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 164948 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 164820 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 164949 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 164821 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 164950 | .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } }, | 164822 | .{ .type = .usize, .kind = .{ .extern_func = "fmaxf128" } }, |
| 164951 | .{ .type = .f128, .kind = .mem }, | 164823 | .{ .type = .f128, .kind = .mem }, |
| 164952 | .unused, | 164824 | .unused, |
| 164953 | .unused, | 164825 | .unused, |
| ... | @@ -164981,7 +164853,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -164981,7 +164853,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 164981 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | 164853 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 164982 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 164854 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 164983 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 164855 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 164984 | .{ .type = .usize, .kind = .{ .extern_func = "fmaxq" } }, | 164856 | .{ .type = .usize, .kind = .{ .extern_func = "fmaxf128" } }, |
| 164985 | .{ .type = .f128, .kind = .mem }, | 164857 | .{ .type = .f128, .kind = .mem }, |
| 164986 | .unused, | 164858 | .unused, |
| 164987 | .unused, | 164859 | .unused, |
| ... | @@ -172785,7 +172657,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -172785,7 +172657,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 172785 | }, | 172657 | }, |
| 172786 | .call_frame = .{ .alignment = .@"16" }, | 172658 | .call_frame = .{ .alignment = .@"16" }, |
| 172787 | .extra_temps = .{ | 172659 | .extra_temps = .{ |
| 172788 | .{ .type = .usize, .kind = .{ .extern_func = "fmaq" } }, | 172660 | .{ .type = .usize, .kind = .{ .extern_func = "fmaf128" } }, |
| 172789 | .unused, | 172661 | .unused, |
| 172790 | .unused, | 172662 | .unused, |
| 172791 | .unused, | 172663 | .unused, |
| ... | @@ -172818,7 +172690,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -172818,7 +172690,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 172818 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 172690 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 172819 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 172691 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 172820 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 2, .at = 2 } } }, | 172692 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 2, .at = 2 } } }, |
| 172821 | .{ .type = .usize, .kind = .{ .extern_func = "fmaq" } }, | 172693 | .{ .type = .usize, .kind = .{ .extern_func = "fmaf128" } }, |
| 172822 | .unused, | 172694 | .unused, |
| 172823 | .unused, | 172695 | .unused, |
| 172824 | .unused, | 172696 | .unused, |
| ... | @@ -172852,7 +172724,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -172852,7 +172724,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 172852 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 172724 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 172853 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 172725 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 172854 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 2, .at = 2 } } }, | 172726 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 2, .at = 2 } } }, |
| 172855 | .{ .type = .usize, .kind = .{ .extern_func = "fmaq" } }, | 172727 | .{ .type = .usize, .kind = .{ .extern_func = "fmaf128" } }, |
| 172856 | .unused, | 172728 | .unused, |
| 172857 | .unused, | 172729 | .unused, |
| 172858 | .unused, | 172730 | .unused, |
| ... | @@ -172889,7 +172761,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -172889,7 +172761,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 172889 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 172761 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 172890 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 172762 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 172891 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 2, .at = 2 } } }, | 172763 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 2, .at = 2 } } }, |
| 172892 | .{ .type = .usize, .kind = .{ .extern_func = "fmaq" } }, | 172764 | .{ .type = .usize, .kind = .{ .extern_func = "fmaf128" } }, |
| 172893 | .unused, | 172765 | .unused, |
| 172894 | .unused, | 172766 | .unused, |
| 172895 | .unused, | 172767 | .unused, |
| ... | @@ -172926,7 +172798,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -172926,7 +172798,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 172926 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 172798 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 172927 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 172799 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 172928 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 2, .at = 2 } } }, | 172800 | .{ .type = .f128, .kind = .{ .param_sse = .{ .cc = .ccc, .after = 2, .at = 2 } } }, |
| 172929 | .{ .type = .usize, .kind = .{ .extern_func = "fmaq" } }, | 172801 | .{ .type = .usize, .kind = .{ .extern_func = "fmaf128" } }, |
| 172930 | .unused, | 172802 | .unused, |
| 172931 | .unused, | 172803 | .unused, |
| 172932 | .unused, | 172804 | .unused, |
| ... | @@ -172963,7 +172835,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -172963,7 +172835,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 172963 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 172835 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 172964 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 172836 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 172965 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 2, .at = 2 } } }, | 172837 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 2, .at = 2 } } }, |
| 172966 | .{ .type = .usize, .kind = .{ .extern_func = "fmaq" } }, | 172838 | .{ .type = .usize, .kind = .{ .extern_func = "fmaf128" } }, |
| 172967 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 172839 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 172968 | .unused, | 172840 | .unused, |
| 172969 | .unused, | 172841 | .unused, |
| ... | @@ -173000,7 +172872,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -173000,7 +172872,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 173000 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 172872 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 173001 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 172873 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 173002 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 2, .at = 2 } } }, | 172874 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 2, .at = 2 } } }, |
| 173003 | .{ .type = .usize, .kind = .{ .extern_func = "fmaq" } }, | 172875 | .{ .type = .usize, .kind = .{ .extern_func = "fmaf128" } }, |
| 173004 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 172876 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 173005 | .unused, | 172877 | .unused, |
| 173006 | .unused, | 172878 | .unused, |
| ... | @@ -173037,7 +172909,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -173037,7 +172909,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 173037 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 172909 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 173038 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, | 172910 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 1, .at = 1 } } }, |
| 173039 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 2, .at = 2 } } }, | 172911 | .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .after = 2, .at = 2 } } }, |
| 173040 | .{ .type = .usize, .kind = .{ .extern_func = "fmaq" } }, | 172912 | .{ .type = .usize, .kind = .{ .extern_func = "fmaf128" } }, |
| 173041 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, | 172913 | .{ .type = .f128, .kind = .{ .ret_sse = .{ .cc = .ccc, .after = 0, .at = 0 } } }, |
| 173042 | .unused, | 172914 | .unused, |
| 173043 | .unused, | 172915 | .unused, |
| ... | @@ -176621,10 +176493,20 @@ fn genCall(cg: *CodeGen, info: union(enum) { | ... | @@ -176621,10 +176493,20 @@ fn genCall(cg: *CodeGen, info: union(enum) { |
| 176621 | 176493 | ||
| 176622 | for (call_info.args, arg_types, args, frame_indices) |dst_arg, arg_ty, src_arg, frame_index| switch (dst_arg) { | 176494 | for (call_info.args, arg_types, args, frame_indices) |dst_arg, arg_ty, src_arg, frame_index| switch (dst_arg) { |
| 176623 | .none, .load_frame, .indirect_load_frame => {}, | 176495 | .none, .load_frame, .indirect_load_frame => {}, |
| 176624 | .register => |dst_reg| try cg.genSetReg(registerAlias( | 176496 | .register => |dst_reg| switch (fn_info.cc) { |
| 176625 | dst_reg, | 176497 | else => try cg.genSetReg(registerAlias( |
| 176626 | @intCast(cg.unalignedSize(arg_ty)), | 176498 | dst_reg, |
| 176627 | ), arg_ty, src_arg, opts), | 176499 | @intCast(cg.unalignedSize(arg_ty)), |
| 176500 | ), arg_ty, src_arg, opts), | ||
| 176501 | .x86_64_sysv, .x86_64_win => { | ||
| 176502 | const promoted_ty = cg.promoteInt(arg_ty); | ||
| 176503 | const promoted_unaligned_size: u32 = @intCast(cg.unalignedSize(promoted_ty)); | ||
| 176504 | const dst_alias = registerAlias(dst_reg, promoted_unaligned_size); | ||
| 176505 | try cg.genSetReg(dst_alias, promoted_ty, src_arg, opts); | ||
| 176506 | if (promoted_ty.toIntern() != arg_ty.toIntern()) | ||
| 176507 | try cg.truncateRegister(arg_ty, dst_alias); | ||
| 176508 | }, | ||
| 176509 | }, | ||
| 176628 | .register_pair, | 176510 | .register_pair, |
| 176629 | .register_triple, | 176511 | .register_triple, |
| 176630 | .register_quadruple, | 176512 | .register_quadruple, |
| ... | @@ -177096,7 +176978,7 @@ fn lowerBlock(self: *CodeGen, inst: Air.Inst.Index, body: []const Air.Inst.Index | ... | @@ -177096,7 +176978,7 @@ fn lowerBlock(self: *CodeGen, inst: Air.Inst.Index, body: []const Air.Inst.Index |
| 177096 | defer block_data.value.deinit(self.gpa); | 176978 | defer block_data.value.deinit(self.gpa); |
| 177097 | if (block_data.value.relocs.items.len > 0) { | 176979 | if (block_data.value.relocs.items.len > 0) { |
| 177098 | var last_inst: Mir.Inst.Index = @intCast(self.mir_instructions.len - 1); | 176980 | var last_inst: Mir.Inst.Index = @intCast(self.mir_instructions.len - 1); |
| 177099 | while (block_data.value.relocs.getLast() == last_inst) { | 176981 | while (block_data.value.relocs.last() == last_inst) { |
| 177100 | block_data.value.relocs.items.len -= 1; | 176982 | block_data.value.relocs.items.len -= 1; |
| 177101 | self.mir_instructions.set(last_inst, .{ | 176983 | self.mir_instructions.set(last_inst, .{ |
| 177102 | .tag = .pseudo, | 176984 | .tag = .pseudo, |
| ... | @@ -178017,7 +177899,7 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -178017,7 +177899,7 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 178017 | else if (std.mem.endsWith(u8, mnem_str, "l")) | 177899 | else if (std.mem.endsWith(u8, mnem_str, "l")) |
| 178018 | .dword | 177900 | .dword |
| 178019 | else if (std.mem.endsWith(u8, mnem_str, "q") and | 177901 | else if (std.mem.endsWith(u8, mnem_str, "q") and |
| 178020 | (std.mem.indexOfScalar(u8, "vp", mnem_str[0]) == null or | 177902 | (std.mem.findScalar(u8, "vp", mnem_str[0]) == null or |
| 178021 | !std.mem.endsWith(u8, mnem_str, "dq"))) | 177903 | !std.mem.endsWith(u8, mnem_str, "dq"))) |
| 178022 | .qword | 177904 | .qword |
| 178023 | else if (std.mem.endsWith(u8, mnem_str, "t")) | 177905 | else if (std.mem.endsWith(u8, mnem_str, "t")) |
| ... | @@ -178084,8 +177966,8 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -178084,8 +177966,8 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 178084 | }) + 1, | 177966 | }) + 1, |
| 178085 | } | 177967 | } |
| 178086 | }; | 177968 | }; |
| 178087 | const untrimmed_op_str = if (std.mem.indexOfScalar(u8, full_op_str, '#') orelse | 177969 | const untrimmed_op_str = if (std.mem.findScalar(u8, full_op_str, '#') orelse |
| 178088 | std.mem.indexOf(u8, full_op_str, "//")) |comment| | 177970 | std.mem.find(u8, full_op_str, "//")) |comment| |
| 178089 | untrimmed_op_str: { | 177971 | untrimmed_op_str: { |
| 178090 | ops_index = ops_str.len; | 177972 | ops_index = ops_str.len; |
| 178091 | break :untrimmed_op_str full_op_str[0..comment]; | 177973 | break :untrimmed_op_str full_op_str[0..comment]; |
| ... | @@ -178094,7 +177976,7 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -178094,7 +177976,7 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 178094 | if (trimmed_op_str.len > 0) break trimmed_op_str; | 177976 | if (trimmed_op_str.len > 0) break trimmed_op_str; |
| 178095 | }; | 177977 | }; |
| 178096 | if (std.mem.startsWith(u8, op_str, "%%")) { | 177978 | if (std.mem.startsWith(u8, op_str, "%%")) { |
| 178097 | const colon = std.mem.indexOfScalarPos(u8, op_str, "%%".len + 2, ':'); | 177979 | const colon = std.mem.findScalarPos(u8, op_str, "%%".len + 2, ':'); |
| 178098 | const reg = parseRegName(op_str["%%".len .. colon orelse op_str.len]) orelse | 177980 | const reg = parseRegName(op_str["%%".len .. colon orelse op_str.len]) orelse |
| 178099 | return self.fail("invalid register: '{s}'", .{op_str}); | 177981 | return self.fail("invalid register: '{s}'", .{op_str}); |
| 178100 | if (colon) |colon_pos| { | 177982 | if (colon) |colon_pos| { |
| ... | @@ -178115,7 +177997,7 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -178115,7 +177997,7 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 178115 | op.* = .{ .reg = reg }; | 177997 | op.* = .{ .reg = reg }; |
| 178116 | } | 177998 | } |
| 178117 | } else if (std.mem.startsWith(u8, op_str, "%[") and std.mem.endsWith(u8, op_str, "]")) { | 177999 | } else if (std.mem.startsWith(u8, op_str, "%[") and std.mem.endsWith(u8, op_str, "]")) { |
| 178118 | const colon = std.mem.indexOfScalarPos(u8, op_str, "%[".len, ':'); | 178000 | const colon = std.mem.findScalarPos(u8, op_str, "%[".len, ':'); |
| 178119 | const modifier = if (colon) |colon_pos| | 178001 | const modifier = if (colon) |colon_pos| |
| 178120 | op_str[colon_pos + ":".len .. op_str.len - "]".len] | 178002 | op_str[colon_pos + ":".len .. op_str.len - "]".len] |
| 178121 | else | 178003 | else |
| ... | @@ -178198,7 +178080,7 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -178198,7 +178080,7 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 178198 | else |_| | 178080 | else |_| |
| 178199 | return self.fail("invalid immediate: '{s}'", .{op_str}); | 178081 | return self.fail("invalid immediate: '{s}'", .{op_str}); |
| 178200 | } else if (std.mem.endsWith(u8, op_str, ")")) { | 178082 | } else if (std.mem.endsWith(u8, op_str, ")")) { |
| 178201 | const open = std.mem.indexOfScalar(u8, op_str, '(') orelse | 178083 | const open = std.mem.findScalar(u8, op_str, '(') orelse |
| 178202 | return self.fail("invalid operand: '{s}'", .{op_str}); | 178084 | return self.fail("invalid operand: '{s}'", .{op_str}); |
| 178203 | var sib_it = | 178085 | var sib_it = |
| 178204 | std.mem.splitScalar(u8, op_str[open + "(".len .. op_str.len - ")".len], ','); | 178086 | std.mem.splitScalar(u8, op_str[open + "(".len .. op_str.len - ")".len], ','); |
| ... | @@ -178259,7 +178141,7 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -178259,7 +178141,7 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 178259 | .disp = if (std.mem.startsWith(u8, op_str[0..open], "%[") and | 178141 | .disp = if (std.mem.startsWith(u8, op_str[0..open], "%[") and |
| 178260 | std.mem.endsWith(u8, op_str[0..open], "]")) | 178142 | std.mem.endsWith(u8, op_str[0..open], "]")) |
| 178261 | disp: { | 178143 | disp: { |
| 178262 | const colon = std.mem.indexOfScalarPos(u8, op_str[0..open], "%[".len, ':'); | 178144 | const colon = std.mem.findScalarPos(u8, op_str[0..open], "%[".len, ':'); |
| 178263 | const modifier = if (colon) |colon_pos| | 178145 | const modifier = if (colon) |colon_pos| |
| 178264 | op_str[colon_pos + ":".len .. open - "]".len] | 178146 | op_str[colon_pos + ":".len .. open - "]".len] |
| 178265 | else | 178147 | else |
| ... | @@ -178328,14 +178210,14 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -178328,14 +178210,14 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 178328 | .{ ._, .pseudo } | 178210 | .{ ._, .pseudo } |
| 178329 | else for (std.enums.values(Mir.Inst.Fixes)) |fixes| { | 178211 | else for (std.enums.values(Mir.Inst.Fixes)) |fixes| { |
| 178330 | const fixes_name = @tagName(fixes); | 178212 | const fixes_name = @tagName(fixes); |
| 178331 | const space_index = std.mem.indexOfScalar(u8, fixes_name, ' '); | 178213 | const space_index = std.mem.findScalar(u8, fixes_name, ' '); |
| 178332 | const fixes_prefix = if (space_index) |index| | 178214 | const fixes_prefix = if (space_index) |index| |
| 178333 | std.meta.stringToEnum(encoder.Instruction.Prefix, fixes_name[0..index]).? | 178215 | std.meta.stringToEnum(encoder.Instruction.Prefix, fixes_name[0..index]).? |
| 178334 | else | 178216 | else |
| 178335 | .none; | 178217 | .none; |
| 178336 | if (fixes_prefix != prefix) continue; | 178218 | if (fixes_prefix != prefix) continue; |
| 178337 | const pattern = fixes_name[if (space_index) |index| index + " ".len else 0..]; | 178219 | const pattern = fixes_name[if (space_index) |index| index + " ".len else 0..]; |
| 178338 | const wildcard_index = std.mem.indexOfScalar(u8, pattern, '_').?; | 178220 | const wildcard_index = std.mem.findScalar(u8, pattern, '_').?; |
| 178339 | const mnem_prefix = pattern[0..wildcard_index]; | 178221 | const mnem_prefix = pattern[0..wildcard_index]; |
| 178340 | const mnem_suffix = pattern[wildcard_index + "_".len ..]; | 178222 | const mnem_suffix = pattern[wildcard_index + "_".len ..]; |
| 178341 | if (!std.mem.startsWith(u8, mnem_name, mnem_prefix)) continue; | 178223 | if (!std.mem.startsWith(u8, mnem_name, mnem_prefix)) continue; |
| ... | @@ -178581,11 +178463,11 @@ fn moveStrategy(cg: *CodeGen, ty: Type, class: Register.Class, aligned: bool) !M | ... | @@ -178581,11 +178463,11 @@ fn moveStrategy(cg: *CodeGen, ty: Type, class: Register.Class, aligned: bool) !M |
| 178581 | .sse => switch (ty.zigTypeTag(zcu)) { | 178463 | .sse => switch (ty.zigTypeTag(zcu)) { |
| 178582 | else => { | 178464 | else => { |
| 178583 | const classes = std.mem.sliceTo(&abi.classifySystemV(ty, zcu, cg.target, .other), .none); | 178465 | const classes = std.mem.sliceTo(&abi.classifySystemV(ty, zcu, cg.target, .other), .none); |
| 178584 | assert(std.mem.indexOfNone(abi.Class, classes, &.{ | 178466 | assert(std.mem.findNone(abi.Class, classes, &.{ |
| 178585 | .integer, .sse, .sseup, .memory, .float, .float_combine, | 178467 | .integer, .sse, .sseup, .memory, .float, .float_combine, |
| 178586 | }) == null); | 178468 | }) == null); |
| 178587 | const abi_size = ty.abiSize(zcu); | 178469 | const abi_size = ty.abiSize(zcu); |
| 178588 | if (abi_size < 4 or std.mem.indexOfScalar(abi.Class, classes, .integer) != null) switch (abi_size) { | 178470 | if (abi_size < 4 or std.mem.findScalar(abi.Class, classes, .integer) != null) switch (abi_size) { |
| 178589 | 1 => return if (cg.hasFeature(.avx)) .{ .vex_insert_extract = .{ | 178471 | 1 => return if (cg.hasFeature(.avx)) .{ .vex_insert_extract = .{ |
| 178590 | .insert = .{ .vp_b, .insr }, | 178472 | .insert = .{ .vp_b, .insr }, |
| 178591 | .extract = .{ .vp_b, .extr }, | 178473 | .extract = .{ .vp_b, .extr }, |
| ... | @@ -181994,7 +181876,7 @@ fn resolveCallingConventionValues( | ... | @@ -181994,7 +181876,7 @@ fn resolveCallingConventionValues( |
| 181994 | } | 181876 | } |
| 181995 | 181877 | ||
| 181996 | const save_param_gpr_index = param_gpr_index; | 181878 | const save_param_gpr_index = param_gpr_index; |
| 181997 | const save_param_sse_index = param_gpr_index; | 181879 | const save_param_sse_index = param_sse_index; |
| 181998 | 181880 | ||
| 181999 | var arg_mcv: [4]MCValue = undefined; | 181881 | var arg_mcv: [4]MCValue = undefined; |
| 182000 | var arg_mcv_len: u32 = 0; | 181882 | var arg_mcv_len: u32 = 0; |
| ... | @@ -182502,8 +182384,8 @@ fn hasFeature(cg: *CodeGen, feature: std.Target.x86.Feature) bool { | ... | @@ -182502,8 +182384,8 @@ fn hasFeature(cg: *CodeGen, feature: std.Target.x86.Feature) bool { |
| 182502 | .slow_unaligned_mem_16, | 182384 | .slow_unaligned_mem_16, |
| 182503 | .slow_unaligned_mem_32, | 182385 | .slow_unaligned_mem_32, |
| 182504 | => switch (cg.mod.optimize_mode) { | 182386 | => switch (cg.mod.optimize_mode) { |
| 182505 | .Debug, .ReleaseSafe, .ReleaseFast => null, | 182387 | .debug, .safe, .fast => null, |
| 182506 | .ReleaseSmall => false, | 182388 | .small => false, |
| 182507 | }, | 182389 | }, |
| 182508 | .fast_11bytenop, | 182390 | .fast_11bytenop, |
| 182509 | .fast_15bytenop, | 182391 | .fast_15bytenop, |
| ... | @@ -182523,8 +182405,8 @@ fn hasFeature(cg: *CodeGen, feature: std.Target.x86.Feature) bool { | ... | @@ -182523,8 +182405,8 @@ fn hasFeature(cg: *CodeGen, feature: std.Target.x86.Feature) bool { |
| 182523 | .fast_vector_fsqrt, | 182405 | .fast_vector_fsqrt, |
| 182524 | .fast_vector_shift_masks, | 182406 | .fast_vector_shift_masks, |
| 182525 | => switch (cg.mod.optimize_mode) { | 182407 | => switch (cg.mod.optimize_mode) { |
| 182526 | .Debug, .ReleaseSafe, .ReleaseFast => null, | 182408 | .debug, .safe, .fast => null, |
| 182527 | .ReleaseSmall => true, | 182409 | .small => true, |
| 182528 | }, | 182410 | }, |
| 182529 | .mmx => false, | 182411 | .mmx => false, |
| 182530 | .sahf => switch (cg.target.cpu.arch) { | 182412 | .sahf => switch (cg.target.cpu.arch) { |
| ... | @@ -182626,15 +182508,15 @@ fn intInfo(cg: *CodeGen, ty: Type) ?std.lang.Type.Int { | ... | @@ -182626,15 +182508,15 @@ fn intInfo(cg: *CodeGen, ty: Type) ?std.lang.Type.Int { |
| 182626 | .anyerror => .{ .signedness = .unsigned, .bits = zcu.errorSetBits() }, | 182508 | .anyerror => .{ .signedness = .unsigned, .bits = zcu.errorSetBits() }, |
| 182627 | .isize => .{ .signedness = .signed, .bits = cg.target.ptrBitWidth() }, | 182509 | .isize => .{ .signedness = .signed, .bits = cg.target.ptrBitWidth() }, |
| 182628 | .usize => .{ .signedness = .unsigned, .bits = cg.target.ptrBitWidth() }, | 182510 | .usize => .{ .signedness = .unsigned, .bits = cg.target.ptrBitWidth() }, |
| 182629 | .c_char => .{ .signedness = cg.target.cCharSignedness(), .bits = cg.target.cTypeBitSize(.char) }, | 182511 | .c_char => .{ .signedness = cg.target.cCharSignedness().?, .bits = cg.target.cTypeBitSize(.char).? }, |
| 182630 | .c_short => .{ .signedness = .signed, .bits = cg.target.cTypeBitSize(.short) }, | 182512 | .c_short => .{ .signedness = .signed, .bits = cg.target.cTypeBitSize(.short).? }, |
| 182631 | .c_ushort => .{ .signedness = .unsigned, .bits = cg.target.cTypeBitSize(.short) }, | 182513 | .c_ushort => .{ .signedness = .unsigned, .bits = cg.target.cTypeBitSize(.short).? }, |
| 182632 | .c_int => .{ .signedness = .signed, .bits = cg.target.cTypeBitSize(.int) }, | 182514 | .c_int => .{ .signedness = .signed, .bits = cg.target.cTypeBitSize(.int).? }, |
| 182633 | .c_uint => .{ .signedness = .unsigned, .bits = cg.target.cTypeBitSize(.int) }, | 182515 | .c_uint => .{ .signedness = .unsigned, .bits = cg.target.cTypeBitSize(.int).? }, |
| 182634 | .c_long => .{ .signedness = .signed, .bits = cg.target.cTypeBitSize(.long) }, | 182516 | .c_long => .{ .signedness = .signed, .bits = cg.target.cTypeBitSize(.long).? }, |
| 182635 | .c_ulong => .{ .signedness = .unsigned, .bits = cg.target.cTypeBitSize(.long) }, | 182517 | .c_ulong => .{ .signedness = .unsigned, .bits = cg.target.cTypeBitSize(.long).? }, |
| 182636 | .c_longlong => .{ .signedness = .signed, .bits = cg.target.cTypeBitSize(.longlong) }, | 182518 | .c_longlong => .{ .signedness = .signed, .bits = cg.target.cTypeBitSize(.longlong).? }, |
| 182637 | .c_ulonglong => .{ .signedness = .unsigned, .bits = cg.target.cTypeBitSize(.longlong) }, | 182519 | .c_ulonglong => .{ .signedness = .unsigned, .bits = cg.target.cTypeBitSize(.longlong).? }, |
| 182638 | .f16, .f32, .f64, .f80, .f128, .c_longdouble => null, | 182520 | .f16, .f32, .f64, .f80, .f128, .c_longdouble => null, |
| 182639 | .anyopaque, | 182521 | .anyopaque, |
| 182640 | .void, | 182522 | .void, |
| ... | @@ -183696,8 +183578,8 @@ const Temp = struct { | ... | @@ -183696,8 +183578,8 @@ const Temp = struct { |
| 183696 | const class = classes[class_index]; | 183578 | const class = classes[class_index]; |
| 183697 | next_class_index = @intCast(switch (class) { | 183579 | next_class_index = @intCast(switch (class) { |
| 183698 | .integer, .memory, .float, .float_combine => class_index + 1, | 183580 | .integer, .memory, .float, .float_combine => class_index + 1, |
| 183699 | .sse => std.mem.indexOfNonePos(abi.Class, classes, class_index + 1, &.{.sseup}) orelse classes.len, | 183581 | .sse => std.mem.findNonePos(abi.Class, classes, class_index + 1, &.{.sseup}) orelse classes.len, |
| 183700 | .x87 => std.mem.indexOfNonePos(abi.Class, classes, class_index + 1, &.{.x87up}) orelse classes.len, | 183582 | .x87 => std.mem.findNonePos(abi.Class, classes, class_index + 1, &.{.x87up}) orelse classes.len, |
| 183701 | .sseup, | 183583 | .sseup, |
| 183702 | .x87up, | 183584 | .x87up, |
| 183703 | .none, | 183585 | .none, |
| ... | @@ -189943,7 +189825,7 @@ const Select = struct { | ... | @@ -189943,7 +189825,7 @@ const Select = struct { |
| 189943 | s.cg.asmOps(mir_tag, mir_ops) catch |err| switch (err) { | 189825 | s.cg.asmOps(mir_tag, mir_ops) catch |err| switch (err) { |
| 189944 | error.InvalidInstruction => { | 189826 | error.InvalidInstruction => { |
| 189945 | const fixes = @tagName(mir_tag[0]); | 189827 | const fixes = @tagName(mir_tag[0]); |
| 189946 | const fixes_blank = std.mem.indexOfScalar(u8, fixes, '_').?; | 189828 | const fixes_blank = std.mem.findScalar(u8, fixes, '_').?; |
| 189947 | return s.cg.fail("invalid instruction: '{s}{s}{s} {s} {s} {s} {s}'", .{ | 189829 | return s.cg.fail("invalid instruction: '{s}{s}{s} {s} {s} {s} {s}'", .{ |
| 189948 | fixes[0..fixes_blank], | 189830 | fixes[0..fixes_blank], |
| 189949 | @tagName(mir_tag[1]), | 189831 | @tagName(mir_tag[1]), |
| ... | @@ -190023,7 +189905,7 @@ const Select = struct { | ... | @@ -190023,7 +189905,7 @@ const Select = struct { |
| 190023 | .add, .com, .comi, .div, .divr, .mul, .st, .sub, .subr, .ucom, .ucomi => s.top +%= 1, | 189905 | .add, .com, .comi, .div, .divr, .mul, .st, .sub, .subr, .ucom, .ucomi => s.top +%= 1, |
| 190024 | else => { | 189906 | else => { |
| 190025 | const fixes = @tagName(mir_tag[0]); | 189907 | const fixes = @tagName(mir_tag[0]); |
| 190026 | const fixes_blank = std.mem.indexOfScalar(u8, fixes, '_').?; | 189908 | const fixes_blank = std.mem.findScalar(u8, fixes, '_').?; |
| 190027 | std.debug.panic("{s}: {s}{s}{s}\n", .{ | 189909 | std.debug.panic("{s}: {s}{s}{s}\n", .{ |
| 190028 | @src().fn_name, | 189910 | @src().fn_name, |
| 190029 | fixes[0..fixes_blank], | 189911 | fixes[0..fixes_blank], |
src/codegen/x86_64/Lower.zig+5-5| ... | @@ -435,11 +435,11 @@ const mnemonic_table: [inst_tags_len * inst_fixes_len]?Mnemonic = table: { | ... | @@ -435,11 +435,11 @@ const mnemonic_table: [inst_tags_len * inst_fixes_len]?Mnemonic = table: { |
| 435 | for (0..inst_fixes_len) |fixes_i| { | 435 | for (0..inst_fixes_len) |fixes_i| { |
| 436 | const fixes: Mir.Inst.Fixes = @fromBackingInt(@intCast(fixes_i)); | 436 | const fixes: Mir.Inst.Fixes = @fromBackingInt(@intCast(fixes_i)); |
| 437 | const prefix, const suffix = affix: { | 437 | const prefix, const suffix = affix: { |
| 438 | const pattern = if (std.mem.indexOfScalar(u8, @tagName(fixes), ' ')) |i| | 438 | const pattern = if (std.mem.findScalar(u8, @tagName(fixes), ' ')) |i| |
| 439 | @tagName(fixes)[i + 1 ..] | 439 | @tagName(fixes)[i + 1 ..] |
| 440 | else | 440 | else |
| 441 | @tagName(fixes); | 441 | @tagName(fixes); |
| 442 | const wildcard_idx = std.mem.indexOfScalar(u8, pattern, '_').?; | 442 | const wildcard_idx = std.mem.findScalar(u8, pattern, '_').?; |
| 443 | break :affix .{ pattern[0..wildcard_idx], pattern[wildcard_idx + 1 ..] }; | 443 | break :affix .{ pattern[0..wildcard_idx], pattern[wildcard_idx + 1 ..] }; |
| 444 | }; | 444 | }; |
| 445 | for (0..inst_tags_len) |inst_tag_i| { | 445 | for (0..inst_tags_len) |inst_tag_i| { |
| ... | @@ -477,7 +477,7 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void { | ... | @@ -477,7 +477,7 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void { |
| 477 | else => return lower.fail("TODO lower .{s}", .{@tagName(inst.ops)}), | 477 | else => return lower.fail("TODO lower .{s}", .{@tagName(inst.ops)}), |
| 478 | }; | 478 | }; |
| 479 | try lower.encode(switch (fixes) { | 479 | try lower.encode(switch (fixes) { |
| 480 | inline else => |tag| comptime if (std.mem.indexOfScalar(u8, @tagName(tag), ' ')) |space| | 480 | inline else => |tag| comptime if (std.mem.findScalar(u8, @tagName(tag), ' ')) |space| |
| 481 | @field(Prefix, @tagName(tag)[0..space]) | 481 | @field(Prefix, @tagName(tag)[0..space]) |
| 482 | else | 482 | else |
| 483 | .none, | 483 | .none, |
| ... | @@ -487,8 +487,8 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void { | ... | @@ -487,8 +487,8 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void { |
| 487 | } | 487 | } |
| 488 | // This combination is invalid; make the theoretical mnemonic name and emit an error with it. | 488 | // This combination is invalid; make the theoretical mnemonic name and emit an error with it. |
| 489 | const fixes_name = @tagName(fixes); | 489 | const fixes_name = @tagName(fixes); |
| 490 | const pattern = fixes_name[if (std.mem.indexOfScalar(u8, fixes_name, ' ')) |i| i + " ".len else 0..]; | 490 | const pattern = fixes_name[if (std.mem.findScalar(u8, fixes_name, ' ')) |i| i + " ".len else 0..]; |
| 491 | const wildcard_index = std.mem.indexOfScalar(u8, pattern, '_').?; | 491 | const wildcard_index = std.mem.findScalar(u8, pattern, '_').?; |
| 492 | return lower.fail("unsupported mnemonic: '{s}{s}{s}'", .{ | 492 | return lower.fail("unsupported mnemonic: '{s}{s}{s}'", .{ |
| 493 | pattern[0..wildcard_index], | 493 | pattern[0..wildcard_index], |
| 494 | @tagName(inst.tag), | 494 | @tagName(inst.tag), |
src/codegen/x86_64/Mir.zig+3-3| ... | @@ -1745,8 +1745,8 @@ pub const Inst = struct { | ... | @@ -1745,8 +1745,8 @@ pub const Inst = struct { |
| 1745 | for (@typeInfo(Mnemonic).@"enum".field_names) |mnemonic_name| { | 1745 | for (@typeInfo(Mnemonic).@"enum".field_names) |mnemonic_name| { |
| 1746 | if (mnemonic_name[0] == '.') continue; | 1746 | if (mnemonic_name[0] == '.') continue; |
| 1747 | for (@typeInfo(Fixes).@"enum".field_names) |fixes_name| { | 1747 | for (@typeInfo(Fixes).@"enum".field_names) |fixes_name| { |
| 1748 | const pattern = fixes_name[if (std.mem.indexOfScalar(u8, fixes_name, ' ')) |index| index + " ".len else 0..]; | 1748 | const pattern = fixes_name[if (std.mem.findScalar(u8, fixes_name, ' ')) |index| index + " ".len else 0..]; |
| 1749 | const wildcard_index = std.mem.indexOfScalar(u8, pattern, '_').?; | 1749 | const wildcard_index = std.mem.findScalar(u8, pattern, '_').?; |
| 1750 | const mnem_prefix = pattern[0..wildcard_index]; | 1750 | const mnem_prefix = pattern[0..wildcard_index]; |
| 1751 | const mnem_suffix = pattern[wildcard_index + "_".len ..]; | 1751 | const mnem_suffix = pattern[wildcard_index + "_".len ..]; |
| 1752 | if (!std.mem.startsWith(u8, mnemonic_name, mnem_prefix)) continue; | 1752 | if (!std.mem.startsWith(u8, mnemonic_name, mnem_prefix)) continue; |
| ... | @@ -1823,7 +1823,7 @@ pub const NullTerminatedString = enum(u32) { | ... | @@ -1823,7 +1823,7 @@ pub const NullTerminatedString = enum(u32) { |
| 1823 | pub fn toSlice(nts: NullTerminatedString, mir: *const Mir) ?[:0]const u8 { | 1823 | pub fn toSlice(nts: NullTerminatedString, mir: *const Mir) ?[:0]const u8 { |
| 1824 | if (nts == .none) return null; | 1824 | if (nts == .none) return null; |
| 1825 | const string_bytes = mir.string_bytes[@backingInt(nts)..]; | 1825 | const string_bytes = mir.string_bytes[@backingInt(nts)..]; |
| 1826 | return string_bytes[0..std.mem.indexOfScalar(u8, string_bytes, 0).? :0]; | 1826 | return string_bytes[0..std.mem.findScalar(u8, string_bytes, 0).? :0]; |
| 1827 | } | 1827 | } |
| 1828 | }; | 1828 | }; |
| 1829 | 1829 |
src/codegen/x86_64/abi.zig+39-16| ... | @@ -133,7 +133,7 @@ pub fn classifyWindows(init_ty: Type, zcu: *Zcu, target: *const std.Target, ctx: | ... | @@ -133,7 +133,7 @@ pub fn classifyWindows(init_ty: Type, zcu: *Zcu, target: *const std.Target, ctx: |
| 133 | .float => switch (ty.floatBits(target)) { | 133 | .float => switch (ty.floatBits(target)) { |
| 134 | 16, 32, 64 => .sse, | 134 | 16, 32, 64 => .sse, |
| 135 | 80 => .memory, | 135 | 80 => .memory, |
| 136 | 128 => if (ctx == .arg) .memory else .sse, | 136 | 128 => .win_i128, |
| 137 | else => unreachable, | 137 | else => unreachable, |
| 138 | }, | 138 | }, |
| 139 | .vector => { | 139 | .vector => { |
| ... | @@ -238,16 +238,18 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: *const std.Target, ctx: Cont | ... | @@ -238,16 +238,18 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: *const std.Target, ctx: Cont |
| 238 | }; | 238 | }; |
| 239 | const unaligned_size = elem_ty.abiSize(zcu) * len; | 239 | const unaligned_size = elem_ty.abiSize(zcu) * len; |
| 240 | if (unaligned_size <= 4) return Class.one_integer; | 240 | if (unaligned_size <= 4) return Class.one_integer; |
| 241 | if (ctx == .arg and unaligned_size == 8 * 1 * 1 and len == 1 and | 241 | if (unaligned_size == 8 * 1 * 1 and len == 1) { |
| 242 | elem_ty.isRuntimeFloat()) return Class.stack; // what | 242 | if (ctx == .arg and elem_ty.isRuntimeFloat()) return Class.stack; // what? |
| 243 | if (ctx != .other and !elem_ty.isRuntimeFloat() and target.os.tag == .freebsd) return Class.one_integer; // who? | ||
| 244 | } | ||
| 243 | if (unaligned_size <= 8 * 1) return .{ .sse, .none, .none, .none, .none, .none, .none, .none }; | 245 | if (unaligned_size <= 8 * 1) return .{ .sse, .none, .none, .none, .none, .none, .none, .none }; |
| 244 | if (unaligned_size <= 8 * 2) return .{ .sse, .sseup, .none, .none, .none, .none, .none, .none }; | 246 | if (unaligned_size <= 8 * 2) return .{ .sse, .sseup, .none, .none, .none, .none, .none, .none }; |
| 245 | if (!target.cpu.has(.x86, .avx)) { | 247 | if (!target.cpu.has(.x86, .avx)) { |
| 246 | if (ctx == .ret) switch (unaligned_size) { | 248 | if (ctx == .ret) switch (unaligned_size) { |
| 247 | else => {}, | 249 | else => {}, |
| 248 | 8 * 3 => if (len == 3) return if (elem_ty.isRuntimeFloat()) .{ | 250 | 8 * 3 => if (len == 3) return if (elem_ty.isRuntimeFloat()) .{ |
| 249 | .sse_sse_x87_per_qword, .none, .none, .none, .none, .none, .none, .none, // how | 251 | .sse_sse_x87_per_qword, .none, .none, .none, .none, .none, .none, .none, // how? |
| 250 | } else Class.len_integers, // why | 252 | } else Class.len_integers, // why? |
| 251 | 8 * 2 * 2, 8 * 2 * 4 => return .{ .sse_per_xword, .none, .none, .none, .none, .none, .none, .none }, | 253 | 8 * 2 * 2, 8 * 2 * 4 => return .{ .sse_per_xword, .none, .none, .none, .none, .none, .none, .none }, |
| 252 | }; | 254 | }; |
| 253 | return Class.stack; | 255 | return Class.stack; |
| ... | @@ -316,7 +318,7 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: *const std.Target, ctx: Cont | ... | @@ -316,7 +318,7 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: *const std.Target, ctx: Cont |
| 316 | // byte isn't SSE or any other eightbyte isn't SSEUP, the whole argument | 318 | // byte isn't SSE or any other eightbyte isn't SSEUP, the whole argument |
| 317 | // is passed in memory." | 319 | // is passed in memory." |
| 318 | if (ty_size > 16 and (result[0] != .sse or | 320 | if (ty_size > 16 and (result[0] != .sse or |
| 319 | std.mem.indexOfNone(Class, result[1..], &.{ .sseup, .none }) != null)) return Class.stack; | 321 | std.mem.findNone(Class, result[1..], &.{ .sseup, .none }) != null)) return Class.stack; |
| 320 | 322 | ||
| 321 | // "If SSEUP is not preceded by SSE or SSEUP, it is converted to SSE." | 323 | // "If SSEUP is not preceded by SSE or SSEUP, it is converted to SSE." |
| 322 | for (&result, 0..) |*class, i| switch (class.*) { | 324 | for (&result, 0..) |*class, i| switch (class.*) { |
| ... | @@ -356,11 +358,10 @@ fn classifySystemVStruct( | ... | @@ -356,11 +358,10 @@ fn classifySystemVStruct( |
| 356 | while (field_it.next()) |field_index| { | 358 | while (field_it.next()) |field_index| { |
| 357 | const field_ty = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]); | 359 | const field_ty = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]); |
| 358 | const field_align = loaded_struct.field_aligns.getOrNone(ip, field_index); | 360 | const field_align = loaded_struct.field_aligns.getOrNone(ip, field_index); |
| 359 | byte_offset = std.mem.alignForward( | 361 | byte_offset = switch (field_align) { |
| 360 | u64, | 362 | .none => field_ty.abiAlignment(zcu), |
| 361 | byte_offset, | 363 | else => field_align, |
| 362 | field_align.toByteUnits() orelse field_ty.abiAlignment(zcu).toByteUnits().?, | 364 | }.forward(byte_offset); |
| 363 | ); | ||
| 364 | if (zcu.typeToStruct(field_ty)) |field_loaded_struct| { | 365 | if (zcu.typeToStruct(field_ty)) |field_loaded_struct| { |
| 365 | switch (field_loaded_struct.layout) { | 366 | switch (field_loaded_struct.layout) { |
| 366 | .auto => unreachable, | 367 | .auto => unreachable, |
| ... | @@ -379,6 +380,9 @@ fn classifySystemVStruct( | ... | @@ -379,6 +380,9 @@ fn classifySystemVStruct( |
| 379 | }, | 380 | }, |
| 380 | .@"packed" => {}, | 381 | .@"packed" => {}, |
| 381 | } | 382 | } |
| 383 | } else if (field_ty.zigTypeTag(zcu) == .array) { | ||
| 384 | byte_offset = classifySystemVArray(result, byte_offset, field_ty, zcu, target); | ||
| 385 | continue; | ||
| 382 | } | 386 | } |
| 383 | const field_classes = std.mem.sliceTo(&classifySystemV(field_ty, zcu, target, .other), .none); | 387 | const field_classes = std.mem.sliceTo(&classifySystemV(field_ty, zcu, target, .other), .none); |
| 384 | for (result[@intCast(byte_offset / 8)..][0..field_classes.len], field_classes) |*result_class, field_class| | 388 | for (result[@intCast(byte_offset / 8)..][0..field_classes.len], field_classes) |*result_class, field_class| |
| ... | @@ -386,11 +390,7 @@ fn classifySystemVStruct( | ... | @@ -386,11 +390,7 @@ fn classifySystemVStruct( |
| 386 | byte_offset += field_ty.abiSize(zcu); | 390 | byte_offset += field_ty.abiSize(zcu); |
| 387 | } | 391 | } |
| 388 | const final_byte_offset = starting_byte_offset + loaded_struct.size; | 392 | const final_byte_offset = starting_byte_offset + loaded_struct.size; |
| 389 | std.debug.assert(final_byte_offset == std.mem.alignForward( | 393 | std.debug.assert(final_byte_offset == loaded_struct.alignment.forward(byte_offset)); |
| 390 | u64, | ||
| 391 | byte_offset, | ||
| 392 | loaded_struct.alignment.toByteUnits().?, | ||
| 393 | )); | ||
| 394 | return final_byte_offset; | 394 | return final_byte_offset; |
| 395 | } | 395 | } |
| 396 | 396 | ||
| ... | @@ -422,6 +422,9 @@ fn classifySystemVUnion( | ... | @@ -422,6 +422,9 @@ fn classifySystemVUnion( |
| 422 | }, | 422 | }, |
| 423 | .@"packed" => {}, | 423 | .@"packed" => {}, |
| 424 | } | 424 | } |
| 425 | } else if (field_ty.zigTypeTag(zcu) == .array) { | ||
| 426 | _ = classifySystemVArray(result, starting_byte_offset, field_ty, zcu, target); | ||
| 427 | continue; | ||
| 425 | } | 428 | } |
| 426 | const field_classes = std.mem.sliceTo(&classifySystemV(field_ty, zcu, target, .other), .none); | 429 | const field_classes = std.mem.sliceTo(&classifySystemV(field_ty, zcu, target, .other), .none); |
| 427 | for (result[@intCast(starting_byte_offset / 8)..][0..field_classes.len], field_classes) |*result_class, field_class| | 430 | for (result[@intCast(starting_byte_offset / 8)..][0..field_classes.len], field_classes) |*result_class, field_class| |
| ... | @@ -430,6 +433,26 @@ fn classifySystemVUnion( | ... | @@ -430,6 +433,26 @@ fn classifySystemVUnion( |
| 430 | return starting_byte_offset + loaded_union.size; | 433 | return starting_byte_offset + loaded_union.size; |
| 431 | } | 434 | } |
| 432 | 435 | ||
| 436 | fn classifySystemVArray( | ||
| 437 | result: *[8]Class, | ||
| 438 | starting_byte_offset: u64, | ||
| 439 | array_ty: Type, | ||
| 440 | zcu: *Zcu, | ||
| 441 | target: *const std.Target, | ||
| 442 | ) u64 { | ||
| 443 | const field_classes = std.mem.sliceTo(&classifySystemV(array_ty.childType(zcu), zcu, target, .other), .none); | ||
| 444 | var byte_offset = starting_byte_offset; | ||
| 445 | const elem_size = array_ty.childType(zcu).abiSize(zcu); | ||
| 446 | for (0..@intCast(array_ty.arrayLenIncludingSentinel(zcu))) |_| { | ||
| 447 | for (result[@intCast(byte_offset / 8)..][0..field_classes.len], field_classes) |*result_class, field_class| | ||
| 448 | result_class.* = result_class.combineSystemV(field_class); | ||
| 449 | byte_offset += elem_size; | ||
| 450 | } | ||
| 451 | const final_byte_offset = starting_byte_offset + array_ty.abiSize(zcu); | ||
| 452 | assert(final_byte_offset == byte_offset); | ||
| 453 | return final_byte_offset; | ||
| 454 | } | ||
| 455 | |||
| 433 | pub const zigcc = struct { | 456 | pub const zigcc = struct { |
| 434 | pub const stack_align: ?InternPool.Alignment = null; | 457 | pub const stack_align: ?InternPool.Alignment = null; |
| 435 | pub const return_in_regs = true; | 458 | pub const return_in_regs = true; |
src/codegen/x86_64/encoder.zig+1-1| ... | @@ -1171,7 +1171,7 @@ fn expectEqualHexStrings(expected: []const u8, given: []const u8, assembly: []co | ... | @@ -1171,7 +1171,7 @@ fn expectEqualHexStrings(expected: []const u8, given: []const u8, assembly: []co |
| 1171 | defer testing.allocator.free(expected_fmt); | 1171 | defer testing.allocator.free(expected_fmt); |
| 1172 | const given_fmt = try std.fmt.allocPrint(testing.allocator, "{x}", .{given}); | 1172 | const given_fmt = try std.fmt.allocPrint(testing.allocator, "{x}", .{given}); |
| 1173 | defer testing.allocator.free(given_fmt); | 1173 | defer testing.allocator.free(given_fmt); |
| 1174 | const idx = std.mem.indexOfDiff(u8, expected_fmt, given_fmt).?; | 1174 | const idx = std.mem.findDiff(u8, expected_fmt, given_fmt).?; |
| 1175 | const padding = try testing.allocator.alloc(u8, idx + 5); | 1175 | const padding = try testing.allocator.alloc(u8, idx + 5); |
| 1176 | defer testing.allocator.free(padding); | 1176 | defer testing.allocator.free(padding); |
| 1177 | @memset(padding, ' '); | 1177 | @memset(padding, ' '); |
src/libs/freebsd.zig-1| ... | @@ -1077,7 +1077,6 @@ fn buildSharedLib( | ... | @@ -1077,7 +1077,6 @@ fn buildSharedLib( |
| 1077 | .omit_frame_pointer = comp.root_mod.omit_frame_pointer, | 1077 | .omit_frame_pointer = comp.root_mod.omit_frame_pointer, |
| 1078 | .valgrind = false, | 1078 | .valgrind = false, |
| 1079 | .optimize_mode = optimize_mode, | 1079 | .optimize_mode = optimize_mode, |
| 1080 | .structured_cfg = comp.root_mod.structured_cfg, | ||
| 1081 | }, | 1080 | }, |
| 1082 | .global = config, | 1081 | .global = config, |
| 1083 | .cc_argv = &.{}, | 1082 | .cc_argv = &.{}, |
src/libs/glibc.zig+1-4| ... | @@ -398,7 +398,7 @@ fn start_asm_path(comp: *Compilation, arena: Allocator, basename: []const u8) ![ | ... | @@ -398,7 +398,7 @@ fn start_asm_path(comp: *Compilation, arena: Allocator, basename: []const u8) ![ |
| 398 | try result.appendSlice("powerpc" ++ s ++ "powerpc32"); | 398 | try result.appendSlice("powerpc" ++ s ++ "powerpc32"); |
| 399 | } | 399 | } |
| 400 | } else if (arch == .s390x) { | 400 | } else if (arch == .s390x) { |
| 401 | try result.appendSlice("s390" ++ s ++ "s390-64"); | 401 | try result.appendSlice("s390"); |
| 402 | } else if (arch.isLoongArch()) { | 402 | } else if (arch.isLoongArch()) { |
| 403 | try result.appendSlice("loongarch"); | 403 | try result.appendSlice("loongarch"); |
| 404 | } else if (arch == .m68k) { | 404 | } else if (arch == .m68k) { |
| ... | @@ -607,8 +607,6 @@ fn add_include_dirs_arch( | ... | @@ -607,8 +607,6 @@ fn add_include_dirs_arch( |
| 607 | try args.append("-I"); | 607 | try args.append("-I"); |
| 608 | try args.append(try path.join(arena, &[_][]const u8{ dir, "s390", nptl })); | 608 | try args.append(try path.join(arena, &[_][]const u8{ dir, "s390", nptl })); |
| 609 | } else { | 609 | } else { |
| 610 | try args.append("-I"); | ||
| 611 | try args.append(try path.join(arena, &[_][]const u8{ dir, "s390" ++ s ++ "s390-64" })); | ||
| 612 | try args.append("-I"); | 610 | try args.append("-I"); |
| 613 | try args.append(try path.join(arena, &[_][]const u8{ dir, "s390" })); | 611 | try args.append(try path.join(arena, &[_][]const u8{ dir, "s390" })); |
| 614 | } | 612 | } |
| ... | @@ -1223,7 +1221,6 @@ fn buildSharedLib( | ... | @@ -1223,7 +1221,6 @@ fn buildSharedLib( |
| 1223 | .omit_frame_pointer = comp.root_mod.omit_frame_pointer, | 1221 | .omit_frame_pointer = comp.root_mod.omit_frame_pointer, |
| 1224 | .valgrind = false, | 1222 | .valgrind = false, |
| 1225 | .optimize_mode = optimize_mode, | 1223 | .optimize_mode = optimize_mode, |
| 1226 | .structured_cfg = comp.root_mod.structured_cfg, | ||
| 1227 | }, | 1224 | }, |
| 1228 | .global = config, | 1225 | .global = config, |
| 1229 | .cc_argv = &.{}, | 1226 | .cc_argv = &.{}, |
src/libs/libcxx.zig+3-5| ... | @@ -172,7 +172,6 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError! | ... | @@ -172,7 +172,6 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError! |
| 172 | .omit_frame_pointer = comp.root_mod.omit_frame_pointer, | 172 | .omit_frame_pointer = comp.root_mod.omit_frame_pointer, |
| 173 | .valgrind = false, | 173 | .valgrind = false, |
| 174 | .optimize_mode = optimize_mode, | 174 | .optimize_mode = optimize_mode, |
| 175 | .structured_cfg = comp.root_mod.structured_cfg, | ||
| 176 | .pic = if (target_util.supports_fpic(target)) true else null, | 175 | .pic = if (target_util.supports_fpic(target)) true else null, |
| 177 | .code_model = comp.root_mod.code_model, | 176 | .code_model = comp.root_mod.code_model, |
| 178 | }, | 177 | }, |
| ... | @@ -366,7 +365,6 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr | ... | @@ -366,7 +365,6 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr |
| 366 | .omit_frame_pointer = comp.root_mod.omit_frame_pointer, | 365 | .omit_frame_pointer = comp.root_mod.omit_frame_pointer, |
| 367 | .valgrind = false, | 366 | .valgrind = false, |
| 368 | .optimize_mode = optimize_mode, | 367 | .optimize_mode = optimize_mode, |
| 369 | .structured_cfg = comp.root_mod.structured_cfg, | ||
| 370 | .unwind_tables = unwind_tables, | 368 | .unwind_tables = unwind_tables, |
| 371 | .pic = if (target_util.supports_fpic(target)) true else null, | 369 | .pic = if (target_util.supports_fpic(target)) true else null, |
| 372 | .code_model = comp.root_mod.code_model, | 370 | .code_model = comp.root_mod.code_model, |
| ... | @@ -539,15 +537,15 @@ pub fn addCxxArgs( | ... | @@ -539,15 +537,15 @@ pub fn addCxxArgs( |
| 539 | // is simple and works everywhere. | 537 | // is simple and works everywhere. |
| 540 | try cflags.append("-D_LIBCPP_PSTL_BACKEND_SERIAL"); | 538 | try cflags.append("-D_LIBCPP_PSTL_BACKEND_SERIAL"); |
| 541 | switch (optimize_mode) { | 539 | switch (optimize_mode) { |
| 542 | .Debug => { | 540 | .debug => { |
| 543 | try cflags.append("-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_DEBUG"); | 541 | try cflags.append("-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_DEBUG"); |
| 544 | try cflags.append("-D_LIBCPP_ASSERTION_SEMANTIC_DEFAULT=_LIBCPP_ASSERTION_SEMANTIC_ENFORCE"); | 542 | try cflags.append("-D_LIBCPP_ASSERTION_SEMANTIC_DEFAULT=_LIBCPP_ASSERTION_SEMANTIC_ENFORCE"); |
| 545 | }, | 543 | }, |
| 546 | .ReleaseFast, .ReleaseSmall => { | 544 | .fast, .small => { |
| 547 | try cflags.append("-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_NONE"); | 545 | try cflags.append("-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_NONE"); |
| 548 | try cflags.append("-D_LIBCPP_ASSERTION_SEMANTIC_DEFAULT=_LIBCPP_ASSERTION_SEMANTIC_IGNORE"); | 546 | try cflags.append("-D_LIBCPP_ASSERTION_SEMANTIC_DEFAULT=_LIBCPP_ASSERTION_SEMANTIC_IGNORE"); |
| 549 | }, | 547 | }, |
| 550 | .ReleaseSafe => { | 548 | .safe => { |
| 551 | try cflags.append("-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST"); | 549 | try cflags.append("-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST"); |
| 552 | try cflags.append("-D_LIBCPP_ASSERTION_SEMANTIC_DEFAULT=_LIBCPP_ASSERTION_SEMANTIC_ENFORCE"); | 550 | try cflags.append("-D_LIBCPP_ASSERTION_SEMANTIC_DEFAULT=_LIBCPP_ASSERTION_SEMANTIC_ENFORCE"); |
| 553 | }, | 551 | }, |
src/libs/libtsan.zig-1| ... | @@ -100,7 +100,6 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo | ... | @@ -100,7 +100,6 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo |
| 100 | .valgrind = false, | 100 | .valgrind = false, |
| 101 | .unwind_tables = unwind_tables, | 101 | .unwind_tables = unwind_tables, |
| 102 | .optimize_mode = optimize_mode, | 102 | .optimize_mode = optimize_mode, |
| 103 | .structured_cfg = comp.root_mod.structured_cfg, | ||
| 104 | .pic = true, | 103 | .pic = true, |
| 105 | .no_builtin = true, | 104 | .no_builtin = true, |
| 106 | .code_model = comp.root_mod.code_model, | 105 | .code_model = comp.root_mod.code_model, |
src/libs/libunwind.zig+1-1| ... | @@ -118,7 +118,7 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr | ... | @@ -118,7 +118,7 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr |
| 118 | // defines will be correct. | 118 | // defines will be correct. |
| 119 | try cflags.append("-D_LIBUNWIND_IS_NATIVE_ONLY"); | 119 | try cflags.append("-D_LIBUNWIND_IS_NATIVE_ONLY"); |
| 120 | 120 | ||
| 121 | if (comp.root_mod.optimize_mode == .Debug) { | 121 | if (comp.root_mod.optimize_mode == .debug) { |
| 122 | try cflags.append("-D_DEBUG"); | 122 | try cflags.append("-D_DEBUG"); |
| 123 | } | 123 | } |
| 124 | if (!comp.config.any_non_single_threaded) { | 124 | if (!comp.config.any_non_single_threaded) { |
src/libs/mingw.zig+2-2| ... | @@ -135,8 +135,8 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -135,8 +135,8 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 135 | }); | 135 | }); |
| 136 | 136 | ||
| 137 | switch (comp.compilerRtOptMode()) { | 137 | switch (comp.compilerRtOptMode()) { |
| 138 | .Debug, .ReleaseSafe => try winpthreads_args.append("-DWINPTHREAD_DBG"), | 138 | .debug, .safe => try winpthreads_args.append("-DWINPTHREAD_DBG"), |
| 139 | .ReleaseFast, .ReleaseSmall => {}, | 139 | .fast, .small => {}, |
| 140 | } | 140 | } |
| 141 | 141 | ||
| 142 | for (mingw32_winpthreads_src) |dep| { | 142 | for (mingw32_winpthreads_src) |dep| { |
src/libs/mingw/Preprocessor.zig+4-4| ... | @@ -15,7 +15,7 @@ const RawTokenList = std.ArrayList(Token); | ... | @@ -15,7 +15,7 @@ const RawTokenList = std.ArrayList(Token); |
| 15 | const ExpandBuf = std.ArrayList(Token); | 15 | const ExpandBuf = std.ArrayList(Token); |
| 16 | 16 | ||
| 17 | const Preprocessor = @This(); | 17 | const Preprocessor = @This(); |
| 18 | const DefineMap = std.StringArrayHashMapUnmanaged(Macro); | 18 | const DefineMap = std.array_hash_map.String(Macro); |
| 19 | 19 | ||
| 20 | const GeneratedTokens = std.ArrayList(u8); | 20 | const GeneratedTokens = std.ArrayList(u8); |
| 21 | 21 | ||
| ... | @@ -29,7 +29,7 @@ pub const Source = struct { | ... | @@ -29,7 +29,7 @@ pub const Source = struct { |
| 29 | buf: []const u8, | 29 | buf: []const u8, |
| 30 | }; | 30 | }; |
| 31 | 31 | ||
| 32 | sources: std.StringArrayHashMapUnmanaged(Source) = .empty, | 32 | sources: std.array_hash_map.String(Source) = .empty, |
| 33 | 33 | ||
| 34 | arena: Allocator, | 34 | arena: Allocator, |
| 35 | io: std.Io, | 35 | io: std.Io, |
| ... | @@ -91,9 +91,9 @@ fn addTokenAssumeCapacity(pp: *Preprocessor, tok: Token) void { | ... | @@ -91,9 +91,9 @@ fn addTokenAssumeCapacity(pp: *Preprocessor, tok: Token) void { |
| 91 | 91 | ||
| 92 | fn defineBuiltins(pp: *Preprocessor) !void { | 92 | fn defineBuiltins(pp: *Preprocessor) !void { |
| 93 | var buf: [5]u8 = undefined; | 93 | var buf: [5]u8 = undefined; |
| 94 | var val = std.fmt.bufPrint(&buf, "{d}", .{pp.target.cTypeBitSize(.longdouble)}) catch unreachable; | 94 | var val = std.fmt.bufPrint(&buf, "{d}", .{pp.target.cTypeByteSize(.longdouble).?}) catch unreachable; |
| 95 | try pp.defineBuiltinValue("__SIZEOF_LONG_DOUBLE__", val, .pp_num); | 95 | try pp.defineBuiltinValue("__SIZEOF_LONG_DOUBLE__", val, .pp_num); |
| 96 | val = std.fmt.bufPrint(&buf, "{d}", .{pp.target.cTypeBitSize(.double)}) catch unreachable; | 96 | val = std.fmt.bufPrint(&buf, "{d}", .{pp.target.cTypeByteSize(.double).?}) catch unreachable; |
| 97 | try pp.defineBuiltinValue("__SIZEOF_DOUBLE__", val, .pp_num); | 97 | try pp.defineBuiltinValue("__SIZEOF_DOUBLE__", val, .pp_num); |
| 98 | 98 | ||
| 99 | if (pp.target.abi.isGnu()) { | 99 | if (pp.target.abi.isGnu()) { |
src/libs/mingw/def.zig+4-4| ... | @@ -61,7 +61,7 @@ pub const ModuleDefinition = struct { | ... | @@ -61,7 +61,7 @@ pub const ModuleDefinition = struct { |
| 61 | // or ? for C++ functions). Vectorcall functions won't have any | 61 | // or ? for C++ functions). Vectorcall functions won't have any |
| 62 | // fixed prefix, but the function base name will still be at least | 62 | // fixed prefix, but the function base name will still be at least |
| 63 | // one char. | 63 | // one char. |
| 64 | const name_len_without_at_suffix = std.mem.indexOfScalarPos(u8, e.name, 1, '@') orelse e.name.len; | 64 | const name_len_without_at_suffix = std.mem.findScalarPos(u8, e.name, 1, '@') orelse e.name.len; |
| 65 | e.name = e.name[0..name_len_without_at_suffix]; | 65 | e.name = e.name[0..name_len_without_at_suffix]; |
| 66 | } | 66 | } |
| 67 | } | 67 | } |
| ... | @@ -452,7 +452,7 @@ pub const Parser = struct { | ... | @@ -452,7 +452,7 @@ pub const Parser = struct { |
| 452 | var ext_name_needs_underscore = false; | 452 | var ext_name_needs_underscore = false; |
| 453 | if (self.machine_type == .I386) { | 453 | if (self.machine_type == .I386) { |
| 454 | const is_decorated = isDecorated(name_tok.slice(self.tokenizer.source), self.module_definition_type); | 454 | const is_decorated = isDecorated(name_tok.slice(self.tokenizer.source), self.module_definition_type); |
| 455 | const is_forward_target = ext_name_tok != null and std.mem.indexOfScalar(u8, name_tok.slice(self.tokenizer.source), '.') != null; | 455 | const is_forward_target = ext_name_tok != null and std.mem.findScalar(u8, name_tok.slice(self.tokenizer.source), '.') != null; |
| 456 | name_needs_underscore = !is_decorated and !is_forward_target; | 456 | name_needs_underscore = !is_decorated and !is_forward_target; |
| 457 | 457 | ||
| 458 | if (ext_name_tok) |ext_name| { | 458 | if (ext_name_tok) |ext_name| { |
| ... | @@ -578,9 +578,9 @@ pub const Parser = struct { | ... | @@ -578,9 +578,9 @@ pub const Parser = struct { |
| 578 | // themselves can start with an underscore, while a second one still needs | 578 | // themselves can start with an underscore, while a second one still needs |
| 579 | // to be added. | 579 | // to be added. |
| 580 | if (std.mem.startsWith(u8, symbol, "@")) return true; | 580 | if (std.mem.startsWith(u8, symbol, "@")) return true; |
| 581 | if (std.mem.indexOf(u8, symbol, "@@") != null) return true; | 581 | if (std.mem.find(u8, symbol, "@@") != null) return true; |
| 582 | if (std.mem.startsWith(u8, symbol, "?")) return true; | 582 | if (std.mem.startsWith(u8, symbol, "?")) return true; |
| 583 | if (module_definition_type != .mingw and std.mem.indexOfScalar(u8, symbol, '@') != null) return true; | 583 | if (module_definition_type != .mingw and std.mem.findScalar(u8, symbol, '@') != null) return true; |
| 584 | return false; | 584 | return false; |
| 585 | } | 585 | } |
| 586 | 586 |
src/libs/mingw/implib.zig+1-1| ... | @@ -351,7 +351,7 @@ fn getNameType( | ... | @@ -351,7 +351,7 @@ fn getNameType( |
| 351 | // the leading underscore. In MinGW on the other hand, a decorated | 351 | // the leading underscore. In MinGW on the other hand, a decorated |
| 352 | // stdcall function still omits the underscore (IMPORT_NAME_NOPREFIX). | 352 | // stdcall function still omits the underscore (IMPORT_NAME_NOPREFIX). |
| 353 | if (std.mem.startsWith(u8, ext_name, "_") and | 353 | if (std.mem.startsWith(u8, ext_name, "_") and |
| 354 | std.mem.indexOfScalar(u8, ext_name, '@') != null and | 354 | std.mem.findScalar(u8, ext_name, '@') != null and |
| 355 | module_definition_type != .mingw) | 355 | module_definition_type != .mingw) |
| 356 | return .NAME; | 356 | return .NAME; |
| 357 | if (!std.mem.eql(u8, symbol, ext_name)) | 357 | if (!std.mem.eql(u8, symbol, ext_name)) |
src/libs/musl.zig-1| ... | @@ -225,7 +225,6 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro | ... | @@ -225,7 +225,6 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro |
| 225 | .omit_frame_pointer = comp.root_mod.omit_frame_pointer, | 225 | .omit_frame_pointer = comp.root_mod.omit_frame_pointer, |
| 226 | .valgrind = false, | 226 | .valgrind = false, |
| 227 | .optimize_mode = optimize_mode, | 227 | .optimize_mode = optimize_mode, |
| 228 | .structured_cfg = comp.root_mod.structured_cfg, | ||
| 229 | }, | 228 | }, |
| 230 | .global = config, | 229 | .global = config, |
| 231 | .cc_argv = cc_argv, | 230 | .cc_argv = cc_argv, |
src/libs/netbsd.zig-1| ... | @@ -727,7 +727,6 @@ fn buildSharedLib( | ... | @@ -727,7 +727,6 @@ fn buildSharedLib( |
| 727 | .omit_frame_pointer = comp.root_mod.omit_frame_pointer, | 727 | .omit_frame_pointer = comp.root_mod.omit_frame_pointer, |
| 728 | .valgrind = false, | 728 | .valgrind = false, |
| 729 | .optimize_mode = optimize_mode, | 729 | .optimize_mode = optimize_mode, |
| 730 | .structured_cfg = comp.root_mod.structured_cfg, | ||
| 731 | }, | 730 | }, |
| 732 | .global = config, | 731 | .global = config, |
| 733 | .cc_argv = &.{}, | 732 | .cc_argv = &.{}, |
src/libs/openbsd.zig-1| ... | @@ -647,7 +647,6 @@ fn buildSharedLib( | ... | @@ -647,7 +647,6 @@ fn buildSharedLib( |
| 647 | .omit_frame_pointer = comp.root_mod.omit_frame_pointer, | 647 | .omit_frame_pointer = comp.root_mod.omit_frame_pointer, |
| 648 | .valgrind = false, | 648 | .valgrind = false, |
| 649 | .optimize_mode = optimize_mode, | 649 | .optimize_mode = optimize_mode, |
| 650 | .structured_cfg = comp.root_mod.structured_cfg, | ||
| 651 | }, | 650 | }, |
| 652 | .global = config, | 651 | .global = config, |
| 653 | .cc_argv = &.{}, | 652 | .cc_argv = &.{}, |
src/link.zig+57-3| ... | @@ -1238,11 +1238,11 @@ pub const File = struct { | ... | @@ -1238,11 +1238,11 @@ pub const File = struct { |
| 1238 | } | 1238 | } |
| 1239 | 1239 | ||
| 1240 | switch (base.tag) { | 1240 | switch (base.tag) { |
| 1241 | inline .elf2, .coff2, .wasm => |tag| { | 1241 | inline .elf2, .coff2, .wasm, .c => |tag| { |
| 1242 | dev.check(tag.devFeature()); | 1242 | dev.check(tag.devFeature()); |
| 1243 | try @as(*tag.Type(), @fieldParentPtr("base", base)).prelink(base.comp.link_prog_node); | 1243 | try @as(*tag.Type(), @fieldParentPtr("base", base)).prelink(base.comp.link_prog_node); |
| 1244 | }, | 1244 | }, |
| 1245 | else => {}, | 1245 | else => base.comp.link_prog_node.completeOne(), |
| 1246 | } | 1246 | } |
| 1247 | 1247 | ||
| 1248 | base.post_prelink = true; | 1248 | base.post_prelink = true; |
| ... | @@ -2127,7 +2127,7 @@ pub fn resolveInputs( | ... | @@ -2127,7 +2127,7 @@ pub fn resolveInputs( |
| 2127 | continue; | 2127 | continue; |
| 2128 | }, | 2128 | }, |
| 2129 | } | 2129 | } |
| 2130 | @compileError("unreachable"); | 2130 | comptime unreachable; |
| 2131 | } | 2131 | } |
| 2132 | 2132 | ||
| 2133 | if (failed_libs.items.len > 0) { | 2133 | if (failed_libs.items.len > 0) { |
| ... | @@ -2239,6 +2239,60 @@ fn resolveLibInput( | ... | @@ -2239,6 +2239,60 @@ fn resolveLibInput( |
| 2239 | return finishResolveLibInput(io, resolved_inputs, archive_dedup, test_path, file, link_mode, name_query.query); | 2239 | return finishResolveLibInput(io, resolved_inputs, archive_dedup, test_path, file, link_mode, name_query.query); |
| 2240 | } | 2240 | } |
| 2241 | 2241 | ||
| 2242 | // In the case of OpenBSD, dynamic libraries are always versioned, without | ||
| 2243 | // unversioned symlinks. OpenBSD patches LLD to select the highest-versioned | ||
| 2244 | // shared library, and this code is intended to match that upstream behavior. | ||
| 2245 | if (target.isOpenBSDLibC() and link_mode == .dynamic) versioned: { | ||
| 2246 | const prefix = try std.fmt.allocPrint(arena, "lib{s}.so.", .{lib_name}); | ||
| 2247 | |||
| 2248 | var dir = lib_directory.handle.openDir(io, ".", .{ .iterate = true }) catch |err| switch (err) { | ||
| 2249 | error.NotDir, error.FileNotFound => break :versioned, | ||
| 2250 | else => |e| fatal("unable to search for shared library '{s}.*': {s}", .{ prefix, @errorName(e) }), | ||
| 2251 | }; | ||
| 2252 | defer dir.close(io); | ||
| 2253 | |||
| 2254 | var best_match_major: u32 = 0; | ||
| 2255 | var best_match_minor: u32 = 0; | ||
| 2256 | var best_match: ?[]const u8 = null; | ||
| 2257 | |||
| 2258 | var iter = dir.iterate(); | ||
| 2259 | while (iter.next(io) catch |err| { | ||
| 2260 | fatal("unable to scan library directory '{s}'", .{@errorName(err)}); | ||
| 2261 | }) |entry| { | ||
| 2262 | if (entry.kind != .file) continue; | ||
| 2263 | if (!std.mem.startsWith(u8, entry.name, prefix)) continue; | ||
| 2264 | |||
| 2265 | const rest = entry.name[prefix.len..]; | ||
| 2266 | var sit = std.mem.splitScalar(u8, rest, '.'); | ||
| 2267 | const major_str = sit.next() orelse continue; | ||
| 2268 | const minor_str = sit.next() orelse continue; | ||
| 2269 | if (sit.next() != null) continue; | ||
| 2270 | const major = std.fmt.parseInt(u32, major_str, 10) catch continue; | ||
| 2271 | const minor = std.fmt.parseInt(u32, minor_str, 10) catch continue; | ||
| 2272 | |||
| 2273 | if (major > best_match_major or (major == best_match_major and minor >= best_match_minor)) { | ||
| 2274 | best_match_major = major; | ||
| 2275 | best_match_minor = minor; | ||
| 2276 | best_match = try arena.dupe(u8, entry.name); | ||
| 2277 | } | ||
| 2278 | } | ||
| 2279 | |||
| 2280 | if (best_match) |found| { | ||
| 2281 | const test_path: Path = .{ | ||
| 2282 | .root_dir = lib_directory, | ||
| 2283 | .sub_path = found, | ||
| 2284 | }; | ||
| 2285 | try checked_paths.print(gpa, "\n {f}", .{test_path}); | ||
| 2286 | switch (try resolvePathInputLib(gpa, arena, io, unresolved_inputs, resolved_inputs, ld_script_bytes, archive_dedup, target, .{ | ||
| 2287 | .path = test_path, | ||
| 2288 | .query = name_query.query, | ||
| 2289 | }, link_mode, color)) { | ||
| 2290 | .no_match => {}, | ||
| 2291 | .ok => return .ok, | ||
| 2292 | } | ||
| 2293 | } | ||
| 2294 | } | ||
| 2295 | |||
| 2242 | return .no_match; | 2296 | return .no_match; |
| 2243 | } | 2297 | } |
| 2244 | 2298 |
src/link/C.zig+26-25| ... | @@ -43,6 +43,8 @@ type_dependencies: std.ArrayList(link.ConstPool.Index), | ... | @@ -43,6 +43,8 @@ type_dependencies: std.ArrayList(link.ConstPool.Index), |
| 43 | /// one array. | 43 | /// one array. |
| 44 | align_dependency_masks: std.ArrayList(u64), | 44 | align_dependency_masks: std.ArrayList(u64), |
| 45 | 45 | ||
| 46 | /// Emitted at the top of the file. This can be cached since it only depends on the target. | ||
| 47 | header: String, | ||
| 46 | /// All NAVs, regardless of whether they are functions or simple constants, are put in this map. | 48 | /// All NAVs, regardless of whether they are functions or simple constants, are put in this map. |
| 47 | navs: std.array_hash_map.Auto(InternPool.Nav.Index, RenderedDecl), | 49 | navs: std.array_hash_map.Auto(InternPool.Nav.Index, RenderedDecl), |
| 48 | /// All UAVs which may be referenced are in this map. The UAV alignment is not included in the | 50 | /// All UAVs which may be referenced are in this map. The UAV alignment is not included in the |
| ... | @@ -404,9 +406,8 @@ pub fn createEmpty( | ... | @@ -404,9 +406,8 @@ pub fn createEmpty( |
| 404 | emit: Path, | 406 | emit: Path, |
| 405 | options: link.File.OpenOptions, | 407 | options: link.File.OpenOptions, |
| 406 | ) !*C { | 408 | ) !*C { |
| 409 | assert(comp.root_mod.resolved_target.result.ofmt == .c); | ||
| 407 | const io = comp.io; | 410 | const io = comp.io; |
| 408 | const target = &comp.root_mod.resolved_target.result; | ||
| 409 | assert(target.ofmt == .c); | ||
| 410 | const optimize_mode = comp.root_mod.optimize_mode; | 411 | const optimize_mode = comp.root_mod.optimize_mode; |
| 411 | const use_lld = build_options.have_llvm and comp.config.use_lld; | 412 | const use_lld = build_options.have_llvm and comp.config.use_lld; |
| 412 | const use_llvm = comp.config.use_llvm; | 413 | const use_llvm = comp.config.use_llvm; |
| ... | @@ -422,14 +423,13 @@ pub fn createEmpty( | ... | @@ -422,14 +423,13 @@ pub fn createEmpty( |
| 422 | }); | 423 | }); |
| 423 | errdefer file.close(io); | 424 | errdefer file.close(io); |
| 424 | 425 | ||
| 425 | const c_file = try arena.create(C); | 426 | const c = try arena.create(C); |
| 426 | 427 | c.* = .{ | |
| 427 | c_file.* = .{ | ||
| 428 | .base = .{ | 428 | .base = .{ |
| 429 | .tag = .c, | 429 | .tag = .c, |
| 430 | .comp = comp, | 430 | .comp = comp, |
| 431 | .emit = emit, | 431 | .emit = emit, |
| 432 | .gc_sections = options.gc_sections orelse (optimize_mode != .Debug and output_mode != .Obj), | 432 | .gc_sections = options.gc_sections orelse (optimize_mode != .debug and output_mode != .Obj), |
| 433 | .print_gc_sections = options.print_gc_sections, | 433 | .print_gc_sections = options.print_gc_sections, |
| 434 | .stack_size = options.stack_size orelse 16777216, | 434 | .stack_size = options.stack_size orelse 16777216, |
| 435 | .allow_shlib_undefined = options.allow_shlib_undefined orelse false, | 435 | .allow_shlib_undefined = options.allow_shlib_undefined orelse false, |
| ... | @@ -439,6 +439,7 @@ pub fn createEmpty( | ... | @@ -439,6 +439,7 @@ pub fn createEmpty( |
| 439 | .string_bytes = .empty, | 439 | .string_bytes = .empty, |
| 440 | .type_dependencies = .empty, | 440 | .type_dependencies = .empty, |
| 441 | .align_dependency_masks = .empty, | 441 | .align_dependency_masks = .empty, |
| 442 | .header = .empty, | ||
| 442 | .navs = .empty, | 443 | .navs = .empty, |
| 443 | .uavs = .empty, | 444 | .uavs = .empty, |
| 444 | .type_pool = .empty, | 445 | .type_pool = .empty, |
| ... | @@ -447,8 +448,7 @@ pub fn createEmpty( | ... | @@ -447,8 +448,7 @@ pub fn createEmpty( |
| 447 | .exported_navs = .empty, | 448 | .exported_navs = .empty, |
| 448 | .exported_uavs = .empty, | 449 | .exported_uavs = .empty, |
| 449 | }; | 450 | }; |
| 450 | 451 | return c; | |
| 451 | return c_file; | ||
| 452 | } | 452 | } |
| 453 | 453 | ||
| 454 | pub fn deinit(c: *C) void { | 454 | pub fn deinit(c: *C) void { |
| ... | @@ -469,6 +469,21 @@ pub fn deinit(c: *C) void { | ... | @@ -469,6 +469,21 @@ pub fn deinit(c: *C) void { |
| 469 | c.exported_uavs.deinit(gpa); | 469 | c.exported_uavs.deinit(gpa); |
| 470 | } | 470 | } |
| 471 | 471 | ||
| 472 | pub fn prelink(c: *C, prog_node: std.Progress.Node) !void { | ||
| 473 | const comp = c.base.comp; | ||
| 474 | |||
| 475 | const sub_prog_node = prog_node.start("Generate Header", 0); | ||
| 476 | defer sub_prog_node.end(); | ||
| 477 | |||
| 478 | var header_aw: std.Io.Writer.Allocating = .init(comp.gpa); | ||
| 479 | defer header_aw.deinit(); | ||
| 480 | codegen.genHeader(comp.zcu.?, &header_aw.writer) catch |err| switch (err) { | ||
| 481 | error.WriteFailed => return error.OutOfMemory, | ||
| 482 | else => |e| return e, | ||
| 483 | }; | ||
| 484 | c.header = try c.addString(&.{header_aw.written()}); | ||
| 485 | } | ||
| 486 | |||
| 472 | pub fn updateContainerType( | 487 | pub fn updateContainerType( |
| 473 | c: *C, | 488 | c: *C, |
| 474 | pt: Zcu.PerThread, | 489 | pt: Zcu.PerThread, |
| ... | @@ -727,7 +742,6 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog | ... | @@ -727,7 +742,6 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog |
| 727 | const io = comp.io; | 742 | const io = comp.io; |
| 728 | const zcu = c.base.comp.zcu.?; | 743 | const zcu = c.base.comp.zcu.?; |
| 729 | const ip = &zcu.intern_pool; | 744 | const ip = &zcu.intern_pool; |
| 730 | const target = zcu.getTarget(); | ||
| 731 | const active = zcu.activate(tid); | 745 | const active = zcu.activate(tid); |
| 732 | defer active.deactivate(); | 746 | defer active.deactivate(); |
| 733 | const pt = active.pt; | 747 | const pt = active.pt; |
| ... | @@ -943,7 +957,7 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog | ... | @@ -943,7 +957,7 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog |
| 943 | // We have discovered the full set of NAVs, UAVs, and types we need to emit, and will now begin | 957 | // We have discovered the full set of NAVs, UAVs, and types we need to emit, and will now begin |
| 944 | // to build the output buffer. Our strategy is to emit the C source in this order: | 958 | // to build the output buffer. Our strategy is to emit the C source in this order: |
| 945 | // | 959 | // |
| 946 | // * ABI defines and `#include "zig.h"` | 960 | // * Header |
| 947 | // * Big-int type definitions | 961 | // * Big-int type definitions |
| 948 | // * Other CType definitions (traversing the dependency graph to sort topologically) | 962 | // * Other CType definitions (traversing the dependency graph to sort topologically) |
| 949 | // * Global assembly | 963 | // * Global assembly |
| ... | @@ -968,7 +982,7 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog | ... | @@ -968,7 +982,7 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog |
| 968 | 982 | ||
| 969 | // We know exactly what we'll be emitting, so can reserve capacity for all of our buffers! | 983 | // We know exactly what we'll be emitting, so can reserve capacity for all of our buffers! |
| 970 | 984 | ||
| 971 | try f.all_buffers.ensureUnusedCapacity(gpa, 3 + // ABI defines and `#include "zig.h"` | 985 | try f.all_buffers.ensureUnusedCapacity(gpa, 1 + // Header |
| 972 | 1 + // Big-int type definitions | 986 | 1 + // Big-int type definitions |
| 973 | need_types.count() + // `RenderedType.fwd_decl` (worst-case) | 987 | need_types.count() + // `RenderedType.fwd_decl` (worst-case) |
| 974 | need_types.count() + // `RenderedType.definition` | 988 | need_types.count() + // `RenderedType.definition` |
| ... | @@ -984,20 +998,7 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog | ... | @@ -984,20 +998,7 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog |
| 984 | need_uavs.count() * 3 + // UAV definitions ("static ", "zig_align(4)", "<definition body>") | 998 | need_uavs.count() * 3 + // UAV definitions ("static ", "zig_align(4)", "<definition body>") |
| 985 | need_navs.count() * 2); // NAV definitions ("static ", "<definition body>") | 999 | need_navs.count() * 2); // NAV definitions ("static ", "<definition body>") |
| 986 | 1000 | ||
| 987 | // ABI defines and `#include "zig.h"` | 1001 | f.appendBufAssumeCapacity(c.header.get(c)); |
| 988 | switch (target.abi) { | ||
| 989 | .msvc, .itanium => f.appendBufAssumeCapacity("#define ZIG_TARGET_ABI_MSVC\n"), | ||
| 990 | else => {}, | ||
| 991 | } | ||
| 992 | f.appendBufAssumeCapacity(try std.fmt.allocPrint( | ||
| 993 | arena, | ||
| 994 | "#define ZIG_TARGET_MAX_INT_ALIGNMENT {d}\n", | ||
| 995 | .{target.cMaxIntAlignment()}, | ||
| 996 | )); | ||
| 997 | f.appendBufAssumeCapacity( | ||
| 998 | \\#include "zig.h" | ||
| 999 | \\ | ||
| 1000 | ); | ||
| 1001 | 1002 | ||
| 1002 | // Big-int type definitions | 1003 | // Big-int type definitions |
| 1003 | var bigint_aw: std.Io.Writer.Allocating = .init(gpa); | 1004 | var bigint_aw: std.Io.Writer.Allocating = .init(gpa); |
src/link/Coff.zig+22-18| ... | @@ -621,7 +621,7 @@ pub const LongNamesTable = struct { | ... | @@ -621,7 +621,7 @@ pub const LongNamesTable = struct { |
| 621 | } | 621 | } |
| 622 | 622 | ||
| 623 | pub fn hash(_: Adapter, key: []const u8) u32 { | 623 | pub fn hash(_: Adapter, key: []const u8) u32 { |
| 624 | assert(std.mem.indexOfScalar(u8, key, 0) == null); | 624 | assert(std.mem.findScalar(u8, key, 0) == null); |
| 625 | return std.array_hash_map.hashString(key); | 625 | return std.array_hash_map.hashString(key); |
| 626 | } | 626 | } |
| 627 | }; | 627 | }; |
| ... | @@ -711,7 +711,7 @@ pub const ExportTable = struct { | ... | @@ -711,7 +711,7 @@ pub const ExportTable = struct { |
| 711 | } | 711 | } |
| 712 | 712 | ||
| 713 | pub fn hash(_: Adapter, key: []const u8) u32 { | 713 | pub fn hash(_: Adapter, key: []const u8) u32 { |
| 714 | assert(std.mem.indexOfScalar(u8, key, 0) == null); | 714 | assert(std.mem.findScalar(u8, key, 0) == null); |
| 715 | return std.array_hash_map.hashString(key); | 715 | return std.array_hash_map.hashString(key); |
| 716 | } | 716 | } |
| 717 | }; | 717 | }; |
| ... | @@ -759,7 +759,7 @@ pub const ImportTable = struct { | ... | @@ -759,7 +759,7 @@ pub const ImportTable = struct { |
| 759 | } | 759 | } |
| 760 | 760 | ||
| 761 | pub fn hash(_: Adapter, key: []const u8) u32 { | 761 | pub fn hash(_: Adapter, key: []const u8) u32 { |
| 762 | assert(std.mem.indexOfScalar(u8, key, 0) == null); | 762 | assert(std.mem.findScalar(u8, key, 0) == null); |
| 763 | return std.array_hash_map.hashString(key); | 763 | return std.array_hash_map.hashString(key); |
| 764 | } | 764 | } |
| 765 | }; | 765 | }; |
| ... | @@ -822,7 +822,7 @@ pub const String = enum(u32) { | ... | @@ -822,7 +822,7 @@ pub const String = enum(u32) { |
| 822 | 822 | ||
| 823 | pub fn toSlice(s: String, coff: *Coff) [:0]const u8 { | 823 | pub fn toSlice(s: String, coff: *Coff) [:0]const u8 { |
| 824 | const slice = coff.string_bytes.items[@backingInt(s)..]; | 824 | const slice = coff.string_bytes.items[@backingInt(s)..]; |
| 825 | return slice[0..std.mem.indexOfScalar(u8, slice, 0).? :0]; | 825 | return slice[0..std.mem.findScalar(u8, slice, 0).? :0]; |
| 826 | } | 826 | } |
| 827 | 827 | ||
| 828 | pub fn toOptional(s: String) String.Optional { | 828 | pub fn toOptional(s: String) String.Optional { |
| ... | @@ -3535,7 +3535,7 @@ fn objectSectionParentName(coff: *Coff, name: []const u8) []const u8 { | ... | @@ -3535,7 +3535,7 @@ fn objectSectionParentName(coff: *Coff, name: []const u8) []const u8 { |
| 3535 | // Otherwise, we want to keep the full name so that this sort can occur correctly when | 3535 | // Otherwise, we want to keep the full name so that this sort can occur correctly when |
| 3536 | // the object is finally linked into an image. | 3536 | // the object is finally linked into an image. |
| 3537 | return if (coff.isImage()) | 3537 | return if (coff.isImage()) |
| 3538 | name[0 .. std.mem.indexOfScalar(u8, name, '$') orelse name.len] | 3538 | name[0 .. std.mem.findScalar(u8, name, '$') orelse name.len] |
| 3539 | else | 3539 | else |
| 3540 | name; | 3540 | name; |
| 3541 | } | 3541 | } |
| ... | @@ -3654,7 +3654,7 @@ fn verifyParentSectionAttributes( | ... | @@ -3654,7 +3654,7 @@ fn verifyParentSectionAttributes( |
| 3654 | parent.name(coff).toSlice(coff), | 3654 | parent.name(coff).toSlice(coff), |
| 3655 | }); | 3655 | }); |
| 3656 | 3656 | ||
| 3657 | inline for (comptime std.meta.fieldNames(ObjectSectionAttributes)) |field| { | 3657 | inline for (@typeInfo(ObjectSectionAttributes).@"struct".field_names) |field| { |
| 3658 | if (@field(child_attrs, field) != @field(parent_attrs, field)) { | 3658 | if (@field(child_attrs, field) != @field(parent_attrs, field)) { |
| 3659 | err.addNote("flags.{s} was {d} in {s}, but {d} in {s}", .{ | 3659 | err.addNote("flags.{s} was {d} in {s}, but {d} in {s}", .{ |
| 3660 | field, | 3660 | field, |
| ... | @@ -5370,7 +5370,9 @@ fn loadDll(coff: *Coff, path: std.Build.Cache.Path, fr: *Io.File.Reader) LoadInp | ... | @@ -5370,7 +5370,9 @@ fn loadDll(coff: *Coff, path: std.Build.Cache.Path, fr: *Io.File.Reader) LoadInp |
| 5370 | } | 5370 | } |
| 5371 | 5371 | ||
| 5372 | pub fn prelink(coff: *Coff, prog_node: std.Progress.Node) link.Error!void { | 5372 | pub fn prelink(coff: *Coff, prog_node: std.Progress.Node) link.Error!void { |
| 5373 | _ = prog_node; | 5373 | const sub_prog_node = prog_node.start("COFF Prelink", 0); |
| 5374 | defer sub_prog_node.end(); | ||
| 5375 | |||
| 5374 | const base = coff.base; | 5376 | const base = coff.base; |
| 5375 | const comp = base.comp; | 5377 | const comp = base.comp; |
| 5376 | 5378 | ||
| ... | @@ -5598,11 +5600,11 @@ fn updateFuncInner( | ... | @@ -5598,11 +5600,11 @@ fn updateFuncInner( |
| 5598 | const ni = try coff.mf.addLastChildNode(gpa, sec_si.node(coff), .{ | 5600 | const ni = try coff.mf.addLastChildNode(gpa, sec_si.node(coff), .{ |
| 5599 | .alignment = switch (nav.resolved.?.@"align") { | 5601 | .alignment = switch (nav.resolved.?.@"align") { |
| 5600 | .none => switch (mod.optimize_mode) { | 5602 | .none => switch (mod.optimize_mode) { |
| 5601 | .Debug, | 5603 | .debug, |
| 5602 | .ReleaseSafe, | 5604 | .safe, |
| 5603 | .ReleaseFast, | 5605 | .fast, |
| 5604 | => target_util.defaultFunctionAlignment(target), | 5606 | => target_util.defaultFunctionAlignment(target), |
| 5605 | .ReleaseSmall => target_util.minFunctionAlignment(target), | 5607 | .small => target_util.minFunctionAlignment(target), |
| 5606 | }, | 5608 | }, |
| 5607 | else => |a| a.maxStrict(target_util.minFunctionAlignment(target)), | 5609 | else => |a| a.maxStrict(target_util.minFunctionAlignment(target)), |
| 5608 | }.toStdMem(), | 5610 | }.toStdMem(), |
| ... | @@ -5735,7 +5737,7 @@ fn reportUndefs(coff: *Coff, tid: Zcu.PerThread.Id) !void { | ... | @@ -5735,7 +5737,7 @@ fn reportUndefs(coff: *Coff, tid: Zcu.PerThread.Id) !void { |
| 5735 | const gpa = comp.gpa; | 5737 | const gpa = comp.gpa; |
| 5736 | const max_notes = 4; | 5738 | const max_notes = 4; |
| 5737 | 5739 | ||
| 5738 | var undef_indices: std.ArrayListUnmanaged(u32) = .empty; | 5740 | var undef_indices: std.ArrayList(u32) = .empty; |
| 5739 | for (coff.relocs.items, 0..) |reloc, reloc_i| { | 5741 | for (coff.relocs.items, 0..) |reloc, reloc_i| { |
| 5740 | if (reloc.flags.free) continue; | 5742 | if (reloc.flags.free) continue; |
| 5741 | const target_sym = reloc.target.get(coff); | 5743 | const target_sym = reloc.target.get(coff); |
| ... | @@ -5886,7 +5888,9 @@ pub fn flush( | ... | @@ -5886,7 +5888,9 @@ pub fn flush( |
| 5886 | prog_node: std.Progress.Node, | 5888 | prog_node: std.Progress.Node, |
| 5887 | ) link.Error!void { | 5889 | ) link.Error!void { |
| 5888 | _ = arena; | 5890 | _ = arena; |
| 5889 | _ = prog_node; | 5891 | const sub_prog_node = prog_node.start("COFF Flush", 0); |
| 5892 | defer sub_prog_node.end(); | ||
| 5893 | |||
| 5890 | const comp = coff.base.comp; | 5894 | const comp = coff.base.comp; |
| 5891 | 5895 | ||
| 5892 | // TODO: When https://github.com/ziglang/zig/issues/23617 is in, | 5896 | // TODO: When https://github.com/ziglang/zig/issues/23617 is in, |
| ... | @@ -6649,11 +6653,11 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool { | ... | @@ -6649,11 +6653,11 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool { |
| 6649 | 6653 | ||
| 6650 | const target = &comp.root_mod.resolved_target.result; | 6654 | const target = &comp.root_mod.resolved_target.result; |
| 6651 | const alignment = switch (comp.root_mod.optimize_mode) { | 6655 | const alignment = switch (comp.root_mod.optimize_mode) { |
| 6652 | .Debug, | 6656 | .debug, |
| 6653 | .ReleaseSafe, | 6657 | .safe, |
| 6654 | .ReleaseFast, | 6658 | .fast, |
| 6655 | => target_util.defaultFunctionAlignment(target), | 6659 | => target_util.defaultFunctionAlignment(target), |
| 6656 | .ReleaseSmall => target_util.minFunctionAlignment(target), | 6660 | .small => target_util.minFunctionAlignment(target), |
| 6657 | }.toStdMem(); | 6661 | }.toStdMem(); |
| 6658 | const parent_si = (try coff.pseudoSectionMapIndex( | 6662 | const parent_si = (try coff.pseudoSectionMapIndex( |
| 6659 | .@".thunks", | 6663 | .@".thunks", |
| ... | @@ -6983,7 +6987,7 @@ fn flushMoved(coff: *Coff, ni: MappedFile.Node.Index) !void { | ... | @@ -6983,7 +6987,7 @@ fn flushMoved(coff: *Coff, ni: MappedFile.Node.Index) !void { |
| 6983 | continue; | 6987 | continue; |
| 6984 | 6988 | ||
| 6985 | import_hint_name_index = @intCast(import_hint_name_align.forward( | 6989 | import_hint_name_index = @intCast(import_hint_name_align.forward( |
| 6986 | std.mem.indexOfScalarPos( | 6990 | std.mem.findScalarPos( |
| 6987 | u8, | 6991 | u8, |
| 6988 | import_hint_name_slice, | 6992 | import_hint_name_slice, |
| 6989 | import_hint_name_index, | 6993 | import_hint_name_index, |
src/link/Dwarf.zig+3-2| ... | @@ -4151,8 +4151,8 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co | ... | @@ -4151,8 +4151,8 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co |
| 4151 | .x86_64_regcall_v3_sysv => .LLVM_X86RegCall, | 4151 | .x86_64_regcall_v3_sysv => .LLVM_X86RegCall, |
| 4152 | .x86_64_regcall_v4_win => .LLVM_X86RegCall, | 4152 | .x86_64_regcall_v4_win => .LLVM_X86RegCall, |
| 4153 | .x86_64_vectorcall => .LLVM_vectorcall, | 4153 | .x86_64_vectorcall => .LLVM_vectorcall, |
| 4154 | .x86_sysv => .normal, | 4154 | .x86_sysv, .x86_win, .x86_mingw => .normal, |
| 4155 | .x86_win => .normal, | 4155 | .x86_64_preserve_none => .LLVM_PreserveNone, |
| 4156 | .x86_stdcall => .BORLAND_stdcall, | 4156 | .x86_stdcall => .BORLAND_stdcall, |
| 4157 | .x86_fastcall => .BORLAND_msfastcall, | 4157 | .x86_fastcall => .BORLAND_msfastcall, |
| 4158 | .x86_thiscall => .BORLAND_thiscall, | 4158 | .x86_thiscall => .BORLAND_thiscall, |
| ... | @@ -4166,6 +4166,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co | ... | @@ -4166,6 +4166,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co |
| 4166 | .aarch64_aapcs_win => .normal, | 4166 | .aarch64_aapcs_win => .normal, |
| 4167 | .aarch64_vfabi => .LLVM_AAPCS, | 4167 | .aarch64_vfabi => .LLVM_AAPCS, |
| 4168 | .aarch64_vfabi_sve => .LLVM_AAPCS, | 4168 | .aarch64_vfabi_sve => .LLVM_AAPCS, |
| 4169 | .aarch64_preserve_none => .LLVM_PreserveNone, | ||
| 4169 | 4170 | ||
| 4170 | .arm_aapcs => .LLVM_AAPCS, | 4171 | .arm_aapcs => .LLVM_AAPCS, |
| 4171 | .arm_aapcs_vfp => .LLVM_AAPCS_VFP, | 4172 | .arm_aapcs_vfp => .LLVM_AAPCS_VFP, |
src/link/Elf.zig+136-137| ... | @@ -127,7 +127,7 @@ const SectionIndexes = struct { | ... | @@ -127,7 +127,7 @@ const SectionIndexes = struct { |
| 127 | symtab: ?u32 = null, | 127 | symtab: ?u32 = null, |
| 128 | }; | 128 | }; |
| 129 | 129 | ||
| 130 | const ProgramHeaderList = std.ArrayList(elf.Elf64_Phdr); | 130 | const ProgramHeaderList = std.ArrayList(elf.Elf64.Phdr); |
| 131 | 131 | ||
| 132 | const OptionalProgramHeaderIndex = enum(u16) { | 132 | const OptionalProgramHeaderIndex = enum(u16) { |
| 133 | none = std.math.maxInt(u16), | 133 | none = std.math.maxInt(u16), |
| ... | @@ -159,21 +159,21 @@ const ProgramHeaderIndex = enum(u16) { | ... | @@ -159,21 +159,21 @@ const ProgramHeaderIndex = enum(u16) { |
| 159 | }; | 159 | }; |
| 160 | 160 | ||
| 161 | const ProgramHeaderIndexes = struct { | 161 | const ProgramHeaderIndexes = struct { |
| 162 | /// PT_PHDR | 162 | /// PT.PHDR |
| 163 | table: OptionalProgramHeaderIndex = .none, | 163 | table: OptionalProgramHeaderIndex = .none, |
| 164 | /// PT_LOAD for PHDR table | 164 | /// PT.LOAD for PHDR table |
| 165 | /// We add this special load segment to ensure the EHDR and PHDR table are always | 165 | /// We add this special load segment to ensure the EHDR and PHDR table are always |
| 166 | /// loaded into memory. | 166 | /// loaded into memory. |
| 167 | table_load: OptionalProgramHeaderIndex = .none, | 167 | table_load: OptionalProgramHeaderIndex = .none, |
| 168 | /// PT_INTERP | 168 | /// PT.INTERP |
| 169 | interp: OptionalProgramHeaderIndex = .none, | 169 | interp: OptionalProgramHeaderIndex = .none, |
| 170 | /// PT_DYNAMIC | 170 | /// PT.DYNAMIC |
| 171 | dynamic: OptionalProgramHeaderIndex = .none, | 171 | dynamic: OptionalProgramHeaderIndex = .none, |
| 172 | /// PT_GNU_EH_FRAME | 172 | /// PT.GNU_EH_FRAME |
| 173 | gnu_eh_frame: OptionalProgramHeaderIndex = .none, | 173 | gnu_eh_frame: OptionalProgramHeaderIndex = .none, |
| 174 | /// PT_GNU_STACK | 174 | /// PT.GNU_STACK |
| 175 | gnu_stack: OptionalProgramHeaderIndex = .none, | 175 | gnu_stack: OptionalProgramHeaderIndex = .none, |
| 176 | /// PT_TLS | 176 | /// PT.TLS |
| 177 | /// TODO I think ELF permits multiple TLS segments but for now, assume one per file. | 177 | /// TODO I think ELF permits multiple TLS segments but for now, assume one per file. |
| 178 | tls: OptionalProgramHeaderIndex = .none, | 178 | tls: OptionalProgramHeaderIndex = .none, |
| 179 | }; | 179 | }; |
| ... | @@ -260,7 +260,7 @@ pub fn createEmpty( | ... | @@ -260,7 +260,7 @@ pub fn createEmpty( |
| 260 | .tag = .elf, | 260 | .tag = .elf, |
| 261 | .comp = comp, | 261 | .comp = comp, |
| 262 | .emit = emit, | 262 | .emit = emit, |
| 263 | .gc_sections = options.gc_sections orelse (optimize_mode != .Debug and output_mode != .Obj), | 263 | .gc_sections = options.gc_sections orelse (optimize_mode != .debug and output_mode != .Obj), |
| 264 | .print_gc_sections = options.print_gc_sections, | 264 | .print_gc_sections = options.print_gc_sections, |
| 265 | .stack_size = options.stack_size orelse 16777216, | 265 | .stack_size = options.stack_size orelse 16777216, |
| 266 | .allow_shlib_undefined = options.allow_shlib_undefined orelse !is_native_os, | 266 | .allow_shlib_undefined = options.allow_shlib_undefined orelse !is_native_os, |
| ... | @@ -334,23 +334,23 @@ pub fn createEmpty( | ... | @@ -334,23 +334,23 @@ pub fn createEmpty( |
| 334 | if (!is_obj_or_ar) { | 334 | if (!is_obj_or_ar) { |
| 335 | try self.dynstrtab.append(gpa, 0); | 335 | try self.dynstrtab.append(gpa, 0); |
| 336 | 336 | ||
| 337 | // Initialize PT_PHDR program header | 337 | // Initialize PT.PHDR program header |
| 338 | const p_align: u16 = switch (self.ptr_width) { | 338 | const p_align: u16 = switch (self.ptr_width) { |
| 339 | .p32 => @alignOf(elf.Elf32_Phdr), | 339 | .p32 => @alignOf(elf.Elf32.Phdr), |
| 340 | .p64 => @alignOf(elf.Elf64_Phdr), | 340 | .p64 => @alignOf(elf.Elf64.Phdr), |
| 341 | }; | 341 | }; |
| 342 | const ehsize: u64 = switch (self.ptr_width) { | 342 | const ehsize: u64 = switch (self.ptr_width) { |
| 343 | .p32 => @sizeOf(elf.Elf32_Ehdr), | 343 | .p32 => @sizeOf(elf.Elf32_Ehdr), |
| 344 | .p64 => @sizeOf(elf.Elf64_Ehdr), | 344 | .p64 => @sizeOf(elf.Elf64_Ehdr), |
| 345 | }; | 345 | }; |
| 346 | const phsize: u64 = switch (self.ptr_width) { | 346 | const phsize: u64 = switch (self.ptr_width) { |
| 347 | .p32 => @sizeOf(elf.Elf32_Phdr), | 347 | .p32 => @sizeOf(elf.Elf32.Phdr), |
| 348 | .p64 => @sizeOf(elf.Elf64_Phdr), | 348 | .p64 => @sizeOf(elf.Elf64.Phdr), |
| 349 | }; | 349 | }; |
| 350 | const max_nphdrs = comptime getMaxNumberOfPhdrs(); | 350 | const max_nphdrs = comptime getMaxNumberOfPhdrs(); |
| 351 | const reserved: u64 = mem.alignForward(u64, padToIdeal(max_nphdrs * phsize), self.page_size); | 351 | const reserved: u64 = mem.alignForward(u64, padToIdeal(max_nphdrs * phsize), self.page_size); |
| 352 | self.phdr_indexes.table = (try self.addPhdr(.{ | 352 | self.phdr_indexes.table = (try self.addPhdr(.{ |
| 353 | .type = elf.PT_PHDR, | 353 | .type = @backingInt(elf.PT.PHDR), |
| 354 | .flags = elf.PF_R, | 354 | .flags = elf.PF_R, |
| 355 | .@"align" = p_align, | 355 | .@"align" = p_align, |
| 356 | .addr = self.image_base + ehsize, | 356 | .addr = self.image_base + ehsize, |
| ... | @@ -359,7 +359,7 @@ pub fn createEmpty( | ... | @@ -359,7 +359,7 @@ pub fn createEmpty( |
| 359 | .memsz = reserved, | 359 | .memsz = reserved, |
| 360 | })).toOptional(); | 360 | })).toOptional(); |
| 361 | self.phdr_indexes.table_load = (try self.addPhdr(.{ | 361 | self.phdr_indexes.table_load = (try self.addPhdr(.{ |
| 362 | .type = elf.PT_LOAD, | 362 | .type = @backingInt(elf.PT.LOAD), |
| 363 | .flags = elf.PF_R, | 363 | .flags = elf.PF_R, |
| 364 | .@"align" = self.page_size, | 364 | .@"align" = self.page_size, |
| 365 | .addr = self.image_base, | 365 | .addr = self.image_base, |
| ... | @@ -514,11 +514,11 @@ fn detectAllocCollision(self: *Elf, start: u64, size: u64) !?u64 { | ... | @@ -514,11 +514,11 @@ fn detectAllocCollision(self: *Elf, start: u64, size: u64) !?u64 { |
| 514 | } | 514 | } |
| 515 | 515 | ||
| 516 | for (self.phdrs.items) |phdr| { | 516 | for (self.phdrs.items) |phdr| { |
| 517 | if (phdr.p_type != elf.PT_LOAD) continue; | 517 | if (phdr.type != .LOAD) continue; |
| 518 | const increased_size = padToIdeal(phdr.p_filesz); | 518 | const increased_size = padToIdeal(phdr.filesz); |
| 519 | const test_end = phdr.p_offset +| increased_size; | 519 | const test_end = phdr.offset +| increased_size; |
| 520 | if (start < test_end) { | 520 | if (start < test_end) { |
| 521 | if (end > phdr.p_offset) return test_end; | 521 | if (end > phdr.offset) return test_end; |
| 522 | if (test_end < std.math.maxInt(u64)) at_end = false; | 522 | if (test_end < std.math.maxInt(u64)) at_end = false; |
| 523 | } | 523 | } |
| 524 | } | 524 | } |
| ... | @@ -538,8 +538,8 @@ pub fn allocatedSize(self: *Elf, start: u64) u64 { | ... | @@ -538,8 +538,8 @@ pub fn allocatedSize(self: *Elf, start: u64) u64 { |
| 538 | if (section.sh_offset < min_pos) min_pos = section.sh_offset; | 538 | if (section.sh_offset < min_pos) min_pos = section.sh_offset; |
| 539 | } | 539 | } |
| 540 | for (self.phdrs.items) |phdr| { | 540 | for (self.phdrs.items) |phdr| { |
| 541 | if (phdr.p_offset <= start) continue; | 541 | if (phdr.offset <= start) continue; |
| 542 | if (phdr.p_offset < min_pos) min_pos = phdr.p_offset; | 542 | if (phdr.offset < min_pos) min_pos = phdr.offset; |
| 543 | } | 543 | } |
| 544 | return min_pos - start; | 544 | return min_pos - start; |
| 545 | } | 545 | } |
| ... | @@ -714,7 +714,6 @@ pub fn loadInput(self: *Elf, input: link.Input) !void { | ... | @@ -714,7 +714,6 @@ pub fn loadInput(self: *Elf, input: link.Input) !void { |
| 714 | const target = self.getTarget(); | 714 | const target = self.getTarget(); |
| 715 | const debug_fmt_strip = comp.config.debug_format == .strip; | 715 | const debug_fmt_strip = comp.config.debug_format == .strip; |
| 716 | const default_sym_version = self.default_sym_version; | 716 | const default_sym_version = self.default_sym_version; |
| 717 | const is_static_lib = self.base.isStaticLib(); | ||
| 718 | 717 | ||
| 719 | if (comp.verbose_link) { | 718 | if (comp.verbose_link) { |
| 720 | comp.mutex.lockUncancelable(io); // protect comp.arena | 719 | comp.mutex.lockUncancelable(io); // protect comp.arena |
| ... | @@ -733,7 +732,11 @@ pub fn loadInput(self: *Elf, input: link.Input) !void { | ... | @@ -733,7 +732,11 @@ pub fn loadInput(self: *Elf, input: link.Input) !void { |
| 733 | .res => unreachable, | 732 | .res => unreachable, |
| 734 | .dso_exact => @panic("TODO"), | 733 | .dso_exact => @panic("TODO"), |
| 735 | .object => |obj| try parseObject(self, obj), | 734 | .object => |obj| try parseObject(self, obj), |
| 736 | .archive => |obj| try parseArchive(gpa, io, diags, &self.file_handles, &self.files, target, debug_fmt_strip, default_sym_version, &self.objects, obj, is_static_lib), | 735 | .archive => |obj| if (self.base.isStaticLib()) { |
| 736 | // Ignore static library inputs when generating a static library. | ||
| 737 | } else { | ||
| 738 | try parseArchive(gpa, io, diags, &self.file_handles, &self.files, target, debug_fmt_strip, default_sym_version, &self.objects, obj); | ||
| 739 | }, | ||
| 737 | .dso => |dso| try parseDso(gpa, io, diags, dso, &self.shared_objects, &self.files, target), | 740 | .dso => |dso| try parseDso(gpa, io, diags, dso, &self.shared_objects, &self.files, target), |
| 738 | } | 741 | } |
| 739 | } | 742 | } |
| ... | @@ -1083,7 +1086,6 @@ fn parseArchive( | ... | @@ -1083,7 +1086,6 @@ fn parseArchive( |
| 1083 | default_sym_version: elf.Versym, | 1086 | default_sym_version: elf.Versym, |
| 1084 | objects: *std.ArrayList(File.Index), | 1087 | objects: *std.ArrayList(File.Index), |
| 1085 | obj: link.Input.Object, | 1088 | obj: link.Input.Object, |
| 1086 | is_static_lib: bool, | ||
| 1087 | ) !void { | 1089 | ) !void { |
| 1088 | const tracy = trace(@src()); | 1090 | const tracy = trace(@src()); |
| 1089 | defer tracy.end(); | 1091 | defer tracy.end(); |
| ... | @@ -1092,17 +1094,14 @@ fn parseArchive( | ... | @@ -1092,17 +1094,14 @@ fn parseArchive( |
| 1092 | var archive = try Archive.parse(gpa, io, diags, file_handles, obj.path, fh); | 1094 | var archive = try Archive.parse(gpa, io, diags, file_handles, obj.path, fh); |
| 1093 | defer archive.deinit(gpa); | 1095 | defer archive.deinit(gpa); |
| 1094 | 1096 | ||
| 1095 | const init_alive = if (is_static_lib) true else obj.must_link; | ||
| 1096 | |||
| 1097 | for (archive.objects) |extracted| { | 1097 | for (archive.objects) |extracted| { |
| 1098 | const index: File.Index = @intCast(try files.addOne(gpa)); | 1098 | const index: File.Index = @intCast(try files.addOne(gpa)); |
| 1099 | files.set(index, .{ .object = extracted }); | 1099 | files.set(index, .{ .object = extracted }); |
| 1100 | const object = &files.items(.data)[index].object; | 1100 | const object = &files.items(.data)[index].object; |
| 1101 | object.index = index; | 1101 | object.index = index; |
| 1102 | object.alive = init_alive; | 1102 | object.alive = obj.must_link; |
| 1103 | try object.parseCommon(gpa, io, diags, obj.path, obj.file, target); | 1103 | try object.parseCommon(gpa, io, diags, obj.path, obj.file, target); |
| 1104 | if (!is_static_lib) | 1104 | try object.parse(gpa, io, diags, obj.path, obj.file, target, debug_fmt_strip, default_sym_version); |
| 1105 | try object.parse(gpa, io, diags, obj.path, obj.file, target, debug_fmt_strip, default_sym_version); | ||
| 1106 | try objects.append(gpa, index); | 1105 | try objects.append(gpa, index); |
| 1107 | } | 1106 | } |
| 1108 | } | 1107 | } |
| ... | @@ -1471,34 +1470,34 @@ fn writePhdrTable(self: *Elf) !void { | ... | @@ -1471,34 +1470,34 @@ fn writePhdrTable(self: *Elf) !void { |
| 1471 | const phdr_table = &self.phdrs.items[self.phdr_indexes.table.int().?]; | 1470 | const phdr_table = &self.phdrs.items[self.phdr_indexes.table.int().?]; |
| 1472 | 1471 | ||
| 1473 | log.debug("writing program headers from 0x{x} to 0x{x}", .{ | 1472 | log.debug("writing program headers from 0x{x} to 0x{x}", .{ |
| 1474 | phdr_table.p_offset, | 1473 | phdr_table.offset, |
| 1475 | phdr_table.p_offset + phdr_table.p_filesz, | 1474 | phdr_table.offset + phdr_table.filesz, |
| 1476 | }); | 1475 | }); |
| 1477 | 1476 | ||
| 1478 | switch (self.ptr_width) { | 1477 | switch (self.ptr_width) { |
| 1479 | .p32 => { | 1478 | .p32 => { |
| 1480 | const buf = try gpa.alloc(elf.Elf32_Phdr, self.phdrs.items.len); | 1479 | const buf = try gpa.alloc(elf.Elf32.Phdr, self.phdrs.items.len); |
| 1481 | defer gpa.free(buf); | 1480 | defer gpa.free(buf); |
| 1482 | 1481 | ||
| 1483 | for (buf, 0..) |*phdr, i| { | 1482 | for (buf, 0..) |*phdr, i| { |
| 1484 | phdr.* = phdrTo32(self.phdrs.items[i]); | 1483 | phdr.* = phdrTo32(self.phdrs.items[i]); |
| 1485 | if (foreign_endian) { | 1484 | if (foreign_endian) { |
| 1486 | mem.byteSwapAllFields(elf.Elf32_Phdr, phdr); | 1485 | mem.byteSwapAllFields(elf.Elf32.Phdr, phdr); |
| 1487 | } | 1486 | } |
| 1488 | } | 1487 | } |
| 1489 | try self.pwriteAll(@ptrCast(buf), phdr_table.p_offset); | 1488 | try self.pwriteAll(@ptrCast(buf), phdr_table.offset); |
| 1490 | }, | 1489 | }, |
| 1491 | .p64 => { | 1490 | .p64 => { |
| 1492 | const buf = try gpa.alloc(elf.Elf64_Phdr, self.phdrs.items.len); | 1491 | const buf = try gpa.alloc(elf.Elf64.Phdr, self.phdrs.items.len); |
| 1493 | defer gpa.free(buf); | 1492 | defer gpa.free(buf); |
| 1494 | 1493 | ||
| 1495 | for (buf, 0..) |*phdr, i| { | 1494 | for (buf, 0..) |*phdr, i| { |
| 1496 | phdr.* = self.phdrs.items[i]; | 1495 | phdr.* = self.phdrs.items[i]; |
| 1497 | if (foreign_endian) { | 1496 | if (foreign_endian) { |
| 1498 | mem.byteSwapAllFields(elf.Elf64_Phdr, phdr); | 1497 | mem.byteSwapAllFields(elf.Elf64.Phdr, phdr); |
| 1499 | } | 1498 | } |
| 1500 | } | 1499 | } |
| 1501 | try self.pwriteAll(@ptrCast(buf), phdr_table.p_offset); | 1500 | try self.pwriteAll(@ptrCast(buf), phdr_table.offset); |
| 1502 | }, | 1501 | }, |
| 1503 | } | 1502 | } |
| 1504 | } | 1503 | } |
| ... | @@ -1581,7 +1580,7 @@ pub fn writeElfHeader(self: *Elf) !void { | ... | @@ -1581,7 +1580,7 @@ pub fn writeElfHeader(self: *Elf) !void { |
| 1581 | const entry_sym = obj.entrySymbol(self) orelse break :blk 0; | 1580 | const entry_sym = obj.entrySymbol(self) orelse break :blk 0; |
| 1582 | break :blk @intCast(entry_sym.address(.{}, self)); | 1581 | break :blk @intCast(entry_sym.address(.{}, self)); |
| 1583 | } else 0; | 1582 | } else 0; |
| 1584 | const phdr_table_offset = if (self.phdr_indexes.table.int()) |phndx| self.phdrs.items[phndx].p_offset else 0; | 1583 | const phdr_table_offset = if (self.phdr_indexes.table.int()) |phndx| self.phdrs.items[phndx].offset else 0; |
| 1585 | switch (self.ptr_width) { | 1584 | switch (self.ptr_width) { |
| 1586 | .p32 => { | 1585 | .p32 => { |
| 1587 | mem.writeInt(u32, hdr_buf[index..][0..4], @intCast(e_entry), endian); | 1586 | mem.writeInt(u32, hdr_buf[index..][0..4], @intCast(e_entry), endian); |
| ... | @@ -1622,8 +1621,8 @@ pub fn writeElfHeader(self: *Elf) !void { | ... | @@ -1622,8 +1621,8 @@ pub fn writeElfHeader(self: *Elf) !void { |
| 1622 | index += 2; | 1621 | index += 2; |
| 1623 | 1622 | ||
| 1624 | const e_phentsize: u16 = switch (self.ptr_width) { | 1623 | const e_phentsize: u16 = switch (self.ptr_width) { |
| 1625 | .p32 => @sizeOf(elf.Elf32_Phdr), | 1624 | .p32 => @sizeOf(elf.Elf32.Phdr), |
| 1626 | .p64 => @sizeOf(elf.Elf64_Phdr), | 1625 | .p64 => @sizeOf(elf.Elf64.Phdr), |
| 1627 | }; | 1626 | }; |
| 1628 | mem.writeInt(u16, hdr_buf[index..][0..2], e_phentsize, endian); | 1627 | mem.writeInt(u16, hdr_buf[index..][0..2], e_phentsize, endian); |
| 1629 | index += 2; | 1628 | index += 2; |
| ... | @@ -2091,26 +2090,26 @@ fn initSpecialPhdrs(self: *Elf) !void { | ... | @@ -2091,26 +2090,26 @@ fn initSpecialPhdrs(self: *Elf) !void { |
| 2091 | 2090 | ||
| 2092 | if (self.section_indexes.interp != null and self.phdr_indexes.interp == .none) { | 2091 | if (self.section_indexes.interp != null and self.phdr_indexes.interp == .none) { |
| 2093 | self.phdr_indexes.interp = (try self.addPhdr(.{ | 2092 | self.phdr_indexes.interp = (try self.addPhdr(.{ |
| 2094 | .type = elf.PT_INTERP, | 2093 | .type = @backingInt(elf.PT.INTERP), |
| 2095 | .flags = elf.PF_R, | 2094 | .flags = elf.PF_R, |
| 2096 | .@"align" = 1, | 2095 | .@"align" = 1, |
| 2097 | })).toOptional(); | 2096 | })).toOptional(); |
| 2098 | } | 2097 | } |
| 2099 | if (self.section_indexes.dynamic != null and self.phdr_indexes.dynamic == .none) { | 2098 | if (self.section_indexes.dynamic != null and self.phdr_indexes.dynamic == .none) { |
| 2100 | self.phdr_indexes.dynamic = (try self.addPhdr(.{ | 2099 | self.phdr_indexes.dynamic = (try self.addPhdr(.{ |
| 2101 | .type = elf.PT_DYNAMIC, | 2100 | .type = @backingInt(elf.PT.DYNAMIC), |
| 2102 | .flags = elf.PF_R | elf.PF_W, | 2101 | .flags = elf.PF_R | elf.PF_W, |
| 2103 | })).toOptional(); | 2102 | })).toOptional(); |
| 2104 | } | 2103 | } |
| 2105 | if (self.section_indexes.eh_frame_hdr != null and self.phdr_indexes.gnu_eh_frame == .none) { | 2104 | if (self.section_indexes.eh_frame_hdr != null and self.phdr_indexes.gnu_eh_frame == .none) { |
| 2106 | self.phdr_indexes.gnu_eh_frame = (try self.addPhdr(.{ | 2105 | self.phdr_indexes.gnu_eh_frame = (try self.addPhdr(.{ |
| 2107 | .type = elf.PT_GNU_EH_FRAME, | 2106 | .type = @backingInt(elf.PT.GNU_EH_FRAME), |
| 2108 | .flags = elf.PF_R, | 2107 | .flags = elf.PF_R, |
| 2109 | })).toOptional(); | 2108 | })).toOptional(); |
| 2110 | } | 2109 | } |
| 2111 | if (self.phdr_indexes.gnu_stack == .none) { | 2110 | if (self.phdr_indexes.gnu_stack == .none) { |
| 2112 | self.phdr_indexes.gnu_stack = (try self.addPhdr(.{ | 2111 | self.phdr_indexes.gnu_stack = (try self.addPhdr(.{ |
| 2113 | .type = elf.PT_GNU_STACK, | 2112 | .type = @backingInt(elf.PT.GNU_STACK), |
| 2114 | .flags = elf.PF_W | elf.PF_R, | 2113 | .flags = elf.PF_W | elf.PF_R, |
| 2115 | .memsz = self.base.stack_size, | 2114 | .memsz = self.base.stack_size, |
| 2116 | .@"align" = 1, | 2115 | .@"align" = 1, |
| ... | @@ -2122,7 +2121,7 @@ fn initSpecialPhdrs(self: *Elf) !void { | ... | @@ -2122,7 +2121,7 @@ fn initSpecialPhdrs(self: *Elf) !void { |
| 2122 | } else false; | 2121 | } else false; |
| 2123 | if (has_tls and self.phdr_indexes.tls == .none) { | 2122 | if (has_tls and self.phdr_indexes.tls == .none) { |
| 2124 | self.phdr_indexes.tls = (try self.addPhdr(.{ | 2123 | self.phdr_indexes.tls = (try self.addPhdr(.{ |
| 2125 | .type = elf.PT_TLS, | 2124 | .type = @backingInt(elf.PT.TLS), |
| 2126 | .flags = elf.PF_R, | 2125 | .flags = elf.PF_R, |
| 2127 | .@"align" = 1, | 2126 | .@"align" = 1, |
| 2128 | })).toOptional(); | 2127 | })).toOptional(); |
| ... | @@ -2173,7 +2172,7 @@ fn sortInitFini(self: *Elf) !void { | ... | @@ -2173,7 +2172,7 @@ fn sortInitFini(self: *Elf) !void { |
| 2173 | => is_init_fini = true, | 2172 | => is_init_fini = true, |
| 2174 | else => { | 2173 | else => { |
| 2175 | const name = self.getShString(shdr.sh_name); | 2174 | const name = self.getShString(shdr.sh_name); |
| 2176 | is_ctor_dtor = mem.indexOf(u8, name, ".ctors") != null or mem.indexOf(u8, name, ".dtors") != null; | 2175 | is_ctor_dtor = mem.find(u8, name, ".ctors") != null or mem.find(u8, name, ".dtors") != null; |
| 2177 | }, | 2176 | }, |
| 2178 | } | 2177 | } |
| 2179 | if (!is_init_fini and !is_ctor_dtor) continue; | 2178 | if (!is_init_fini and !is_ctor_dtor) continue; |
| ... | @@ -2260,15 +2259,15 @@ fn setHashSections(self: *Elf) !void { | ... | @@ -2260,15 +2259,15 @@ fn setHashSections(self: *Elf) !void { |
| 2260 | } | 2259 | } |
| 2261 | } | 2260 | } |
| 2262 | 2261 | ||
| 2263 | fn phdrRank(phdr: elf.Elf64_Phdr) u8 { | 2262 | fn phdrRank(phdr: elf.Elf64.Phdr) u8 { |
| 2264 | return switch (phdr.p_type) { | 2263 | return switch (phdr.type) { |
| 2265 | elf.PT_NULL => 0, | 2264 | .NULL => 0, |
| 2266 | elf.PT_PHDR => 1, | 2265 | .PHDR => 1, |
| 2267 | elf.PT_INTERP => 2, | 2266 | .INTERP => 2, |
| 2268 | elf.PT_LOAD => 3, | 2267 | .LOAD => 3, |
| 2269 | elf.PT_DYNAMIC, elf.PT_TLS => 4, | 2268 | .DYNAMIC, .TLS => 4, |
| 2270 | elf.PT_GNU_EH_FRAME => 5, | 2269 | .GNU_EH_FRAME => 5, |
| 2271 | elf.PT_GNU_STACK => 6, | 2270 | .GNU_STACK => 6, |
| 2272 | else => 7, | 2271 | else => 7, |
| 2273 | }; | 2272 | }; |
| 2274 | } | 2273 | } |
| ... | @@ -2282,12 +2281,12 @@ fn sortPhdrs( | ... | @@ -2282,12 +2281,12 @@ fn sortPhdrs( |
| 2282 | const Entry = struct { | 2281 | const Entry = struct { |
| 2283 | phndx: u16, | 2282 | phndx: u16, |
| 2284 | 2283 | ||
| 2285 | pub fn lessThan(program_headers: []const elf.Elf64_Phdr, lhs: @This(), rhs: @This()) bool { | 2284 | pub fn lessThan(program_headers: []const elf.Elf64.Phdr, lhs: @This(), rhs: @This()) bool { |
| 2286 | const lhs_phdr = program_headers[lhs.phndx]; | 2285 | const lhs_phdr = program_headers[lhs.phndx]; |
| 2287 | const rhs_phdr = program_headers[rhs.phndx]; | 2286 | const rhs_phdr = program_headers[rhs.phndx]; |
| 2288 | const lhs_rank = phdrRank(lhs_phdr); | 2287 | const lhs_rank = phdrRank(lhs_phdr); |
| 2289 | const rhs_rank = phdrRank(rhs_phdr); | 2288 | const rhs_rank = phdrRank(rhs_phdr); |
| 2290 | if (lhs_rank == rhs_rank) return lhs_phdr.p_vaddr < rhs_phdr.p_vaddr; | 2289 | if (lhs_rank == rhs_rank) return lhs_phdr.vaddr < rhs_phdr.vaddr; |
| 2291 | return lhs_rank < rhs_rank; | 2290 | return lhs_rank < rhs_rank; |
| 2292 | } | 2291 | } |
| 2293 | }; | 2292 | }; |
| ... | @@ -2299,7 +2298,7 @@ fn sortPhdrs( | ... | @@ -2299,7 +2298,7 @@ fn sortPhdrs( |
| 2299 | } | 2298 | } |
| 2300 | 2299 | ||
| 2301 | // The `@as` here works around a bug in the C backend. | 2300 | // The `@as` here works around a bug in the C backend. |
| 2302 | mem.sort(Entry, entries, @as([]const elf.Elf64_Phdr, phdrs.items), Entry.lessThan); | 2301 | mem.sort(Entry, entries, @as([]const elf.Elf64.Phdr, phdrs.items), Entry.lessThan); |
| 2303 | 2302 | ||
| 2304 | const backlinks = try gpa.alloc(u16, entries.len); | 2303 | const backlinks = try gpa.alloc(u16, entries.len); |
| 2305 | defer gpa.free(backlinks); | 2304 | defer gpa.free(backlinks); |
| ... | @@ -2655,8 +2654,8 @@ fn addLoadPhdrs(self: *Elf) error{OutOfMemory}!void { | ... | @@ -2655,8 +2654,8 @@ fn addLoadPhdrs(self: *Elf) error{OutOfMemory}!void { |
| 2655 | if (shdr.sh_type == elf.SHT_NULL) continue; | 2654 | if (shdr.sh_type == elf.SHT_NULL) continue; |
| 2656 | if (shdr.sh_flags & elf.SHF_ALLOC == 0) continue; | 2655 | if (shdr.sh_flags & elf.SHF_ALLOC == 0) continue; |
| 2657 | const flags = shdrToPhdrFlags(shdr.sh_flags); | 2656 | const flags = shdrToPhdrFlags(shdr.sh_flags); |
| 2658 | if (self.getPhdr(.{ .flags = flags, .type = elf.PT_LOAD }) == .none) { | 2657 | if (self.getPhdr(.{ .flags = flags, .type = @backingInt(elf.PT.LOAD) }) == .none) { |
| 2659 | _ = try self.addPhdr(.{ .flags = flags, .type = elf.PT_LOAD }); | 2658 | _ = try self.addPhdr(.{ .flags = flags, .type = @backingInt(elf.PT.LOAD) }); |
| 2660 | } | 2659 | } |
| 2661 | } | 2660 | } |
| 2662 | } | 2661 | } |
| ... | @@ -2672,11 +2671,11 @@ fn allocatePhdrTable(self: *Elf) error{OutOfMemory}!void { | ... | @@ -2672,11 +2671,11 @@ fn allocatePhdrTable(self: *Elf) error{OutOfMemory}!void { |
| 2672 | .p64 => @sizeOf(elf.Elf64_Ehdr), | 2671 | .p64 => @sizeOf(elf.Elf64_Ehdr), |
| 2673 | }; | 2672 | }; |
| 2674 | const phsize: u64 = switch (self.ptr_width) { | 2673 | const phsize: u64 = switch (self.ptr_width) { |
| 2675 | .p32 => @sizeOf(elf.Elf32_Phdr), | 2674 | .p32 => @sizeOf(elf.Elf32.Phdr), |
| 2676 | .p64 => @sizeOf(elf.Elf64_Phdr), | 2675 | .p64 => @sizeOf(elf.Elf64.Phdr), |
| 2677 | }; | 2676 | }; |
| 2678 | const needed_size = self.phdrs.items.len * phsize; | 2677 | const needed_size = self.phdrs.items.len * phsize; |
| 2679 | const available_space = self.allocatedSize(phdr_table.p_offset); | 2678 | const available_space = self.allocatedSize(phdr_table.offset); |
| 2680 | 2679 | ||
| 2681 | if (needed_size > available_space) { | 2680 | if (needed_size > available_space) { |
| 2682 | // In this case, we have two options: | 2681 | // In this case, we have two options: |
| ... | @@ -2689,10 +2688,10 @@ fn allocatePhdrTable(self: *Elf) error{OutOfMemory}!void { | ... | @@ -2689,10 +2688,10 @@ fn allocatePhdrTable(self: *Elf) error{OutOfMemory}!void { |
| 2689 | err.addNote("required 0x{x}, available 0x{x}", .{ needed_size, available_space }); | 2688 | err.addNote("required 0x{x}, available 0x{x}", .{ needed_size, available_space }); |
| 2690 | } | 2689 | } |
| 2691 | 2690 | ||
| 2692 | phdr_table_load.p_filesz = needed_size + ehsize; | 2691 | phdr_table_load.filesz = needed_size + ehsize; |
| 2693 | phdr_table_load.p_memsz = needed_size + ehsize; | 2692 | phdr_table_load.memsz = needed_size + ehsize; |
| 2694 | phdr_table.p_filesz = needed_size; | 2693 | phdr_table.filesz = needed_size; |
| 2695 | phdr_table.p_memsz = needed_size; | 2694 | phdr_table.memsz = needed_size; |
| 2696 | } | 2695 | } |
| 2697 | 2696 | ||
| 2698 | /// Allocates alloc sections and creates load segments for sections | 2697 | /// Allocates alloc sections and creates load segments for sections |
| ... | @@ -2758,7 +2757,7 @@ pub fn allocateAllocSections(self: *Elf) !void { | ... | @@ -2758,7 +2757,7 @@ pub fn allocateAllocSections(self: *Elf) !void { |
| 2758 | // of any section that is contained in a cover and use it to align | 2757 | // of any section that is contained in a cover and use it to align |
| 2759 | // the start address of the segement (and first section). | 2758 | // the start address of the segement (and first section). |
| 2760 | const phdr_table = &self.phdrs.items[self.phdr_indexes.table_load.int().?]; | 2759 | const phdr_table = &self.phdrs.items[self.phdr_indexes.table_load.int().?]; |
| 2761 | var addr = phdr_table.p_vaddr + phdr_table.p_memsz; | 2760 | var addr = phdr_table.vaddr + phdr_table.memsz; |
| 2762 | 2761 | ||
| 2763 | for (covers) |cover| { | 2762 | for (covers) |cover| { |
| 2764 | if (cover.items.len == 0) continue; | 2763 | if (cover.items.len == 0) continue; |
| ... | @@ -2817,14 +2816,14 @@ pub fn allocateAllocSections(self: *Elf) !void { | ... | @@ -2817,14 +2816,14 @@ pub fn allocateAllocSections(self: *Elf) !void { |
| 2817 | } | 2816 | } |
| 2818 | 2817 | ||
| 2819 | const first = slice.items(.shdr)[cover.items[0]]; | 2818 | const first = slice.items(.shdr)[cover.items[0]]; |
| 2820 | const phndx = self.getPhdr(.{ .type = elf.PT_LOAD, .flags = shdrToPhdrFlags(first.sh_flags) }).unwrap().?; | 2819 | const phndx = self.getPhdr(.{ .type = @backingInt(elf.PT.LOAD), .flags = shdrToPhdrFlags(first.sh_flags) }).unwrap().?; |
| 2821 | const phdr = &self.phdrs.items[phndx.int()]; | 2820 | const phdr = &self.phdrs.items[phndx.int()]; |
| 2822 | const allocated_size = self.allocatedSize(phdr.p_offset); | 2821 | const allocated_size = self.allocatedSize(phdr.offset); |
| 2823 | if (filesz > allocated_size) { | 2822 | if (filesz > allocated_size) { |
| 2824 | const old_offset = phdr.p_offset; | 2823 | const old_offset = phdr.offset; |
| 2825 | phdr.p_offset = 0; | 2824 | phdr.offset = 0; |
| 2826 | var new_offset = try self.findFreeSpace(filesz, @"align"); | 2825 | var new_offset = try self.findFreeSpace(filesz, @"align"); |
| 2827 | phdr.p_offset = new_offset; | 2826 | phdr.offset = new_offset; |
| 2828 | 2827 | ||
| 2829 | log.debug("moving phdr({d}) from 0x{x} to 0x{x}", .{ phndx, old_offset, new_offset }); | 2828 | log.debug("moving phdr({d}) from 0x{x} to 0x{x}", .{ phndx, old_offset, new_offset }); |
| 2830 | 2829 | ||
| ... | @@ -2854,11 +2853,11 @@ pub fn allocateAllocSections(self: *Elf) !void { | ... | @@ -2854,11 +2853,11 @@ pub fn allocateAllocSections(self: *Elf) !void { |
| 2854 | } | 2853 | } |
| 2855 | } | 2854 | } |
| 2856 | 2855 | ||
| 2857 | phdr.p_vaddr = first.sh_addr; | 2856 | phdr.vaddr = first.sh_addr; |
| 2858 | phdr.p_paddr = first.sh_addr; | 2857 | phdr.paddr = first.sh_addr; |
| 2859 | phdr.p_memsz = memsz; | 2858 | phdr.memsz = memsz; |
| 2860 | phdr.p_filesz = filesz; | 2859 | phdr.filesz = filesz; |
| 2861 | phdr.p_align = @"align"; | 2860 | phdr.@"align" = @"align"; |
| 2862 | 2861 | ||
| 2863 | addr = mem.alignForward(u64, addr, self.page_size); | 2862 | addr = mem.alignForward(u64, addr, self.page_size); |
| 2864 | } | 2863 | } |
| ... | @@ -2902,12 +2901,12 @@ fn allocateSpecialPhdrs(self: *Elf) void { | ... | @@ -2902,12 +2901,12 @@ fn allocateSpecialPhdrs(self: *Elf) void { |
| 2902 | if (pair[0].int()) |index| { | 2901 | if (pair[0].int()) |index| { |
| 2903 | const shdr = slice.items(.shdr)[pair[1].?]; | 2902 | const shdr = slice.items(.shdr)[pair[1].?]; |
| 2904 | const phdr = &self.phdrs.items[index]; | 2903 | const phdr = &self.phdrs.items[index]; |
| 2905 | phdr.p_align = shdr.sh_addralign; | 2904 | phdr.@"align" = shdr.sh_addralign; |
| 2906 | phdr.p_offset = shdr.sh_offset; | 2905 | phdr.offset = shdr.sh_offset; |
| 2907 | phdr.p_vaddr = shdr.sh_addr; | 2906 | phdr.vaddr = shdr.sh_addr; |
| 2908 | phdr.p_paddr = shdr.sh_addr; | 2907 | phdr.paddr = shdr.sh_addr; |
| 2909 | phdr.p_filesz = shdr.sh_size; | 2908 | phdr.filesz = shdr.sh_size; |
| 2910 | phdr.p_memsz = shdr.sh_size; | 2909 | phdr.memsz = shdr.sh_size; |
| 2911 | } | 2910 | } |
| 2912 | } | 2911 | } |
| 2913 | 2912 | ||
| ... | @@ -2924,25 +2923,25 @@ fn allocateSpecialPhdrs(self: *Elf) void { | ... | @@ -2924,25 +2923,25 @@ fn allocateSpecialPhdrs(self: *Elf) void { |
| 2924 | shndx += 1; | 2923 | shndx += 1; |
| 2925 | continue; | 2924 | continue; |
| 2926 | } | 2925 | } |
| 2927 | phdr.p_offset = shdr.sh_offset; | 2926 | phdr.offset = shdr.sh_offset; |
| 2928 | phdr.p_vaddr = shdr.sh_addr; | 2927 | phdr.vaddr = shdr.sh_addr; |
| 2929 | phdr.p_paddr = shdr.sh_addr; | 2928 | phdr.paddr = shdr.sh_addr; |
| 2930 | phdr.p_align = shdr.sh_addralign; | 2929 | phdr.@"align" = shdr.sh_addralign; |
| 2931 | shndx += 1; | 2930 | shndx += 1; |
| 2932 | phdr.p_align = @max(phdr.p_align, shdr.sh_addralign); | 2931 | phdr.@"align" = @max(phdr.@"align", shdr.sh_addralign); |
| 2933 | if (shdr.sh_type != elf.SHT_NOBITS) { | 2932 | if (shdr.sh_type != elf.SHT_NOBITS) { |
| 2934 | phdr.p_filesz = shdr.sh_offset + shdr.sh_size - phdr.p_offset; | 2933 | phdr.filesz = shdr.sh_offset + shdr.sh_size - phdr.offset; |
| 2935 | } | 2934 | } |
| 2936 | phdr.p_memsz = shdr.sh_addr + shdr.sh_size - phdr.p_vaddr; | 2935 | phdr.memsz = shdr.sh_addr + shdr.sh_size - phdr.vaddr; |
| 2937 | 2936 | ||
| 2938 | while (shndx < shdrs.len) : (shndx += 1) { | 2937 | while (shndx < shdrs.len) : (shndx += 1) { |
| 2939 | const next = shdrs[shndx]; | 2938 | const next = shdrs[shndx]; |
| 2940 | if (next.sh_flags & elf.SHF_TLS == 0) break; | 2939 | if (next.sh_flags & elf.SHF_TLS == 0) break; |
| 2941 | phdr.p_align = @max(phdr.p_align, next.sh_addralign); | 2940 | phdr.@"align" = @max(phdr.@"align", next.sh_addralign); |
| 2942 | if (next.sh_type != elf.SHT_NOBITS) { | 2941 | if (next.sh_type != elf.SHT_NOBITS) { |
| 2943 | phdr.p_filesz = next.sh_offset + next.sh_size - phdr.p_offset; | 2942 | phdr.filesz = next.sh_offset + next.sh_size - phdr.offset; |
| 2944 | } | 2943 | } |
| 2945 | phdr.p_memsz = next.sh_addr + next.sh_size - phdr.p_vaddr; | 2944 | phdr.memsz = next.sh_addr + next.sh_size - phdr.vaddr; |
| 2946 | } | 2945 | } |
| 2947 | } | 2946 | } |
| 2948 | } | 2947 | } |
| ... | @@ -3347,16 +3346,16 @@ pub fn archPtrWidthBytes(self: Elf) u8 { | ... | @@ -3347,16 +3346,16 @@ pub fn archPtrWidthBytes(self: Elf) u8 { |
| 3347 | return @intCast(@divExact(self.getTarget().ptrBitWidth(), 8)); | 3346 | return @intCast(@divExact(self.getTarget().ptrBitWidth(), 8)); |
| 3348 | } | 3347 | } |
| 3349 | 3348 | ||
| 3350 | fn phdrTo32(phdr: elf.Elf64_Phdr) elf.Elf32_Phdr { | 3349 | fn phdrTo32(phdr: elf.Elf64.Phdr) elf.Elf32.Phdr { |
| 3351 | return .{ | 3350 | return .{ |
| 3352 | .p_type = phdr.p_type, | 3351 | .type = phdr.type, |
| 3353 | .p_flags = phdr.p_flags, | 3352 | .flags = phdr.flags, |
| 3354 | .p_offset = @as(u32, @intCast(phdr.p_offset)), | 3353 | .offset = @intCast(phdr.offset), |
| 3355 | .p_vaddr = @as(u32, @intCast(phdr.p_vaddr)), | 3354 | .vaddr = @intCast(phdr.vaddr), |
| 3356 | .p_paddr = @as(u32, @intCast(phdr.p_paddr)), | 3355 | .paddr = @intCast(phdr.paddr), |
| 3357 | .p_filesz = @as(u32, @intCast(phdr.p_filesz)), | 3356 | .filesz = @intCast(phdr.filesz), |
| 3358 | .p_memsz = @as(u32, @intCast(phdr.p_memsz)), | 3357 | .memsz = @intCast(phdr.memsz), |
| 3359 | .p_align = @as(u32, @intCast(phdr.p_align)), | 3358 | .@"align" = @intCast(phdr.@"align"), |
| 3360 | }; | 3359 | }; |
| 3361 | } | 3360 | } |
| 3362 | 3361 | ||
| ... | @@ -3397,7 +3396,7 @@ fn getPhdr(self: *Elf, opts: struct { | ... | @@ -3397,7 +3396,7 @@ fn getPhdr(self: *Elf, opts: struct { |
| 3397 | if (self.phdr_indexes.table_load.int()) |index| { | 3396 | if (self.phdr_indexes.table_load.int()) |index| { |
| 3398 | if (phndx == index) continue; | 3397 | if (phndx == index) continue; |
| 3399 | } | 3398 | } |
| 3400 | if (phdr.p_type == opts.type and phdr.p_flags == opts.flags) | 3399 | if (@backingInt(phdr.type) == opts.type and @backingInt(phdr.flags) == opts.flags) |
| 3401 | return @fromBackingInt(@intCast(phndx)); | 3400 | return @fromBackingInt(@intCast(phndx)); |
| 3402 | } | 3401 | } |
| 3403 | return .none; | 3402 | return .none; |
| ... | @@ -3415,14 +3414,14 @@ fn addPhdr(self: *Elf, opts: struct { | ... | @@ -3415,14 +3414,14 @@ fn addPhdr(self: *Elf, opts: struct { |
| 3415 | const gpa = self.base.comp.gpa; | 3414 | const gpa = self.base.comp.gpa; |
| 3416 | const index: ProgramHeaderIndex = @fromBackingInt(@intCast(self.phdrs.items.len)); | 3415 | const index: ProgramHeaderIndex = @fromBackingInt(@intCast(self.phdrs.items.len)); |
| 3417 | try self.phdrs.append(gpa, .{ | 3416 | try self.phdrs.append(gpa, .{ |
| 3418 | .p_type = opts.type, | 3417 | .type = @fromBackingInt(opts.type), |
| 3419 | .p_flags = opts.flags, | 3418 | .flags = @fromBackingInt(opts.flags), |
| 3420 | .p_offset = opts.offset, | 3419 | .offset = opts.offset, |
| 3421 | .p_vaddr = opts.addr, | 3420 | .vaddr = opts.addr, |
| 3422 | .p_paddr = opts.addr, | 3421 | .paddr = opts.addr, |
| 3423 | .p_filesz = opts.filesz, | 3422 | .filesz = opts.filesz, |
| 3424 | .p_memsz = opts.memsz, | 3423 | .memsz = opts.memsz, |
| 3425 | .p_align = opts.@"align", | 3424 | .@"align" = opts.@"align", |
| 3426 | }); | 3425 | }); |
| 3427 | return index; | 3426 | return index; |
| 3428 | } | 3427 | } |
| ... | @@ -3673,9 +3672,9 @@ pub fn tpAddress(self: *Elf) i64 { | ... | @@ -3673,9 +3672,9 @@ pub fn tpAddress(self: *Elf) i64 { |
| 3673 | const index = self.phdr_indexes.tls.int() orelse return 0; | 3672 | const index = self.phdr_indexes.tls.int() orelse return 0; |
| 3674 | const phdr = self.phdrs.items[index]; | 3673 | const phdr = self.phdrs.items[index]; |
| 3675 | const addr = switch (self.getTarget().cpu.arch) { | 3674 | const addr = switch (self.getTarget().cpu.arch) { |
| 3676 | .x86_64 => mem.alignForward(u64, phdr.p_vaddr + phdr.p_memsz, phdr.p_align), | 3675 | .x86_64 => mem.alignForward(u64, phdr.vaddr + phdr.memsz, phdr.@"align"), |
| 3677 | .aarch64, .aarch64_be => mem.alignBackward(u64, phdr.p_vaddr - 16, phdr.p_align), | 3676 | .aarch64, .aarch64_be => mem.alignBackward(u64, phdr.vaddr - 16, phdr.@"align"), |
| 3678 | .riscv64, .riscv64be => phdr.p_vaddr, | 3677 | .riscv64, .riscv64be => phdr.vaddr, |
| 3679 | else => |arch| std.debug.panic("TODO implement getTpAddress for {s}", .{@tagName(arch)}), | 3678 | else => |arch| std.debug.panic("TODO implement getTpAddress for {s}", .{@tagName(arch)}), |
| 3680 | }; | 3679 | }; |
| 3681 | return @intCast(addr); | 3680 | return @intCast(addr); |
| ... | @@ -3684,13 +3683,13 @@ pub fn tpAddress(self: *Elf) i64 { | ... | @@ -3684,13 +3683,13 @@ pub fn tpAddress(self: *Elf) i64 { |
| 3684 | pub fn dtpAddress(self: *Elf) i64 { | 3683 | pub fn dtpAddress(self: *Elf) i64 { |
| 3685 | const index = self.phdr_indexes.tls.int() orelse return 0; | 3684 | const index = self.phdr_indexes.tls.int() orelse return 0; |
| 3686 | const phdr = self.phdrs.items[index]; | 3685 | const phdr = self.phdrs.items[index]; |
| 3687 | return @intCast(phdr.p_vaddr); | 3686 | return @intCast(phdr.vaddr); |
| 3688 | } | 3687 | } |
| 3689 | 3688 | ||
| 3690 | pub fn tlsAddress(self: *Elf) i64 { | 3689 | pub fn tlsAddress(self: *Elf) i64 { |
| 3691 | const index = self.phdr_indexes.tls.int() orelse return 0; | 3690 | const index = self.phdr_indexes.tls.int() orelse return 0; |
| 3692 | const phdr = self.phdrs.items[index]; | 3691 | const phdr = self.phdrs.items[index]; |
| 3693 | return @intCast(phdr.p_vaddr); | 3692 | return @intCast(phdr.vaddr); |
| 3694 | } | 3693 | } |
| 3695 | 3694 | ||
| 3696 | pub fn getShString(self: Elf, off: u32) [:0]const u8 { | 3695 | pub fn getShString(self: Elf, off: u32) [:0]const u8 { |
| ... | @@ -3702,7 +3701,7 @@ fn shString( | ... | @@ -3702,7 +3701,7 @@ fn shString( |
| 3702 | off: u32, | 3701 | off: u32, |
| 3703 | ) [:0]const u8 { | 3702 | ) [:0]const u8 { |
| 3704 | const slice = shstrtab[off..]; | 3703 | const slice = shstrtab[off..]; |
| 3705 | return slice[0..mem.indexOfScalar(u8, slice, 0).? :0]; | 3704 | return slice[0..mem.findScalar(u8, slice, 0).? :0]; |
| 3706 | } | 3705 | } |
| 3707 | 3706 | ||
| 3708 | pub fn insertShString(self: *Elf, name: [:0]const u8) error{OutOfMemory}!u32 { | 3707 | pub fn insertShString(self: *Elf, name: [:0]const u8) error{OutOfMemory}!u32 { |
| ... | @@ -3886,10 +3885,10 @@ fn formatShdrFlags(sh_flags: u64, writer: *std.Io.Writer) std.Io.Writer.Error!vo | ... | @@ -3886,10 +3885,10 @@ fn formatShdrFlags(sh_flags: u64, writer: *std.Io.Writer) std.Io.Writer.Error!vo |
| 3886 | 3885 | ||
| 3887 | const FormatPhdr = struct { | 3886 | const FormatPhdr = struct { |
| 3888 | elf_file: *Elf, | 3887 | elf_file: *Elf, |
| 3889 | phdr: elf.Elf64_Phdr, | 3888 | phdr: elf.Elf64.Phdr, |
| 3890 | }; | 3889 | }; |
| 3891 | 3890 | ||
| 3892 | fn fmtPhdr(self: *Elf, phdr: elf.Elf64_Phdr) std.fmt.Alt(FormatPhdr, formatPhdr) { | 3891 | fn fmtPhdr(self: *Elf, phdr: elf.Elf64.Phdr) std.fmt.Alt(FormatPhdr, formatPhdr) { |
| 3893 | return .{ .data = .{ | 3892 | return .{ .data = .{ |
| 3894 | .phdr = phdr, | 3893 | .phdr = phdr, |
| 3895 | .elf_file = self, | 3894 | .elf_file = self, |
| ... | @@ -3898,28 +3897,28 @@ fn fmtPhdr(self: *Elf, phdr: elf.Elf64_Phdr) std.fmt.Alt(FormatPhdr, formatPhdr) | ... | @@ -3898,28 +3897,28 @@ fn fmtPhdr(self: *Elf, phdr: elf.Elf64_Phdr) std.fmt.Alt(FormatPhdr, formatPhdr) |
| 3898 | 3897 | ||
| 3899 | fn formatPhdr(ctx: FormatPhdr, writer: *std.Io.Writer) std.Io.Writer.Error!void { | 3898 | fn formatPhdr(ctx: FormatPhdr, writer: *std.Io.Writer) std.Io.Writer.Error!void { |
| 3900 | const phdr = ctx.phdr; | 3899 | const phdr = ctx.phdr; |
| 3901 | const write = phdr.p_flags & elf.PF_W != 0; | 3900 | const write = phdr.flags.W; |
| 3902 | const read = phdr.p_flags & elf.PF_R != 0; | 3901 | const read = phdr.flags.R; |
| 3903 | const exec = phdr.p_flags & elf.PF_X != 0; | 3902 | const exec = phdr.flags.X; |
| 3904 | var flags: [3]u8 = @splat('_'); | 3903 | var flags: [3]u8 = @splat('_'); |
| 3905 | if (exec) flags[0] = 'X'; | 3904 | if (exec) flags[0] = 'X'; |
| 3906 | if (write) flags[1] = 'W'; | 3905 | if (write) flags[1] = 'W'; |
| 3907 | if (read) flags[2] = 'R'; | 3906 | if (read) flags[2] = 'R'; |
| 3908 | const p_type = switch (phdr.p_type) { | 3907 | const p_type = switch (phdr.type) { |
| 3909 | elf.PT_LOAD => "LOAD", | 3908 | .LOAD => "LOAD", |
| 3910 | elf.PT_TLS => "TLS", | 3909 | .TLS => "TLS", |
| 3911 | elf.PT_GNU_EH_FRAME => "GNU_EH_FRAME", | 3910 | .GNU_EH_FRAME => "GNU_EH_FRAME", |
| 3912 | elf.PT_GNU_STACK => "GNU_STACK", | 3911 | .GNU_STACK => "GNU_STACK", |
| 3913 | elf.PT_DYNAMIC => "DYNAMIC", | 3912 | .DYNAMIC => "DYNAMIC", |
| 3914 | elf.PT_INTERP => "INTERP", | 3913 | .INTERP => "INTERP", |
| 3915 | elf.PT_NULL => "NULL", | 3914 | .NULL => "NULL", |
| 3916 | elf.PT_PHDR => "PHDR", | 3915 | .PHDR => "PHDR", |
| 3917 | elf.PT_NOTE => "NOTE", | 3916 | .NOTE => "NOTE", |
| 3918 | else => "UNKNOWN", | 3917 | else => "UNKNOWN", |
| 3919 | }; | 3918 | }; |
| 3920 | try writer.print("{s} : {s} : @{x} ({x}) : align({x}) : filesz({x}) : memsz({x})", .{ | 3919 | try writer.print("{s} : {s} : @{x} ({x}) : align({x}) : filesz({x}) : memsz({x})", .{ |
| 3921 | p_type, flags, phdr.p_offset, phdr.p_vaddr, | 3920 | p_type, flags, phdr.offset, phdr.vaddr, |
| 3922 | phdr.p_align, phdr.p_filesz, phdr.p_memsz, | 3921 | phdr.@"align", phdr.filesz, phdr.memsz, |
| 3923 | }); | 3922 | }); |
| 3924 | } | 3923 | } |
| 3925 | 3924 | ||
| ... | @@ -4376,7 +4375,7 @@ fn createThunks(elf_file: *Elf, atom_list: *AtomList) !void { | ... | @@ -4376,7 +4375,7 @@ fn createThunks(elf_file: *Elf, atom_list: *AtomList) !void { |
| 4376 | 4375 | ||
| 4377 | pub fn stringTableLookup(strtab: []const u8, off: u32) [:0]const u8 { | 4376 | pub fn stringTableLookup(strtab: []const u8, off: u32) [:0]const u8 { |
| 4378 | const slice = strtab[off..]; | 4377 | const slice = strtab[off..]; |
| 4379 | return slice[0..mem.indexOfScalar(u8, slice, 0).? :0]; | 4378 | return slice[0..mem.findScalar(u8, slice, 0).? :0]; |
| 4380 | } | 4379 | } |
| 4381 | 4380 | ||
| 4382 | pub fn pwriteAll(elf_file: *Elf, bytes: []const u8, offset: u64) error{AlreadyReported}!void { | 4381 | pub fn pwriteAll(elf_file: *Elf, bytes: []const u8, offset: u64) error{AlreadyReported}!void { |
src/link/Elf/Archive.zig+1-1| ... | @@ -118,7 +118,7 @@ pub fn parse( | ... | @@ -118,7 +118,7 @@ pub fn parse( |
| 118 | 118 | ||
| 119 | pub fn stringTableLookup(strtab: []const u8, off: u32) [:'\n']const u8 { | 119 | pub fn stringTableLookup(strtab: []const u8, off: u32) [:'\n']const u8 { |
| 120 | const slice = strtab[off..]; | 120 | const slice = strtab[off..]; |
| 121 | return slice[0..mem.indexOfScalar(u8, slice, '\n').? :'\n']; | 121 | return slice[0..mem.findScalar(u8, slice, '\n').? :'\n']; |
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | pub fn setArHdr(opts: struct { | 124 | pub fn setArHdr(opts: struct { |
src/link/Elf/ZigObject.zig+4-4| ... | @@ -1299,7 +1299,7 @@ fn getNavShdrIndex( | ... | @@ -1299,7 +1299,7 @@ fn getNavShdrIndex( |
| 1299 | } | 1299 | } |
| 1300 | if (nav_val.isUndef(zcu)) | 1300 | if (nav_val.isUndef(zcu)) |
| 1301 | return switch (zcu.navFileScope(nav_index).mod.?.optimize_mode) { | 1301 | return switch (zcu.navFileScope(nav_index).mod.?.optimize_mode) { |
| 1302 | .Debug, .ReleaseSafe => { | 1302 | .debug, .safe => { |
| 1303 | if (self.data_index) |symbol_index| | 1303 | if (self.data_index) |symbol_index| |
| 1304 | return self.symbol(symbol_index).outputShndx(elf_file).?; | 1304 | return self.symbol(symbol_index).outputShndx(elf_file).?; |
| 1305 | const osec = try elf_file.addSection(.{ | 1305 | const osec = try elf_file.addSection(.{ |
| ... | @@ -1311,7 +1311,7 @@ fn getNavShdrIndex( | ... | @@ -1311,7 +1311,7 @@ fn getNavShdrIndex( |
| 1311 | self.data_index = try self.addSectionSymbol(gpa, try self.addString(gpa, ".data"), osec); | 1311 | self.data_index = try self.addSectionSymbol(gpa, try self.addString(gpa, ".data"), osec); |
| 1312 | return osec; | 1312 | return osec; |
| 1313 | }, | 1313 | }, |
| 1314 | .ReleaseFast, .ReleaseSmall => { | 1314 | .fast, .small => { |
| 1315 | if (self.bss_index) |symbol_index| | 1315 | if (self.bss_index) |symbol_index| |
| 1316 | return self.symbol(symbol_index).outputShndx(elf_file).?; | 1316 | return self.symbol(symbol_index).outputShndx(elf_file).?; |
| 1317 | const osec = try elf_file.addSection(.{ | 1317 | const osec = try elf_file.addSection(.{ |
| ... | @@ -1374,8 +1374,8 @@ fn updateNavCode( | ... | @@ -1374,8 +1374,8 @@ fn updateNavCode( |
| 1374 | const target = &mod.resolved_target.result; | 1374 | const target = &mod.resolved_target.result; |
| 1375 | const required_alignment = switch (nav.resolved.?.@"align") { | 1375 | const required_alignment = switch (nav.resolved.?.@"align") { |
| 1376 | .none => switch (mod.optimize_mode) { | 1376 | .none => switch (mod.optimize_mode) { |
| 1377 | .Debug, .ReleaseSafe, .ReleaseFast => target_util.defaultFunctionAlignment(target), | 1377 | .debug, .safe, .fast => target_util.defaultFunctionAlignment(target), |
| 1378 | .ReleaseSmall => target_util.minFunctionAlignment(target), | 1378 | .small => target_util.minFunctionAlignment(target), |
| 1379 | }.maxStrict(Type.fromInterned(nav.resolved.?.type).abiAlignment(zcu)), | 1379 | }.maxStrict(Type.fromInterned(nav.resolved.?.type).abiAlignment(zcu)), |
| 1380 | else => |a| a.maxStrict(target_util.minFunctionAlignment(target)), | 1380 | else => |a| a.maxStrict(target_util.minFunctionAlignment(target)), |
| 1381 | }; | 1381 | }; |
src/link/Elf2.zig+464-218| ... | @@ -126,8 +126,14 @@ needed: std.array_hash_map.Auto(String(.dynstr), void), | ... | @@ -126,8 +126,14 @@ needed: std.array_hash_map.Auto(String(.dynstr), void), |
| 126 | inputs: std.ArrayList(struct { | 126 | inputs: std.ArrayList(struct { |
| 127 | path: std.Build.Cache.Path, | 127 | path: std.Build.Cache.Path, |
| 128 | member: ?[]const u8, | 128 | member: ?[]const u8, |
| 129 | file_symbol: Symbol.LocalIndex, | 129 | extra: union { |
| 130 | /// Active for static libraries. | ||
| 131 | node: MappedFile.Node.Index, | ||
| 132 | /// Active otherwise. | ||
| 133 | file_symbol: Symbol.LocalIndex, | ||
| 134 | }, | ||
| 130 | }), | 135 | }), |
| 136 | input_pending_index: u32, | ||
| 131 | input_sections: std.ArrayList(InputSection), | 137 | input_sections: std.ArrayList(InputSection), |
| 132 | input_section_pending_index: u32, | 138 | input_section_pending_index: u32, |
| 133 | navs: std.array_hash_map.Auto(InternPool.Nav.Index, struct { | 139 | navs: std.array_hash_map.Auto(InternPool.Nav.Index, struct { |
| ... | @@ -181,7 +187,10 @@ input_prog_node: std.Progress.Node, | ... | @@ -181,7 +187,10 @@ input_prog_node: std.Progress.Node, |
| 181 | const Error = link.Error || error{MappedFileIo}; | 187 | const Error = link.Error || error{MappedFileIo}; |
| 182 | 188 | ||
| 183 | const Node = union(enum) { | 189 | const Node = union(enum) { |
| 184 | file, | 190 | archive, |
| 191 | /// This includes the archive magic and long file member. | ||
| 192 | archive_header, | ||
| 193 | elf, | ||
| 185 | ehdr, | 194 | ehdr, |
| 186 | shdr, | 195 | shdr, |
| 187 | segment: u32, | 196 | segment: u32, |
| ... | @@ -189,6 +198,8 @@ const Node = union(enum) { | ... | @@ -189,6 +198,8 @@ const Node = union(enum) { |
| 189 | /// | 198 | /// |
| 190 | /// The section '.dynamic' may contain relocations via `elf.dynamic_first_symbol_reloc`. | 199 | /// The section '.dynamic' may contain relocations via `elf.dynamic_first_symbol_reloc`. |
| 191 | section: Section.Index, | 200 | section: Section.Index, |
| 201 | /// Only valid for static libraries, represents one non-zcu archive member. | ||
| 202 | input_member: InputIndex, | ||
| 192 | /// May contain relocations. | 203 | /// May contain relocations. |
| 193 | input_section: InputSection.Index, | 204 | input_section: InputSection.Index, |
| 194 | /// Value is the name of a global which has an entry in `elf.copied_globals`, so, a global for | 205 | /// Value is the name of a global which has an entry in `elf.copied_globals`, so, a global for |
| ... | @@ -219,19 +230,23 @@ const Node = union(enum) { | ... | @@ -219,19 +230,23 @@ const Node = union(enum) { |
| 219 | return elf.inputs.items[@backingInt(ii)].member; | 230 | return elf.inputs.items[@backingInt(ii)].member; |
| 220 | } | 231 | } |
| 221 | 232 | ||
| 233 | pub fn node(ii: InputIndex, elf: *const Elf) MappedFile.Node.Index { | ||
| 234 | return elf.inputs.items[@backingInt(ii)].extra.node; | ||
| 235 | } | ||
| 236 | |||
| 222 | pub fn fileSymbol(ii: InputIndex, elf: *const Elf) Symbol.LocalIndex { | 237 | pub fn fileSymbol(ii: InputIndex, elf: *const Elf) Symbol.LocalIndex { |
| 223 | return elf.inputs.items[@backingInt(ii)].file_symbol; | 238 | return elf.inputs.items[@backingInt(ii)].extra.file_symbol; |
| 224 | } | 239 | } |
| 225 | 240 | ||
| 226 | pub fn localSymbolRange(ii: InputIndex, elf: *Elf) [2]Symbol.LocalIndex { | 241 | pub fn localSymbolRange(ii: InputIndex, elf: *Elf) [2]Symbol.LocalIndex { |
| 227 | if (@backingInt(ii) + 1 < elf.inputs.items.len) { | 242 | if (@backingInt(ii) + 1 < elf.inputs.items.len) { |
| 228 | const next_ii: InputIndex = @fromBackingInt(@intCast(@backingInt(ii) + 1)); | 243 | const next_ii: InputIndex = @fromBackingInt(@backingInt(ii) + 1); |
| 229 | return .{ ii.fileSymbol(elf), next_ii.fileSymbol(elf) }; | 244 | return .{ ii.fileSymbol(elf), next_ii.fileSymbol(elf) }; |
| 230 | } else { | 245 | } else { |
| 231 | const local_symbols_len = switch (elf.shdrPtr(.symtab)) { | 246 | const local_symbols_len = switch (elf.shdrPtr(.symtab)) { |
| 232 | inline else => |shdr| elf.targetLoad(&shdr.info), | 247 | inline else => |shdr| elf.targetLoad(&shdr.info), |
| 233 | }; | 248 | }; |
| 234 | return .{ ii.fileSymbol(elf), @fromBackingInt(@intCast(local_symbols_len)) }; | 249 | return .{ ii.fileSymbol(elf), @fromBackingInt(local_symbols_len) }; |
| 235 | } | 250 | } |
| 236 | } | 251 | } |
| 237 | }; | 252 | }; |
| ... | @@ -315,15 +330,16 @@ const Node = union(enum) { | ... | @@ -315,15 +330,16 @@ const Node = union(enum) { |
| 315 | }; | 330 | }; |
| 316 | 331 | ||
| 317 | pub const Known = struct { | 332 | pub const Known = struct { |
| 318 | comptime file: MappedFile.Node.Index = .root, | 333 | archive: MappedFile.Node.Index, |
| 319 | comptime ehdr: MappedFile.Node.Index = @fromBackingInt(@intCast(1)), | 334 | archive_header: MappedFile.Node.Index, |
| 320 | comptime shdr: MappedFile.Node.Index = @fromBackingInt(@intCast(2)), | 335 | elf: MappedFile.Node.Index, |
| 321 | comptime rodata: MappedFile.Node.Index = @fromBackingInt(@intCast(3)), | 336 | ehdr: MappedFile.Node.Index, |
| 322 | comptime phdr: MappedFile.Node.Index = @fromBackingInt(@intCast(4)), | 337 | shdr: MappedFile.Node.Index, |
| 323 | comptime text: MappedFile.Node.Index = @fromBackingInt(@intCast(5)), | 338 | rodata: MappedFile.Node.Index, |
| 324 | comptime data: MappedFile.Node.Index = @fromBackingInt(@intCast(6)), | 339 | phdr: MappedFile.Node.Index, |
| 325 | comptime data_rel_ro: MappedFile.Node.Index = @fromBackingInt(@intCast(7)), | 340 | text: MappedFile.Node.Index, |
| 326 | 341 | data: MappedFile.Node.Index, | |
| 342 | data_rel_ro: MappedFile.Node.Index, | ||
| 327 | tls: MappedFile.Node.Index, | 343 | tls: MappedFile.Node.Index, |
| 328 | }; | 344 | }; |
| 329 | 345 | ||
| ... | @@ -333,11 +349,11 @@ const Node = union(enum) { | ... | @@ -333,11 +349,11 @@ const Node = union(enum) { |
| 333 | 349 | ||
| 334 | /// In this linker implementation, `link.File.AtomId` is a type-erased `MappedFile.Node.Index`. | 350 | /// In this linker implementation, `link.File.AtomId` is a type-erased `MappedFile.Node.Index`. |
| 335 | fn toAtom(ni: MappedFile.Node.Index) link.File.AtomId { | 351 | fn toAtom(ni: MappedFile.Node.Index) link.File.AtomId { |
| 336 | return @fromBackingInt(@intCast(@backingInt(ni))); | 352 | return @fromBackingInt(@backingInt(ni)); |
| 337 | } | 353 | } |
| 338 | /// In this linker implementation, `link.File.AtomId` is a type-erased `MappedFile.Node.Index`. | 354 | /// In this linker implementation, `link.File.AtomId` is a type-erased `MappedFile.Node.Index`. |
| 339 | fn fromAtom(atom: link.File.AtomId) MappedFile.Node.Index { | 355 | fn fromAtom(atom: link.File.AtomId) MappedFile.Node.Index { |
| 340 | return @fromBackingInt(@intCast(@backingInt(atom))); | 356 | return @fromBackingInt(@backingInt(atom)); |
| 341 | } | 357 | } |
| 342 | }; | 358 | }; |
| 343 | 359 | ||
| ... | @@ -424,13 +440,13 @@ const Section = struct { | ... | @@ -424,13 +440,13 @@ const Section = struct { |
| 424 | fn unwrap(opt: RelaIndex.Optional) ?RelaIndex { | 440 | fn unwrap(opt: RelaIndex.Optional) ?RelaIndex { |
| 425 | return switch (opt) { | 441 | return switch (opt) { |
| 426 | .none => null, | 442 | .none => null, |
| 427 | _ => @fromBackingInt(@intCast(@backingInt(opt))), | 443 | _ => @fromBackingInt(@backingInt(opt)), |
| 428 | }; | 444 | }; |
| 429 | } | 445 | } |
| 430 | }; | 446 | }; |
| 431 | 447 | ||
| 432 | fn toOptional(i: RelaIndex) RelaIndex.Optional { | 448 | fn toOptional(i: RelaIndex) RelaIndex.Optional { |
| 433 | return @fromBackingInt(@intCast(@backingInt(i))); | 449 | return @fromBackingInt(@backingInt(i)); |
| 434 | } | 450 | } |
| 435 | }; | 451 | }; |
| 436 | 452 | ||
| ... | @@ -465,8 +481,8 @@ const Section = struct { | ... | @@ -465,8 +481,8 @@ const Section = struct { |
| 465 | 481 | ||
| 466 | pub fn fromSection(sec: std.elf.Section) Index { | 482 | pub fn fromSection(sec: std.elf.Section) Index { |
| 467 | return switch (sec) { | 483 | return switch (sec) { |
| 468 | std.elf.SHN_UNDEF...std.elf.SHN_LORESERVE - 1 => @fromBackingInt(@intCast(sec)), | 484 | std.elf.SHN_UNDEF...std.elf.SHN_LORESERVE - 1 => @fromBackingInt(sec), |
| 469 | std.elf.SHN_LORESERVE...std.elf.SHN_HIRESERVE => @fromBackingInt(@intCast(reserve(sec))), | 485 | std.elf.SHN_LORESERVE...std.elf.SHN_HIRESERVE => @fromBackingInt(reserve(sec)), |
| 470 | }; | 486 | }; |
| 471 | } | 487 | } |
| 472 | pub fn toSection(s: Index) ?std.elf.Section { | 488 | pub fn toSection(s: Index) ?std.elf.Section { |
| ... | @@ -485,7 +501,7 @@ const Section = struct { | ... | @@ -485,7 +501,7 @@ const Section = struct { |
| 485 | 501 | ||
| 486 | fn name(s: Index, elf: *Elf) String(.shstrtab) { | 502 | fn name(s: Index, elf: *Elf) String(.shstrtab) { |
| 487 | return switch (elf.shdrPtr(s)) { | 503 | return switch (elf.shdrPtr(s)) { |
| 488 | inline else => |shdr| @fromBackingInt(@intCast(elf.targetLoad(&shdr.name))), | 504 | inline else => |shdr| @fromBackingInt(elf.targetLoad(&shdr.name)), |
| 489 | }; | 505 | }; |
| 490 | } | 506 | } |
| 491 | 507 | ||
| ... | @@ -928,21 +944,7 @@ const GotReloc = struct { | ... | @@ -928,21 +944,7 @@ const GotReloc = struct { |
| 928 | } | 944 | } |
| 929 | } | 945 | } |
| 930 | fn applyInner(reloc: *const GotReloc, elf: *Elf) error{ RelocationOverflow, RelocationMisaligned }!void { | 946 | fn applyInner(reloc: *const GotReloc, elf: *Elf) error{ RelocationOverflow, RelocationMisaligned }!void { |
| 931 | const node_vaddr: u64 = switch (elf.getNode(reloc.node)) { | 947 | const dest_vaddr = elf.getNodeVAddr(reloc.node) + reloc.offset; |
| 932 | .file => unreachable, | ||
| 933 | .ehdr => unreachable, | ||
| 934 | .shdr => unreachable, | ||
| 935 | .segment => unreachable, | ||
| 936 | .copied_global => unreachable, | ||
| 937 | .section => |shndx| shndx.vaddr(elf), | ||
| 938 | .input_section => |isi| isi.ptrConst(elf).vaddr, | ||
| 939 | inline .nav, | ||
| 940 | .uav, | ||
| 941 | .lazy_code, | ||
| 942 | .lazy_const_data, | ||
| 943 | => |i| Symbol.Id.local(i.symbol(elf)).value(elf), | ||
| 944 | }; | ||
| 945 | const dest_vaddr = node_vaddr + reloc.offset; | ||
| 946 | const dest_slice = reloc.node.slice(&elf.mf)[@intCast(reloc.offset)..]; | 948 | const dest_slice = reloc.node.slice(&elf.mf)[@intCast(reloc.offset)..]; |
| 947 | 949 | ||
| 948 | const got_vaddr = elf.shndx.got.vaddr(elf); | 950 | const got_vaddr = elf.shndx.got.vaddr(elf); |
| ... | @@ -1131,12 +1133,12 @@ pub const MachineRelocType = union { | ... | @@ -1131,12 +1133,12 @@ pub const MachineRelocType = union { |
| 1131 | 1133 | ||
| 1132 | pub fn wrap(int: u32, elf: *const Elf) MachineRelocType { | 1134 | pub fn wrap(int: u32, elf: *const Elf) MachineRelocType { |
| 1133 | return switch (elf.ehdrMachine()) { | 1135 | return switch (elf.ehdrMachine()) { |
| 1134 | .AARCH64 => .{ .AARCH64 = @fromBackingInt(@intCast(int)) }, | 1136 | .AARCH64 => .{ .AARCH64 = @fromBackingInt(int) }, |
| 1135 | .LOONGARCH => .{ .LARCH = @fromBackingInt(@intCast(int)) }, | 1137 | .LOONGARCH => .{ .LARCH = @fromBackingInt(int) }, |
| 1136 | .PPC64 => .{ .PPC64 = @fromBackingInt(@intCast(int)) }, | 1138 | .PPC64 => .{ .PPC64 = @fromBackingInt(int) }, |
| 1137 | .RISCV => .{ .RISCV = @fromBackingInt(@intCast(int)) }, | 1139 | .RISCV => .{ .RISCV = @fromBackingInt(int) }, |
| 1138 | .SPARCV9 => .{ .SPARC = @fromBackingInt(@intCast(int)) }, | 1140 | .SPARCV9 => .{ .SPARC = @fromBackingInt(int) }, |
| 1139 | .X86_64 => .{ .X86_64 = @fromBackingInt(@intCast(int)) }, | 1141 | .X86_64 => .{ .X86_64 = @fromBackingInt(int) }, |
| 1140 | }; | 1142 | }; |
| 1141 | } | 1143 | } |
| 1142 | pub fn unwrap(rt: MachineRelocType, elf: *const Elf) u32 { | 1144 | pub fn unwrap(rt: MachineRelocType, elf: *const Elf) u32 { |
| ... | @@ -1646,21 +1648,7 @@ const SymbolReloc = struct { | ... | @@ -1646,21 +1648,7 @@ const SymbolReloc = struct { |
| 1646 | } | 1648 | } |
| 1647 | } | 1649 | } |
| 1648 | fn applyInner(reloc: *const SymbolReloc, elf: *Elf) error{ RelocationOverflow, RelocationMisaligned }!void { | 1650 | fn applyInner(reloc: *const SymbolReloc, elf: *Elf) error{ RelocationOverflow, RelocationMisaligned }!void { |
| 1649 | const node_vaddr: u64 = switch (elf.getNode(reloc.node)) { | 1651 | const dest_vaddr = elf.getNodeVAddr(reloc.node) + reloc.offset; |
| 1650 | .file => unreachable, | ||
| 1651 | .ehdr => unreachable, | ||
| 1652 | .shdr => unreachable, | ||
| 1653 | .segment => unreachable, | ||
| 1654 | .copied_global => unreachable, | ||
| 1655 | .section => |shndx| shndx.vaddr(elf), | ||
| 1656 | .input_section => |isi| isi.ptrConst(elf).vaddr, | ||
| 1657 | inline .nav, | ||
| 1658 | .uav, | ||
| 1659 | .lazy_code, | ||
| 1660 | .lazy_const_data, | ||
| 1661 | => |i| Symbol.Id.local(i.symbol(elf)).value(elf), | ||
| 1662 | }; | ||
| 1663 | const dest_vaddr = node_vaddr + reloc.offset; | ||
| 1664 | const dest_slice = reloc.node.slice(&elf.mf)[@intCast(reloc.offset)..]; | 1652 | const dest_slice = reloc.node.slice(&elf.mf)[@intCast(reloc.offset)..]; |
| 1665 | 1653 | ||
| 1666 | const addend: u64 = @bitCast(reloc.addend); | 1654 | const addend: u64 = @bitCast(reloc.addend); |
| ... | @@ -1875,7 +1863,7 @@ fn addLocalSymbolAssumeCapacity(elf: *Elf, opts: AddLocalSymbolOptions) Symbol.L | ... | @@ -1875,7 +1863,7 @@ fn addLocalSymbolAssumeCapacity(elf: *Elf, opts: AddLocalSymbolOptions) Symbol.L |
| 1875 | 1863 | ||
| 1876 | // `shdr.info` stores the index of the first global symbol. We will replace it with our | 1864 | // `shdr.info` stores the index of the first global symbol. We will replace it with our |
| 1877 | // new local symbol, and move the global symbol to a new index at the end of the symtab. | 1865 | // new local symbol, and move the global symbol to a new index at the end of the symtab. |
| 1878 | const target_index: Symbol.Index = @fromBackingInt(@intCast(elf.targetLoad(&shdr.info))); | 1866 | const target_index: Symbol.Index = @fromBackingInt(elf.targetLoad(&shdr.info)); |
| 1879 | 1867 | ||
| 1880 | const old_size = elf.targetLoad(&shdr.size); | 1868 | const old_size = elf.targetLoad(&shdr.size); |
| 1881 | const new_size = old_size + ent_size; | 1869 | const new_size = old_size + ent_size; |
| ... | @@ -1897,7 +1885,7 @@ fn addLocalSymbolAssumeCapacity(elf: *Elf, opts: AddLocalSymbolOptions) Symbol.L | ... | @@ -1897,7 +1885,7 @@ fn addLocalSymbolAssumeCapacity(elf: *Elf, opts: AddLocalSymbolOptions) Symbol.L |
| 1897 | // ...then the `elf.symtab` metadata... | 1885 | // ...then the `elf.symtab` metadata... |
| 1898 | new_index.ptr(elf).* = target_index.ptr(elf).*; | 1886 | new_index.ptr(elf).* = target_index.ptr(elf).*; |
| 1899 | // ...then update the `elf.globals` tracking. | 1887 | // ...then update the `elf.globals` tracking. |
| 1900 | const global_name: String(.strtab) = @fromBackingInt(@intCast(elf.targetLoad(&new_sym.name))); | 1888 | const global_name: String(.strtab) = @fromBackingInt(elf.targetLoad(&new_sym.name)); |
| 1901 | elf.globalByName(global_name).?.symtab_index = new_index; | 1889 | elf.globalByName(global_name).?.symtab_index = new_index; |
| 1902 | 1890 | ||
| 1903 | if (elf.ehdrType() == .REL and target_index.ptr(elf).first_target_reloc != .none) { | 1891 | if (elf.ehdrType() == .REL and target_index.ptr(elf).first_target_reloc != .none) { |
| ... | @@ -1923,7 +1911,7 @@ fn addLocalSymbolAssumeCapacity(elf: *Elf, opts: AddLocalSymbolOptions) Symbol.L | ... | @@ -1923,7 +1911,7 @@ fn addLocalSymbolAssumeCapacity(elf: *Elf, opts: AddLocalSymbolOptions) Symbol.L |
| 1923 | std.mem.byteSwapAllFields(class.ElfN().Sym, target_sym); | 1911 | std.mem.byteSwapAllFields(class.ElfN().Sym, target_sym); |
| 1924 | } | 1912 | } |
| 1925 | 1913 | ||
| 1926 | return @fromBackingInt(@intCast(@backingInt(target_index))); | 1914 | return @fromBackingInt(@backingInt(target_index)); |
| 1927 | }, | 1915 | }, |
| 1928 | } | 1916 | } |
| 1929 | } | 1917 | } |
| ... | @@ -2371,7 +2359,7 @@ fn moveDemotedGlobal(elf: *Elf, global_ptr: *Symbol.Global) void { | ... | @@ -2371,7 +2359,7 @@ fn moveDemotedGlobal(elf: *Elf, global_ptr: *Symbol.Global) void { |
| 2371 | inline else => |shdr, class| { | 2359 | inline else => |shdr, class| { |
| 2372 | // `shdr.info` stores the index of the first global symbol. We are going to swap the | 2360 | // `shdr.info` stores the index of the first global symbol. We are going to swap the |
| 2373 | // demoted symbol with that first global symbol, then increment that start index. | 2361 | // demoted symbol with that first global symbol, then increment that start index. |
| 2374 | const dest_index: Symbol.Index = @fromBackingInt(@intCast(elf.targetLoad(&shdr.info))); | 2362 | const dest_index: Symbol.Index = @fromBackingInt(elf.targetLoad(&shdr.info)); |
| 2375 | const src_index = global_ptr.symtab_index; | 2363 | const src_index = global_ptr.symtab_index; |
| 2376 | 2364 | ||
| 2377 | // This global should currently be in the "global symbols" part of the symtab, since our | 2365 | // This global should currently be in the "global symbols" part of the symtab, since our |
| ... | @@ -2387,10 +2375,10 @@ fn moveDemotedGlobal(elf: *Elf, global_ptr: *Symbol.Global) void { | ... | @@ -2387,10 +2375,10 @@ fn moveDemotedGlobal(elf: *Elf, global_ptr: *Symbol.Global) void { |
| 2387 | const src_sym_ptr = @field(elf.symPtr(src_index), @tagName(class)); | 2375 | const src_sym_ptr = @field(elf.symPtr(src_index), @tagName(class)); |
| 2388 | const dest_sym_ptr = @field(elf.symPtr(dest_index), @tagName(class)); | 2376 | const dest_sym_ptr = @field(elf.symPtr(dest_index), @tagName(class)); |
| 2389 | 2377 | ||
| 2390 | const this_name: String(.strtab) = @fromBackingInt(@intCast(elf.targetLoad(&src_sym_ptr.name))); | 2378 | const this_name: String(.strtab) = @fromBackingInt(elf.targetLoad(&src_sym_ptr.name)); |
| 2391 | assert(elf.globalByName(this_name).? == global_ptr); | 2379 | assert(elf.globalByName(this_name).? == global_ptr); |
| 2392 | 2380 | ||
| 2393 | const other_name: String(.strtab) = @fromBackingInt(@intCast(elf.targetLoad(&dest_sym_ptr.name))); | 2381 | const other_name: String(.strtab) = @fromBackingInt(elf.targetLoad(&dest_sym_ptr.name)); |
| 2394 | const other_global_ptr = elf.globalByName(other_name).?; | 2382 | const other_global_ptr = elf.globalByName(other_name).?; |
| 2395 | assert(other_global_ptr.symtab_index == dest_index); | 2383 | assert(other_global_ptr.symtab_index == dest_index); |
| 2396 | 2384 | ||
| ... | @@ -2426,7 +2414,7 @@ fn moveDemotedGlobal(elf: *Elf, global_ptr: *Symbol.Global) void { | ... | @@ -2426,7 +2414,7 @@ fn moveDemotedGlobal(elf: *Elf, global_ptr: *Symbol.Global) void { |
| 2426 | const src_dynsym_ptr = @field(elf.dynsymPtr(remove_dynsym_index), @tagName(class)); | 2414 | const src_dynsym_ptr = @field(elf.dynsymPtr(remove_dynsym_index), @tagName(class)); |
| 2427 | const dest_dynsym_ptr = @field(elf.dynsymPtr(free_dynsym_index), @tagName(class)); | 2415 | const dest_dynsym_ptr = @field(elf.dynsymPtr(free_dynsym_index), @tagName(class)); |
| 2428 | 2416 | ||
| 2429 | const moved_name_dynstr: String(.dynstr) = @fromBackingInt(@intCast(elf.targetLoad(&src_dynsym_ptr.name))); | 2417 | const moved_name_dynstr: String(.dynstr) = @fromBackingInt(elf.targetLoad(&src_dynsym_ptr.name)); |
| 2430 | const moved_name = elf.stringExisting(.strtab, moved_name_dynstr.slice(elf)); | 2418 | const moved_name = elf.stringExisting(.strtab, moved_name_dynstr.slice(elf)); |
| 2431 | const moved_global_ptr = elf.globalByName(moved_name).?; | 2419 | const moved_global_ptr = elf.globalByName(moved_name).?; |
| 2432 | 2420 | ||
| ... | @@ -2505,7 +2493,7 @@ const Symbol = struct { | ... | @@ -2505,7 +2493,7 @@ const Symbol = struct { |
| 2505 | _, | 2493 | _, |
| 2506 | 2494 | ||
| 2507 | fn index(li: LocalIndex) Index { | 2495 | fn index(li: LocalIndex) Index { |
| 2508 | return @fromBackingInt(@intCast(@backingInt(li))); | 2496 | return @fromBackingInt(@backingInt(li)); |
| 2509 | } | 2497 | } |
| 2510 | }; | 2498 | }; |
| 2511 | 2499 | ||
| ... | @@ -2527,16 +2515,16 @@ const Symbol = struct { | ... | @@ -2527,16 +2515,16 @@ const Symbol = struct { |
| 2527 | global: String(.strtab), | 2515 | global: String(.strtab), |
| 2528 | } { | 2516 | } { |
| 2529 | return switch (s.kind) { | 2517 | return switch (s.kind) { |
| 2530 | .local => .{ .local = @fromBackingInt(@intCast(s.raw)) }, | 2518 | .local => .{ .local = @fromBackingInt(s.raw) }, |
| 2531 | .global => .{ .global = @fromBackingInt(@intCast(s.raw)) }, | 2519 | .global => .{ .global = @fromBackingInt(s.raw) }, |
| 2532 | }; | 2520 | }; |
| 2533 | } | 2521 | } |
| 2534 | 2522 | ||
| 2535 | fn toTypeErased(s: Symbol.Id) link.File.SymbolId { | 2523 | fn toTypeErased(s: Symbol.Id) link.File.SymbolId { |
| 2536 | return @fromBackingInt(@intCast(@as(u32, @bitCast(s)))); | 2524 | return @bitCast(s); |
| 2537 | } | 2525 | } |
| 2538 | fn fromTypeErased(s: link.File.SymbolId) Symbol.Id { | 2526 | fn fromTypeErased(s: link.File.SymbolId) Symbol.Id { |
| 2539 | return @bitCast(@backingInt(s)); | 2527 | return @bitCast(s); |
| 2540 | } | 2528 | } |
| 2541 | 2529 | ||
| 2542 | fn index(s: Symbol.Id, elf: *const Elf) Symbol.Index { | 2530 | fn index(s: Symbol.Id, elf: *const Elf) Symbol.Index { |
| ... | @@ -2648,24 +2636,10 @@ const Symbol = struct { | ... | @@ -2648,24 +2636,10 @@ const Symbol = struct { |
| 2648 | .yes_textrel => elf.textrel_count += 1, | 2636 | .yes_textrel => elf.textrel_count += 1, |
| 2649 | .yes => {}, | 2637 | .yes => {}, |
| 2650 | } | 2638 | } |
| 2651 | const node_vaddr: u64 = switch (elf.getNode(reloc.node)) { | ||
| 2652 | .file => unreachable, | ||
| 2653 | .ehdr => unreachable, | ||
| 2654 | .shdr => unreachable, | ||
| 2655 | .segment => unreachable, | ||
| 2656 | .copied_global => unreachable, | ||
| 2657 | .section => |shndx| shndx.vaddr(elf), | ||
| 2658 | .input_section => |isi| isi.ptrConst(elf).vaddr, | ||
| 2659 | inline .nav, | ||
| 2660 | .uav, | ||
| 2661 | .lazy_code, | ||
| 2662 | .lazy_const_data, | ||
| 2663 | => |i| Symbol.Id.local(i.symbol(elf)).value(elf), | ||
| 2664 | }; | ||
| 2665 | // There is capacity for a relocation because we just deleted one earlier. | 2639 | // There is capacity for a relocation because we just deleted one earlier. |
| 2666 | reloc.rela_index = elf.shndx.rela_dyn.relaAddOneAssumeCapacity(elf, .{ | 2640 | reloc.rela_index = elf.shndx.rela_dyn.relaAddOneAssumeCapacity(elf, .{ |
| 2667 | .type = .relative(elf), | 2641 | .type = .relative(elf), |
| 2668 | .offset = node_vaddr + reloc.offset, | 2642 | .offset = elf.getNodeVAddr(reloc.node) + reloc.offset, |
| 2669 | .raw_sym_index = 0, | 2643 | .raw_sym_index = 0, |
| 2670 | .addend = 0, | 2644 | .addend = 0, |
| 2671 | }).toOptional(); | 2645 | }).toOptional(); |
| ... | @@ -2771,11 +2745,14 @@ fn classifySymbolValue(elf: *Elf, sym: Symbol.Id) enum { | ... | @@ -2771,11 +2745,14 @@ fn classifySymbolValue(elf: *Elf, sym: Symbol.Id) enum { |
| 2771 | 2745 | ||
| 2772 | pub fn symbolForAtom(elf: *Elf, atom: link.File.AtomId) link.File.SymbolId { | 2746 | pub fn symbolForAtom(elf: *Elf, atom: link.File.AtomId) link.File.SymbolId { |
| 2773 | const lsi: Symbol.LocalIndex = switch (elf.getNode(Node.fromAtom(atom))) { | 2747 | const lsi: Symbol.LocalIndex = switch (elf.getNode(Node.fromAtom(atom))) { |
| 2774 | .file, | 2748 | .archive, |
| 2749 | .archive_header, | ||
| 2750 | .elf, | ||
| 2775 | .ehdr, | 2751 | .ehdr, |
| 2776 | .shdr, | 2752 | .shdr, |
| 2777 | .segment, | 2753 | .segment, |
| 2778 | .section, | 2754 | .section, |
| 2755 | .input_member, | ||
| 2779 | .input_section, | 2756 | .input_section, |
| 2780 | .copied_global, | 2757 | .copied_global, |
| 2781 | => unreachable, | 2758 | => unreachable, |
| ... | @@ -3001,12 +2978,12 @@ fn String(section: StringSection) type { | ... | @@ -3001,12 +2978,12 @@ fn String(section: StringSection) type { |
| 3001 | } | 2978 | } |
| 3002 | fn string(elf: *Elf, comptime section: StringSection, key: []const u8) Error!String(section) { | 2979 | fn string(elf: *Elf, comptime section: StringSection, key: []const u8) Error!String(section) { |
| 3003 | const st: *StringTable = &@field(elf, @tagName(section)); | 2980 | const st: *StringTable = &@field(elf, @tagName(section)); |
| 3004 | return @fromBackingInt(@intCast(try st.get(elf, section.shndx(elf), key))); | 2981 | return @fromBackingInt(try st.get(elf, section.shndx(elf), key)); |
| 3005 | } | 2982 | } |
| 3006 | /// Like `string`, but asserts that the string is already in `section`. | 2983 | /// Like `string`, but asserts that the string is already in `section`. |
| 3007 | fn stringExisting(elf: *Elf, comptime section: StringSection, key: []const u8) String(section) { | 2984 | fn stringExisting(elf: *Elf, comptime section: StringSection, key: []const u8) String(section) { |
| 3008 | const st: *StringTable = &@field(elf, @tagName(section)); | 2985 | const st: *StringTable = &@field(elf, @tagName(section)); |
| 3009 | return @fromBackingInt(@intCast(st.getExisting(elf, section.shndx(elf), key))); | 2986 | return @fromBackingInt(st.getExisting(elf, section.shndx(elf), key)); |
| 3010 | } | 2987 | } |
| 3011 | 2988 | ||
| 3012 | const StringTable = struct { | 2989 | const StringTable = struct { |
| ... | @@ -3033,7 +3010,7 @@ const StringTable = struct { | ... | @@ -3033,7 +3010,7 @@ const StringTable = struct { |
| 3033 | } | 3010 | } |
| 3034 | 3011 | ||
| 3035 | pub fn hash(_: Adapter, key: []const u8) u64 { | 3012 | pub fn hash(_: Adapter, key: []const u8) u64 { |
| 3036 | assert(std.mem.indexOfScalar(u8, key, 0) == null); | 3013 | assert(std.mem.findScalar(u8, key, 0) == null); |
| 3037 | return std.hash_map.hashString(key); | 3014 | return std.hash_map.hashString(key); |
| 3038 | } | 3015 | } |
| 3039 | }; | 3016 | }; |
| ... | @@ -3172,6 +3149,16 @@ fn create( | ... | @@ -3172,6 +3149,16 @@ fn create( |
| 3172 | .options = options, | 3149 | .options = options, |
| 3173 | .mf = try .init(file, comp.gpa, io), | 3150 | .mf = try .init(file, comp.gpa, io), |
| 3174 | .ni = .{ | 3151 | .ni = .{ |
| 3152 | .archive = .root, | ||
| 3153 | .archive_header = .none, | ||
| 3154 | .elf = .root, | ||
| 3155 | .ehdr = .none, | ||
| 3156 | .shdr = .none, | ||
| 3157 | .rodata = .none, | ||
| 3158 | .phdr = .none, | ||
| 3159 | .text = .none, | ||
| 3160 | .data = .none, | ||
| 3161 | .data_rel_ro = .none, | ||
| 3175 | .tls = .none, | 3162 | .tls = .none, |
| 3176 | }, | 3163 | }, |
| 3177 | .nodes = .empty, | 3164 | .nodes = .empty, |
| ... | @@ -3218,6 +3205,7 @@ fn create( | ... | @@ -3218,6 +3205,7 @@ fn create( |
| 3218 | .dynamic_first_symbol_reloc = .none, | 3205 | .dynamic_first_symbol_reloc = .none, |
| 3219 | .needed = .empty, | 3206 | .needed = .empty, |
| 3220 | .inputs = .empty, | 3207 | .inputs = .empty, |
| 3208 | .input_pending_index = 0, | ||
| 3221 | .input_sections = .empty, | 3209 | .input_sections = .empty, |
| 3222 | .input_section_pending_index = 0, | 3210 | .input_section_pending_index = 0, |
| 3223 | .navs = .empty, | 3211 | .navs = .empty, |
| ... | @@ -3293,6 +3281,7 @@ fn initHeaders( | ... | @@ -3293,6 +3281,7 @@ fn initHeaders( |
| 3293 | const comp = elf.base.comp; | 3281 | const comp = elf.base.comp; |
| 3294 | const gpa = comp.gpa; | 3282 | const gpa = comp.gpa; |
| 3295 | 3283 | ||
| 3284 | const is_archive = comp.config.output_mode == .Lib and comp.config.link_mode == .static; | ||
| 3296 | const have_dynamic_section = switch (@"type") { | 3285 | const have_dynamic_section = switch (@"type") { |
| 3297 | .REL => false, | 3286 | .REL => false, |
| 3298 | .EXEC => comp.config.link_mode == .dynamic, | 3287 | .EXEC => comp.config.link_mode == .dynamic, |
| ... | @@ -3389,7 +3378,8 @@ fn initHeaders( | ... | @@ -3389,7 +3378,8 @@ fn initHeaders( |
| 3389 | }, phnum }; | 3378 | }, phnum }; |
| 3390 | }; | 3379 | }; |
| 3391 | 3380 | ||
| 3392 | const expected_nodes_len = 3 + // `.file`, `.ehdr`, and `.shdr` nodes | 3381 | const expected_nodes_len = @as(usize, if (is_archive) 2 else 0) + // .archive, .archive_header |
| 3382 | 3 + // `.file`, `.ehdr`, and `.shdr` nodes | ||
| 3393 | (shnum - 1) + // -1 because the null shdr does not have a `.section` node | 3383 | (shnum - 1) + // -1 because the null shdr does not have a `.section` node |
| 3394 | (phnum -| 1); // -1 because the GNU_STACK phdr does not have a `.segment` node | 3384 | (phnum -| 1); // -1 because the GNU_STACK phdr does not have a `.segment` node |
| 3395 | 3385 | ||
| ... | @@ -3398,17 +3388,49 @@ fn initHeaders( | ... | @@ -3398,17 +3388,49 @@ fn initHeaders( |
| 3398 | try elf.section_by_name.ensureUnusedCapacity(gpa, shnum); | 3388 | try elf.section_by_name.ensureUnusedCapacity(gpa, shnum); |
| 3399 | try elf.phdrs.resize(gpa, phnum); | 3389 | try elf.phdrs.resize(gpa, phnum); |
| 3400 | try elf.symtab.ensureTotalCapacity(gpa, 1); | 3390 | try elf.symtab.ensureTotalCapacity(gpa, 1); |
| 3401 | elf.nodes.appendAssumeCapacity(.file); | 3391 | |
| 3392 | if (is_archive) { | ||
| 3393 | elf.nodes.appendAssumeCapacity(.archive); | ||
| 3394 | elf.ni.archive_header = try elf.mf.addOnlyChildNode(gpa, elf.ni.archive, .{ | ||
| 3395 | .size = std.elf.ARMAG.len + @sizeOf(std.elf.ar_hdr) * 2, | ||
| 3396 | .alignment = .@"2", | ||
| 3397 | .fixed = true, | ||
| 3398 | .next_moved = true, | ||
| 3399 | .bubbles_moved = false, | ||
| 3400 | .enable_next_moved = true, | ||
| 3401 | }); | ||
| 3402 | const archive_header_slice = elf.ni.archive_header.slice(&elf.mf); | ||
| 3403 | @memcpy(archive_header_slice[0..std.elf.ARMAG.len], std.elf.ARMAG); | ||
| 3404 | const strtab_ar_hdr: *std.elf.ar_hdr = @ptrCast(archive_header_slice[std.elf.ARMAG.len..]); | ||
| 3405 | strtab_ar_hdr.* = .{ | ||
| 3406 | .ar_name = std.elf.STRNAME.*, | ||
| 3407 | .ar_date = @splat(' '), | ||
| 3408 | .ar_uid = @splat(' '), | ||
| 3409 | .ar_gid = @splat(' '), | ||
| 3410 | .ar_mode = @splat(' '), | ||
| 3411 | .ar_size = @splat(' '), | ||
| 3412 | .ar_fmag = std.elf.ARFMAG.*, | ||
| 3413 | }; | ||
| 3414 | |||
| 3415 | elf.nodes.appendAssumeCapacity(.archive_header); | ||
| 3416 | elf.ni.elf = try elf.mf.addLastChildNode(gpa, elf.ni.archive, .{ | ||
| 3417 | .alignment = elf.mf.flags.block_size.max(.@"2"), | ||
| 3418 | .next_moved = true, | ||
| 3419 | .bubbles_moved = false, | ||
| 3420 | .enable_next_moved = true, | ||
| 3421 | }); | ||
| 3422 | } | ||
| 3423 | elf.nodes.appendAssumeCapacity(.elf); | ||
| 3402 | 3424 | ||
| 3403 | const entsize: struct { ph: u32, sh: u32 } = switch (class) { | 3425 | const entsize: struct { ph: u32, sh: u32 } = switch (class) { |
| 3404 | .NONE, _ => unreachable, | 3426 | .NONE, _ => unreachable, |
| 3405 | inline else => |ct_class| entsize: { | 3427 | inline else => |ct_class| entsize: { |
| 3406 | const ElfN = ct_class.ElfN(); | 3428 | const ElfN = ct_class.ElfN(); |
| 3407 | assert(elf.ni.ehdr == try elf.mf.addOnlyChildNode(gpa, elf.ni.file, .{ | 3429 | elf.ni.ehdr = try elf.mf.addLastChildNode(gpa, elf.ni.elf, .{ |
| 3408 | .size = @sizeOf(ElfN.Ehdr), | 3430 | .size = @sizeOf(ElfN.Ehdr), |
| 3409 | .alignment = addr_align, | 3431 | .alignment = addr_align, |
| 3410 | .fixed = true, | 3432 | .fixed = true, |
| 3411 | })); | 3433 | }); |
| 3412 | elf.nodes.appendAssumeCapacity(.ehdr); | 3434 | elf.nodes.appendAssumeCapacity(.ehdr); |
| 3413 | 3435 | ||
| 3414 | const ehdr: *ElfN.Ehdr = @ptrCast(@alignCast(elf.ni.ehdr.slice(&elf.mf))); | 3436 | const ehdr: *ElfN.Ehdr = @ptrCast(@alignCast(elf.ni.ehdr.slice(&elf.mf))); |
| ... | @@ -3461,12 +3483,12 @@ fn initHeaders( | ... | @@ -3461,12 +3483,12 @@ fn initHeaders( |
| 3461 | }, | 3483 | }, |
| 3462 | }; | 3484 | }; |
| 3463 | 3485 | ||
| 3464 | assert(elf.ni.shdr == try elf.mf.addLastChildNode(gpa, elf.ni.file, .{ | 3486 | elf.ni.shdr = try elf.mf.addLastChildNode(gpa, elf.ni.elf, .{ |
| 3465 | .size = 1 * entsize.sh, // as above, only the null shdr initially | 3487 | .size = 1 * entsize.sh, // as above, only the null shdr initially |
| 3466 | .alignment = elf.mf.flags.block_size, | 3488 | .alignment = elf.mf.flags.block_size, |
| 3467 | .moved = true, | 3489 | .moved = true, |
| 3468 | .resized = true, | 3490 | .resized = true, |
| 3469 | })); | 3491 | }); |
| 3470 | elf.nodes.appendAssumeCapacity(.shdr); | 3492 | elf.nodes.appendAssumeCapacity(.shdr); |
| 3471 | 3493 | ||
| 3472 | const page_align: std.mem.Alignment = .fromByteUnits(switch (machine) { | 3494 | const page_align: std.mem.Alignment = .fromByteUnits(switch (machine) { |
| ... | @@ -3491,45 +3513,45 @@ fn initHeaders( | ... | @@ -3491,45 +3513,45 @@ fn initHeaders( |
| 3491 | }); | 3513 | }); |
| 3492 | 3514 | ||
| 3493 | var ph_vaddr: u32 = if (@"type" != .REL) ph_vaddr: { | 3515 | var ph_vaddr: u32 = if (@"type" != .REL) ph_vaddr: { |
| 3494 | assert(elf.ni.rodata == try elf.mf.addLastChildNode(gpa, elf.ni.file, .{ | 3516 | elf.ni.rodata = try elf.mf.addLastChildNode(gpa, elf.ni.elf, .{ |
| 3495 | .alignment = elf.mf.flags.block_size, | 3517 | .alignment = elf.mf.flags.block_size, |
| 3496 | .moved = true, | 3518 | .moved = true, |
| 3497 | .bubbles_moved = false, | 3519 | .bubbles_moved = false, |
| 3498 | })); | 3520 | }); |
| 3499 | elf.nodes.appendAssumeCapacity(.{ .segment = phndx.rodata }); | 3521 | elf.nodes.appendAssumeCapacity(.{ .segment = phndx.rodata }); |
| 3500 | elf.phdrs.items[phndx.rodata] = elf.ni.rodata; | 3522 | elf.phdrs.items[phndx.rodata] = elf.ni.rodata; |
| 3501 | 3523 | ||
| 3502 | assert(elf.ni.phdr == try elf.mf.addOnlyChildNode(gpa, elf.ni.rodata, .{ | 3524 | elf.ni.phdr = try elf.mf.addOnlyChildNode(gpa, elf.ni.rodata, .{ |
| 3503 | .size = @as(u64, phnum) * entsize.ph, | 3525 | .size = @as(u64, phnum) * entsize.ph, |
| 3504 | .alignment = addr_align, | 3526 | .alignment = addr_align, |
| 3505 | .moved = true, | 3527 | .moved = true, |
| 3506 | .resized = true, | 3528 | .resized = true, |
| 3507 | .bubbles_moved = false, | 3529 | .bubbles_moved = false, |
| 3508 | })); | 3530 | }); |
| 3509 | elf.nodes.appendAssumeCapacity(.{ .segment = phndx.phdr }); | 3531 | elf.nodes.appendAssumeCapacity(.{ .segment = phndx.phdr }); |
| 3510 | elf.phdrs.items[phndx.phdr] = elf.ni.phdr; | 3532 | elf.phdrs.items[phndx.phdr] = elf.ni.phdr; |
| 3511 | 3533 | ||
| 3512 | assert(elf.ni.text == try elf.mf.addLastChildNode(gpa, elf.ni.file, .{ | 3534 | elf.ni.text = try elf.mf.addLastChildNode(gpa, elf.ni.elf, .{ |
| 3513 | .alignment = elf.mf.flags.block_size, | 3535 | .alignment = elf.mf.flags.block_size, |
| 3514 | .moved = true, | 3536 | .moved = true, |
| 3515 | .bubbles_moved = false, | 3537 | .bubbles_moved = false, |
| 3516 | })); | 3538 | }); |
| 3517 | elf.nodes.appendAssumeCapacity(.{ .segment = phndx.text }); | 3539 | elf.nodes.appendAssumeCapacity(.{ .segment = phndx.text }); |
| 3518 | elf.phdrs.items[phndx.text] = elf.ni.text; | 3540 | elf.phdrs.items[phndx.text] = elf.ni.text; |
| 3519 | 3541 | ||
| 3520 | assert(elf.ni.data == try elf.mf.addLastChildNode(gpa, elf.ni.file, .{ | 3542 | elf.ni.data = try elf.mf.addLastChildNode(gpa, elf.ni.elf, .{ |
| 3521 | .alignment = elf.mf.flags.block_size, | 3543 | .alignment = elf.mf.flags.block_size, |
| 3522 | .moved = true, | 3544 | .moved = true, |
| 3523 | .bubbles_moved = false, | 3545 | .bubbles_moved = false, |
| 3524 | })); | 3546 | }); |
| 3525 | elf.nodes.appendAssumeCapacity(.{ .segment = phndx.data }); | 3547 | elf.nodes.appendAssumeCapacity(.{ .segment = phndx.data }); |
| 3526 | elf.phdrs.items[phndx.data] = elf.ni.data; | 3548 | elf.phdrs.items[phndx.data] = elf.ni.data; |
| 3527 | 3549 | ||
| 3528 | assert(elf.ni.data_rel_ro == try elf.mf.addOnlyChildNode(gpa, elf.ni.data, .{ | 3550 | elf.ni.data_rel_ro = try elf.mf.addOnlyChildNode(gpa, elf.ni.data, .{ |
| 3529 | .alignment = elf.mf.flags.block_size, | 3551 | .alignment = elf.mf.flags.block_size, |
| 3530 | .moved = true, | 3552 | .moved = true, |
| 3531 | .bubbles_moved = false, | 3553 | .bubbles_moved = false, |
| 3532 | })); | 3554 | }); |
| 3533 | elf.nodes.appendAssumeCapacity(.{ .segment = phndx.relro }); | 3555 | elf.nodes.appendAssumeCapacity(.{ .segment = phndx.relro }); |
| 3534 | elf.phdrs.items[phndx.relro] = elf.ni.data_rel_ro; | 3556 | elf.phdrs.items[phndx.relro] = elf.ni.data_rel_ro; |
| 3535 | 3557 | ||
| ... | @@ -3706,7 +3728,7 @@ fn initHeaders( | ... | @@ -3706,7 +3728,7 @@ fn initHeaders( |
| 3706 | .node = .none, | 3728 | .node = .none, |
| 3707 | .first_target_reloc = .none, | 3729 | .first_target_reloc = .none, |
| 3708 | }; | 3730 | }; |
| 3709 | assert(.symtab == try elf.addSection(elf.ni.file, .{ | 3731 | assert(.symtab == try elf.addSection(elf.ni.elf, .{ |
| 3710 | .type = .SYMTAB, | 3732 | .type = .SYMTAB, |
| 3711 | .size = @sizeOf(ElfN.Sym) * 1, | 3733 | .size = @sizeOf(ElfN.Sym) * 1, |
| 3712 | .addralign = addr_align, | 3734 | .addralign = addr_align, |
| ... | @@ -3729,7 +3751,7 @@ fn initHeaders( | ... | @@ -3729,7 +3751,7 @@ fn initHeaders( |
| 3729 | ehdr.shstrndx = ehdr.shnum; | 3751 | ehdr.shstrndx = ehdr.shnum; |
| 3730 | }, | 3752 | }, |
| 3731 | } | 3753 | } |
| 3732 | assert(.shstrtab == try elf.addSection(elf.ni.file, .{ | 3754 | assert(.shstrtab == try elf.addSection(elf.ni.elf, .{ |
| 3733 | .type = .STRTAB, | 3755 | .type = .STRTAB, |
| 3734 | .size = 1, | 3756 | .size = 1, |
| 3735 | .entsize = 1, | 3757 | .entsize = 1, |
| ... | @@ -3740,7 +3762,7 @@ fn initHeaders( | ... | @@ -3740,7 +3762,7 @@ fn initHeaders( |
| 3740 | try Section.Index.symtab.rename(elf, ".symtab"); | 3762 | try Section.Index.symtab.rename(elf, ".symtab"); |
| 3741 | try Section.Index.shstrtab.rename(elf, ".shstrtab"); | 3763 | try Section.Index.shstrtab.rename(elf, ".shstrtab"); |
| 3742 | 3764 | ||
| 3743 | assert(.strtab == try elf.addSection(elf.ni.file, .{ | 3765 | assert(.strtab == try elf.addSection(elf.ni.elf, .{ |
| 3744 | .name = ".strtab", | 3766 | .name = ".strtab", |
| 3745 | .type = .STRTAB, | 3767 | .type = .STRTAB, |
| 3746 | .size = 1, | 3768 | .size = 1, |
| ... | @@ -4210,6 +4232,8 @@ fn initHeaders( | ... | @@ -4210,6 +4232,8 @@ fn initHeaders( |
| 4210 | break :str try elf.string(.dynstr, slice); | 4232 | break :str try elf.string(.dynstr, slice); |
| 4211 | }, | 4233 | }, |
| 4212 | }; | 4234 | }; |
| 4235 | |||
| 4236 | try elf.ensureElfNodeSize(); | ||
| 4213 | } | 4237 | } |
| 4214 | 4238 | ||
| 4215 | pub fn startProgress(elf: *Elf, prog_node: std.Progress.Node) void { | 4239 | pub fn startProgress(elf: *Elf, prog_node: std.Progress.Node) void { |
| ... | @@ -4221,10 +4245,8 @@ pub fn startProgress(elf: *Elf, prog_node: std.Progress.Node) void { | ... | @@ -4221,10 +4245,8 @@ pub fn startProgress(elf: *Elf, prog_node: std.Progress.Node) void { |
| 4221 | break :count count; | 4245 | break :count count; |
| 4222 | }); | 4246 | }); |
| 4223 | elf.mf.update_prog_node = prog_node.start("Relocations", elf.mf.updates.items.len); | 4247 | elf.mf.update_prog_node = prog_node.start("Relocations", elf.mf.updates.items.len); |
| 4224 | elf.input_prog_node = prog_node.start( | 4248 | elf.input_prog_node = prog_node.start("Inputs", (elf.inputs.items.len - elf.input_pending_index) + |
| 4225 | "Inputs", | 4249 | (elf.input_sections.items.len - elf.input_section_pending_index)); |
| 4226 | elf.input_sections.items.len - elf.input_section_pending_index, | ||
| 4227 | ); | ||
| 4228 | } | 4250 | } |
| 4229 | 4251 | ||
| 4230 | pub fn endProgress(elf: *Elf) void { | 4252 | pub fn endProgress(elf: *Elf) void { |
| ... | @@ -4244,13 +4266,15 @@ fn getNode(elf: *const Elf, ni: MappedFile.Node.Index) Node { | ... | @@ -4244,13 +4266,15 @@ fn getNode(elf: *const Elf, ni: MappedFile.Node.Index) Node { |
| 4244 | /// Asserts that `ni` is a section, input section, copied global, NAV, UAV, or lazy code/data. | 4266 | /// Asserts that `ni` is a section, input section, copied global, NAV, UAV, or lazy code/data. |
| 4245 | fn getNodeShndx(elf: *const Elf, ni: MappedFile.Node.Index) Section.Index { | 4267 | fn getNodeShndx(elf: *const Elf, ni: MappedFile.Node.Index) Section.Index { |
| 4246 | return switch (elf.getNode(ni)) { | 4268 | return switch (elf.getNode(ni)) { |
| 4247 | .file => unreachable, | 4269 | .archive, |
| 4248 | .ehdr => unreachable, | 4270 | .archive_header, |
| 4249 | .shdr => unreachable, | 4271 | .elf, |
| 4250 | .segment => unreachable, | 4272 | .ehdr, |
| 4251 | 4273 | .shdr, | |
| 4274 | .segment, | ||
| 4275 | .input_member, | ||
| 4276 | => unreachable, | ||
| 4252 | .section => |shndx| shndx, | 4277 | .section => |shndx| shndx, |
| 4253 | |||
| 4254 | .input_section, | 4278 | .input_section, |
| 4255 | .copied_global, | 4279 | .copied_global, |
| 4256 | .nav, | 4280 | .nav, |
| ... | @@ -4260,21 +4284,44 @@ fn getNodeShndx(elf: *const Elf, ni: MappedFile.Node.Index) Section.Index { | ... | @@ -4260,21 +4284,44 @@ fn getNodeShndx(elf: *const Elf, ni: MappedFile.Node.Index) Section.Index { |
| 4260 | => elf.getNode(ni.parent(&elf.mf)).section, | 4284 | => elf.getNode(ni.parent(&elf.mf)).section, |
| 4261 | }; | 4285 | }; |
| 4262 | } | 4286 | } |
| 4287 | fn getNodeVAddr(elf: *Elf, ni: MappedFile.Node.Index) u64 { | ||
| 4288 | return switch (elf.getNode(ni)) { | ||
| 4289 | .archive, | ||
| 4290 | .archive_header, | ||
| 4291 | .elf, | ||
| 4292 | .ehdr, | ||
| 4293 | .shdr, | ||
| 4294 | .segment, | ||
| 4295 | .input_member, | ||
| 4296 | .copied_global, | ||
| 4297 | => unreachable, | ||
| 4298 | .section => |shndx| shndx.vaddr(elf), | ||
| 4299 | .input_section => |isi| isi.ptrConst(elf).vaddr, | ||
| 4300 | inline .nav, | ||
| 4301 | .uav, | ||
| 4302 | .lazy_code, | ||
| 4303 | .lazy_const_data, | ||
| 4304 | => |i| Symbol.Id.local(i.symbol(elf)).value(elf), | ||
| 4305 | }; | ||
| 4306 | } | ||
| 4263 | fn computeNodeVAddr(elf: *Elf, ni: MappedFile.Node.Index) u64 { | 4307 | fn computeNodeVAddr(elf: *Elf, ni: MappedFile.Node.Index) u64 { |
| 4264 | const parent_vaddr = switch (elf.getNode(ni.parent(&elf.mf))) { | 4308 | const parent_vaddr = switch (elf.getNode(ni.parent(&elf.mf))) { |
| 4265 | .file => return 0, | 4309 | .archive, .archive_header => unreachable, |
| 4310 | .elf => return 0, | ||
| 4266 | .ehdr, .shdr => unreachable, | 4311 | .ehdr, .shdr => unreachable, |
| 4267 | .segment => |phndx| switch (elf.phdrSlice()) { | 4312 | .segment => |phndx| switch (elf.phdrSlice()) { |
| 4268 | inline else => |phdr| elf.targetLoad(&phdr[phndx].vaddr), | 4313 | inline else => |phdr| elf.targetLoad(&phdr[phndx].vaddr), |
| 4269 | }, | 4314 | }, |
| 4270 | .section => |shndx| if (shndx == elf.shndx.tdata) 0 else shndx.vaddr(elf), | 4315 | .section => |shndx| if (shndx == elf.shndx.tdata) 0 else shndx.vaddr(elf), |
| 4271 | .input_section => unreachable, | 4316 | .input_member, .input_section, .copied_global => unreachable, |
| 4272 | .copied_global => unreachable, | ||
| 4273 | inline .nav, .uav, .lazy_code, .lazy_const_data => |i| Symbol.Id.local(i.symbol(elf)).value(elf), | 4317 | inline .nav, .uav, .lazy_code, .lazy_const_data => |i| Symbol.Id.local(i.symbol(elf)).value(elf), |
| 4274 | }; | 4318 | }; |
| 4275 | const offset, _ = ni.location(&elf.mf).resolve(&elf.mf); | 4319 | const offset, _ = ni.location(&elf.mf).resolve(&elf.mf); |
| 4276 | return parent_vaddr + offset; | 4320 | return parent_vaddr + offset; |
| 4277 | } | 4321 | } |
| 4322 | fn getNodeElfOffset(elf: *Elf, ni: MappedFile.Node.Index) u64 { | ||
| 4323 | return ni.fileLocation(&elf.mf, false).offset - elf.ni.elf.fileLocation(&elf.mf, false).offset; | ||
| 4324 | } | ||
| 4278 | 4325 | ||
| 4279 | /// Deletes any existing relocations in the given node, and marks the start of the node's contiguous | 4326 | /// Deletes any existing relocations in the given node, and marks the start of the node's contiguous |
| 4280 | /// sequence of relocations, so that the caller may append the node's updated relocations. | 4327 | /// sequence of relocations, so that the caller may append the node's updated relocations. |
| ... | @@ -4283,12 +4330,16 @@ fn computeNodeVAddr(elf: *Elf, ni: MappedFile.Node.Index) u64 { | ... | @@ -4283,12 +4330,16 @@ fn computeNodeVAddr(elf: *Elf, ni: MappedFile.Node.Index) u64 { |
| 4283 | /// the special-case sections '.plt' and '.dynamic'. | 4330 | /// the special-case sections '.plt' and '.dynamic'. |
| 4284 | fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void { | 4331 | fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void { |
| 4285 | const symbol_relocs: *SymbolReloc.Index, const got_relocs: ?*GotReloc.Index = switch (elf.getNode(ni)) { | 4332 | const symbol_relocs: *SymbolReloc.Index, const got_relocs: ?*GotReloc.Index = switch (elf.getNode(ni)) { |
| 4286 | .file => unreachable, // cannot contain relocs | 4333 | .archive, |
| 4287 | .ehdr => unreachable, // cannot contain relocs | 4334 | .archive_header, |
| 4288 | .shdr => unreachable, // cannot contain relocs | 4335 | .elf, |
| 4289 | .segment => unreachable, // cannot contain relocs | 4336 | .ehdr, |
| 4337 | .shdr, | ||
| 4338 | .segment, | ||
| 4339 | .input_member, | ||
| 4340 | .copied_global, | ||
| 4341 | => unreachable, // cannot contain relocs | ||
| 4290 | .section => unreachable, // cannot contain relocs (.plt and .dynamic unsupported) | 4342 | .section => unreachable, // cannot contain relocs (.plt and .dynamic unsupported) |
| 4291 | .copied_global => unreachable, // cannot contain relocs | ||
| 4292 | .input_section => |isi| .{ | 4343 | .input_section => |isi| .{ |
| 4293 | &elf.input_sections.items[@backingInt(isi)].first_symbol_reloc, | 4344 | &elf.input_sections.items[@backingInt(isi)].first_symbol_reloc, |
| 4294 | &elf.input_sections.items[@backingInt(isi)].first_got_reloc, | 4345 | &elf.input_sections.items[@backingInt(isi)].first_got_reloc, |
| ... | @@ -4359,7 +4410,7 @@ fn flushMovedNodeRelocs( | ... | @@ -4359,7 +4410,7 @@ fn flushMovedNodeRelocs( |
| 4359 | } | 4410 | } |
| 4360 | 4411 | ||
| 4361 | fn identClass(elf: *const Elf) std.elf.CLASS { | 4412 | fn identClass(elf: *const Elf) std.elf.CLASS { |
| 4362 | return @fromBackingInt(@intCast(elf.mf.memory_map.memory[std.elf.EI.CLASS])); | 4413 | return @fromBackingInt(elf.ni.elf.sliceConst(&elf.mf)[std.elf.EI.CLASS]); |
| 4363 | } | 4414 | } |
| 4364 | 4415 | ||
| 4365 | /// Like `std.elf.ET`, but only includes the ELF machine architectures we support, so that we can | 4416 | /// Like `std.elf.ET`, but only includes the ELF machine architectures we support, so that we can |
| ... | @@ -4415,7 +4466,7 @@ fn targetPtrSize(elf: *const Elf) u8 { | ... | @@ -4415,7 +4466,7 @@ fn targetPtrSize(elf: *const Elf) u8 { |
| 4415 | return elf.identClass().size(); | 4466 | return elf.identClass().size(); |
| 4416 | } | 4467 | } |
| 4417 | fn targetEndian(elf: *const Elf) std.lang.Endian { | 4468 | fn targetEndian(elf: *const Elf) std.lang.Endian { |
| 4418 | const ident_data: std.elf.DATA = @fromBackingInt(@intCast(elf.mf.memory_map.memory[std.elf.EI.DATA])); | 4469 | const ident_data: std.elf.DATA = @fromBackingInt(elf.ni.elf.sliceConst(&elf.mf)[std.elf.EI.DATA]); |
| 4419 | return ident_data.endian(); | 4470 | return ident_data.endian(); |
| 4420 | } | 4471 | } |
| 4421 | fn targetTlsVariant(elf: *const Elf) union(enum) { | 4472 | fn targetTlsVariant(elf: *const Elf) union(enum) { |
| ... | @@ -4487,7 +4538,7 @@ fn targetLoad(elf: *const Elf, ptr: anytype) @typeInfo(@TypeOf(ptr)).pointer.chi | ... | @@ -4487,7 +4538,7 @@ fn targetLoad(elf: *const Elf, ptr: anytype) @typeInfo(@TypeOf(ptr)).pointer.chi |
| 4487 | return switch (@typeInfo(Child)) { | 4538 | return switch (@typeInfo(Child)) { |
| 4488 | else => @compileError(@typeName(Child)), | 4539 | else => @compileError(@typeName(Child)), |
| 4489 | .int => std.mem.toNative(Child, ptr.*, elf.targetEndian()), | 4540 | .int => std.mem.toNative(Child, ptr.*, elf.targetEndian()), |
| 4490 | .@"enum" => |@"enum"| @fromBackingInt(@intCast(elf.targetLoad(@as(*align(alignment) const @"enum".tag_type, @ptrCast(ptr))))), | 4541 | .@"enum" => |@"enum"| @fromBackingInt(elf.targetLoad(@as(*align(alignment) const @"enum".tag_type, @ptrCast(ptr)))), |
| 4491 | .@"struct" => |@"struct"| @bitCast( | 4542 | .@"struct" => |@"struct"| @bitCast( |
| 4492 | elf.targetLoad(@as(*align(alignment) @"struct".backing_integer.?, @ptrCast(ptr))), | 4543 | elf.targetLoad(@as(*align(alignment) @"struct".backing_integer.?, @ptrCast(ptr))), |
| 4493 | ), | 4544 | ), |
| ... | @@ -4563,6 +4614,16 @@ fn shdrPtr(elf: *Elf, shndx: Section.Index) ShdrPtr { | ... | @@ -4563,6 +4614,16 @@ fn shdrPtr(elf: *Elf, shndx: Section.Index) ShdrPtr { |
| 4563 | } | 4614 | } |
| 4564 | } | 4615 | } |
| 4565 | 4616 | ||
| 4617 | fn arHdrPtr(elf: *Elf, ni: MappedFile.Node.Index) *align(2) std.elf.ar_hdr { | ||
| 4618 | assert(elf.ni.elf != MappedFile.Node.Index.root); | ||
| 4619 | const file_offset = ni.fileLocation(&elf.mf, false).offset; | ||
| 4620 | return @ptrCast(@alignCast(elf.mf.memory_map.memory[@intCast(switch (elf.getNode(ni)) { | ||
| 4621 | else => unreachable, | ||
| 4622 | .archive_header => file_offset + std.elf.ARMAG.len, | ||
| 4623 | .elf, .input_member => file_offset - @sizeOf(std.elf.ar_hdr), | ||
| 4624 | })..][0..@sizeOf(std.elf.ar_hdr)])); | ||
| 4625 | } | ||
| 4626 | |||
| 4566 | const SymPtr = union(std.elf.CLASS) { | 4627 | const SymPtr = union(std.elf.CLASS) { |
| 4567 | NONE: noreturn, | 4628 | NONE: noreturn, |
| 4568 | @"32": *std.elf.Elf32.Sym, | 4629 | @"32": *std.elf.Elf32.Sym, |
| ... | @@ -4657,7 +4718,7 @@ fn mapInputSection(elf: *Elf, opts: struct { | ... | @@ -4657,7 +4718,7 @@ fn mapInputSection(elf: *Elf, opts: struct { |
| 4657 | } | 4718 | } |
| 4658 | errdefer assert(elf.section_by_name.pop().?.key == name_shstrtab); | 4719 | errdefer assert(elf.section_by_name.pop().?.key == name_shstrtab); |
| 4659 | const parent_node: MappedFile.Node.Index = parent: { | 4720 | const parent_node: MappedFile.Node.Index = parent: { |
| 4660 | if (!opts.flags.ALLOC) break :parent elf.ni.file; | 4721 | if (!opts.flags.ALLOC) break :parent elf.ni.elf; |
| 4661 | if (opts.flags.EXECINSTR) break :parent elf.ni.text; | 4722 | if (opts.flags.EXECINSTR) break :parent elf.ni.text; |
| 4662 | if (opts.flags.TLS) break :parent elf.ni.tls; | 4723 | if (opts.flags.TLS) break :parent elf.ni.tls; |
| 4663 | if (opts.flags.WRITE) break :parent elf.ni.data; | 4724 | if (opts.flags.WRITE) break :parent elf.ni.data; |
| ... | @@ -4782,11 +4843,11 @@ fn navMapIndex(elf: *Elf, zcu: *Zcu, nav_index: InternPool.Nav.Index) Error!Node | ... | @@ -4782,11 +4843,11 @@ fn navMapIndex(elf: *Elf, zcu: *Zcu, nav_index: InternPool.Nav.Index) Error!Node |
| 4782 | break :a switch (nav.resolved.?.@"align") { | 4843 | break :a switch (nav.resolved.?.@"align") { |
| 4783 | else => |a| a.maxStrict(min), | 4844 | else => |a| a.maxStrict(min), |
| 4784 | .none => switch (mod.optimize_mode) { | 4845 | .none => switch (mod.optimize_mode) { |
| 4785 | .Debug, | 4846 | .debug, |
| 4786 | .ReleaseSafe, | 4847 | .safe, |
| 4787 | .ReleaseFast, | 4848 | .fast, |
| 4788 | => target_util.defaultFunctionAlignment(target), | 4849 | => target_util.defaultFunctionAlignment(target), |
| 4789 | .ReleaseSmall => min, | 4850 | .small => min, |
| 4790 | }.maxStrict(Type.fromInterned(nav.resolved.?.type).abiAlignment(zcu)), | 4851 | }.maxStrict(Type.fromInterned(nav.resolved.?.type).abiAlignment(zcu)), |
| 4791 | }; | 4852 | }; |
| 4792 | }, | 4853 | }, |
| ... | @@ -4878,7 +4939,7 @@ const LoadParseInputError = Error || Io.File.SeekError || Io.Reader.Error; | ... | @@ -4878,7 +4939,7 @@ const LoadParseInputError = Error || Io.File.SeekError || Io.Reader.Error; |
| 4878 | /// indicates to the frontend that the input could be a GNU ld script instead. | 4939 | /// indicates to the frontend that the input could be a GNU ld script instead. |
| 4879 | pub fn loadInput(elf: *Elf, input: link.Input) (link.Error || error{BadMagic})!void { | 4940 | pub fn loadInput(elf: *Elf, input: link.Input) (link.Error || error{BadMagic})!void { |
| 4880 | const diags = &elf.base.comp.link_diags; | 4941 | const diags = &elf.base.comp.link_diags; |
| 4881 | return elf.loadInputInner(input) catch |err| switch (err) { | 4942 | elf.loadInputInner(input) catch |err| switch (err) { |
| 4882 | else => |e| return e, | 4943 | else => |e| return e, |
| 4883 | error.MappedFileIo => return diags.fail( | 4944 | error.MappedFileIo => return diags.fail( |
| 4884 | "failed to write output file: {t}", | 4945 | "failed to write output file: {t}", |
| ... | @@ -4986,6 +5047,9 @@ fn loadArchive(elf: *Elf, path: std.Build.Cache.Path, fr: *Io.File.Reader) (Load | ... | @@ -4986,6 +5047,9 @@ fn loadArchive(elf: *Elf, path: std.Build.Cache.Path, fr: *Io.File.Reader) (Load |
| 4986 | const r = &fr.interface; | 5047 | const r = &fr.interface; |
| 4987 | 5048 | ||
| 4988 | log.debug("loadArchive({f})", .{path.fmtEscapeString()}); | 5049 | log.debug("loadArchive({f})", .{path.fmtEscapeString()}); |
| 5050 | |||
| 5051 | if (elf.ehdrType() == .REL) return; // this input does not affect the output artifact | ||
| 5052 | |||
| 4989 | { | 5053 | { |
| 4990 | const magic = r.take(std.elf.ARMAG.len) catch |err| switch (err) { | 5054 | const magic = r.take(std.elf.ARMAG.len) catch |err| switch (err) { |
| 4991 | error.ReadFailed => |e| return e, | 5055 | error.ReadFailed => |e| return e, |
| ... | @@ -5071,21 +5135,40 @@ fn loadObject( | ... | @@ -5071,21 +5135,40 @@ fn loadObject( |
| 5071 | .{}, | 5135 | .{}, |
| 5072 | ), | 5136 | ), |
| 5073 | }; | 5137 | }; |
| 5138 | |||
| 5139 | const input = try elf.inputs.addOne(gpa); | ||
| 5140 | input.* = .{ | ||
| 5141 | .path = path, | ||
| 5142 | .member = if (member) |m| try gpa.dupe(u8, m) else null, | ||
| 5143 | .extra = undefined, | ||
| 5144 | }; | ||
| 5145 | if (elf.ni.elf != MappedFile.Node.Index.root) { | ||
| 5146 | try elf.nodes.ensureUnusedCapacity(gpa, 1); | ||
| 5147 | input.extra = .{ .node = try elf.mf.addLastChildNode(gpa, .root, .{ | ||
| 5148 | .size = fl.size + @sizeOf(std.elf.ar_hdr), | ||
| 5149 | .alignment = .@"2", | ||
| 5150 | .next_moved = true, | ||
| 5151 | .bubbles_moved = false, | ||
| 5152 | .enable_next_moved = true, | ||
| 5153 | }) }; | ||
| 5154 | elf.nodes.appendAssumeCapacity(.{ .input_member = input_index }); | ||
| 5155 | elf.input_prog_node.increaseEstimatedTotalItems(1); | ||
| 5156 | |||
| 5157 | // Since we are not emitting the archive symbol table (yet?) we do not need to parse | ||
| 5158 | // the symbols in this input. | ||
| 5159 | return; | ||
| 5160 | } | ||
| 5161 | |||
| 5162 | elf.input_pending_index += 1; | ||
| 5074 | try elf.ensureUnusedSymbolCapacity(1, .all_local); | 5163 | try elf.ensureUnusedSymbolCapacity(1, .all_local); |
| 5075 | try elf.inputs.ensureUnusedCapacity(gpa, 1); | 5164 | input.extra = .{ .file_symbol = elf.addLocalSymbolAssumeCapacity(.{ |
| 5076 | const file_symbol = elf.addLocalSymbolAssumeCapacity(.{ | ||
| 5077 | .node = .none, | 5165 | .node = .none, |
| 5078 | .name = try elf.string(.strtab, std.fs.path.stem(member orelse path.sub_path)), | 5166 | .name = try elf.string(.strtab, std.fs.path.stem(member orelse path.sub_path)), |
| 5079 | .value = 0, | 5167 | .value = 0, |
| 5080 | .size = 0, | 5168 | .size = 0, |
| 5081 | .type = .FILE, | 5169 | .type = .FILE, |
| 5082 | .shndx = .ABS, | 5170 | .shndx = .ABS, |
| 5083 | }); | 5171 | }) }; |
| 5084 | elf.inputs.addOneAssumeCapacity().* = .{ | ||
| 5085 | .path = path, | ||
| 5086 | .member = if (member) |m| try gpa.dupe(u8, m) else null, | ||
| 5087 | .file_symbol = file_symbol, | ||
| 5088 | }; | ||
| 5089 | const target_endian = elf.targetEndian(); | 5172 | const target_endian = elf.targetEndian(); |
| 5090 | switch (elf.identClass()) { | 5173 | switch (elf.identClass()) { |
| 5091 | .NONE, _ => unreachable, | 5174 | .NONE, _ => unreachable, |
| ... | @@ -5267,7 +5350,7 @@ fn loadObject( | ... | @@ -5267,7 +5350,7 @@ fn loadObject( |
| 5267 | .first_symbol_reloc = .none, | 5350 | .first_symbol_reloc = .none, |
| 5268 | .first_got_reloc = .none, | 5351 | .first_got_reloc = .none, |
| 5269 | }; | 5352 | }; |
| 5270 | elf.synth_prog_node.increaseEstimatedTotalItems(1); | 5353 | elf.input_prog_node.increaseEstimatedTotalItems(1); |
| 5271 | } | 5354 | } |
| 5272 | var symmap: std.ArrayList(Symbol.Id) = .empty; | 5355 | var symmap: std.ArrayList(Symbol.Id) = .empty; |
| 5273 | defer symmap.deinit(gpa); | 5356 | defer symmap.deinit(gpa); |
| ... | @@ -5479,6 +5562,9 @@ fn loadDso(elf: *Elf, path: std.Build.Cache.Path, fr: *Io.File.Reader) (LoadPars | ... | @@ -5479,6 +5562,9 @@ fn loadDso(elf: *Elf, path: std.Build.Cache.Path, fr: *Io.File.Reader) (LoadPars |
| 5479 | 5562 | ||
| 5480 | log.debug("loadDso({f})", .{path.fmtEscapeString()}); | 5563 | log.debug("loadDso({f})", .{path.fmtEscapeString()}); |
| 5481 | try elf.checkInputIdent(path, r); | 5564 | try elf.checkInputIdent(path, r); |
| 5565 | |||
| 5566 | if (elf.ehdrType() == .REL) return; // this input does not affect the output artifact | ||
| 5567 | |||
| 5482 | const target_endian = elf.targetEndian(); | 5568 | const target_endian = elf.targetEndian(); |
| 5483 | switch (elf.identClass()) { | 5569 | switch (elf.identClass()) { |
| 5484 | .NONE, _ => unreachable, | 5570 | .NONE, _ => unreachable, |
| ... | @@ -5709,7 +5795,8 @@ fn checkInputIdent( | ... | @@ -5709,7 +5795,8 @@ fn checkInputIdent( |
| 5709 | } | 5795 | } |
| 5710 | 5796 | ||
| 5711 | const ident = try r.peekStructPointer(std.elf.Ident); | 5797 | const ident = try r.peekStructPointer(std.elf.Ident); |
| 5712 | const target: *const std.elf.Ident = @ptrCast(elf.mf.memory_map.memory[0..@sizeOf(std.elf.Ident)]); | 5798 | const target: *const std.elf.Ident = |
| 5799 | @ptrCast(elf.ni.elf.sliceConst(&elf.mf)[0..@sizeOf(std.elf.Ident)]); | ||
| 5713 | 5800 | ||
| 5714 | if (ident.class != target.class) return diags.failParse( | 5801 | if (ident.class != target.class) return diags.failParse( |
| 5715 | path, | 5802 | path, |
| ... | @@ -5812,7 +5899,9 @@ fn updateInitFiniArraySectionSize( | ... | @@ -5812,7 +5899,9 @@ fn updateInitFiniArraySectionSize( |
| 5812 | } | 5899 | } |
| 5813 | 5900 | ||
| 5814 | pub fn prelink(elf: *Elf, prog_node: std.Progress.Node) link.Error!void { | 5901 | pub fn prelink(elf: *Elf, prog_node: std.Progress.Node) link.Error!void { |
| 5815 | _ = prog_node; | 5902 | const sub_prog_node = prog_node.start("ELF Prelink", 0); |
| 5903 | defer sub_prog_node.end(); | ||
| 5904 | |||
| 5816 | const diags = &elf.base.comp.link_diags; | 5905 | const diags = &elf.base.comp.link_diags; |
| 5817 | elf.prelinkInner() catch |err| switch (err) { | 5906 | elf.prelinkInner() catch |err| switch (err) { |
| 5818 | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), | 5907 | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), |
| ... | @@ -5823,13 +5912,11 @@ fn prelinkInner(elf: *Elf) Error!void { | ... | @@ -5823,13 +5912,11 @@ fn prelinkInner(elf: *Elf) Error!void { |
| 5823 | const comp = elf.base.comp; | 5912 | const comp = elf.base.comp; |
| 5824 | const gpa = comp.gpa; | 5913 | const gpa = comp.gpa; |
| 5825 | 5914 | ||
| 5826 | if (comp.zcu != null and !comp.config.use_llvm) { | 5915 | if (comp.zcu != null and !comp.config.use_llvm and elf.ni.elf == MappedFile.Node.Index.root) { |
| 5827 | // We're use self-hosted codegen---add an input representing the Zig "object". | 5916 | // We're using self-hosted codegen---add an input representing the Zig "object". |
| 5828 | try elf.ensureUnusedSymbolCapacity(1, .all_local); | 5917 | try elf.ensureUnusedSymbolCapacity(1, .all_local); |
| 5829 | try elf.inputs.ensureUnusedCapacity(gpa, 1); | 5918 | try elf.inputs.ensureUnusedCapacity(gpa, 1); |
| 5830 | const zcu_name = try std.fmt.allocPrint(gpa, "{s}_zcu", .{ | 5919 | const zcu_name = try std.fmt.allocPrint(gpa, "{s}_zcu", .{comp.root_name}); |
| 5831 | std.fs.path.stem(elf.base.emit.sub_path), | ||
| 5832 | }); | ||
| 5833 | defer gpa.free(zcu_name); | 5920 | defer gpa.free(zcu_name); |
| 5834 | const zcu_file_symbol = elf.addLocalSymbolAssumeCapacity(.{ | 5921 | const zcu_file_symbol = elf.addLocalSymbolAssumeCapacity(.{ |
| 5835 | .node = .none, | 5922 | .node = .none, |
| ... | @@ -5842,9 +5929,12 @@ fn prelinkInner(elf: *Elf) Error!void { | ... | @@ -5842,9 +5929,12 @@ fn prelinkInner(elf: *Elf) Error!void { |
| 5842 | elf.inputs.addOneAssumeCapacity().* = .{ | 5929 | elf.inputs.addOneAssumeCapacity().* = .{ |
| 5843 | .path = elf.base.emit, | 5930 | .path = elf.base.emit, |
| 5844 | .member = null, | 5931 | .member = null, |
| 5845 | .file_symbol = zcu_file_symbol, | 5932 | .extra = .{ .file_symbol = zcu_file_symbol }, |
| 5846 | }; | 5933 | }; |
| 5934 | elf.input_pending_index += 1; | ||
| 5847 | } | 5935 | } |
| 5936 | |||
| 5937 | try elf.ensureElfNodeSize(); | ||
| 5848 | } | 5938 | } |
| 5849 | 5939 | ||
| 5850 | fn prepareDynamic(elf: *Elf) Error!void { | 5940 | fn prepareDynamic(elf: *Elf) Error!void { |
| ... | @@ -6034,12 +6124,12 @@ fn addSection(elf: *Elf, segment_ni: MappedFile.Node.Index, opts: struct { | ... | @@ -6034,12 +6124,12 @@ fn addSection(elf: *Elf, segment_ni: MappedFile.Node.Index, opts: struct { |
| 6034 | }, | 6124 | }, |
| 6035 | }; | 6125 | }; |
| 6036 | assert(shndx < @backingInt(Section.Index.LORESERVE)); | 6126 | assert(shndx < @backingInt(Section.Index.LORESERVE)); |
| 6037 | break :shndx .{ @fromBackingInt(@intCast(shndx)), @as(u64, elf.targetLoad(&ehdr.shentsize)) * @as(u64, shnum) }; | 6127 | break :shndx .{ @fromBackingInt(shndx), @as(u64, elf.targetLoad(&ehdr.shentsize)) * @as(u64, shnum) }; |
| 6038 | }, | 6128 | }, |
| 6039 | }; | 6129 | }; |
| 6040 | try elf.ensureNodeSize(elf.ni.shdr, new_shdr_size); | 6130 | try elf.ensureNodeSize(elf.ni.shdr, new_shdr_size); |
| 6041 | const ni = try elf.mf.addLastChildNode(gpa, switch (elf.ehdrType()) { | 6131 | const ni = try elf.mf.addLastChildNode(gpa, switch (elf.ehdrType()) { |
| 6042 | .REL => elf.ni.file, | 6132 | .REL => elf.ni.elf, |
| 6043 | .EXEC, .DYN => segment_ni, | 6133 | .EXEC, .DYN => segment_ni, |
| 6044 | }, .{ | 6134 | }, .{ |
| 6045 | .size = opts.size, | 6135 | .size = opts.size, |
| ... | @@ -6062,7 +6152,6 @@ fn addSection(elf: *Elf, segment_ni: MappedFile.Node.Index, opts: struct { | ... | @@ -6062,7 +6152,6 @@ fn addSection(elf: *Elf, segment_ni: MappedFile.Node.Index, opts: struct { |
| 6062 | else => .{ .shndx = .UNDEF }, | 6152 | else => .{ .shndx = .UNDEF }, |
| 6063 | } }); | 6153 | } }); |
| 6064 | elf.nodes.appendAssumeCapacity(.{ .section = shndx }); | 6154 | elf.nodes.appendAssumeCapacity(.{ .section = shndx }); |
| 6065 | const offset = ni.fileLocation(&elf.mf, false).offset; | ||
| 6066 | switch (elf.shdrPtr(shndx)) { | 6155 | switch (elf.shdrPtr(shndx)) { |
| 6067 | inline else => |shdr, class| { | 6156 | inline else => |shdr, class| { |
| 6068 | shdr.* = .{ | 6157 | shdr.* = .{ |
| ... | @@ -6070,7 +6159,7 @@ fn addSection(elf: *Elf, segment_ni: MappedFile.Node.Index, opts: struct { | ... | @@ -6070,7 +6159,7 @@ fn addSection(elf: *Elf, segment_ni: MappedFile.Node.Index, opts: struct { |
| 6070 | .type = opts.type, | 6159 | .type = opts.type, |
| 6071 | .flags = .{ .shf = opts.flags }, | 6160 | .flags = .{ .shf = opts.flags }, |
| 6072 | .addr = @intCast(addr), | 6161 | .addr = @intCast(addr), |
| 6073 | .offset = @intCast(offset), | 6162 | .offset = @intCast(elf.getNodeElfOffset(ni)), |
| 6074 | .size = @intCast(opts.size), | 6163 | .size = @intCast(opts.size), |
| 6075 | .link = opts.link, | 6164 | .link = opts.link, |
| 6076 | .info = opts.info, | 6165 | .info = opts.info, |
| ... | @@ -6504,20 +6593,7 @@ fn addSymbolRelocAssumeCapacity( | ... | @@ -6504,20 +6593,7 @@ fn addSymbolRelocAssumeCapacity( |
| 6504 | 6593 | ||
| 6505 | // If we emit a runtime relocation entry, its `offset` is a virtual address, so we need to | 6594 | // If we emit a runtime relocation entry, its `offset` is a virtual address, so we need to |
| 6506 | // determine the vaddr of `node`. | 6595 | // determine the vaddr of `node`. |
| 6507 | const node_vaddr: u64 = switch (elf.getNode(node)) { | 6596 | const node_vaddr = elf.getNodeVAddr(node); |
| 6508 | .file => unreachable, | ||
| 6509 | .ehdr => unreachable, | ||
| 6510 | .shdr => unreachable, | ||
| 6511 | .segment => unreachable, | ||
| 6512 | .copied_global => unreachable, | ||
| 6513 | .section => |shndx| shndx.vaddr(elf), | ||
| 6514 | .input_section => |isi| isi.ptrConst(elf).vaddr, | ||
| 6515 | inline .nav, | ||
| 6516 | .uav, | ||
| 6517 | .lazy_code, | ||
| 6518 | .lazy_const_data, | ||
| 6519 | => |i| Symbol.Id.local(i.symbol(elf)).value(elf), | ||
| 6520 | }; | ||
| 6521 | 6597 | ||
| 6522 | // If this is `true`, we will try to create a copy relocation for the target symbol if it is | 6598 | // If this is `true`, we will try to create a copy relocation for the target symbol if it is |
| 6523 | // not locally defined. If the relocation value is always computed from the target symbol's | 6599 | // not locally defined. If the relocation value is always computed from the target symbol's |
| ... | @@ -6656,20 +6732,23 @@ fn addGotRelocAssumeCapacity( | ... | @@ -6656,20 +6732,23 @@ fn addGotRelocAssumeCapacity( |
| 6656 | ) void { | 6732 | ) void { |
| 6657 | assert(elf.ehdrType() != .REL); | 6733 | assert(elf.ehdrType() != .REL); |
| 6658 | switch (elf.getNode(node)) { | 6734 | switch (elf.getNode(node)) { |
| 6735 | .archive, | ||
| 6736 | .archive_header, | ||
| 6737 | .elf, | ||
| 6738 | .ehdr, | ||
| 6739 | .shdr, | ||
| 6740 | .segment, | ||
| 6741 | .input_member, | ||
| 6742 | .copied_global, | ||
| 6743 | => unreachable, // cannot contain relocs, | ||
| 6744 | .section, | ||
| 6745 | .uav, | ||
| 6746 | => unreachable, // cannot contain GOT relocs | ||
| 6659 | .input_section, | 6747 | .input_section, |
| 6660 | .nav, | 6748 | .nav, |
| 6661 | .lazy_code, | 6749 | .lazy_code, |
| 6662 | .lazy_const_data, | 6750 | .lazy_const_data, |
| 6663 | => {}, | 6751 | => {}, |
| 6664 | |||
| 6665 | .section => unreachable, // cannot contain GOT relocs | ||
| 6666 | .uav => unreachable, // cannot contain GOT relocs | ||
| 6667 | |||
| 6668 | .file => unreachable, // cannot contain relocs | ||
| 6669 | .ehdr => unreachable, // cannot contain relocs | ||
| 6670 | .shdr => unreachable, // cannot contain relocs | ||
| 6671 | .segment => unreachable, // cannot contain relocs | ||
| 6672 | .copied_global => unreachable, // cannot contain relocs | ||
| 6673 | } | 6752 | } |
| 6674 | 6753 | ||
| 6675 | const gop = elf.got.getOrPutAssumeCapacity(target); | 6754 | const gop = elf.got.getOrPutAssumeCapacity(target); |
| ... | @@ -7053,11 +7132,24 @@ pub fn flush( | ... | @@ -7053,11 +7132,24 @@ pub fn flush( |
| 7053 | tid: Zcu.PerThread.Id, | 7132 | tid: Zcu.PerThread.Id, |
| 7054 | prog_node: std.Progress.Node, | 7133 | prog_node: std.Progress.Node, |
| 7055 | ) link.Error!void { | 7134 | ) link.Error!void { |
| 7135 | elf.flushInner(arena, tid, prog_node) catch |err| switch (err) { | ||
| 7136 | error.MappedFileIo => return elf.base.comp.link_diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), | ||
| 7137 | else => |e| return e, | ||
| 7138 | }; | ||
| 7139 | } | ||
| 7140 | fn flushInner( | ||
| 7141 | elf: *Elf, | ||
| 7142 | arena: std.mem.Allocator, | ||
| 7143 | tid: Zcu.PerThread.Id, | ||
| 7144 | prog_node: std.Progress.Node, | ||
| 7145 | ) Error!void { | ||
| 7056 | const comp = elf.base.comp; | 7146 | const comp = elf.base.comp; |
| 7057 | const diags = &comp.link_diags; | 7147 | const diags = &comp.link_diags; |
| 7058 | _ = prog_node; | ||
| 7059 | _ = arena; | 7148 | _ = arena; |
| 7060 | 7149 | ||
| 7150 | const sub_prog_node = prog_node.start("ELF Flush", 0); | ||
| 7151 | defer sub_prog_node.end(); | ||
| 7152 | |||
| 7061 | if (comp.config.output_mode == .Exe) { | 7153 | if (comp.config.output_mode == .Exe) { |
| 7062 | var any_undef = false; | 7154 | var any_undef = false; |
| 7063 | for (elf.globals.strong_undef.keys()) |name| { | 7155 | for (elf.globals.strong_undef.keys()) |name| { |
| ... | @@ -7068,11 +7160,9 @@ pub fn flush( | ... | @@ -7068,11 +7160,9 @@ pub fn flush( |
| 7068 | if (any_undef) return error.AlreadyReported; | 7160 | if (any_undef) return error.AlreadyReported; |
| 7069 | } | 7161 | } |
| 7070 | 7162 | ||
| 7071 | elf.prepareDynamic() catch |err| switch (err) { | 7163 | try elf.prepareDynamic(); |
| 7072 | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), | ||
| 7073 | else => |e| return e, | ||
| 7074 | }; | ||
| 7075 | 7164 | ||
| 7165 | try elf.ensureElfNodeSize(); | ||
| 7076 | while (try elf.idle(tid)) {} | 7166 | while (try elf.idle(tid)) {} |
| 7077 | 7167 | ||
| 7078 | // We've done the final `idle` loop, so everything is at its final place in the file. We have a | 7168 | // We've done the final `idle` loop, so everything is at its final place in the file. We have a |
| ... | @@ -7097,10 +7187,7 @@ pub fn flush( | ... | @@ -7097,10 +7187,7 @@ pub fn flush( |
| 7097 | .enabled => "_start", | 7187 | .enabled => "_start", |
| 7098 | .named => |named| named, | 7188 | .named => |named| named, |
| 7099 | }; | 7189 | }; |
| 7100 | const sym_name_strtab = elf.string(.strtab, sym_name_slice) catch |err| switch (err) { | 7190 | const sym_name_strtab = try elf.string(.strtab, sym_name_slice); |
| 7101 | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), | ||
| 7102 | else => |e| return e, | ||
| 7103 | }; | ||
| 7104 | if (elf.globalByName(sym_name_strtab) == null) break :entry 0; | 7191 | if (elf.globalByName(sym_name_strtab) == null) break :entry 0; |
| 7105 | break :entry Symbol.Id.global(sym_name_strtab).value(elf); | 7192 | break :entry Symbol.Id.global(sym_name_strtab).value(elf); |
| 7106 | }; | 7193 | }; |
| ... | @@ -7108,10 +7195,11 @@ pub fn flush( | ... | @@ -7108,10 +7195,11 @@ pub fn flush( |
| 7108 | inline else => |ehdr| elf.targetStore(&ehdr.entry, @intCast(entry_addr)), | 7195 | inline else => |ehdr| elf.targetStore(&ehdr.entry, @intCast(entry_addr)), |
| 7109 | } | 7196 | } |
| 7110 | 7197 | ||
| 7111 | elf.mf.flush() catch |err| switch (err) { | 7198 | try elf.mf.flush(); |
| 7112 | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), | 7199 | |
| 7113 | else => |e| return e, | 7200 | if (elf.options.enable_link_snapshots) |
| 7114 | }; | 7201 | elf.dumpStderr(tid) catch |err| |
| 7202 | return comp.link_diags.fail("dumping link snapshot failed: {t}", .{err}); | ||
| 7115 | } | 7203 | } |
| 7116 | 7204 | ||
| 7117 | pub fn idle(elf: *Elf, tid: Zcu.PerThread.Id) link.Error!bool { | 7205 | pub fn idle(elf: *Elf, tid: Zcu.PerThread.Id) link.Error!bool { |
| ... | @@ -7124,8 +7212,19 @@ pub fn idle(elf: *Elf, tid: Zcu.PerThread.Id) link.Error!bool { | ... | @@ -7124,8 +7212,19 @@ pub fn idle(elf: *Elf, tid: Zcu.PerThread.Id) link.Error!bool { |
| 7124 | } | 7212 | } |
| 7125 | 7213 | ||
| 7126 | task: { | 7214 | task: { |
| 7215 | if (elf.input_pending_index < elf.inputs.items.len) { | ||
| 7216 | const ii: Node.InputIndex = @fromBackingInt(elf.input_pending_index); | ||
| 7217 | elf.input_pending_index += 1; | ||
| 7218 | const sub_prog_node = elf.idleProgNode(tid, elf.input_prog_node, elf.getNode(ii.node(elf))); | ||
| 7219 | defer sub_prog_node.end(); | ||
| 7220 | elf.flushInput(ii) catch |err| switch (err) { | ||
| 7221 | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), | ||
| 7222 | else => |e| return e, | ||
| 7223 | }; | ||
| 7224 | break :task; | ||
| 7225 | } | ||
| 7127 | if (elf.input_section_pending_index < elf.input_sections.items.len) { | 7226 | if (elf.input_section_pending_index < elf.input_sections.items.len) { |
| 7128 | const isi: InputSection.Index = @fromBackingInt(@intCast(elf.input_section_pending_index)); | 7227 | const isi: InputSection.Index = @fromBackingInt(elf.input_section_pending_index); |
| 7129 | elf.input_section_pending_index += 1; | 7228 | elf.input_section_pending_index += 1; |
| 7130 | const sub_prog_node = elf.idleProgNode(tid, elf.input_prog_node, elf.getNode(isi.node(elf))); | 7229 | const sub_prog_node = elf.idleProgNode(tid, elf.input_prog_node, elf.getNode(isi.node(elf))); |
| 7131 | defer sub_prog_node.end(); | 7230 | defer sub_prog_node.end(); |
| ... | @@ -7213,11 +7312,13 @@ pub fn idle(elf: *Elf, tid: Zcu.PerThread.Id) link.Error!bool { | ... | @@ -7213,11 +7312,13 @@ pub fn idle(elf: *Elf, tid: Zcu.PerThread.Id) link.Error!bool { |
| 7213 | while (elf.mf.updates.pop()) |ni| { | 7312 | while (elf.mf.updates.pop()) |ni| { |
| 7214 | const clean_moved = ni.cleanMoved(&elf.mf); | 7313 | const clean_moved = ni.cleanMoved(&elf.mf); |
| 7215 | const clean_resized = ni.cleanResized(&elf.mf); | 7314 | const clean_resized = ni.cleanResized(&elf.mf); |
| 7216 | if (clean_moved or clean_resized) { | 7315 | const clean_next_moved = ni.cleanNextMoved(&elf.mf); |
| 7316 | if (clean_moved or clean_resized or clean_next_moved) { | ||
| 7217 | const sub_prog_node = elf.idleProgNode(tid, elf.mf.update_prog_node, elf.getNode(ni)); | 7317 | const sub_prog_node = elf.idleProgNode(tid, elf.mf.update_prog_node, elf.getNode(ni)); |
| 7218 | defer sub_prog_node.end(); | 7318 | defer sub_prog_node.end(); |
| 7219 | if (clean_moved) try elf.flushMoved(ni); | 7319 | if (clean_moved) try elf.flushMoved(ni); |
| 7220 | if (clean_resized) try elf.flushResized(ni); | 7320 | if (clean_resized) try elf.flushResized(ni); |
| 7321 | if (clean_next_moved) try elf.flushNextMoved(ni); | ||
| 7221 | break :task; | 7322 | break :task; |
| 7222 | } else elf.mf.update_prog_node.completeOne(); | 7323 | } else elf.mf.update_prog_node.completeOne(); |
| 7223 | } | 7324 | } |
| ... | @@ -7238,6 +7339,10 @@ fn idleProgNode( | ... | @@ -7238,6 +7339,10 @@ fn idleProgNode( |
| 7238 | return prog_node.start(name: switch (node) { | 7339 | return prog_node.start(name: switch (node) { |
| 7239 | else => |tag| @tagName(tag), | 7340 | else => |tag| @tagName(tag), |
| 7240 | .section => |shndx| shndx.name(elf).slice(elf), | 7341 | .section => |shndx| shndx.name(elf).slice(elf), |
| 7342 | .input_member => |ii| std.fmt.bufPrint(&name, "{f}{f}", .{ | ||
| 7343 | ii.path(elf).fmtEscapeString(), | ||
| 7344 | fmtMemberString(ii.member(elf)), | ||
| 7345 | }) catch &name, | ||
| 7241 | .input_section => |isi| { | 7346 | .input_section => |isi| { |
| 7242 | const ii = isi.input(elf); | 7347 | const ii = isi.input(elf); |
| 7243 | break :name std.fmt.bufPrint(&name, "{f}{f} {s}", .{ | 7348 | break :name std.fmt.bufPrint(&name, "{f}{f} {s}", .{ |
| ... | @@ -7290,6 +7395,8 @@ fn genPending(elf: *Elf, pt: Zcu.PerThread) Error!void { | ... | @@ -7290,6 +7395,8 @@ fn genPending(elf: *Elf, pt: Zcu.PerThread) Error!void { |
| 7290 | }; | 7395 | }; |
| 7291 | break; | 7396 | break; |
| 7292 | } | 7397 | } |
| 7398 | |||
| 7399 | try elf.ensureElfNodeSize(); | ||
| 7293 | } | 7400 | } |
| 7294 | 7401 | ||
| 7295 | fn genUav( | 7402 | fn genUav( |
| ... | @@ -7358,6 +7465,36 @@ fn genLazy(elf: *Elf, pt: Zcu.PerThread, lmr: Node.LazyMapRef) Error!void { | ... | @@ -7358,6 +7465,36 @@ fn genLazy(elf: *Elf, pt: Zcu.PerThread, lmr: Node.LazyMapRef) Error!void { |
| 7358 | } | 7465 | } |
| 7359 | } | 7466 | } |
| 7360 | 7467 | ||
| 7468 | fn flushInput(elf: *Elf, ii: Node.InputIndex) Error!void { | ||
| 7469 | const comp = elf.base.comp; | ||
| 7470 | const io = comp.io; | ||
| 7471 | const gpa = comp.gpa; | ||
| 7472 | const diags = &comp.link_diags; | ||
| 7473 | const path = ii.path(elf); | ||
| 7474 | const file = path.root_dir.handle.openFile(io, path.sub_path, .{}) catch |err| switch (err) { | ||
| 7475 | error.Canceled => |e| return e, | ||
| 7476 | else => |e| return diags.fail("failed to open input file \"{f}\": {t}", .{ path.fmtEscapeString(), e }), | ||
| 7477 | }; | ||
| 7478 | defer file.close(io); | ||
| 7479 | var fr = file.reader(io, &.{}); | ||
| 7480 | var nw: MappedFile.Node.Writer = undefined; | ||
| 7481 | ii.node(elf).writer(&elf.mf, gpa, &nw); | ||
| 7482 | defer nw.deinit(); | ||
| 7483 | const size = nw.interface.buffer.len - @sizeOf(std.elf.ar_hdr); | ||
| 7484 | const n_bytes = nw.interface.sendFileAll(&fr, .limited(size)) catch |err| switch (err) { | ||
| 7485 | error.ReadFailed => return diags.fail("failed to read input \"{f}{f}\": {t}", .{ | ||
| 7486 | path.fmtEscapeString(), | ||
| 7487 | fmtMemberString(ii.member(elf)), | ||
| 7488 | fr.err orelse (fr.seek_err orelse fr.size_err.?), | ||
| 7489 | }), | ||
| 7490 | error.WriteFailed => return nw.err.?, | ||
| 7491 | }; | ||
| 7492 | if (n_bytes + 1 < size) return diags.fail("failed to read input \"{f}{f}\": unexpected eof", .{ | ||
| 7493 | path.fmtEscapeString(), | ||
| 7494 | fmtMemberString(ii.member(elf)), | ||
| 7495 | }); | ||
| 7496 | } | ||
| 7497 | |||
| 7361 | fn flushInputSection(elf: *Elf, isi: InputSection.Index) Error!void { | 7498 | fn flushInputSection(elf: *Elf, isi: InputSection.Index) Error!void { |
| 7362 | const file_loc = isi.fileLocation(elf); | 7499 | const file_loc = isi.fileLocation(elf); |
| 7363 | if (file_loc.size == 0) return; | 7500 | if (file_loc.size == 0) return; |
| ... | @@ -7404,33 +7541,29 @@ fn flushInputSection(elf: *Elf, isi: InputSection.Index) Error!void { | ... | @@ -7404,33 +7541,29 @@ fn flushInputSection(elf: *Elf, isi: InputSection.Index) Error!void { |
| 7404 | assert(isi.node(elf).hasMoved(&elf.mf)); | 7541 | assert(isi.node(elf).hasMoved(&elf.mf)); |
| 7405 | } | 7542 | } |
| 7406 | 7543 | ||
| 7407 | fn flushFileOffset(elf: *Elf, ni: MappedFile.Node.Index) void { | 7544 | fn flushElfOffset(elf: *Elf, ni: MappedFile.Node.Index) void { |
| 7545 | const elf_offset = elf.getNodeElfOffset(ni); | ||
| 7408 | switch (elf.getNode(ni)) { | 7546 | switch (elf.getNode(ni)) { |
| 7409 | else => unreachable, | 7547 | else => unreachable, |
| 7410 | .ehdr => assert(ni.fileLocation(&elf.mf, false).offset == 0), | 7548 | .ehdr => assert(elf_offset == 0), |
| 7411 | .shdr => switch (elf.ehdrPtr()) { | 7549 | .shdr => switch (elf.ehdrPtr()) { |
| 7412 | inline else => |ehdr| elf.targetStore( | 7550 | inline else => |ehdr| elf.targetStore(&ehdr.shoff, @intCast(elf_offset)), |
| 7413 | &ehdr.shoff, | ||
| 7414 | @intCast(ni.fileLocation(&elf.mf, false).offset), | ||
| 7415 | ), | ||
| 7416 | }, | 7551 | }, |
| 7417 | .segment => |phndx| { | 7552 | .segment => |phndx| { |
| 7418 | switch (elf.phdrSlice()) { | 7553 | switch (elf.phdrSlice()) { |
| 7419 | inline else => |phdr, class| { | 7554 | inline else => |phdr, class| { |
| 7420 | const ph = &phdr[phndx]; | 7555 | const ph = &phdr[phndx]; |
| 7421 | elf.targetStore(&ph.offset, @intCast(ni.fileLocation(&elf.mf, false).offset)); | 7556 | elf.targetStore(&ph.offset, @intCast(elf_offset)); |
| 7422 | if (elf.targetLoad(&ph.type) == .PHDR) { | 7557 | if (elf.targetLoad(&ph.type) == .PHDR) { |
| 7423 | @field(elf.ehdrPtr(), @tagName(class)).phoff = ph.offset; | 7558 | @field(elf.ehdrPtr(), @tagName(class)).phoff = ph.offset; |
| 7424 | } | 7559 | } |
| 7425 | }, | 7560 | }, |
| 7426 | } | 7561 | } |
| 7427 | var child_it = ni.children(&elf.mf); | 7562 | var child_it = ni.children(&elf.mf); |
| 7428 | while (child_it.next()) |child_ni| elf.flushFileOffset(child_ni); | 7563 | while (child_it.next()) |child_ni| elf.flushElfOffset(child_ni); |
| 7429 | }, | 7564 | }, |
| 7430 | .section => |shndx| switch (elf.shdrPtr(shndx)) { | 7565 | .section => |shndx| switch (elf.shdrPtr(shndx)) { |
| 7431 | inline else => |shdr| elf.targetStore(&shdr.offset, @intCast( | 7566 | inline else => |shdr| elf.targetStore(&shdr.offset, @intCast(elf_offset)), |
| 7432 | ni.fileLocation(&elf.mf, false).offset, | ||
| 7433 | )), | ||
| 7434 | }, | 7567 | }, |
| 7435 | } | 7568 | } |
| 7436 | } | 7569 | } |
| ... | @@ -7443,10 +7576,11 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void | ... | @@ -7443,10 +7576,11 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void |
| 7443 | defer elf.mf.nodes_lock.unlock(); | 7576 | defer elf.mf.nodes_lock.unlock(); |
| 7444 | 7577 | ||
| 7445 | switch (elf.getNode(ni)) { | 7578 | switch (elf.getNode(ni)) { |
| 7446 | .file => unreachable, | 7579 | .archive, .archive_header => unreachable, |
| 7447 | .ehdr, .shdr => elf.flushFileOffset(ni), | 7580 | .elf => {}, |
| 7581 | .ehdr, .shdr => elf.flushElfOffset(ni), | ||
| 7448 | .segment => |phndx| { | 7582 | .segment => |phndx| { |
| 7449 | elf.flushFileOffset(ni); | 7583 | elf.flushElfOffset(ni); |
| 7450 | switch (elf.phdrSlice()) { | 7584 | switch (elf.phdrSlice()) { |
| 7451 | inline else => |phdr| { | 7585 | inline else => |phdr| { |
| 7452 | const ph = &phdr[phndx]; | 7586 | const ph = &phdr[phndx]; |
| ... | @@ -7467,7 +7601,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void | ... | @@ -7467,7 +7601,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void |
| 7467 | } | 7601 | } |
| 7468 | }, | 7602 | }, |
| 7469 | .section => |shndx| { | 7603 | .section => |shndx| { |
| 7470 | elf.flushFileOffset(ni); | 7604 | elf.flushElfOffset(ni); |
| 7471 | const addr = elf.computeNodeVAddr(ni); | 7605 | const addr = elf.computeNodeVAddr(ni); |
| 7472 | const old_addr: u64, const flags: std.elf.SHF = switch (elf.shdrPtr(shndx)) { | 7606 | const old_addr: u64, const flags: std.elf.SHF = switch (elf.shdrPtr(shndx)) { |
| 7473 | inline else => |shdr| .{ | 7607 | inline else => |shdr| .{ |
| ... | @@ -7518,6 +7652,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void | ... | @@ -7518,6 +7652,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void |
| 7518 | elf.flushMovedNodeRelocs(ni, addr, elf.dynamic_first_symbol_reloc, .none); | 7652 | elf.flushMovedNodeRelocs(ni, addr, elf.dynamic_first_symbol_reloc, .none); |
| 7519 | } | 7653 | } |
| 7520 | }, | 7654 | }, |
| 7655 | .input_member => {}, | ||
| 7521 | .input_section => |isi| { | 7656 | .input_section => |isi| { |
| 7522 | const old_section_addr = isi.ptr(elf).vaddr; | 7657 | const old_section_addr = isi.ptr(elf).vaddr; |
| 7523 | const new_section_addr = elf.computeNodeVAddr(ni); | 7658 | const new_section_addr = elf.computeNodeVAddr(ni); |
| ... | @@ -7526,7 +7661,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void | ... | @@ -7526,7 +7661,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void |
| 7526 | // Update local symbols | 7661 | // Update local symbols |
| 7527 | const ii = isi.input(elf); | 7662 | const ii = isi.input(elf); |
| 7528 | var lsi, const end_lsi = ii.localSymbolRange(elf); | 7663 | var lsi, const end_lsi = ii.localSymbolRange(elf); |
| 7529 | while (lsi != end_lsi) : (lsi = @fromBackingInt(@intCast(@backingInt(lsi) + 1))) { | 7664 | while (lsi != end_lsi) : (lsi = @fromBackingInt(@backingInt(lsi) + 1)) { |
| 7530 | if (lsi.index().ptr(elf).node != ni) continue; | 7665 | if (lsi.index().ptr(elf).node != ni) continue; |
| 7531 | const visibility: std.elf.STV = switch (elf.symPtr(lsi.index())) { | 7666 | const visibility: std.elf.STV = switch (elf.symPtr(lsi.index())) { |
| 7532 | inline else => |sym| elf.targetLoad(&sym.other).visibility, | 7667 | inline else => |sym| elf.targetLoad(&sym.other).visibility, |
| ... | @@ -7613,7 +7748,17 @@ fn flushResized(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!vo | ... | @@ -7613,7 +7748,17 @@ fn flushResized(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!vo |
| 7613 | 7748 | ||
| 7614 | _, const size = ni.location(&elf.mf).resolve(&elf.mf); | 7749 | _, const size = ni.location(&elf.mf).resolve(&elf.mf); |
| 7615 | switch (elf.getNode(ni)) { | 7750 | switch (elf.getNode(ni)) { |
| 7616 | .file => {}, | 7751 | .archive => { |
| 7752 | var child_it = ni.reverseChildren(&elf.mf); | ||
| 7753 | if (child_it.next()) |last_ni| { | ||
| 7754 | if (child_it.next()) |prev_ni| if (prev_ni.hasNextMoved(&elf.mf)) return; | ||
| 7755 | const offset, _ = last_ni.location(&elf.mf).resolve(&elf.mf); | ||
| 7756 | _ = std.mem.print(&elf.arHdrPtr(last_ni).ar_size, "{d:<10}", .{ | ||
| 7757 | size - offset, | ||
| 7758 | }) catch @panic("archive member too large"); | ||
| 7759 | } | ||
| 7760 | }, | ||
| 7761 | .archive_header, .elf => {}, | ||
| 7617 | .ehdr => unreachable, | 7762 | .ehdr => unreachable, |
| 7618 | .shdr => {}, | 7763 | .shdr => {}, |
| 7619 | .segment => |phndx| switch (elf.phdrSlice()) { | 7764 | .segment => |phndx| switch (elf.phdrSlice()) { |
| ... | @@ -7713,9 +7858,88 @@ fn flushResized(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!vo | ... | @@ -7713,9 +7858,88 @@ fn flushResized(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!vo |
| 7713 | } | 7858 | } |
| 7714 | }, | 7859 | }, |
| 7715 | }, | 7860 | }, |
| 7716 | .copied_global, .input_section, .nav, .uav, .lazy_code, .lazy_const_data => {}, | 7861 | .input_member, .input_section, .copied_global, .nav, .uav, .lazy_code, .lazy_const_data => {}, |
| 7717 | } | 7862 | } |
| 7718 | } | 7863 | } |
| 7864 | |||
| 7865 | fn flushNextMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void { | ||
| 7866 | const trace = tracy.trace(@src()); | ||
| 7867 | defer trace.end(); | ||
| 7868 | |||
| 7869 | elf.mf.nodes_lock.lock(); | ||
| 7870 | defer elf.mf.nodes_lock.unlock(); | ||
| 7871 | |||
| 7872 | switch (elf.getNode(ni)) { | ||
| 7873 | .archive, | ||
| 7874 | .ehdr, | ||
| 7875 | .shdr, | ||
| 7876 | .segment, | ||
| 7877 | .section, | ||
| 7878 | .input_section, | ||
| 7879 | .copied_global, | ||
| 7880 | .nav, | ||
| 7881 | .uav, | ||
| 7882 | .lazy_code, | ||
| 7883 | .lazy_const_data, | ||
| 7884 | => unreachable, | ||
| 7885 | .archive_header, .elf, .input_member => |_, tag| { | ||
| 7886 | const member_offset, const update_size = member_offset: { | ||
| 7887 | const offset, _ = ni.location(&elf.mf).resolve(&elf.mf); | ||
| 7888 | break :member_offset switch (tag) { | ||
| 7889 | else => unreachable, | ||
| 7890 | .archive_header => .{ offset + std.elf.ARMAG.len + @sizeOf(std.elf.ar_hdr), true }, | ||
| 7891 | .elf, .input_member => .{ offset, switch (ni.prev(&elf.mf)) { | ||
| 7892 | .none => unreachable, | ||
| 7893 | else => |prev_ni| !prev_ni.hasNextMoved(&elf.mf), | ||
| 7894 | } }, | ||
| 7895 | }; | ||
| 7896 | }; | ||
| 7897 | const member_size = member_end: switch (ni.next(&elf.mf)) { | ||
| 7898 | else => |next_ni| { | ||
| 7899 | const next_offset, _ = next_ni.location(&elf.mf).resolve(&elf.mf); | ||
| 7900 | const next_member_size = next_member_end: switch (next_ni.next(&elf.mf)) { | ||
| 7901 | else => |next_next_ni| { | ||
| 7902 | const next_next_offset, _ = next_next_ni.location(&elf.mf).resolve(&elf.mf); | ||
| 7903 | break :next_member_end next_next_offset - @sizeOf(std.elf.ar_hdr); | ||
| 7904 | }, | ||
| 7905 | .none => { | ||
| 7906 | _, const parent_size = | ||
| 7907 | ni.parent(&elf.mf).location(&elf.mf).resolve(&elf.mf); | ||
| 7908 | break :next_member_end parent_size; | ||
| 7909 | }, | ||
| 7910 | } - next_offset; | ||
| 7911 | const ar_hdr = elf.arHdrPtr(next_ni); | ||
| 7912 | var name_buf: [16]u8 = undefined; | ||
| 7913 | _ = std.mem.print(&ar_hdr.ar_name, "{s:<16}", .{ | ||
| 7914 | switch (elf.getNode(next_ni)) { | ||
| 7915 | else => unreachable, | ||
| 7916 | .elf => std.mem.print(&name_buf, "{s}_zcu.o/", .{elf.base.comp.root_name}), | ||
| 7917 | .input_member => |ii| std.mem.print(&name_buf, "{s}/", .{ | ||
| 7918 | std.fs.path.basename(ii.path(elf).sub_path), | ||
| 7919 | }), | ||
| 7920 | } catch @panic("TODO: long archive member names"), | ||
| 7921 | }) catch @panic("TODO: long archive member names"); | ||
| 7922 | ar_hdr.ar_date = "0 ".*; | ||
| 7923 | ar_hdr.ar_uid = "0 ".*; | ||
| 7924 | ar_hdr.ar_gid = "0 ".*; | ||
| 7925 | ar_hdr.ar_mode = "644 ".*; | ||
| 7926 | _ = std.mem.print(&ar_hdr.ar_size, "{d:<10}", .{next_member_size}) catch | ||
| 7927 | @panic("archive member too large"); | ||
| 7928 | ar_hdr.ar_fmag = std.elf.ARFMAG.*; | ||
| 7929 | break :member_end next_offset - @sizeOf(std.elf.ar_hdr); | ||
| 7930 | }, | ||
| 7931 | .none => { | ||
| 7932 | _, const parent_size = ni.parent(&elf.mf).location(&elf.mf).resolve(&elf.mf); | ||
| 7933 | break :member_end parent_size; | ||
| 7934 | }, | ||
| 7935 | } - member_offset; | ||
| 7936 | if (update_size) _ = std.mem.print(&elf.arHdrPtr(ni).ar_size, "{d:<10}", .{ | ||
| 7937 | member_size, | ||
| 7938 | }) catch @panic("archive member too large"); | ||
| 7939 | }, | ||
| 7940 | } | ||
| 7941 | } | ||
| 7942 | |||
| 7719 | fn updateDynamicEntry(elf: *Elf, key: u32, new_val: u64) void { | 7943 | fn updateDynamicEntry(elf: *Elf, key: u32, new_val: u64) void { |
| 7720 | switch (elf.shdrPtr(elf.shndx.dynamic)) { | 7944 | switch (elf.shdrPtr(elf.shndx.dynamic)) { |
| 7721 | inline else => |shdr, class| { | 7945 | inline else => |shdr, class| { |
| ... | @@ -7756,7 +7980,7 @@ fn addPltEntry(elf: *Elf, global_name: String(.strtab), dynsym_index: u32) void | ... | @@ -7756,7 +7980,7 @@ fn addPltEntry(elf: *Elf, global_name: String(.strtab), dynsym_index: u32) void |
| 7756 | }; | 7980 | }; |
| 7757 | 7981 | ||
| 7758 | // Now that we know the index, we can set the relocation's offset. | 7982 | // Now that we know the index, we can set the relocation's offset. |
| 7759 | elf.shndx.rela_plt.relaSetOffset(elf, @fromBackingInt(@intCast(plt_index)), got_plt_section.vaddr(elf) + got_plt_offset); | 7983 | elf.shndx.rela_plt.relaSetOffset(elf, @fromBackingInt(plt_index), got_plt_section.vaddr(elf) + got_plt_offset); |
| 7760 | 7984 | ||
| 7761 | if (plt_index < elf.plt.count()) { | 7985 | if (plt_index < elf.plt.count()) { |
| 7762 | // We reused a free entry, so we're already done! | 7986 | // We reused a free entry, so we're already done! |
| ... | @@ -8096,7 +8320,10 @@ fn updateExportsInner( | ... | @@ -8096,7 +8320,10 @@ fn updateExportsInner( |
| 8096 | }, | 8320 | }, |
| 8097 | .uav => |uav| .{ (try elf.uavMapIndex(uav, .none)).symbol(elf), .OBJECT }, | 8321 | .uav => |uav| .{ (try elf.uavMapIndex(uav, .none)).symbol(elf), .OBJECT }, |
| 8098 | }; | 8322 | }; |
| 8323 | |||
| 8324 | try elf.ensureElfNodeSize(); | ||
| 8099 | while (try elf.idle(pt.tid)) {} | 8325 | while (try elf.idle(pt.tid)) {} |
| 8326 | |||
| 8100 | const value: u64 = Symbol.Id.local(exported_lsi).value(elf); | 8327 | const value: u64 = Symbol.Id.local(exported_lsi).value(elf); |
| 8101 | const size: u64, const shndx: Section.Index = switch (elf.symPtr(exported_lsi.index())) { | 8328 | const size: u64, const shndx: Section.Index = switch (elf.symPtr(exported_lsi.index())) { |
| 8102 | inline else => |exported_sym| .{ | 8329 | inline else => |exported_sym| .{ |
| ... | @@ -8150,6 +8377,16 @@ pub fn deleteExport(elf: *Elf, exported: Zcu.Exported, name: InternPool.NullTerm | ... | @@ -8150,6 +8377,16 @@ pub fn deleteExport(elf: *Elf, exported: Zcu.Exported, name: InternPool.NullTerm |
| 8150 | _ = name; | 8377 | _ = name; |
| 8151 | } | 8378 | } |
| 8152 | 8379 | ||
| 8380 | fn dumpStderr(elf: *Elf, tid: Zcu.PerThread.Id) !void { | ||
| 8381 | const comp = elf.base.comp; | ||
| 8382 | const io = comp.io; | ||
| 8383 | var buffer: [512]u8 = undefined; | ||
| 8384 | const stderr = try io.lockStderr(&buffer, null); | ||
| 8385 | defer io.unlockStderr(); | ||
| 8386 | const w = &stderr.file_writer.interface; | ||
| 8387 | _ = try elf.dump(w, tid); | ||
| 8388 | } | ||
| 8389 | |||
| 8153 | pub fn dump(elf: *Elf, w: *Io.Writer, tid: Zcu.PerThread.Id) !link.File.DumpResult { | 8390 | pub fn dump(elf: *Elf, w: *Io.Writer, tid: Zcu.PerThread.Id) !link.File.DumpResult { |
| 8154 | if (elf.options.enable_link_snapshots) { | 8391 | if (elf.options.enable_link_snapshots) { |
| 8155 | try elf.printNode(tid, w, .root, 0); | 8392 | try elf.printNode(tid, w, .root, 0); |
| ... | @@ -8227,13 +8464,14 @@ pub fn printNode( | ... | @@ -8227,13 +8464,14 @@ pub fn printNode( |
| 8227 | { | 8464 | { |
| 8228 | const mf_node = &elf.mf.nodes.items[@backingInt(ni)]; | 8465 | const mf_node = &elf.mf.nodes.items[@backingInt(ni)]; |
| 8229 | const off, const size = mf_node.location().resolve(&elf.mf); | 8466 | const off, const size = mf_node.location().resolve(&elf.mf); |
| 8230 | try w.print(" index={d} offset=0x{x} size=0x{x} align=0x{x}{s}{s}{s}{s}\n", .{ | 8467 | try w.print(" index={d} offset=0x{x} size=0x{x} align=0x{x}{s}{s}{s}{s}{s}\n", .{ |
| 8231 | @backingInt(ni), | 8468 | @backingInt(ni), |
| 8232 | off, | 8469 | off, |
| 8233 | size, | 8470 | size, |
| 8234 | mf_node.flags.alignment.toByteUnits(), | 8471 | mf_node.flags.alignment.toByteUnits(), |
| 8235 | if (mf_node.flags.fixed) " fixed" else "", | 8472 | if (mf_node.flags.fixed) " fixed" else "", |
| 8236 | if (mf_node.flags.moved) " moved" else "", | 8473 | if (mf_node.flags.moved) " moved" else "", |
| 8474 | if (mf_node.flags.next_moved) " next_moved" else "", | ||
| 8237 | if (mf_node.flags.resized) " resized" else "", | 8475 | if (mf_node.flags.resized) " resized" else "", |
| 8238 | if (mf_node.flags.has_content) " has_content" else "", | 8476 | if (mf_node.flags.has_content) " has_content" else "", |
| 8239 | }); | 8477 | }); |
| ... | @@ -8269,11 +8507,19 @@ pub fn printNode( | ... | @@ -8269,11 +8507,19 @@ pub fn printNode( |
| 8269 | } | 8507 | } |
| 8270 | } | 8508 | } |
| 8271 | 8509 | ||
| 8272 | fn ensureNodeSize( | 8510 | /// Must be called deterministically after any call to `MappedFile.Node.Index.resize` |
| 8273 | elf: *Elf, | 8511 | /// (of `elf.ni.elf` or one of its children) before any possible calls to `idle`. |
| 8274 | node: MappedFile.Node.Index, | 8512 | fn ensureElfNodeSize(elf: *Elf) MappedFile.Error!void { |
| 8275 | need_size: u64, | 8513 | if (elf.ni.elf == MappedFile.Node.Index.root) return; |
| 8276 | ) Error!void { | 8514 | var child_it = elf.ni.elf.reverseChildren(&elf.mf); |
| 8515 | const last_end = if (child_it.next()) |last_ni| last_end: { | ||
| 8516 | const last_offset, const last_size = last_ni.location(&elf.mf).resolve(&elf.mf); | ||
| 8517 | break :last_end last_offset + last_size; | ||
| 8518 | } else 0; | ||
| 8519 | try elf.ensureNodeSize(elf.ni.elf, last_end + @sizeOf(std.elf.ar_hdr)); | ||
| 8520 | } | ||
| 8521 | |||
| 8522 | fn ensureNodeSize(elf: *Elf, node: MappedFile.Node.Index, need_size: u64) MappedFile.Error!void { | ||
| 8277 | _, const node_size = node.location(&elf.mf).resolve(&elf.mf); | 8523 | _, const node_size = node.location(&elf.mf).resolve(&elf.mf); |
| 8278 | if (need_size <= node_size) return; | 8524 | if (need_size <= node_size) return; |
| 8279 | const gpa = elf.base.comp.gpa; | 8525 | const gpa = elf.base.comp.gpa; |
src/link/Lld.zig+39-26| ... | @@ -99,8 +99,6 @@ pub const Elf = struct { | ... | @@ -99,8 +99,6 @@ pub const Elf = struct { |
| 99 | bind_global_refs_locally: bool, | 99 | bind_global_refs_locally: bool, |
| 100 | pub const HashStyle = enum { sysv, gnu, both }; | 100 | pub const HashStyle = enum { sysv, gnu, both }; |
| 101 | pub const SortSection = enum { name, alignment }; | 101 | pub const SortSection = enum { name, alignment }; |
| 102 | /// Deprecated; use 'std.zig.CompressDebugSections' instead. To be removed after 0.16.0 is tagged. | ||
| 103 | pub const CompressDebugSections = std.zig.CompressDebugSections; | ||
| 104 | 102 | ||
| 105 | fn init(comp: *Compilation, options: link.File.OpenOptions) !Elf { | 103 | fn init(comp: *Compilation, options: link.File.OpenOptions) !Elf { |
| 106 | const PtrWidth = enum { p32, p64 }; | 104 | const PtrWidth = enum { p32, p64 }; |
| ... | @@ -208,8 +206,8 @@ pub fn createEmpty( | ... | @@ -208,8 +206,8 @@ pub fn createEmpty( |
| 208 | const optimize_mode = comp.root_mod.optimize_mode; | 206 | const optimize_mode = comp.root_mod.optimize_mode; |
| 209 | 207 | ||
| 210 | const gc_sections: bool = options.gc_sections orelse switch (target.ofmt) { | 208 | const gc_sections: bool = options.gc_sections orelse switch (target.ofmt) { |
| 211 | .coff => optimize_mode != .Debug, | 209 | .coff => optimize_mode != .debug, |
| 212 | .elf => optimize_mode != .Debug and output_mode != .Obj, | 210 | .elf => optimize_mode != .debug and output_mode != .Obj, |
| 213 | .wasm => output_mode != .Obj, | 211 | .wasm => output_mode != .Obj, |
| 214 | else => unreachable, | 212 | else => unreachable, |
| 215 | }; | 213 | }; |
| ... | @@ -271,12 +269,12 @@ pub fn flush( | ... | @@ -271,12 +269,12 @@ pub fn flush( |
| 271 | .wasm => wasmLink(lld, arena), | 269 | .wasm => wasmLink(lld, arena), |
| 272 | }; | 270 | }; |
| 273 | result catch |err| switch (err) { | 271 | result catch |err| switch (err) { |
| 274 | error.OutOfMemory, error.AlreadyReported => |e| return e, | 272 | error.OutOfMemory, error.AlreadyReported, error.Canceled => |e| return e, |
| 275 | else => |e| return lld.base.comp.link_diags.fail("failed to link with LLD: {t}", .{e}), | 273 | else => |e| return lld.base.comp.link_diags.fail("failed to link with LLD: {t}", .{e}), |
| 276 | }; | 274 | }; |
| 277 | } | 275 | } |
| 278 | 276 | ||
| 279 | fn linkAsArchive(lld: *Lld, arena: Allocator) !void { | 277 | fn linkAsArchive(lld: *Lld, arena: Allocator) link.Error!void { |
| 280 | const base = &lld.base; | 278 | const base = &lld.base; |
| 281 | const comp = base.comp; | 279 | const comp = base.comp; |
| 282 | const directory = base.emit.root_dir; // Just an alias to make it shorter to type. | 280 | const directory = base.emit.root_dir; // Just an alias to make it shorter to type. |
| ... | @@ -308,8 +306,8 @@ fn linkAsArchive(lld: *Lld, arena: Allocator) !void { | ... | @@ -308,8 +306,8 @@ fn linkAsArchive(lld: *Lld, arena: Allocator) !void { |
| 308 | 306 | ||
| 309 | try object_files.ensureUnusedCapacity(arena, comp.link_inputs.len); | 307 | try object_files.ensureUnusedCapacity(arena, comp.link_inputs.len); |
| 310 | for (comp.link_inputs) |input| switch (input) { | 308 | for (comp.link_inputs) |input| switch (input) { |
| 311 | .res, .dso, .dso_exact => {}, // shared libraries should not be included in static archives | 309 | .dso, .dso_exact, .archive => {}, // static archives should not contain shared libraries or other static archives |
| 312 | .object, .archive => { | 310 | .res, .object => { |
| 313 | const path = try input.path().?.toStringZ(arena); | 311 | const path = try input.path().?.toStringZ(arena); |
| 314 | object_files.appendAssumeCapacity(path); | 312 | object_files.appendAssumeCapacity(path); |
| 315 | }, | 313 | }, |
| ... | @@ -340,7 +338,9 @@ fn linkAsArchive(lld: *Lld, arena: Allocator) !void { | ... | @@ -340,7 +338,9 @@ fn linkAsArchive(lld: *Lld, arena: Allocator) !void { |
| 340 | const llvm = @import("../codegen/llvm.zig"); | 338 | const llvm = @import("../codegen/llvm.zig"); |
| 341 | const target = &comp.root_mod.resolved_target.result; | 339 | const target = &comp.root_mod.resolved_target.result; |
| 342 | llvm.initializeLLVMTarget(target.cpu.arch); | 340 | llvm.initializeLLVMTarget(target.cpu.arch); |
| 343 | const bad = llvm_bindings.WriteArchive( | 341 | var err_file_index: usize = undefined; |
| 342 | var err_msg: [*:0]u8 = undefined; | ||
| 343 | if (llvm_bindings.WriteArchive( | ||
| 344 | full_out_path_z, | 344 | full_out_path_z, |
| 345 | object_files.items.ptr, | 345 | object_files.items.ptr, |
| 346 | object_files.items.len, | 346 | object_files.items.len, |
| ... | @@ -348,8 +348,19 @@ fn linkAsArchive(lld: *Lld, arena: Allocator) !void { | ... | @@ -348,8 +348,19 @@ fn linkAsArchive(lld: *Lld, arena: Allocator) !void { |
| 348 | .windows => .COFF, | 348 | .windows => .COFF, |
| 349 | else => if (target.os.tag.isDarwin()) .DARWIN else .GNU, | 349 | else => if (target.os.tag.isDarwin()) .DARWIN else .GNU, |
| 350 | }, | 350 | }, |
| 351 | ); | 351 | &err_file_index, |
| 352 | if (bad) return error.UnableToWriteArchive; | 352 | &err_msg, |
| 353 | )) { | ||
| 354 | defer std.c.free(err_msg); | ||
| 355 | if (err_file_index < object_files.items.len) { | ||
| 356 | return comp.link_diags.fail("LLD failed to open input file '{s}': {s}", .{ | ||
| 357 | object_files.items[err_file_index], | ||
| 358 | err_msg, | ||
| 359 | }); | ||
| 360 | } else { | ||
| 361 | return comp.link_diags.fail("LLD failed to write archive: {s}", .{err_msg}); | ||
| 362 | } | ||
| 363 | } | ||
| 353 | } | 364 | } |
| 354 | 365 | ||
| 355 | fn addCommonArgs(argv: *std.array_list.Managed([]const u8), coff: bool) !void { | 366 | fn addCommonArgs(argv: *std.array_list.Managed([]const u8), coff: bool) !void { |
| ... | @@ -383,7 +394,7 @@ fn coffLink(lld: *Lld, arena: Allocator) !void { | ... | @@ -383,7 +394,7 @@ fn coffLink(lld: *Lld, arena: Allocator) !void { |
| 383 | const target = &comp.root_mod.resolved_target.result; | 394 | const target = &comp.root_mod.resolved_target.result; |
| 384 | const optimize_mode = comp.root_mod.optimize_mode; | 395 | const optimize_mode = comp.root_mod.optimize_mode; |
| 385 | const entry_name: ?[]const u8 = switch (coff.entry) { | 396 | const entry_name: ?[]const u8 = switch (coff.entry) { |
| 386 | // This logic isn't quite right for disabled or enabled. No point in fixing it | 397 | // This logic isn't quite right for default or enabled. No point in fixing it |
| 387 | // when the goal is to eliminate dependency on LLD anyway. | 398 | // when the goal is to eliminate dependency on LLD anyway. |
| 388 | // https://github.com/ziglang/zig/issues/17751 | 399 | // https://github.com/ziglang/zig/issues/17751 |
| 389 | .disabled, .default, .enabled => null, | 400 | .disabled, .default, .enabled => null, |
| ... | @@ -456,9 +467,9 @@ fn coffLink(lld: *Lld, arena: Allocator) !void { | ... | @@ -456,9 +467,9 @@ fn coffLink(lld: *Lld, arena: Allocator) !void { |
| 456 | 467 | ||
| 457 | if (comp.config.lto != .none) { | 468 | if (comp.config.lto != .none) { |
| 458 | switch (optimize_mode) { | 469 | switch (optimize_mode) { |
| 459 | .Debug => {}, | 470 | .debug => {}, |
| 460 | .ReleaseSmall => try argv.append("-OPT:lldlto=2"), | 471 | .small => try argv.append("-OPT:lldlto=2"), |
| 461 | .ReleaseFast, .ReleaseSafe => try argv.append("-OPT:lldlto=3"), | 472 | .fast, .safe => try argv.append("-OPT:lldlto=3"), |
| 462 | } | 473 | } |
| 463 | } | 474 | } |
| 464 | if (comp.config.output_mode == .Exe) { | 475 | if (comp.config.output_mode == .Exe) { |
| ... | @@ -492,6 +503,8 @@ fn coffLink(lld: *Lld, arena: Allocator) !void { | ... | @@ -492,6 +503,8 @@ fn coffLink(lld: *Lld, arena: Allocator) !void { |
| 492 | 503 | ||
| 493 | if (entry_name) |name| { | 504 | if (entry_name) |name| { |
| 494 | try argv.append(try arena.print("-ENTRY:{s}", .{name})); | 505 | try argv.append(try arena.print("-ENTRY:{s}", .{name})); |
| 506 | } else if (coff.entry == .disabled) { | ||
| 507 | try argv.append("-NOENTRY"); | ||
| 495 | } | 508 | } |
| 496 | 509 | ||
| 497 | if (coff.repro) { | 510 | if (coff.repro) { |
| ... | @@ -865,15 +878,15 @@ fn elfLink(lld: *Lld, arena: Allocator) !void { | ... | @@ -865,15 +878,15 @@ fn elfLink(lld: *Lld, arena: Allocator) !void { |
| 865 | 878 | ||
| 866 | if (comp.config.lto != .none) { | 879 | if (comp.config.lto != .none) { |
| 867 | switch (comp.root_mod.optimize_mode) { | 880 | switch (comp.root_mod.optimize_mode) { |
| 868 | .Debug => {}, | 881 | .debug => {}, |
| 869 | .ReleaseSmall => try argv.append("--lto-O2"), | 882 | .small => try argv.append("--lto-O2"), |
| 870 | .ReleaseFast, .ReleaseSafe => try argv.append("--lto-O3"), | 883 | .fast, .safe => try argv.append("--lto-O3"), |
| 871 | } | 884 | } |
| 872 | } | 885 | } |
| 873 | switch (comp.root_mod.optimize_mode) { | 886 | switch (comp.root_mod.optimize_mode) { |
| 874 | .Debug => {}, | 887 | .debug => {}, |
| 875 | .ReleaseSmall => try argv.append("-O2"), | 888 | .small => try argv.append("-O2"), |
| 876 | .ReleaseFast, .ReleaseSafe => try argv.append("-O3"), | 889 | .fast, .safe => try argv.append("-O3"), |
| 877 | } | 890 | } |
| 878 | 891 | ||
| 879 | if (elf.entry_name) |name| { | 892 | if (elf.entry_name) |name| { |
| ... | @@ -1010,8 +1023,8 @@ fn elfLink(lld: *Lld, arena: Allocator) !void { | ... | @@ -1010,8 +1023,8 @@ fn elfLink(lld: *Lld, arena: Allocator) !void { |
| 1010 | } | 1023 | } |
| 1011 | 1024 | ||
| 1012 | if (is_exe_or_dyn_lib and target.os.tag == .netbsd) { | 1025 | if (is_exe_or_dyn_lib and target.os.tag == .netbsd) { |
| 1013 | // Add options to produce shared objects with only 2 PT_LOAD segments. | 1026 | // Add options to produce shared objects with only 2 PT.LOAD segments. |
| 1014 | // NetBSD expects 2 PT_LOAD segments in a shared object, otherwise | 1027 | // NetBSD expects 2 PT.LOAD segments in a shared object, otherwise |
| 1015 | // ld.elf_so fails loading dynamic libraries with "not found" error. | 1028 | // ld.elf_so fails loading dynamic libraries with "not found" error. |
| 1016 | // See https://github.com/ziglang/zig/issues/9109 . | 1029 | // See https://github.com/ziglang/zig/issues/9109 . |
| 1017 | try argv.append("--no-rosegment"); | 1030 | try argv.append("--no-rosegment"); |
| ... | @@ -1416,9 +1429,9 @@ fn wasmLink(lld: *Lld, arena: Allocator) !void { | ... | @@ -1416,9 +1429,9 @@ fn wasmLink(lld: *Lld, arena: Allocator) !void { |
| 1416 | 1429 | ||
| 1417 | if (comp.config.lto != .none) { | 1430 | if (comp.config.lto != .none) { |
| 1418 | switch (comp.root_mod.optimize_mode) { | 1431 | switch (comp.root_mod.optimize_mode) { |
| 1419 | .Debug => {}, | 1432 | .debug => {}, |
| 1420 | .ReleaseSmall => try argv.append("-O2"), | 1433 | .small => try argv.append("-O2"), |
| 1421 | .ReleaseFast, .ReleaseSafe => try argv.append("-O3"), | 1434 | .fast, .safe => try argv.append("-O3"), |
| 1422 | } | 1435 | } |
| 1423 | } | 1436 | } |
| 1424 | 1437 |
src/link/MachO.zig+35-10| ... | @@ -24,6 +24,8 @@ dylibs: std.ArrayList(File.Index) = .empty, | ... | @@ -24,6 +24,8 @@ dylibs: std.ArrayList(File.Index) = .empty, |
| 24 | 24 | ||
| 25 | segments: std.ArrayList(macho.segment_command_64) = .empty, | 25 | segments: std.ArrayList(macho.segment_command_64) = .empty, |
| 26 | sections: std.MultiArrayList(Section) = .{}, | 26 | sections: std.MultiArrayList(Section) = .{}, |
| 27 | /// Populated by `allocateSections`. | ||
| 28 | header_size: ?u32 = null, | ||
| 27 | 29 | ||
| 28 | resolver: SymbolResolver = .{}, | 30 | resolver: SymbolResolver = .{}, |
| 29 | /// This table will be populated after `scanRelocs` has run. | 31 | /// This table will be populated after `scanRelocs` has run. |
| ... | @@ -181,7 +183,7 @@ pub fn createEmpty( | ... | @@ -181,7 +183,7 @@ pub fn createEmpty( |
| 181 | .tag = .macho, | 183 | .tag = .macho, |
| 182 | .comp = comp, | 184 | .comp = comp, |
| 183 | .emit = emit, | 185 | .emit = emit, |
| 184 | .gc_sections = options.gc_sections orelse (optimize_mode != .Debug), | 186 | .gc_sections = options.gc_sections orelse (optimize_mode != .debug), |
| 185 | .print_gc_sections = options.print_gc_sections, | 187 | .print_gc_sections = options.print_gc_sections, |
| 186 | .stack_size = options.stack_size orelse 16777216, | 188 | .stack_size = options.stack_size orelse 16777216, |
| 187 | .allow_shlib_undefined = allow_shlib_undefined, | 189 | .allow_shlib_undefined = allow_shlib_undefined, |
| ... | @@ -990,6 +992,11 @@ fn addArchive(self: *MachO, lib: link.Input.Object, handle: File.HandleIndex, fa | ... | @@ -990,6 +992,11 @@ fn addArchive(self: *MachO, lib: link.Input.Object, handle: File.HandleIndex, fa |
| 990 | const tracy = trace(@src()); | 992 | const tracy = trace(@src()); |
| 991 | defer tracy.end(); | 993 | defer tracy.end(); |
| 992 | 994 | ||
| 995 | if (self.base.isStaticLib()) { | ||
| 996 | // Ignore static library inputs when generating a static library. | ||
| 997 | return; | ||
| 998 | } | ||
| 999 | |||
| 993 | const gpa = self.base.comp.gpa; | 1000 | const gpa = self.base.comp.gpa; |
| 994 | 1001 | ||
| 995 | var archive: Archive = .{}; | 1002 | var archive: Archive = .{}; |
| ... | @@ -1068,7 +1075,7 @@ fn isHoisted(self: *MachO, install_name: []const u8) bool { | ... | @@ -1068,7 +1075,7 @@ fn isHoisted(self: *MachO, install_name: []const u8) bool { |
| 1068 | if (mem.startsWith(u8, dirname, "/usr/lib")) return true; | 1075 | if (mem.startsWith(u8, dirname, "/usr/lib")) return true; |
| 1069 | if (eatPrefix(dirname, "/System/Library/Frameworks/")) |path| { | 1076 | if (eatPrefix(dirname, "/System/Library/Frameworks/")) |path| { |
| 1070 | const basename = fs.path.basename(install_name); | 1077 | const basename = fs.path.basename(install_name); |
| 1071 | if (mem.indexOfScalar(u8, path, '.')) |index| { | 1078 | if (mem.findScalar(u8, path, '.')) |index| { |
| 1072 | if (mem.eql(u8, basename, path[0..index])) return true; | 1079 | if (mem.eql(u8, basename, path[0..index])) return true; |
| 1073 | } | 1080 | } |
| 1074 | } | 1081 | } |
| ... | @@ -1737,14 +1744,14 @@ fn initSyntheticSections(self: *MachO) !void { | ... | @@ -1737,14 +1744,14 @@ fn initSyntheticSections(self: *MachO) !void { |
| 1737 | }); | 1744 | }); |
| 1738 | } | 1745 | } |
| 1739 | } else if (eatPrefix(name, "section$start$")) |actual_name| { | 1746 | } else if (eatPrefix(name, "section$start$")) |actual_name| { |
| 1740 | const sep = mem.indexOfScalar(u8, actual_name, '$').?; // TODO error rather than a panic | 1747 | const sep = mem.findScalar(u8, actual_name, '$').?; // TODO error rather than a panic |
| 1741 | const segname = actual_name[0..sep]; // TODO check segname is valid | 1748 | const segname = actual_name[0..sep]; // TODO check segname is valid |
| 1742 | const sectname = actual_name[sep + 1 ..]; // TODO check sectname is valid | 1749 | const sectname = actual_name[sep + 1 ..]; // TODO check sectname is valid |
| 1743 | if (self.getSectionByName(segname, sectname) == null) { | 1750 | if (self.getSectionByName(segname, sectname) == null) { |
| 1744 | _ = try self.addSection(segname, sectname, .{}); | 1751 | _ = try self.addSection(segname, sectname, .{}); |
| 1745 | } | 1752 | } |
| 1746 | } else if (eatPrefix(name, "section$end$")) |actual_name| { | 1753 | } else if (eatPrefix(name, "section$end$")) |actual_name| { |
| 1747 | const sep = mem.indexOfScalar(u8, actual_name, '$').?; // TODO error rather than a panic | 1754 | const sep = mem.findScalar(u8, actual_name, '$').?; // TODO error rather than a panic |
| 1748 | const segname = actual_name[0..sep]; // TODO check segname is valid | 1755 | const segname = actual_name[0..sep]; // TODO check segname is valid |
| 1749 | const sectname = actual_name[sep + 1 ..]; // TODO check sectname is valid | 1756 | const sectname = actual_name[sep + 1 ..]; // TODO check sectname is valid |
| 1750 | if (self.getSectionByName(segname, sectname) == null) { | 1757 | if (self.getSectionByName(segname, sectname) == null) { |
| ... | @@ -1765,7 +1772,7 @@ fn getSegmentProt(segname: []const u8) macho.vm_prot_t { | ... | @@ -1765,7 +1772,7 @@ fn getSegmentProt(segname: []const u8) macho.vm_prot_t { |
| 1765 | fn getSegmentRank(segname: []const u8) u8 { | 1772 | fn getSegmentRank(segname: []const u8) u8 { |
| 1766 | if (mem.eql(u8, segname, "__PAGEZERO")) return 0x0; | 1773 | if (mem.eql(u8, segname, "__PAGEZERO")) return 0x0; |
| 1767 | if (mem.eql(u8, segname, "__LINKEDIT")) return 0xf; | 1774 | if (mem.eql(u8, segname, "__LINKEDIT")) return 0xf; |
| 1768 | if (mem.indexOf(u8, segname, "ZIG")) |_| return 0xe; | 1775 | if (mem.find(u8, segname, "ZIG")) |_| return 0xe; |
| 1769 | if (mem.startsWith(u8, segname, "__TEXT")) return 0x1; | 1776 | if (mem.startsWith(u8, segname, "__TEXT")) return 0x1; |
| 1770 | if (mem.startsWith(u8, segname, "__DATA_CONST")) return 0x2; | 1777 | if (mem.startsWith(u8, segname, "__DATA_CONST")) return 0x2; |
| 1771 | if (mem.startsWith(u8, segname, "__DATA")) return 0x3; | 1778 | if (mem.startsWith(u8, segname, "__DATA")) return 0x3; |
| ... | @@ -2209,13 +2216,14 @@ fn initSegments(self: *MachO) !void { | ... | @@ -2209,13 +2216,14 @@ fn initSegments(self: *MachO) !void { |
| 2209 | } | 2216 | } |
| 2210 | 2217 | ||
| 2211 | fn allocateSections(self: *MachO) !void { | 2218 | fn allocateSections(self: *MachO) !void { |
| 2212 | const headerpad = try load_commands.calcMinHeaderPadSize(self); | 2219 | const header_size = try load_commands.calcMinHeaderSize(self); |
| 2220 | self.header_size = header_size; | ||
| 2213 | var vmaddr: u64 = if (self.pagezero_seg_index) |index| | 2221 | var vmaddr: u64 = if (self.pagezero_seg_index) |index| |
| 2214 | self.segments.items[index].vmaddr + self.segments.items[index].vmsize | 2222 | self.segments.items[index].vmaddr + self.segments.items[index].vmsize |
| 2215 | else | 2223 | else |
| 2216 | 0; | 2224 | 0; |
| 2217 | vmaddr += headerpad; | 2225 | vmaddr += header_size; |
| 2218 | var fileoff = headerpad; | 2226 | var fileoff = header_size; |
| 2219 | var prev_seg_id: u8 = if (self.pagezero_seg_index) |index| index + 1 else 0; | 2227 | var prev_seg_id: u8 = if (self.pagezero_seg_index) |index| index + 1 else 0; |
| 2220 | 2228 | ||
| 2221 | const page_size = self.getPageSize(); | 2229 | const page_size = self.getPageSize(); |
| ... | @@ -2339,7 +2347,7 @@ fn allocateSyntheticSymbols(self: *MachO) void { | ... | @@ -2339,7 +2347,7 @@ fn allocateSyntheticSymbols(self: *MachO) void { |
| 2339 | } | 2347 | } |
| 2340 | } else if (mem.startsWith(u8, name, "section$start$")) { | 2348 | } else if (mem.startsWith(u8, name, "section$start$")) { |
| 2341 | const actual_name = name["section$start$".len..]; | 2349 | const actual_name = name["section$start$".len..]; |
| 2342 | const sep = mem.indexOfScalar(u8, actual_name, '$').?; // TODO error rather than a panic | 2350 | const sep = mem.findScalar(u8, actual_name, '$').?; // TODO error rather than a panic |
| 2343 | const segname = actual_name[0..sep]; | 2351 | const segname = actual_name[0..sep]; |
| 2344 | const sectname = actual_name[sep + 1 ..]; | 2352 | const sectname = actual_name[sep + 1 ..]; |
| 2345 | if (self.getSectionByName(segname, sectname)) |sect_id| { | 2353 | if (self.getSectionByName(segname, sectname)) |sect_id| { |
| ... | @@ -2349,7 +2357,7 @@ fn allocateSyntheticSymbols(self: *MachO) void { | ... | @@ -2349,7 +2357,7 @@ fn allocateSyntheticSymbols(self: *MachO) void { |
| 2349 | } | 2357 | } |
| 2350 | } else if (mem.startsWith(u8, name, "section$end$")) { | 2358 | } else if (mem.startsWith(u8, name, "section$end$")) { |
| 2351 | const actual_name = name["section$end$".len..]; | 2359 | const actual_name = name["section$end$".len..]; |
| 2352 | const sep = mem.indexOfScalar(u8, actual_name, '$').?; // TODO error rather than a panic | 2360 | const sep = mem.findScalar(u8, actual_name, '$').?; // TODO error rather than a panic |
| 2353 | const segname = actual_name[0..sep]; | 2361 | const segname = actual_name[0..sep]; |
| 2354 | const sectname = actual_name[sep + 1 ..]; | 2362 | const sectname = actual_name[sep + 1 ..]; |
| 2355 | if (self.getSectionByName(segname, sectname)) |sect_id| { | 2363 | if (self.getSectionByName(segname, sectname)) |sect_id| { |
| ... | @@ -2895,6 +2903,11 @@ fn writeLoadCommands(self: *MachO) !struct { usize, usize, u64 } { | ... | @@ -2895,6 +2903,11 @@ fn writeLoadCommands(self: *MachO) !struct { usize, usize, u64 } { |
| 2895 | ncmds += 1; | 2903 | ncmds += 1; |
| 2896 | } | 2904 | } |
| 2897 | 2905 | ||
| 2906 | if (self.needsEncryptionInfo()) { | ||
| 2907 | try load_commands.writeEncryptionInfoLC(self, &writer); | ||
| 2908 | ncmds += 1; | ||
| 2909 | } | ||
| 2910 | |||
| 2898 | for (self.rpath_list) |rpath| { | 2911 | for (self.rpath_list) |rpath| { |
| 2899 | try load_commands.writeRpathLC(rpath, &writer); | 2912 | try load_commands.writeRpathLC(rpath, &writer); |
| 2900 | ncmds += 1; | 2913 | ncmds += 1; |
| ... | @@ -5410,6 +5423,18 @@ pub fn alignPow(macho_file: *MachO, x: u32) error{AlreadyReported}!u32 { | ... | @@ -5410,6 +5423,18 @@ pub fn alignPow(macho_file: *MachO, x: u32) error{AlreadyReported}!u32 { |
| 5410 | return result; | 5423 | return result; |
| 5411 | } | 5424 | } |
| 5412 | 5425 | ||
| 5426 | pub fn needsEncryptionInfo(macho_file: *MachO) bool { | ||
| 5427 | const target = macho_file.getTarget(); | ||
| 5428 | return switch (target.os.tag) { | ||
| 5429 | .ios, | ||
| 5430 | .tvos, | ||
| 5431 | .visionos, | ||
| 5432 | .watchos, | ||
| 5433 | => target.abi != .simulator, | ||
| 5434 | else => false, | ||
| 5435 | }; | ||
| 5436 | } | ||
| 5437 | |||
| 5413 | /// Branch instruction has 26 bits immediate but is 4 byte aligned. | 5438 | /// Branch instruction has 26 bits immediate but is 4 byte aligned. |
| 5414 | const jump_bits = @bitSizeOf(i28); | 5439 | const jump_bits = @bitSizeOf(i28); |
| 5415 | const max_distance = (1 << (jump_bits - 1)); | 5440 | const max_distance = (1 << (jump_bits - 1)); |
src/link/MachO/Archive.zig+2-2| ... | @@ -45,7 +45,7 @@ pub fn unpack(self: *Archive, macho_file: *MachO, path: Path, handle_index: File | ... | @@ -45,7 +45,7 @@ pub fn unpack(self: *Archive, macho_file: *MachO, path: Path, handle_index: File |
| 45 | const amt = try handle.readPositionalAll(io, buf, pos); | 45 | const amt = try handle.readPositionalAll(io, buf, pos); |
| 46 | if (amt != len) return error.InputOutput; | 46 | if (amt != len) return error.InputOutput; |
| 47 | pos += len; | 47 | pos += len; |
| 48 | const actual_len = mem.indexOfScalar(u8, buf, @as(u8, 0)) orelse len; | 48 | const actual_len = mem.findScalar(u8, buf, @as(u8, 0)) orelse len; |
| 49 | break :name buf[0..actual_len]; | 49 | break :name buf[0..actual_len]; |
| 50 | } | 50 | } |
| 51 | unreachable; | 51 | unreachable; |
| ... | @@ -161,7 +161,7 @@ pub const ar_hdr = extern struct { | ... | @@ -161,7 +161,7 @@ pub const ar_hdr = extern struct { |
| 161 | fn name(self: *const ar_hdr) ?[]const u8 { | 161 | fn name(self: *const ar_hdr) ?[]const u8 { |
| 162 | const value = &self.ar_name; | 162 | const value = &self.ar_name; |
| 163 | if (mem.startsWith(u8, value, "#1/")) return null; | 163 | if (mem.startsWith(u8, value, "#1/")) return null; |
| 164 | const sentinel = mem.indexOfScalar(u8, value, '/') orelse value.len; | 164 | const sentinel = mem.findScalar(u8, value, '/') orelse value.len; |
| 165 | return value[0..sentinel]; | 165 | return value[0..sentinel]; |
| 166 | } | 166 | } |
| 167 | 167 |
src/link/MachO/Symbol.zig+1-1| ... | @@ -43,7 +43,7 @@ pub fn isSymbolStab(symbol: Symbol, macho_file: *MachO) bool { | ... | @@ -43,7 +43,7 @@ pub fn isSymbolStab(symbol: Symbol, macho_file: *MachO) bool { |
| 43 | 43 | ||
| 44 | pub fn isTlvInit(symbol: Symbol, macho_file: *MachO) bool { | 44 | pub fn isTlvInit(symbol: Symbol, macho_file: *MachO) bool { |
| 45 | const name = symbol.getName(macho_file); | 45 | const name = symbol.getName(macho_file); |
| 46 | return std.mem.indexOf(u8, name, "$tlv$init") != null; | 46 | return std.mem.find(u8, name, "$tlv$init") != null; |
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | pub fn weakRef(symbol: Symbol, macho_file: *MachO) bool { | 49 | pub fn weakRef(symbol: Symbol, macho_file: *MachO) bool { |
src/link/MachO/ZigObject.zig+4-4| ... | @@ -946,8 +946,8 @@ fn updateNavCode( | ... | @@ -946,8 +946,8 @@ fn updateNavCode( |
| 946 | const target = &mod.resolved_target.result; | 946 | const target = &mod.resolved_target.result; |
| 947 | const required_alignment = switch (nav.resolved.?.@"align") { | 947 | const required_alignment = switch (nav.resolved.?.@"align") { |
| 948 | .none => switch (mod.optimize_mode) { | 948 | .none => switch (mod.optimize_mode) { |
| 949 | .Debug, .ReleaseSafe, .ReleaseFast => target_util.defaultFunctionAlignment(target), | 949 | .debug, .safe, .fast => target_util.defaultFunctionAlignment(target), |
| 950 | .ReleaseSmall => target_util.minFunctionAlignment(target), | 950 | .small => target_util.minFunctionAlignment(target), |
| 951 | }, | 951 | }, |
| 952 | else => |a| a.maxStrict(target_util.minFunctionAlignment(target)), | 952 | else => |a| a.maxStrict(target_util.minFunctionAlignment(target)), |
| 953 | }; | 953 | }; |
| ... | @@ -1172,8 +1172,8 @@ fn getNavOutputSection( | ... | @@ -1172,8 +1172,8 @@ fn getNavOutputSection( |
| 1172 | if (nav.resolved.?.@"const") return macho_file.zig_const_sect_index.?; | 1172 | if (nav.resolved.?.@"const") return macho_file.zig_const_sect_index.?; |
| 1173 | if (nav_val.isUndef(zcu)) | 1173 | if (nav_val.isUndef(zcu)) |
| 1174 | return switch (zcu.navFileScope(nav_index).mod.?.optimize_mode) { | 1174 | return switch (zcu.navFileScope(nav_index).mod.?.optimize_mode) { |
| 1175 | .Debug, .ReleaseSafe => macho_file.zig_data_sect_index.?, | 1175 | .debug, .safe => macho_file.zig_data_sect_index.?, |
| 1176 | .ReleaseFast, .ReleaseSmall => macho_file.zig_bss_sect_index.?, | 1176 | .fast, .small => macho_file.zig_bss_sect_index.?, |
| 1177 | }; | 1177 | }; |
| 1178 | for (code) |byte| { | 1178 | for (code) |byte| { |
| 1179 | if (byte != 0) break; | 1179 | if (byte != 0) break; |
src/link/MachO/dyld_info/Trie.zig+2-2| ... | @@ -54,7 +54,7 @@ fn putNode(self: *Trie, node_index: Node.Index, allocator: Allocator, label: []c | ... | @@ -54,7 +54,7 @@ fn putNode(self: *Trie, node_index: Node.Index, allocator: Allocator, label: []c |
| 54 | // Check for match with edges from this node. | 54 | // Check for match with edges from this node. |
| 55 | for (self.nodes.items(.edges)[node_index].items) |edge_index| { | 55 | for (self.nodes.items(.edges)[node_index].items) |edge_index| { |
| 56 | const edge = &self.edges.items[edge_index]; | 56 | const edge = &self.edges.items[edge_index]; |
| 57 | const match = mem.indexOfDiff(u8, edge.label, label) orelse return edge.node; | 57 | const match = mem.findDiff(u8, edge.label, label) orelse return edge.node; |
| 58 | if (match == 0) continue; | 58 | if (match == 0) continue; |
| 59 | if (match == edge.label.len) return self.putNode(edge.node, allocator, label[match..]); | 59 | if (match == edge.label.len) return self.putNode(edge.node, allocator, label[match..]); |
| 60 | 60 | ||
| ... | @@ -351,7 +351,7 @@ fn expectEqualHexStrings(expected: []const u8, given: []const u8) !void { | ... | @@ -351,7 +351,7 @@ fn expectEqualHexStrings(expected: []const u8, given: []const u8) !void { |
| 351 | defer testing.allocator.free(expected_fmt); | 351 | defer testing.allocator.free(expected_fmt); |
| 352 | const given_fmt = try std.fmt.allocPrint(testing.allocator, "{x}", .{given}); | 352 | const given_fmt = try std.fmt.allocPrint(testing.allocator, "{x}", .{given}); |
| 353 | defer testing.allocator.free(given_fmt); | 353 | defer testing.allocator.free(given_fmt); |
| 354 | const idx = mem.indexOfDiff(u8, expected_fmt, given_fmt).?; | 354 | const idx = mem.findDiff(u8, expected_fmt, given_fmt).?; |
| 355 | const padding = try testing.allocator.alloc(u8, idx + 5); | 355 | const padding = try testing.allocator.alloc(u8, idx + 5); |
| 356 | defer testing.allocator.free(padding); | 356 | defer testing.allocator.free(padding); |
| 357 | @memset(padding, ' '); | 357 | @memset(padding, ' '); |
src/link/MachO/load_commands.zig+22-5| ... | @@ -62,6 +62,10 @@ pub fn calcLoadCommandsSize(macho_file: *MachO, assume_max_path_len: bool) !u32 | ... | @@ -62,6 +62,10 @@ pub fn calcLoadCommandsSize(macho_file: *MachO, assume_max_path_len: bool) !u32 |
| 62 | assume_max_path_len, | 62 | assume_max_path_len, |
| 63 | ); | 63 | ); |
| 64 | } | 64 | } |
| 65 | // LC_ENCRYPTION_INFO_64 | ||
| 66 | if (macho_file.needsEncryptionInfo()) { | ||
| 67 | sizeofcmds += @sizeOf(macho.encryption_info_command_64); | ||
| 68 | } | ||
| 65 | // LC_RPATH | 69 | // LC_RPATH |
| 66 | { | 70 | { |
| 67 | for (macho_file.rpath_list) |rpath| { | 71 | for (macho_file.rpath_list) |rpath| { |
| ... | @@ -163,23 +167,29 @@ pub fn calcLoadCommandsSizeObject(macho_file: *MachO) u32 { | ... | @@ -163,23 +167,29 @@ pub fn calcLoadCommandsSizeObject(macho_file: *MachO) u32 { |
| 163 | return @as(u32, @intCast(sizeofcmds)); | 167 | return @as(u32, @intCast(sizeofcmds)); |
| 164 | } | 168 | } |
| 165 | 169 | ||
| 166 | pub fn calcMinHeaderPadSize(macho_file: *MachO) !u32 { | 170 | pub fn calcMinHeaderSize(macho_file: *MachO) !u32 { |
| 167 | var padding: u32 = (try calcLoadCommandsSize(macho_file, false)) + | 171 | var padding: u32 = (try calcLoadCommandsSize(macho_file, false)) + |
| 168 | (macho_file.headerpad_size orelse MachO.default_headerpad_size); | 172 | (macho_file.headerpad_size orelse MachO.default_headerpad_size); |
| 169 | log.debug("minimum requested headerpad size 0x{x}", .{padding + @sizeOf(macho.mach_header_64)}); | 173 | log.debug("minimum requested header + padding size 0x{x}", .{padding + @sizeOf(macho.mach_header_64)}); |
| 170 | 174 | ||
| 171 | if (macho_file.headerpad_max_install_names) { | 175 | if (macho_file.headerpad_max_install_names) { |
| 172 | const min_headerpad_size: u32 = try calcLoadCommandsSize(macho_file, true); | 176 | const min_headerpad_size: u32 = try calcLoadCommandsSize(macho_file, true); |
| 173 | log.debug("headerpad_max_install_names minimum headerpad size 0x{x}", .{ | 177 | log.debug("headerpad_max_install_names minimum header + padding size 0x{x}", .{ |
| 174 | min_headerpad_size + @sizeOf(macho.mach_header_64), | 178 | min_headerpad_size + @sizeOf(macho.mach_header_64), |
| 175 | }); | 179 | }); |
| 176 | padding = @max(padding, min_headerpad_size); | 180 | padding = @max(padding, min_headerpad_size); |
| 177 | } | 181 | } |
| 178 | 182 | ||
| 179 | const offset = @sizeOf(macho.mach_header_64) + padding; | 183 | const offset = @sizeOf(macho.mach_header_64) + padding; |
| 180 | log.debug("actual headerpad size 0x{x}", .{offset}); | 184 | log.debug("actual header + padding size 0x{x}", .{offset}); |
| 181 | 185 | ||
| 182 | return offset; | 186 | // Encryption is done at page granularity, so if the output needs a load |
| 187 | // command for encryption info, ensure that the header + load commands have | ||
| 188 | // at least one full, unencrypted page. | ||
| 189 | return if (macho_file.needsEncryptionInfo()) | ||
| 190 | mem.alignForward(u32, offset, macho_file.getPageSize()) | ||
| 191 | else | ||
| 192 | offset; | ||
| 183 | } | 193 | } |
| 184 | 194 | ||
| 185 | pub fn writeDylinkerLC(writer: *Writer) !void { | 195 | pub fn writeDylinkerLC(writer: *Writer) !void { |
| ... | @@ -260,6 +270,13 @@ pub fn writeDylibIdLC(macho_file: *MachO, writer: *Writer) !void { | ... | @@ -260,6 +270,13 @@ pub fn writeDylibIdLC(macho_file: *MachO, writer: *Writer) !void { |
| 260 | }, writer); | 270 | }, writer); |
| 261 | } | 271 | } |
| 262 | 272 | ||
| 273 | pub fn writeEncryptionInfoLC(macho_file: *MachO, writer: *Writer) !void { | ||
| 274 | try writer.writeAll(mem.asBytes(&macho.encryption_info_command_64{ | ||
| 275 | .cryptoff = macho_file.header_size.?, | ||
| 276 | .cryptsize = @as(u32, @intCast(macho_file.getTextSegment().filesize)) - macho_file.header_size.?, | ||
| 277 | })); | ||
| 278 | } | ||
| 279 | |||
| 263 | pub fn writeRpathLC(rpath: []const u8, writer: *Writer) !void { | 280 | pub fn writeRpathLC(rpath: []const u8, writer: *Writer) !void { |
| 264 | const rpath_len = rpath.len + 1; | 281 | const rpath_len = rpath.len + 1; |
| 265 | const cmdsize = @as(u32, @intCast(mem.alignForward( | 282 | const cmdsize = @as(u32, @intCast(mem.alignForward( |
src/link/MappedFile.zig+93-41| ... | @@ -23,6 +23,7 @@ nodes: std.ArrayList(Node), | ... | @@ -23,6 +23,7 @@ nodes: std.ArrayList(Node), |
| 23 | free_ni: Node.Index, | 23 | free_ni: Node.Index, |
| 24 | large: std.ArrayList(u64), | 24 | large: std.ArrayList(u64), |
| 25 | updates: std.ArrayList(Node.Index), | 25 | updates: std.ArrayList(Node.Index), |
| 26 | /// This progress node's estimated total items is increased once for each node appended to `updates`. | ||
| 26 | update_prog_node: std.Progress.Node, | 27 | update_prog_node: std.Progress.Node, |
| 27 | writers: std.SinglyLinkedList, | 28 | writers: std.SinglyLinkedList, |
| 28 | io_err: ?IoError, | 29 | io_err: ?IoError, |
| ... | @@ -61,7 +62,7 @@ pub const Error = Allocator.Error || Io.Cancelable || error{ | ... | @@ -61,7 +62,7 @@ pub const Error = Allocator.Error || Io.Cancelable || error{ |
| 61 | MappedFileIo, | 62 | MappedFileIo, |
| 62 | }; | 63 | }; |
| 63 | 64 | ||
| 64 | pub fn init(file: Io.File, gpa: std.mem.Allocator, io: Io) (Allocator.Error || Io.Cancelable || IoError)!MappedFile { | 65 | pub fn init(file: Io.File, gpa: Allocator, io: Io) (Allocator.Error || Io.Cancelable || IoError)!MappedFile { |
| 65 | var mf: MappedFile = .{ | 66 | var mf: MappedFile = .{ |
| 66 | .io = io, | 67 | .io = io, |
| 67 | .flags = undefined, | 68 | .flags = undefined, |
| ... | @@ -105,7 +106,7 @@ pub fn init(file: Io.File, gpa: std.mem.Allocator, io: Io) (Allocator.Error || I | ... | @@ -105,7 +106,7 @@ pub fn init(file: Io.File, gpa: std.mem.Allocator, io: Io) (Allocator.Error || I |
| 105 | return mf; | 106 | return mf; |
| 106 | } | 107 | } |
| 107 | 108 | ||
| 108 | pub fn deinit(mf: *MappedFile, gpa: std.mem.Allocator) void { | 109 | pub fn deinit(mf: *MappedFile, gpa: Allocator) void { |
| 109 | mf.unmap(); | 110 | mf.unmap(); |
| 110 | mf.nodes.deinit(gpa); | 111 | mf.nodes.deinit(gpa); |
| 111 | mf.large.deinit(gpa); | 112 | mf.large.deinit(gpa); |
| ... | @@ -133,11 +134,15 @@ pub const Node = extern struct { | ... | @@ -133,11 +134,15 @@ pub const Node = extern struct { |
| 133 | moved: bool, | 134 | moved: bool, |
| 134 | /// Whether this node has been resized. | 135 | /// Whether this node has been resized. |
| 135 | resized: bool, | 136 | resized: bool, |
| 137 | /// Whether the next sibling has moved or is a different node. | ||
| 138 | next_moved: bool, | ||
| 136 | /// Whether this node might contain non-zero bytes. | 139 | /// Whether this node might contain non-zero bytes. |
| 137 | has_content: bool, | 140 | has_content: bool, |
| 138 | /// Whether a moved event on this node bubbles down to children. | 141 | /// Whether `moved` events on this node bubble down to children. |
| 139 | bubbles_moved: bool, | 142 | bubbles_moved: bool, |
| 140 | unused: @Int(.unsigned, 32 - @bitSizeOf(std.mem.Alignment) - 6) = 0, | 143 | /// Whether `next_moved` events are reported in `updates`. |
| 144 | enable_next_moved: bool, | ||
| 145 | unused: @Int(.unsigned, 32 - @bitSizeOf(std.mem.Alignment) - 8) = 0, | ||
| 141 | }; | 146 | }; |
| 142 | 147 | ||
| 143 | pub const Location = union(enum(u1)) { | 148 | pub const Location = union(enum(u1)) { |
| ... | @@ -191,6 +196,22 @@ pub const Node = extern struct { | ... | @@ -191,6 +196,22 @@ pub const Node = extern struct { |
| 191 | pub fn next(ni: Node.Index, mf: *const MappedFile) Node.Index { | 196 | pub fn next(ni: Node.Index, mf: *const MappedFile) Node.Index { |
| 192 | return ni.get(mf).next; | 197 | return ni.get(mf).next; |
| 193 | } | 198 | } |
| 199 | fn setNext( | ||
| 200 | prev_ni: Node.Index, | ||
| 201 | gpa: Allocator, | ||
| 202 | next_ni: Node.Index, | ||
| 203 | mf: *MappedFile, | ||
| 204 | ) Allocator.Error!void { | ||
| 205 | assert(prev_ni != .none); | ||
| 206 | const prev_next = &prev_ni.get(mf).next; | ||
| 207 | if (prev_next.* == next_ni) return; | ||
| 208 | prev_next.* = next_ni; | ||
| 209 | try prev_ni.nextMoved(gpa, mf); | ||
| 210 | } | ||
| 211 | |||
| 212 | pub fn prev(ni: Node.Index, mf: *const MappedFile) Node.Index { | ||
| 213 | return ni.get(mf).prev; | ||
| 214 | } | ||
| 194 | 215 | ||
| 195 | pub fn ChildIterator(comptime direction: enum { prev, next }) type { | 216 | pub fn ChildIterator(comptime direction: enum { prev, next }) type { |
| 196 | return struct { | 217 | return struct { |
| ... | @@ -211,7 +232,7 @@ pub const Node = extern struct { | ... | @@ -211,7 +232,7 @@ pub const Node = extern struct { |
| 211 | return .{ .mf = mf, .ni = ni.get(mf).last }; | 232 | return .{ .mf = mf, .ni = ni.get(mf).last }; |
| 212 | } | 233 | } |
| 213 | 234 | ||
| 214 | pub fn childrenMoved(ni: Node.Index, gpa: std.mem.Allocator, mf: *MappedFile) Allocator.Error!void { | 235 | pub fn childrenMoved(ni: Node.Index, gpa: Allocator, mf: *MappedFile) Allocator.Error!void { |
| 215 | var child_ni = ni.get(mf).last; | 236 | var child_ni = ni.get(mf).last; |
| 216 | while (child_ni != .none) { | 237 | while (child_ni != .none) { |
| 217 | try child_ni.moved(gpa, mf); | 238 | try child_ni.moved(gpa, mf); |
| ... | @@ -229,11 +250,11 @@ pub const Node = extern struct { | ... | @@ -229,11 +250,11 @@ pub const Node = extern struct { |
| 229 | } | 250 | } |
| 230 | return false; | 251 | return false; |
| 231 | } | 252 | } |
| 232 | pub fn moved(ni: Node.Index, gpa: std.mem.Allocator, mf: *MappedFile) Allocator.Error!void { | 253 | pub fn moved(ni: Node.Index, gpa: Allocator, mf: *MappedFile) Allocator.Error!void { |
| 233 | try mf.updates.ensureUnusedCapacity(gpa, 1); | 254 | try mf.updates.ensureUnusedCapacity(gpa, 2); |
| 234 | ni.movedAssumeCapacity(mf); | 255 | ni.movedAssumeCapacity(mf); |
| 235 | } | 256 | } |
| 236 | pub fn cleanMoved(ni: Node.Index, mf: *const MappedFile) bool { | 257 | pub fn cleanMoved(ni: Node.Index, mf: *MappedFile) bool { |
| 237 | const node_moved = &ni.get(mf).flags.moved; | 258 | const node_moved = &ni.get(mf).flags.moved; |
| 238 | defer node_moved.* = false; | 259 | defer node_moved.* = false; |
| 239 | return node_moved.*; | 260 | return node_moved.*; |
| ... | @@ -242,7 +263,11 @@ pub const Node = extern struct { | ... | @@ -242,7 +263,11 @@ pub const Node = extern struct { |
| 242 | if (ni.hasMoved(mf)) return; | 263 | if (ni.hasMoved(mf)) return; |
| 243 | const node = ni.get(mf); | 264 | const node = ni.get(mf); |
| 244 | node.flags.moved = true; | 265 | node.flags.moved = true; |
| 245 | if (node.flags.resized) return; | 266 | switch (node.prev) { |
| 267 | .none => {}, | ||
| 268 | else => |prev_ni| prev_ni.nextMovedAssumeCapacity(mf), | ||
| 269 | } | ||
| 270 | if (node.flags.resized or node.flags.next_moved) return; | ||
| 246 | mf.updates.appendAssumeCapacity(ni); | 271 | mf.updates.appendAssumeCapacity(ni); |
| 247 | mf.update_prog_node.increaseEstimatedTotalItems(1); | 272 | mf.update_prog_node.increaseEstimatedTotalItems(1); |
| 248 | } | 273 | } |
| ... | @@ -250,11 +275,11 @@ pub const Node = extern struct { | ... | @@ -250,11 +275,11 @@ pub const Node = extern struct { |
| 250 | pub fn hasResized(ni: Node.Index, mf: *const MappedFile) bool { | 275 | pub fn hasResized(ni: Node.Index, mf: *const MappedFile) bool { |
| 251 | return ni.get(mf).flags.resized; | 276 | return ni.get(mf).flags.resized; |
| 252 | } | 277 | } |
| 253 | pub fn resized(ni: Node.Index, gpa: std.mem.Allocator, mf: *MappedFile) Allocator.Error!void { | 278 | pub fn resized(ni: Node.Index, gpa: Allocator, mf: *MappedFile) Allocator.Error!void { |
| 254 | try mf.updates.ensureUnusedCapacity(gpa, 1); | 279 | try mf.updates.ensureUnusedCapacity(gpa, 1); |
| 255 | ni.resizedAssumeCapacity(mf); | 280 | ni.resizedAssumeCapacity(mf); |
| 256 | } | 281 | } |
| 257 | pub fn cleanResized(ni: Node.Index, mf: *const MappedFile) bool { | 282 | pub fn cleanResized(ni: Node.Index, mf: *MappedFile) bool { |
| 258 | const node_resized = &ni.get(mf).flags.resized; | 283 | const node_resized = &ni.get(mf).flags.resized; |
| 259 | defer node_resized.* = false; | 284 | defer node_resized.* = false; |
| 260 | return node_resized.*; | 285 | return node_resized.*; |
| ... | @@ -263,7 +288,28 @@ pub const Node = extern struct { | ... | @@ -263,7 +288,28 @@ pub const Node = extern struct { |
| 263 | const node = ni.get(mf); | 288 | const node = ni.get(mf); |
| 264 | if (node.flags.resized) return; | 289 | if (node.flags.resized) return; |
| 265 | node.flags.resized = true; | 290 | node.flags.resized = true; |
| 266 | if (node.flags.moved) return; | 291 | if (node.flags.moved or node.flags.next_moved) return; |
| 292 | mf.updates.appendAssumeCapacity(ni); | ||
| 293 | mf.update_prog_node.increaseEstimatedTotalItems(1); | ||
| 294 | } | ||
| 295 | |||
| 296 | pub fn hasNextMoved(ni: Node.Index, mf: *const MappedFile) bool { | ||
| 297 | return ni.get(mf).flags.next_moved; | ||
| 298 | } | ||
| 299 | pub fn nextMoved(ni: Node.Index, gpa: Allocator, mf: *MappedFile) Allocator.Error!void { | ||
| 300 | try mf.updates.ensureUnusedCapacity(gpa, 1); | ||
| 301 | ni.nextMovedAssumeCapacity(mf); | ||
| 302 | } | ||
| 303 | pub fn cleanNextMoved(ni: Node.Index, mf: *MappedFile) bool { | ||
| 304 | const node_next_moved = &ni.get(mf).flags.next_moved; | ||
| 305 | defer node_next_moved.* = false; | ||
| 306 | return node_next_moved.*; | ||
| 307 | } | ||
| 308 | pub fn nextMovedAssumeCapacity(ni: Node.Index, mf: *MappedFile) void { | ||
| 309 | const node = ni.get(mf); | ||
| 310 | if (!node.flags.enable_next_moved or node.flags.next_moved) return; | ||
| 311 | node.flags.next_moved = true; | ||
| 312 | if (node.flags.moved or node.flags.resized) return; | ||
| 267 | mf.updates.appendAssumeCapacity(ni); | 313 | mf.updates.appendAssumeCapacity(ni); |
| 268 | mf.update_prog_node.increaseEstimatedTotalItems(1); | 314 | mf.update_prog_node.increaseEstimatedTotalItems(1); |
| 269 | } | 315 | } |
| ... | @@ -333,7 +379,7 @@ pub const Node = extern struct { | ... | @@ -333,7 +379,7 @@ pub const Node = extern struct { |
| 333 | return mf.memory_map.memory[@intCast(file_loc.offset)..][0..@intCast(file_loc.size)]; | 379 | return mf.memory_map.memory[@intCast(file_loc.offset)..][0..@intCast(file_loc.size)]; |
| 334 | } | 380 | } |
| 335 | 381 | ||
| 336 | pub fn resize(ni: Node.Index, mf: *MappedFile, gpa: std.mem.Allocator, size: u64) Error!void { | 382 | pub fn resize(ni: Node.Index, mf: *MappedFile, gpa: Allocator, size: u64) Error!void { |
| 337 | mf.resizeNode(gpa, ni, size) catch |err| switch (err) { | 383 | mf.resizeNode(gpa, ni, size) catch |err| switch (err) { |
| 338 | error.OutOfMemory, | 384 | error.OutOfMemory, |
| 339 | error.Canceled, | 385 | error.Canceled, |
| ... | @@ -360,7 +406,7 @@ pub const Node = extern struct { | ... | @@ -360,7 +406,7 @@ pub const Node = extern struct { |
| 360 | pub fn realign( | 406 | pub fn realign( |
| 361 | ni: Node.Index, | 407 | ni: Node.Index, |
| 362 | mf: *MappedFile, | 408 | mf: *MappedFile, |
| 363 | gpa: std.mem.Allocator, | 409 | gpa: Allocator, |
| 364 | new_alignment: std.mem.Alignment, | 410 | new_alignment: std.mem.Alignment, |
| 365 | opts: RealignNodeOptions, | 411 | opts: RealignNodeOptions, |
| 366 | ) Error!void { | 412 | ) Error!void { |
| ... | @@ -384,7 +430,7 @@ pub const Node = extern struct { | ... | @@ -384,7 +430,7 @@ pub const Node = extern struct { |
| 384 | pub fn shrink( | 430 | pub fn shrink( |
| 385 | ni: Node.Index, | 431 | ni: Node.Index, |
| 386 | mf: *MappedFile, | 432 | mf: *MappedFile, |
| 387 | gpa: std.mem.Allocator, | 433 | gpa: Allocator, |
| 388 | size: u64, | 434 | size: u64, |
| 389 | shift_next: bool, | 435 | shift_next: bool, |
| 390 | ) Error!void { | 436 | ) Error!void { |
| ... | @@ -392,7 +438,7 @@ pub const Node = extern struct { | ... | @@ -392,7 +438,7 @@ pub const Node = extern struct { |
| 392 | mf.updateWriters(); | 438 | mf.updateWriters(); |
| 393 | } | 439 | } |
| 394 | 440 | ||
| 395 | pub fn writer(ni: Node.Index, mf: *MappedFile, gpa: std.mem.Allocator, w: *Writer) void { | 441 | pub fn writer(ni: Node.Index, mf: *MappedFile, gpa: Allocator, w: *Writer) void { |
| 396 | w.* = .{ | 442 | w.* = .{ |
| 397 | .gpa = gpa, | 443 | .gpa = gpa, |
| 398 | .mf = mf, | 444 | .mf = mf, |
| ... | @@ -419,7 +465,7 @@ pub const Node = extern struct { | ... | @@ -419,7 +465,7 @@ pub const Node = extern struct { |
| 419 | } | 465 | } |
| 420 | 466 | ||
| 421 | pub const Writer = struct { | 467 | pub const Writer = struct { |
| 422 | gpa: std.mem.Allocator, | 468 | gpa: Allocator, |
| 423 | mf: *MappedFile, | 469 | mf: *MappedFile, |
| 424 | writer_node: std.SinglyLinkedList.Node, | 470 | writer_node: std.SinglyLinkedList.Node, |
| 425 | ni: Node.Index, | 471 | ni: Node.Index, |
| ... | @@ -543,14 +589,13 @@ pub const Node = extern struct { | ... | @@ -543,14 +589,13 @@ pub const Node = extern struct { |
| 543 | } | 589 | } |
| 544 | }; | 590 | }; |
| 545 | 591 | ||
| 546 | fn addNode(mf: *MappedFile, gpa: std.mem.Allocator, opts: struct { | 592 | fn addNode(mf: *MappedFile, gpa: Allocator, opts: struct { |
| 547 | parent: Node.Index = .none, | 593 | parent: Node.Index = .none, |
| 548 | prev: Node.Index = .none, | 594 | prev: Node.Index = .none, |
| 549 | next: Node.Index = .none, | 595 | next: Node.Index = .none, |
| 550 | offset: u64 = 0, | 596 | offset: u64 = 0, |
| 551 | add_node: AddNodeOptions, | 597 | add_node: AddNodeOptions, |
| 552 | }) (Allocator.Error || Io.Cancelable || IoError)!Node.Index { | 598 | }) (Allocator.Error || Io.Cancelable || IoError)!Node.Index { |
| 553 | if (opts.add_node.moved or opts.add_node.resized) try mf.updates.ensureUnusedCapacity(gpa, 1); | ||
| 554 | mf.nodes_lock.assertUnlocked(); | 599 | mf.nodes_lock.assertUnlocked(); |
| 555 | const location_tag: Node.Location.Tag, const location_payload: Node.Location.Payload = location: { | 600 | const location_tag: Node.Location.Tag, const location_payload: Node.Location.Payload = location: { |
| 556 | if (std.math.cast(u32, opts.offset)) |small_offset| break :location .{ .small, .{ | 601 | if (std.math.cast(u32, opts.offset)) |small_offset| break :location .{ .small, .{ |
| ... | @@ -570,7 +615,7 @@ fn addNode(mf: *MappedFile, gpa: std.mem.Allocator, opts: struct { | ... | @@ -570,7 +615,7 @@ fn addNode(mf: *MappedFile, gpa: std.mem.Allocator, opts: struct { |
| 570 | }; | 615 | }; |
| 571 | switch (opts.prev) { | 616 | switch (opts.prev) { |
| 572 | .none => opts.parent.get(mf).first = free_ni, | 617 | .none => opts.parent.get(mf).first = free_ni, |
| 573 | else => |prev_ni| prev_ni.get(mf).next = free_ni, | 618 | else => |prev_ni| try prev_ni.setNext(gpa, free_ni, mf), |
| 574 | } | 619 | } |
| 575 | switch (opts.next) { | 620 | switch (opts.next) { |
| 576 | .none => opts.parent.get(mf).last = free_ni, | 621 | .none => opts.parent.get(mf).last = free_ni, |
| ... | @@ -588,22 +633,27 @@ fn addNode(mf: *MappedFile, gpa: std.mem.Allocator, opts: struct { | ... | @@ -588,22 +633,27 @@ fn addNode(mf: *MappedFile, gpa: std.mem.Allocator, opts: struct { |
| 588 | .fixed = opts.add_node.fixed, | 633 | .fixed = opts.add_node.fixed, |
| 589 | .moved = true, | 634 | .moved = true, |
| 590 | .resized = true, | 635 | .resized = true, |
| 636 | .next_moved = true, | ||
| 591 | .has_content = false, | 637 | .has_content = false, |
| 592 | .bubbles_moved = opts.add_node.bubbles_moved, | 638 | .bubbles_moved = opts.add_node.bubbles_moved, |
| 639 | .enable_next_moved = opts.add_node.enable_next_moved, | ||
| 593 | }, | 640 | }, |
| 594 | .location_payload = location_payload, | 641 | .location_payload = location_payload, |
| 595 | }; | 642 | }; |
| 596 | 643 | ||
| 597 | { | 644 | { |
| 645 | defer { | ||
| 646 | free_node.flags.moved = false; | ||
| 647 | free_node.flags.resized = false; | ||
| 648 | free_node.flags.next_moved = false; | ||
| 649 | } | ||
| 598 | try mf.realignNode(gpa, free_ni, opts.add_node.alignment, .{}); | 650 | try mf.realignNode(gpa, free_ni, opts.add_node.alignment, .{}); |
| 599 | try mf.resizeNode(gpa, free_ni, opts.add_node.size); | 651 | try mf.resizeNode(gpa, free_ni, opts.add_node.size); |
| 600 | if (opts.add_node.moved or opts.add_node.resized) try mf.updates.ensureUnusedCapacity(gpa, 1); | ||
| 601 | free_node.flags.moved = false; | ||
| 602 | free_node.flags.resized = false; | ||
| 603 | } | 652 | } |
| 604 | if (opts.add_node.moved) free_ni.movedAssumeCapacity(mf); | ||
| 605 | if (opts.add_node.resized) free_ni.resizedAssumeCapacity(mf); | ||
| 606 | mf.updateWriters(); | 653 | mf.updateWriters(); |
| 654 | if (opts.add_node.moved) try free_ni.moved(gpa, mf); | ||
| 655 | if (opts.add_node.resized) try free_ni.resized(gpa, mf); | ||
| 656 | if (opts.add_node.next_moved) try free_ni.nextMoved(gpa, mf); | ||
| 607 | return free_ni; | 657 | return free_ni; |
| 608 | } | 658 | } |
| 609 | 659 | ||
| ... | @@ -613,12 +663,14 @@ pub const AddNodeOptions = struct { | ... | @@ -613,12 +663,14 @@ pub const AddNodeOptions = struct { |
| 613 | fixed: bool = false, | 663 | fixed: bool = false, |
| 614 | moved: bool = false, | 664 | moved: bool = false, |
| 615 | resized: bool = false, | 665 | resized: bool = false, |
| 666 | next_moved: bool = false, | ||
| 616 | bubbles_moved: bool = true, | 667 | bubbles_moved: bool = true, |
| 668 | enable_next_moved: bool = false, | ||
| 617 | }; | 669 | }; |
| 618 | 670 | ||
| 619 | pub fn addOnlyChildNode( | 671 | pub fn addOnlyChildNode( |
| 620 | mf: *MappedFile, | 672 | mf: *MappedFile, |
| 621 | gpa: std.mem.Allocator, | 673 | gpa: Allocator, |
| 622 | parent_ni: Node.Index, | 674 | parent_ni: Node.Index, |
| 623 | opts: AddNodeOptions, | 675 | opts: AddNodeOptions, |
| 624 | ) Error!Node.Index { | 676 | ) Error!Node.Index { |
| ... | @@ -641,7 +693,7 @@ pub fn addOnlyChildNode( | ... | @@ -641,7 +693,7 @@ pub fn addOnlyChildNode( |
| 641 | 693 | ||
| 642 | pub fn addFirstChildNode( | 694 | pub fn addFirstChildNode( |
| 643 | mf: *MappedFile, | 695 | mf: *MappedFile, |
| 644 | gpa: std.mem.Allocator, | 696 | gpa: Allocator, |
| 645 | parent_ni: Node.Index, | 697 | parent_ni: Node.Index, |
| 646 | opts: AddNodeOptions, | 698 | opts: AddNodeOptions, |
| 647 | ) Error!Node.Index { | 699 | ) Error!Node.Index { |
| ... | @@ -664,7 +716,7 @@ pub fn addFirstChildNode( | ... | @@ -664,7 +716,7 @@ pub fn addFirstChildNode( |
| 664 | 716 | ||
| 665 | pub fn addLastChildNode( | 717 | pub fn addLastChildNode( |
| 666 | mf: *MappedFile, | 718 | mf: *MappedFile, |
| 667 | gpa: std.mem.Allocator, | 719 | gpa: Allocator, |
| 668 | parent_ni: Node.Index, | 720 | parent_ni: Node.Index, |
| 669 | opts: AddNodeOptions, | 721 | opts: AddNodeOptions, |
| 670 | ) Error!Node.Index { | 722 | ) Error!Node.Index { |
| ... | @@ -694,7 +746,7 @@ pub fn addLastChildNode( | ... | @@ -694,7 +746,7 @@ pub fn addLastChildNode( |
| 694 | 746 | ||
| 695 | pub fn addNodeAfter( | 747 | pub fn addNodeAfter( |
| 696 | mf: *MappedFile, | 748 | mf: *MappedFile, |
| 697 | gpa: std.mem.Allocator, | 749 | gpa: Allocator, |
| 698 | prev_ni: Node.Index, | 750 | prev_ni: Node.Index, |
| 699 | opts: AddNodeOptions, | 751 | opts: AddNodeOptions, |
| 700 | ) Error!Node.Index { | 752 | ) Error!Node.Index { |
| ... | @@ -721,7 +773,7 @@ pub fn addNodeAfter( | ... | @@ -721,7 +773,7 @@ pub fn addNodeAfter( |
| 721 | 773 | ||
| 722 | fn shrinkNode( | 774 | fn shrinkNode( |
| 723 | mf: *MappedFile, | 775 | mf: *MappedFile, |
| 724 | gpa: std.mem.Allocator, | 776 | gpa: Allocator, |
| 725 | ni: Node.Index, | 777 | ni: Node.Index, |
| 726 | size: u64, | 778 | size: u64, |
| 727 | shift_next: bool, | 779 | shift_next: bool, |
| ... | @@ -740,7 +792,7 @@ fn shrinkNode( | ... | @@ -740,7 +792,7 @@ fn shrinkNode( |
| 740 | } | 792 | } |
| 741 | 793 | ||
| 742 | try mf.large.ensureUnusedCapacity(gpa, 4); | 794 | try mf.large.ensureUnusedCapacity(gpa, 4); |
| 743 | try mf.updates.ensureUnusedCapacity(gpa, 2); | 795 | try mf.updates.ensureUnusedCapacity(gpa, 4); |
| 744 | 796 | ||
| 745 | ni.setLocationAssumeCapacity(mf, old_offset, size); | 797 | ni.setLocationAssumeCapacity(mf, old_offset, size); |
| 746 | if (!shift_next or node.next == .none) return; | 798 | if (!shift_next or node.next == .none) return; |
| ... | @@ -765,7 +817,7 @@ fn shrinkNode( | ... | @@ -765,7 +817,7 @@ fn shrinkNode( |
| 765 | 817 | ||
| 766 | fn resizeNode( | 818 | fn resizeNode( |
| 767 | mf: *MappedFile, | 819 | mf: *MappedFile, |
| 768 | gpa: std.mem.Allocator, | 820 | gpa: Allocator, |
| 769 | ni: Node.Index, | 821 | ni: Node.Index, |
| 770 | requested_size: u64, | 822 | requested_size: u64, |
| 771 | ) (Allocator.Error || Io.Cancelable || IoError)!void { | 823 | ) (Allocator.Error || Io.Cancelable || IoError)!void { |
| ... | @@ -904,11 +956,11 @@ fn resizeNode( | ... | @@ -904,11 +956,11 @@ fn resizeNode( |
| 904 | next_ni.get(mf).prev = node.prev; | 956 | next_ni.get(mf).prev = node.prev; |
| 905 | switch (node.prev) { | 957 | switch (node.prev) { |
| 906 | .none => parent.first = next_ni, | 958 | .none => parent.first = next_ni, |
| 907 | else => |prev_ni| prev_ni.get(mf).next = next_ni, | 959 | else => |prev_ni| try prev_ni.setNext(gpa, next_ni, mf), |
| 908 | } | 960 | } |
| 909 | last.next = ni; | 961 | try parent.last.setNext(gpa, ni, mf); |
| 910 | node.prev = parent.last; | 962 | node.prev = parent.last; |
| 911 | node.next = .none; | 963 | try ni.setNext(gpa, .none, mf); |
| 912 | parent.last = ni; | 964 | parent.last = ni; |
| 913 | if (node.flags.has_content) { | 965 | if (node.flags.has_content) { |
| 914 | const parent_file_offset = node.parent.fileLocation(mf, false).offset; | 966 | const parent_file_offset = node.parent.fileLocation(mf, false).offset; |
| ... | @@ -972,13 +1024,13 @@ fn resizeNode( | ... | @@ -972,13 +1024,13 @@ fn resizeNode( |
| 972 | if (parent.last != first_floating_ni) { | 1024 | if (parent.last != first_floating_ni) { |
| 973 | first_floating.prev = parent.last; | 1025 | first_floating.prev = parent.last; |
| 974 | parent.last = first_floating_ni; | 1026 | parent.last = first_floating_ni; |
| 975 | last.next = first_floating_ni; | 1027 | try parent.last.setNext(gpa, first_floating_ni, mf); |
| 976 | last_fixed.next = first_floating.next; | 1028 | try last_fixed_ni.setNext(gpa, first_floating.next, mf); |
| 977 | switch (first_floating.next) { | 1029 | switch (first_floating.next) { |
| 978 | .none => {}, | 1030 | .none => {}, |
| 979 | else => |next_ni| next_ni.get(mf).prev = last_fixed_ni, | 1031 | else => |next_ni| next_ni.get(mf).prev = last_fixed_ni, |
| 980 | } | 1032 | } |
| 981 | first_floating.next = .none; | 1033 | try first_floating_ni.setNext(gpa, .none, mf); |
| 982 | } | 1034 | } |
| 983 | if (first_floating.flags.has_content) { | 1035 | if (first_floating.flags.has_content) { |
| 984 | const parent_file_offset = | 1036 | const parent_file_offset = |
| ... | @@ -1040,7 +1092,7 @@ fn resizeNode( | ... | @@ -1040,7 +1092,7 @@ fn resizeNode( |
| 1040 | 1092 | ||
| 1041 | fn realignNode( | 1093 | fn realignNode( |
| 1042 | mf: *MappedFile, | 1094 | mf: *MappedFile, |
| 1043 | gpa: std.mem.Allocator, | 1095 | gpa: Allocator, |
| 1044 | ni: Node.Index, | 1096 | ni: Node.Index, |
| 1045 | new_alignment: std.mem.Alignment, | 1097 | new_alignment: std.mem.Alignment, |
| 1046 | opts: Node.Index.RealignNodeOptions, | 1098 | opts: Node.Index.RealignNodeOptions, |
| ... | @@ -1241,9 +1293,9 @@ fn copyFileRange( | ... | @@ -1241,9 +1293,9 @@ fn copyFileRange( |
| 1241 | return size - remaining_size; | 1293 | return size - remaining_size; |
| 1242 | } | 1294 | } |
| 1243 | 1295 | ||
| 1244 | fn ensureCapacityForSetLocation(mf: *MappedFile, gpa: std.mem.Allocator) Allocator.Error!void { | 1296 | fn ensureCapacityForSetLocation(mf: *MappedFile, gpa: Allocator) Allocator.Error!void { |
| 1245 | try mf.large.ensureUnusedCapacity(gpa, 2); | 1297 | try mf.large.ensureUnusedCapacity(gpa, 2); |
| 1246 | try mf.updates.ensureUnusedCapacity(gpa, 1); | 1298 | try mf.updates.ensureUnusedCapacity(gpa, 2); |
| 1247 | } | 1299 | } |
| 1248 | 1300 | ||
| 1249 | pub fn ensureTotalCapacity(mf: *MappedFile, new_capacity: usize) Error!void { | 1301 | pub fn ensureTotalCapacity(mf: *MappedFile, new_capacity: usize) Error!void { |
src/link/SpirV.zig+13-13| ... | @@ -25,10 +25,10 @@ const Mir = @import("../codegen/spirv/Mir.zig"); | ... | @@ -25,10 +25,10 @@ const Mir = @import("../codegen/spirv/Mir.zig"); |
| 25 | const Linker = @This(); | 25 | const Linker = @This(); |
| 26 | 26 | ||
| 27 | base: link.File, | 27 | base: link.File, |
| 28 | fragments: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, Mir) = .empty, | 28 | fragments: std.array_hash_map.Auto(InternPool.Nav.Index, Mir) = .empty, |
| 29 | pending_navs: std.ArrayListUnmanaged(InternPool.Nav.Index) = .empty, | 29 | pending_navs: std.ArrayList(InternPool.Nav.Index) = .empty, |
| 30 | entry_points: std.ArrayListUnmanaged(EntryPointDecl) = .empty, | 30 | entry_points: std.ArrayList(EntryPointDecl) = .empty, |
| 31 | external_objects: std.ArrayListUnmanaged(ExternalObject) = .empty, | 31 | external_objects: std.ArrayList(ExternalObject) = .empty, |
| 32 | 32 | ||
| 33 | const EntryPointDecl = struct { | 33 | const EntryPointDecl = struct { |
| 34 | nav: InternPool.Nav.Index, | 34 | nav: InternPool.Nav.Index, |
| ... | @@ -363,16 +363,16 @@ fn mergeFragments(linker: *Linker, gpa: Allocator, arena: Allocator) error{OutOf | ... | @@ -363,16 +363,16 @@ fn mergeFragments(linker: *Linker, gpa: Allocator, arena: Allocator) error{OutOf |
| 363 | } | 363 | } |
| 364 | 364 | ||
| 365 | // Resolve Zig extern navs against external objects. | 365 | // Resolve Zig extern navs against external objects. |
| 366 | var ext_id_offsets: std.ArrayListUnmanaged(Word) = .empty; | 366 | var ext_id_offsets: std.ArrayList(Word) = .empty; |
| 367 | defer ext_id_offsets.deinit(gpa); | 367 | defer ext_id_offsets.deinit(gpa); |
| 368 | try ext_id_offsets.ensureTotalCapacity(gpa, linker.external_objects.items.len); | 368 | try ext_id_offsets.ensureTotalCapacity(gpa, linker.external_objects.items.len); |
| 369 | 369 | ||
| 370 | var unresolved_extern_count: u32 = 0; | 370 | var unresolved_extern_count: u32 = 0; |
| 371 | var resolved_ids: std.AutoArrayHashMapUnmanaged(Id, void) = .empty; | 371 | var resolved_ids: std.array_hash_map.Auto(Id, void) = .empty; |
| 372 | defer resolved_ids.deinit(gpa); | 372 | defer resolved_ids.deinit(gpa); |
| 373 | 373 | ||
| 374 | if (maybe_ip) |ip| { | 374 | if (maybe_ip) |ip| { |
| 375 | var extern_name_map: std.StringArrayHashMapUnmanaged(InternPool.Nav.Index) = .empty; | 375 | var extern_name_map: std.array_hash_map.String(InternPool.Nav.Index) = .empty; |
| 376 | defer extern_name_map.deinit(gpa); | 376 | defer extern_name_map.deinit(gpa); |
| 377 | 377 | ||
| 378 | var nav_it = nav_final_ids.iterator(); | 378 | var nav_it = nav_final_ids.iterator(); |
| ... | @@ -518,14 +518,14 @@ fn mergeZigFragments( | ... | @@ -518,14 +518,14 @@ fn mergeZigFragments( |
| 518 | frag_infos: []const FragmentInfo, | 518 | frag_infos: []const FragmentInfo, |
| 519 | nav_final_ids: *const std.AutoHashMapUnmanaged(InternPool.Nav.Index, Id), | 519 | nav_final_ids: *const std.AutoHashMapUnmanaged(InternPool.Nav.Index, Id), |
| 520 | uav_final_ids: *const std.AutoHashMapUnmanaged(struct { InternPool.Index, spec.StorageClass }, Id), | 520 | uav_final_ids: *const std.AutoHashMapUnmanaged(struct { InternPool.Index, spec.StorageClass }, Id), |
| 521 | resolved_ids: *const std.AutoArrayHashMapUnmanaged(Id, void), | 521 | resolved_ids: *const std.array_hash_map.Auto(Id, void), |
| 522 | maybe_ip: ?*InternPool, | 522 | maybe_ip: ?*InternPool, |
| 523 | ) error{OutOfMemory}!void { | 523 | ) error{OutOfMemory}!void { |
| 524 | for (linker.fragments.values(), frag_infos) |*mir, frag_info| { | 524 | for (linker.fragments.values(), frag_infos) |*mir, frag_info| { |
| 525 | var id_remap: std.AutoHashMapUnmanaged(Id, Id) = .empty; | 525 | var id_remap: std.AutoHashMapUnmanaged(Id, Id) = .empty; |
| 526 | defer id_remap.deinit(gpa); | 526 | defer id_remap.deinit(gpa); |
| 527 | 527 | ||
| 528 | var resolved_local_ids: std.AutoArrayHashMapUnmanaged(Id, void) = .empty; | 528 | var resolved_local_ids: std.array_hash_map.Auto(Id, void) = .empty; |
| 529 | defer resolved_local_ids.deinit(gpa); | 529 | defer resolved_local_ids.deinit(gpa); |
| 530 | 530 | ||
| 531 | for (mir.nav_refs) |ref| { | 531 | for (mir.nav_refs) |ref| { |
| ... | @@ -569,7 +569,7 @@ fn remapFilteredInsts( | ... | @@ -569,7 +569,7 @@ fn remapFilteredInsts( |
| 569 | id_offset: Word, | 569 | id_offset: Word, |
| 570 | id_remap: *const std.AutoHashMapUnmanaged(Id, Id), | 570 | id_remap: *const std.AutoHashMapUnmanaged(Id, Id), |
| 571 | parser: *BinaryModule.Parser, | 571 | parser: *BinaryModule.Parser, |
| 572 | skip_ids: *const std.AutoArrayHashMapUnmanaged(Id, void), | 572 | skip_ids: *const std.array_hash_map.Auto(Id, void), |
| 573 | mode: FilterMode, | 573 | mode: FilterMode, |
| 574 | ) error{OutOfMemory}!void { | 574 | ) error{OutOfMemory}!void { |
| 575 | if (words.len == 0) return; | 575 | if (words.len == 0) return; |
| ... | @@ -887,9 +887,9 @@ fn appendExternalObjects( | ... | @@ -887,9 +887,9 @@ fn appendExternalObjects( |
| 887 | has_linkage: *bool, | 887 | has_linkage: *bool, |
| 888 | keep_entry_points: bool, | 888 | keep_entry_points: bool, |
| 889 | is_obj: bool, | 889 | is_obj: bool, |
| 890 | resolved_ids: *const std.AutoArrayHashMapUnmanaged(Id, void), | 890 | resolved_ids: *const std.array_hash_map.Auto(Id, void), |
| 891 | ) error{OutOfMemory}!void { | 891 | ) error{OutOfMemory}!void { |
| 892 | var export_map: std.StringArrayHashMapUnmanaged(Id) = .empty; | 892 | var export_map: std.array_hash_map.String(Id) = .empty; |
| 893 | defer export_map.deinit(gpa); | 893 | defer export_map.deinit(gpa); |
| 894 | 894 | ||
| 895 | for (linker.external_objects.items, ext_id_offsets) |ext_obj, id_offset| { | 895 | for (linker.external_objects.items, ext_id_offsets) |ext_obj, id_offset| { |
| ... | @@ -908,7 +908,7 @@ fn appendExternalObjects( | ... | @@ -908,7 +908,7 @@ fn appendExternalObjects( |
| 908 | } | 908 | } |
| 909 | for (per_obj_remaps) |*m| m.* = .empty; | 909 | for (per_obj_remaps) |*m| m.* = .empty; |
| 910 | 910 | ||
| 911 | var resolved_linkage_ids: std.AutoArrayHashMapUnmanaged(Id, void) = .empty; | 911 | var resolved_linkage_ids: std.array_hash_map.Auto(Id, void) = .empty; |
| 912 | defer resolved_linkage_ids.deinit(gpa); | 912 | defer resolved_linkage_ids.deinit(gpa); |
| 913 | 913 | ||
| 914 | for (resolved_ids.keys()) |id| { | 914 | for (resolved_ids.keys()) |id| { |
src/link/SpirV/dedup_types.zig+2-2| ... | @@ -85,7 +85,7 @@ pub fn run(parser: *BinaryModule.Parser, binary: *BinaryModule) !void { | ... | @@ -85,7 +85,7 @@ pub fn run(parser: *BinaryModule.Parser, binary: *BinaryModule) !void { |
| 85 | 85 | ||
| 86 | for (inst.operands, 0..) |word, i| { | 86 | for (inst.operands, 0..) |word, i| { |
| 87 | if (i == result_id_index) continue; | 87 | if (i == result_id_index) continue; |
| 88 | if (std.mem.indexOfScalar(u16, id_offsets.items, @intCast(i)) != null) { | 88 | if (std.mem.findScalar(u16, id_offsets.items, @intCast(i)) != null) { |
| 89 | const canonical = id_remap.get(@fromBackingInt(@intCast(word))) orelse @as(Id, @fromBackingInt(@intCast(word))); | 89 | const canonical = id_remap.get(@fromBackingInt(@intCast(word))) orelse @as(Id, @fromBackingInt(@intCast(word))); |
| 90 | try key_words.append(gpa, @backingInt(canonical)); | 90 | try key_words.append(gpa, @backingInt(canonical)); |
| 91 | } else { | 91 | } else { |
| ... | @@ -182,7 +182,7 @@ pub fn run(parser: *BinaryModule.Parser, binary: *BinaryModule) !void { | ... | @@ -182,7 +182,7 @@ pub fn run(parser: *BinaryModule.Parser, binary: *BinaryModule) !void { |
| 182 | } else null; | 182 | } else null; |
| 183 | 183 | ||
| 184 | for (inst_slice, 0..) |*word, i| { | 184 | for (inst_slice, 0..) |*word, i| { |
| 185 | if (std.mem.indexOfScalar(u16, id_offsets.items, @intCast(i)) == null) continue; | 185 | if (std.mem.findScalar(u16, id_offsets.items, @intCast(i)) == null) continue; |
| 186 | max_id = @max(max_id, word.*); | 186 | max_id = @max(max_id, word.*); |
| 187 | if (maybe_result_id_index != null and i == maybe_result_id_index.?) continue; | 187 | if (maybe_result_id_index != null and i == maybe_result_id_index.?) continue; |
| 188 | 188 |
src/link/SpirV/prune_unused.zig+1-1| ... | @@ -187,7 +187,7 @@ fn markAlive( | ... | @@ -187,7 +187,7 @@ fn markAlive( |
| 187 | parser: *BinaryModule.Parser, | 187 | parser: *BinaryModule.Parser, |
| 188 | binary: BinaryModule, | 188 | binary: BinaryModule, |
| 189 | inst: BinaryModule.Instruction, | 189 | inst: BinaryModule.Instruction, |
| 190 | alive: *std.DynamicBitSetUnmanaged, | 190 | alive: *std.bit_set.Dynamic, |
| 191 | id_to_index: *const std.AutoHashMapUnmanaged(ResultId, u32), | 191 | id_to_index: *const std.AutoHashMapUnmanaged(ResultId, u32), |
| 192 | code_offsets: *const std.ArrayList(usize), | 192 | code_offsets: *const std.ArrayList(usize), |
| 193 | id_offset_buf: *std.ArrayList(u16), | 193 | id_offset_buf: *std.ArrayList(u16), |
src/link/Wasm.zig+953-206| ... | @@ -133,25 +133,21 @@ object_total_sections: u32 = 0, | ... | @@ -133,25 +133,21 @@ object_total_sections: u32 = 0, |
| 133 | /// All comdat symbols from all objects concatenated. | 133 | /// All comdat symbols from all objects concatenated. |
| 134 | object_comdat_symbols: std.MultiArrayList(Comdat.Symbol) = .empty, | 134 | object_comdat_symbols: std.MultiArrayList(Comdat.Symbol) = .empty, |
| 135 | 135 | ||
| 136 | /// Relocations to be emitted into an object file. Remains empty when not | 136 | /// Relocations produced by Zig code and data lowering. These retain semantic |
| 137 | /// emitting an object file. | 137 | /// targets until `flush`, where final output indexes are known. |
| 138 | out_relocs: std.MultiArrayList(OutReloc) = .empty, | 138 | zcu_relocations: std.MultiArrayList(ZcuRelocation) = .empty, |
| 139 | /// List of locations within `string_bytes` that must be patched with the virtual | 139 | /// List of locations within `string_bytes` that must be patched with the virtual |
| 140 | /// memory address of a Uav during `flush`. | 140 | /// memory address of a Uav during `flush`. |
| 141 | /// When emitting an object file, `out_relocs` is used instead. | 141 | /// When emitting an object file, `zcu_relocations` is used instead. |
| 142 | uav_fixups: std.ArrayList(UavFixup) = .empty, | 142 | uav_fixups: std.ArrayList(UavFixup) = .empty, |
| 143 | /// List of locations within `string_bytes` that must be patched with the virtual | 143 | /// List of locations within `string_bytes` that must be patched with the virtual |
| 144 | /// memory address of a Nav during `flush`. | 144 | /// memory address of a Nav during `flush`. |
| 145 | /// When emitting an object file, `out_relocs` is used instead. | 145 | /// When emitting an object file, `zcu_relocations` is used instead. |
| 146 | /// No functions here only global variables. | 146 | /// No functions here only global variables. |
| 147 | nav_fixups: std.ArrayList(NavFixup) = .empty, | 147 | nav_fixups: std.ArrayList(NavFixup) = .empty, |
| 148 | /// When a nav reference is a function pointer, this tracks the required function | 148 | /// When a nav reference is a function pointer, this tracks the required function |
| 149 | /// table entry index that needs to overwrite the code in the final output. | 149 | /// table entry index that needs to overwrite the code in the final output. |
| 150 | func_table_fixups: std.ArrayList(FuncTableFixup) = .empty, | 150 | func_table_fixups: std.ArrayList(FuncTableFixup) = .empty, |
| 151 | /// Symbols to be emitted into an object file. Remains empty when not emitting | ||
| 152 | /// an object file. | ||
| 153 | symbol_table: std.array_hash_map.Auto(String, void) = .empty, | ||
| 154 | |||
| 155 | /// When importing objects from the host environment, a name must be supplied. | 151 | /// When importing objects from the host environment, a name must be supplied. |
| 156 | /// LLVM uses "env" by default when none is given. | 152 | /// LLVM uses "env" by default when none is given. |
| 157 | /// This value is passed to object files since wasm tooling conventions provides | 153 | /// This value is passed to object files since wasm tooling conventions provides |
| ... | @@ -244,7 +240,9 @@ function_imports: std.array_hash_map.Auto(String, FunctionImportId) = .empty, | ... | @@ -244,7 +240,9 @@ function_imports: std.array_hash_map.Auto(String, FunctionImportId) = .empty, |
| 244 | /// remove elements from the table, and the remainder are either undefined | 240 | /// remove elements from the table, and the remainder are either undefined |
| 245 | /// symbol errors, or symbol table entries depending on the output mode. | 241 | /// symbol errors, or symbol table entries depending on the output mode. |
| 246 | data_imports: std.array_hash_map.Auto(String, DataImportId) = .empty, | 242 | data_imports: std.array_hash_map.Auto(String, DataImportId) = .empty, |
| 247 | /// Set of data symbols that will appear in the final binary. Used to populate | 243 | /// Set of data symbols that will appear in the final binary when outputting an object file. |
| 244 | datas: std.array_hash_map.Auto(ObjectDataImport.Resolution, void) = .empty, | ||
| 245 | /// Set of data segment symbols that will appear in the final binary. Used to populate | ||
| 248 | /// `Flush.data_segments` before sorting. | 246 | /// `Flush.data_segments` before sorting. |
| 249 | data_segments: std.array_hash_map.Auto(DataSegmentId, void) = .empty, | 247 | data_segments: std.array_hash_map.Auto(DataSegmentId, void) = .empty, |
| 250 | 248 | ||
| ... | @@ -302,11 +300,6 @@ pub const TagNameOff = extern struct { | ... | @@ -302,11 +300,6 @@ pub const TagNameOff = extern struct { |
| 302 | len: u32, | 300 | len: u32, |
| 303 | }; | 301 | }; |
| 304 | 302 | ||
| 305 | /// Index into `Wasm.zcu_indirect_function_set`. | ||
| 306 | pub const ZcuIndirectFunctionSetIndex = enum(u32) { | ||
| 307 | _, | ||
| 308 | }; | ||
| 309 | |||
| 310 | pub const UavFixup = extern struct { | 303 | pub const UavFixup = extern struct { |
| 311 | uavs_exe_index: UavsExeIndex, | 304 | uavs_exe_index: UavsExeIndex, |
| 312 | /// Index into `string_bytes`. | 305 | /// Index into `string_bytes`. |
| ... | @@ -315,14 +308,14 @@ pub const UavFixup = extern struct { | ... | @@ -315,14 +308,14 @@ pub const UavFixup = extern struct { |
| 315 | }; | 308 | }; |
| 316 | 309 | ||
| 317 | pub const NavFixup = extern struct { | 310 | pub const NavFixup = extern struct { |
| 318 | navs_exe_index: NavsExeIndex, | 311 | nav_index: InternPool.Nav.Index, |
| 319 | /// Index into `string_bytes`. | 312 | /// Index into `string_bytes`. |
| 320 | offset: u32, | 313 | offset: u32, |
| 321 | addend: u32, | 314 | addend: u32, |
| 322 | }; | 315 | }; |
| 323 | 316 | ||
| 324 | pub const FuncTableFixup = extern struct { | 317 | pub const FuncTableFixup = extern struct { |
| 325 | table_index: ZcuIndirectFunctionSetIndex, | 318 | nav_index: InternPool.Nav.Index, |
| 326 | /// Index into `string_bytes`. | 319 | /// Index into `string_bytes`. |
| 327 | offset: u32, | 320 | offset: u32, |
| 328 | }; | 321 | }; |
| ... | @@ -355,7 +348,9 @@ pub const FunctionIndex = enum(u32) { | ... | @@ -355,7 +348,9 @@ pub const FunctionIndex = enum(u32) { |
| 355 | 348 | ||
| 356 | pub fn fromSymbolName(wasm: *const Wasm, name: String) ?FunctionIndex { | 349 | pub fn fromSymbolName(wasm: *const Wasm, name: String) ?FunctionIndex { |
| 357 | if (wasm.object_function_imports.getPtr(name)) |import| { | 350 | if (wasm.object_function_imports.getPtr(name)) |import| { |
| 358 | return fromResolution(wasm, import.resolution); | 351 | if (import.resolution != .unresolved) { |
| 352 | return fromResolution(wasm, import.resolution); | ||
| 353 | } | ||
| 359 | } | 354 | } |
| 360 | if (wasm.function_exports.get(name)) |index| return index; | 355 | if (wasm.function_exports.get(name)) |index| return index; |
| 361 | if (wasm.hidden_function_exports.get(name)) |index| return index; | 356 | if (wasm.hidden_function_exports.get(name)) |index| return index; |
| ... | @@ -374,7 +369,8 @@ pub const GlobalExport = extern struct { | ... | @@ -374,7 +369,8 @@ pub const GlobalExport = extern struct { |
| 374 | }; | 369 | }; |
| 375 | 370 | ||
| 376 | /// 0. Index into `Flush.function_imports` | 371 | /// 0. Index into `Flush.function_imports` |
| 377 | /// 1. Index into `functions`. | 372 | /// 1. Index into `Flush.intrinsic_function_imports` |
| 373 | /// 2. Index into `functions`. | ||
| 378 | /// | 374 | /// |
| 379 | /// Note that function_imports indexes are subject to swap removals during | 375 | /// Note that function_imports indexes are subject to swap removals during |
| 380 | /// `flush`. | 376 | /// `flush`. |
| ... | @@ -386,7 +382,11 @@ pub const OutputFunctionIndex = enum(u32) { | ... | @@ -386,7 +382,11 @@ pub const OutputFunctionIndex = enum(u32) { |
| 386 | } | 382 | } |
| 387 | 383 | ||
| 388 | pub fn fromFunctionIndex(wasm: *const Wasm, index: FunctionIndex) OutputFunctionIndex { | 384 | pub fn fromFunctionIndex(wasm: *const Wasm, index: FunctionIndex) OutputFunctionIndex { |
| 389 | return @fromBackingInt(@intCast(wasm.flush_buffer.function_imports.entries.len + @backingInt(index))); | 385 | return @fromBackingInt(@intCast( |
| 386 | wasm.flush_buffer.function_imports.entries.len + | ||
| 387 | wasm.flush_buffer.intrinsic_function_imports.entries.len + | ||
| 388 | @backingInt(index), | ||
| 389 | )); | ||
| 390 | } | 390 | } |
| 391 | 391 | ||
| 392 | pub fn fromObjectFunction(wasm: *const Wasm, index: ObjectFunctionIndex) OutputFunctionIndex { | 392 | pub fn fromObjectFunction(wasm: *const Wasm, index: ObjectFunctionIndex) OutputFunctionIndex { |
| ... | @@ -429,6 +429,9 @@ pub const OutputFunctionIndex = enum(u32) { | ... | @@ -429,6 +429,9 @@ pub const OutputFunctionIndex = enum(u32) { |
| 429 | 429 | ||
| 430 | pub fn fromSymbolName(wasm: *const Wasm, name: String) OutputFunctionIndex { | 430 | pub fn fromSymbolName(wasm: *const Wasm, name: String) OutputFunctionIndex { |
| 431 | if (wasm.flush_buffer.function_imports.getIndex(name)) |i| return @fromBackingInt(@intCast(i)); | 431 | if (wasm.flush_buffer.function_imports.getIndex(name)) |i| return @fromBackingInt(@intCast(i)); |
| 432 | if (wasm.flush_buffer.intrinsic_function_imports.getIndex(name)) |i| return @fromBackingInt(@intCast( | ||
| 433 | wasm.flush_buffer.function_imports.entries.len + i, | ||
| 434 | )); | ||
| 432 | return fromFunctionIndex(wasm, FunctionIndex.fromSymbolName(wasm, name) orelse { | 435 | return fromFunctionIndex(wasm, FunctionIndex.fromSymbolName(wasm, name) orelse { |
| 433 | if (std.debug.runtime_safety) { | 436 | if (std.debug.runtime_safety) { |
| 434 | std.debug.panic("function index for symbol not found: {s}", .{name.slice(wasm)}); | 437 | std.debug.panic("function index for symbol not found: {s}", .{name.slice(wasm)}); |
| ... | @@ -437,6 +440,56 @@ pub const OutputFunctionIndex = enum(u32) { | ... | @@ -437,6 +440,56 @@ pub const OutputFunctionIndex = enum(u32) { |
| 437 | } | 440 | } |
| 438 | }; | 441 | }; |
| 439 | 442 | ||
| 443 | // Order | ||
| 444 | // 0. Flush.data_imports | ||
| 445 | // 1. Wasm.datas | ||
| 446 | pub const OutputDataIndex = enum(u32) { | ||
| 447 | _, | ||
| 448 | |||
| 449 | pub fn fromSymbolName(wasm: *const Wasm, name: String) OutputDataIndex { | ||
| 450 | if (wasm.flush_buffer.data_imports.getIndex(name)) |i| return @fromBackingInt(@intCast(i)); | ||
| 451 | if (wasm.object_data_imports.getPtr(name)) |import| { | ||
| 452 | if (import.resolution != .unresolved) return fromResolution(wasm, import.resolution).?; | ||
| 453 | } | ||
| 454 | if (wasm.flush_buffer.data_exports.get(name)) |symbol| return fromResolution(wasm, symbol.resolution).?; | ||
| 455 | if (std.debug.runtime_safety) { | ||
| 456 | std.debug.panic("data index for symbol not found: {s}", .{name.slice(wasm)}); | ||
| 457 | } else unreachable; | ||
| 458 | } | ||
| 459 | |||
| 460 | pub fn fromObjectData(wasm: *const Wasm, index: ObjectData.Index) OutputDataIndex { | ||
| 461 | return fromResolution(wasm, .fromObjectDataIndex(wasm, index)).?; | ||
| 462 | } | ||
| 463 | |||
| 464 | pub fn fromResolution(wasm: *const Wasm, resolution: ObjectDataImport.Resolution) ?OutputDataIndex { | ||
| 465 | const i = wasm.datas.getIndex(resolution) orelse return null; | ||
| 466 | return @fromBackingInt(@intCast(wasm.flush_buffer.data_imports.entries.len + i)); | ||
| 467 | } | ||
| 468 | |||
| 469 | pub fn fromUav(wasm: *const Wasm, ip_index: InternPool.Index) OutputDataIndex { | ||
| 470 | const comp = wasm.base.comp; | ||
| 471 | const resolution: ObjectDataImport.Resolution = if (comp.config.output_mode == .Obj) | ||
| 472 | .pack(wasm, .{ .uav_obj = @fromBackingInt(@intCast(wasm.uavs_obj.getIndex(ip_index).?)) }) | ||
| 473 | else | ||
| 474 | .pack(wasm, .{ .uav_exe = @fromBackingInt(@intCast(wasm.uavs_exe.getIndex(ip_index).?)) }); | ||
| 475 | return fromResolution(wasm, resolution).?; | ||
| 476 | } | ||
| 477 | |||
| 478 | pub fn fromNav(wasm: *const Wasm, nav_index: InternPool.Nav.Index) OutputDataIndex { | ||
| 479 | const zcu = wasm.base.comp.zcu.?; | ||
| 480 | const ip = &zcu.intern_pool; | ||
| 481 | const nav = ip.getNav(nav_index); | ||
| 482 | if (nav.getExtern(ip)) |ext| { | ||
| 483 | return fromSymbolName(wasm, wasm.getExistingString(ext.name.toSlice(ip)).?); | ||
| 484 | } | ||
| 485 | const resolution: ObjectDataImport.Resolution = if (wasm.base.comp.config.output_mode == .Obj) | ||
| 486 | .pack(wasm, .{ .nav_obj = @fromBackingInt(@intCast(wasm.navs_obj.getIndex(nav_index).?)) }) | ||
| 487 | else | ||
| 488 | .pack(wasm, .{ .nav_exe = @fromBackingInt(@intCast(wasm.navs_exe.getIndex(nav_index).?)) }); | ||
| 489 | return fromResolution(wasm, resolution).?; | ||
| 490 | } | ||
| 491 | }; | ||
| 492 | |||
| 440 | /// Index into `Wasm.globals`. | 493 | /// Index into `Wasm.globals`. |
| 441 | pub const GlobalIndex = enum(u32) { | 494 | pub const GlobalIndex = enum(u32) { |
| 442 | _, | 495 | _, |
| ... | @@ -452,17 +505,17 @@ pub const GlobalIndex = enum(u32) { | ... | @@ -452,17 +505,17 @@ pub const GlobalIndex = enum(u32) { |
| 452 | return .stack_pointer; | 505 | return .stack_pointer; |
| 453 | } | 506 | } |
| 454 | 507 | ||
| 455 | pub fn ptr(index: GlobalIndex, f: *const Flush) *Wasm.GlobalImport.Resolution { | 508 | pub fn fromResolution(wasm: *const Wasm, resolution: GlobalImport.Resolution) ?GlobalIndex { |
| 456 | return &f.globals.items[@backingInt(index)]; | 509 | const i = wasm.globals.getIndex(resolution) orelse return null; |
| 510 | return @fromBackingInt(@intCast(wasm.flush_buffer.global_imports.entries.len + i)); | ||
| 457 | } | 511 | } |
| 458 | 512 | ||
| 459 | pub fn fromIpNav(wasm: *const Wasm, nav_index: InternPool.Nav.Index) ?GlobalIndex { | 513 | pub fn fromIpNav(wasm: *const Wasm, nav_index: InternPool.Nav.Index) ?GlobalIndex { |
| 460 | const i = wasm.globals.getIndex(.fromIpNav(wasm, nav_index)) orelse return null; | 514 | return fromResolution(wasm, .fromIpNav(wasm, nav_index)); |
| 461 | return @fromBackingInt(@intCast(i)); | ||
| 462 | } | 515 | } |
| 463 | 516 | ||
| 464 | pub fn fromObjectGlobal(wasm: *const Wasm, i: ObjectGlobalIndex) GlobalIndex { | 517 | pub fn fromObjectGlobal(wasm: *const Wasm, i: ObjectGlobalIndex) GlobalIndex { |
| 465 | return @fromBackingInt(@intCast(wasm.globals.getIndex(.fromObjectGlobal(wasm, i)).?)); | 518 | return fromResolution(wasm, .fromObjectGlobal(wasm, i)).?; |
| 466 | } | 519 | } |
| 467 | 520 | ||
| 468 | pub fn fromObjectGlobalHandlingWeak(wasm: *const Wasm, index: ObjectGlobalIndex) GlobalIndex { | 521 | pub fn fromObjectGlobalHandlingWeak(wasm: *const Wasm, index: ObjectGlobalIndex) GlobalIndex { |
| ... | @@ -474,8 +527,9 @@ pub const GlobalIndex = enum(u32) { | ... | @@ -474,8 +527,9 @@ pub const GlobalIndex = enum(u32) { |
| 474 | } | 527 | } |
| 475 | 528 | ||
| 476 | pub fn fromSymbolName(wasm: *const Wasm, name: String) GlobalIndex { | 529 | pub fn fromSymbolName(wasm: *const Wasm, name: String) GlobalIndex { |
| 530 | if (wasm.flush_buffer.global_imports.getIndex(name)) |i| return @fromBackingInt(@intCast(i)); | ||
| 477 | const import = wasm.object_global_imports.getPtr(name).?; | 531 | const import = wasm.object_global_imports.getPtr(name).?; |
| 478 | return @fromBackingInt(@intCast(wasm.globals.getIndex(import.resolution).?)); | 532 | return fromResolution(wasm, import.resolution).?; |
| 479 | } | 533 | } |
| 480 | }; | 534 | }; |
| 481 | 535 | ||
| ... | @@ -483,10 +537,6 @@ pub const GlobalIndex = enum(u32) { | ... | @@ -483,10 +537,6 @@ pub const GlobalIndex = enum(u32) { |
| 483 | pub const TableIndex = enum(u32) { | 537 | pub const TableIndex = enum(u32) { |
| 484 | _, | 538 | _, |
| 485 | 539 | ||
| 486 | pub fn ptr(index: TableIndex, f: *const Flush) *Wasm.TableImport.Resolution { | ||
| 487 | return &f.tables.items[@backingInt(index)]; | ||
| 488 | } | ||
| 489 | |||
| 490 | pub fn fromObjectTable(wasm: *const Wasm, i: ObjectTableIndex) TableIndex { | 540 | pub fn fromObjectTable(wasm: *const Wasm, i: ObjectTableIndex) TableIndex { |
| 491 | return @fromBackingInt(@intCast(wasm.tables.getIndex(.fromObjectTable(i)).?)); | 541 | return @fromBackingInt(@intCast(wasm.tables.getIndex(.fromObjectTable(i)).?)); |
| 492 | } | 542 | } |
| ... | @@ -668,9 +718,10 @@ pub const SymbolFlags = packed struct(u32) { | ... | @@ -668,9 +718,10 @@ pub const SymbolFlags = packed struct(u32) { |
| 668 | flags.ref_type = .funcref; | 718 | flags.ref_type = .funcref; |
| 669 | } | 719 | } |
| 670 | 720 | ||
| 671 | pub fn isIncluded(flags: SymbolFlags, is_dynamic: bool) bool { | 721 | pub fn isIncluded(flags: SymbolFlags, is_dynamic: bool, is_obj: bool) bool { |
| 672 | return flags.exported or | 722 | return flags.exported or |
| 673 | (is_dynamic and !flags.visibility_hidden) or | 723 | (is_dynamic and !flags.visibility_hidden) or |
| 724 | (is_obj and flags.binding != .local) or | ||
| 674 | (flags.no_strip and flags.must_link); | 725 | (flags.no_strip and flags.must_link); |
| 675 | } | 726 | } |
| 676 | 727 | ||
| ... | @@ -696,8 +747,8 @@ pub const SymbolFlags = packed struct(u32) { | ... | @@ -696,8 +747,8 @@ pub const SymbolFlags = packed struct(u32) { |
| 696 | /// Masks off the Zig-specific stuff. | 747 | /// Masks off the Zig-specific stuff. |
| 697 | pub fn toAbiInteger(flags: SymbolFlags) u32 { | 748 | pub fn toAbiInteger(flags: SymbolFlags) u32 { |
| 698 | var copy = flags; | 749 | var copy = flags; |
| 699 | copy.initZigSpecific(false, false); | 750 | copy.initZigSpecific(false, flags.no_strip); |
| 700 | return @bitCast(copy); | 751 | return @backingInt(copy); |
| 701 | } | 752 | } |
| 702 | }; | 753 | }; |
| 703 | 754 | ||
| ... | @@ -812,7 +863,7 @@ pub const UavsExeIndex = enum(u32) { | ... | @@ -812,7 +863,7 @@ pub const UavsExeIndex = enum(u32) { |
| 812 | /// Used when emitting a relocatable object. | 863 | /// Used when emitting a relocatable object. |
| 813 | pub const ZcuDataObj = extern struct { | 864 | pub const ZcuDataObj = extern struct { |
| 814 | code: DataPayload, | 865 | code: DataPayload, |
| 815 | relocs: OutReloc.Slice, | 866 | relocs: ZcuRelocation.Slice, |
| 816 | }; | 867 | }; |
| 817 | 868 | ||
| 818 | /// Used when not emitting a relocatable object. | 869 | /// Used when not emitting a relocatable object. |
| ... | @@ -855,7 +906,9 @@ const ZcuDataStarts = struct { | ... | @@ -855,7 +906,9 @@ const ZcuDataStarts = struct { |
| 855 | var uavs_i = zds.uavs_i; | 906 | var uavs_i = zds.uavs_i; |
| 856 | while (uavs_i < wasm.uavs_obj.entries.len) : (uavs_i += 1) { | 907 | while (uavs_i < wasm.uavs_obj.entries.len) : (uavs_i += 1) { |
| 857 | // Call to `lowerZcuData` here possibly creates more entries in these tables. | 908 | // Call to `lowerZcuData` here possibly creates more entries in these tables. |
| 858 | wasm.uavs_obj.values()[uavs_i] = try lowerZcuData(wasm, pt, wasm.uavs_obj.keys()[uavs_i]); | 909 | const uav = wasm.uavs_obj.keys()[uavs_i]; |
| 910 | const zcu_data = try lowerZcuData(wasm, pt, uav); | ||
| 911 | wasm.uavs_obj.values()[uavs_i] = zcu_data; | ||
| 859 | } | 912 | } |
| 860 | } | 913 | } |
| 861 | 914 | ||
| ... | @@ -906,6 +959,51 @@ pub const ZcuFunc = union { | ... | @@ -906,6 +959,51 @@ pub const ZcuFunc = union { |
| 906 | return &wasm.zcu_funcs.values()[@backingInt(i)]; | 959 | return &wasm.zcu_funcs.values()[@backingInt(i)]; |
| 907 | } | 960 | } |
| 908 | 961 | ||
| 962 | pub fn flags(i: @This(), wasm: *const Wasm) SymbolFlags { | ||
| 963 | const zcu = wasm.base.comp.zcu.?; | ||
| 964 | const ip = &zcu.intern_pool; | ||
| 965 | const ip_index = i.key(wasm).*; | ||
| 966 | switch (ip.indexToKey(ip_index)) { | ||
| 967 | .func => |func| { | ||
| 968 | const nav = ip.getNav(func.owner_nav); | ||
| 969 | if (nav.getExtern(ip)) |ext| { | ||
| 970 | const name_slice = ext.name.toSlice(ip); | ||
| 971 | const name_string = wasm.getExistingString(name_slice).?; | ||
| 972 | return .{ | ||
| 973 | .binding = switch (ext.linkage) { | ||
| 974 | .internal => .local, | ||
| 975 | .strong => .strong, | ||
| 976 | .weak => .weak, | ||
| 977 | .link_once => @panic("TODO: COMDAT"), | ||
| 978 | }, | ||
| 979 | .visibility_hidden = switch (ext.visibility) { | ||
| 980 | .default => false, | ||
| 981 | .hidden => true, | ||
| 982 | .protected => false, | ||
| 983 | }, | ||
| 984 | .undefined = false, | ||
| 985 | .exported = wasm.missing_exports.contains(name_string), | ||
| 986 | .explicit_name = false, | ||
| 987 | .no_strip = false, | ||
| 988 | .tls = ext.is_threadlocal, | ||
| 989 | .absolute = false, | ||
| 990 | }; | ||
| 991 | } else { | ||
| 992 | return .{ | ||
| 993 | .binding = .local, | ||
| 994 | .tls = nav.resolved.?.@"threadlocal", | ||
| 995 | }; | ||
| 996 | } | ||
| 997 | }, | ||
| 998 | .enum_type => { | ||
| 999 | return .{ | ||
| 1000 | .binding = .local, | ||
| 1001 | }; | ||
| 1002 | }, | ||
| 1003 | else => unreachable, | ||
| 1004 | } | ||
| 1005 | } | ||
| 1006 | |||
| 909 | pub fn name(i: @This(), wasm: *const Wasm) [:0]const u8 { | 1007 | pub fn name(i: @This(), wasm: *const Wasm) [:0]const u8 { |
| 910 | const zcu = wasm.base.comp.zcu.?; | 1008 | const zcu = wasm.base.comp.zcu.?; |
| 911 | const ip = &zcu.intern_pool; | 1009 | const ip = &zcu.intern_pool; |
| ... | @@ -1034,6 +1132,15 @@ pub const FunctionImport = extern struct { | ... | @@ -1034,6 +1132,15 @@ pub const FunctionImport = extern struct { |
| 1034 | return pack(wasm, .{ .object_function = object_function }); | 1132 | return pack(wasm, .{ .object_function = object_function }); |
| 1035 | } | 1133 | } |
| 1036 | 1134 | ||
| 1135 | pub fn flags(r: Resolution, wasm: *Wasm) SymbolFlags { | ||
| 1136 | return switch (unpack(r, wasm)) { | ||
| 1137 | .unresolved => unreachable, | ||
| 1138 | .__wasm_apply_global_tls_relocs, .__wasm_call_ctors, .__wasm_init_memory, .__wasm_init_tls => unreachable, | ||
| 1139 | .object_function => |i| i.ptr(wasm).flags, | ||
| 1140 | .zcu_func => |i| i.flags(wasm), | ||
| 1141 | }; | ||
| 1142 | } | ||
| 1143 | |||
| 1037 | pub fn isNavOrUnresolved(r: Resolution, wasm: *const Wasm) bool { | 1144 | pub fn isNavOrUnresolved(r: Resolution, wasm: *const Wasm) bool { |
| 1038 | return switch (r.unpack(wasm)) { | 1145 | return switch (r.unpack(wasm)) { |
| 1039 | .unresolved, .zcu_func => true, | 1146 | .unresolved, .zcu_func => true, |
| ... | @@ -1136,6 +1243,7 @@ pub const GlobalImport = extern struct { | ... | @@ -1136,6 +1243,7 @@ pub const GlobalImport = extern struct { |
| 1136 | __tls_base, | 1243 | __tls_base, |
| 1137 | __tls_size, | 1244 | __tls_size, |
| 1138 | // Next, index into `object_globals`. | 1245 | // Next, index into `object_globals`. |
| 1246 | // Next, index into `uavs_obj` or `uavs_exe` depending on whether emitting an object. | ||
| 1139 | // Next, index into `navs_obj` or `navs_exe` depending on whether emitting an object. | 1247 | // Next, index into `navs_obj` or `navs_exe` depending on whether emitting an object. |
| 1140 | _, | 1248 | _, |
| 1141 | 1249 | ||
| ... | @@ -1150,6 +1258,8 @@ pub const GlobalImport = extern struct { | ... | @@ -1150,6 +1258,8 @@ pub const GlobalImport = extern struct { |
| 1150 | __tls_base, | 1258 | __tls_base, |
| 1151 | __tls_size, | 1259 | __tls_size, |
| 1152 | object_global: ObjectGlobalIndex, | 1260 | object_global: ObjectGlobalIndex, |
| 1261 | uav_exe: UavsExeIndex, | ||
| 1262 | uav_obj: UavsObjIndex, | ||
| 1153 | nav_exe: NavsExeIndex, | 1263 | nav_exe: NavsExeIndex, |
| 1154 | nav_obj: NavsObjIndex, | 1264 | nav_obj: NavsObjIndex, |
| 1155 | }; | 1265 | }; |
| ... | @@ -1170,12 +1280,22 @@ pub const GlobalImport = extern struct { | ... | @@ -1170,12 +1280,22 @@ pub const GlobalImport = extern struct { |
| 1170 | return .{ .object_global = @fromBackingInt(@intCast(object_global_index)) }; | 1280 | return .{ .object_global = @fromBackingInt(@intCast(object_global_index)) }; |
| 1171 | const comp = wasm.base.comp; | 1281 | const comp = wasm.base.comp; |
| 1172 | const is_obj = comp.config.output_mode == .Obj; | 1282 | const is_obj = comp.config.output_mode == .Obj; |
| 1173 | const nav_index = object_global_index - wasm.object_globals.items.len; | 1283 | const uav_index = object_global_index - wasm.object_globals.items.len; |
| 1174 | return if (is_obj) .{ | 1284 | if (is_obj) { |
| 1175 | .nav_obj = @fromBackingInt(@intCast(nav_index)), | 1285 | if (uav_index < wasm.uavs_obj.entries.len) { |
| 1176 | } else .{ | 1286 | return .{ .uav_obj = @fromBackingInt(@intCast(uav_index)) }; |
| 1177 | .nav_exe = @fromBackingInt(@intCast(nav_index)), | 1287 | } |
| 1178 | }; | 1288 | return .{ .nav_obj = @fromBackingInt( |
| 1289 | @intCast(uav_index - wasm.uavs_obj.entries.len), | ||
| 1290 | ) }; | ||
| 1291 | } else { | ||
| 1292 | if (uav_index < wasm.uavs_exe.entries.len) { | ||
| 1293 | return .{ .uav_exe = @fromBackingInt(@intCast(uav_index)) }; | ||
| 1294 | } | ||
| 1295 | return .{ .nav_exe = @fromBackingInt( | ||
| 1296 | @intCast(uav_index - wasm.uavs_exe.entries.len), | ||
| 1297 | ) }; | ||
| 1298 | } | ||
| 1179 | }, | 1299 | }, |
| 1180 | }; | 1300 | }; |
| 1181 | } | 1301 | } |
| ... | @@ -1190,11 +1310,29 @@ pub const GlobalImport = extern struct { | ... | @@ -1190,11 +1310,29 @@ pub const GlobalImport = extern struct { |
| 1190 | .__tls_base => .__tls_base, | 1310 | .__tls_base => .__tls_base, |
| 1191 | .__tls_size => .__tls_size, | 1311 | .__tls_size => .__tls_size, |
| 1192 | .object_global => |i| @fromBackingInt(@intCast(first_object_global + @backingInt(i))), | 1312 | .object_global => |i| @fromBackingInt(@intCast(first_object_global + @backingInt(i))), |
| 1193 | .nav_obj => |i| @fromBackingInt(@intCast(first_object_global + wasm.object_globals.items.len + @backingInt(i))), | 1313 | inline .uav_obj, .uav_exe => |i| @fromBackingInt(@intCast( |
| 1194 | .nav_exe => |i| @fromBackingInt(@intCast(first_object_global + wasm.object_globals.items.len + @backingInt(i))), | 1314 | first_object_global + wasm.object_globals.items.len + @backingInt(i), |
| 1315 | )), | ||
| 1316 | .nav_obj => |i| @fromBackingInt(@intCast( | ||
| 1317 | first_object_global + wasm.object_globals.items.len + | ||
| 1318 | wasm.uavs_obj.entries.len + @backingInt(i), | ||
| 1319 | )), | ||
| 1320 | .nav_exe => |i| @fromBackingInt(@intCast( | ||
| 1321 | first_object_global + wasm.object_globals.items.len + | ||
| 1322 | wasm.uavs_exe.entries.len + @backingInt(i), | ||
| 1323 | )), | ||
| 1195 | }; | 1324 | }; |
| 1196 | } | 1325 | } |
| 1197 | 1326 | ||
| 1327 | pub fn fromIpIndex(wasm: *const Wasm, ip_index: InternPool.Index) Resolution { | ||
| 1328 | const is_obj = wasm.base.comp.config.output_mode == .Obj; | ||
| 1329 | return pack(wasm, if (is_obj) .{ | ||
| 1330 | .uav_obj = @fromBackingInt(@intCast(wasm.uavs_obj.getIndex(ip_index).?)), | ||
| 1331 | } else .{ | ||
| 1332 | .uav_exe = @fromBackingInt(@intCast(wasm.uavs_exe.getIndex(ip_index).?)), | ||
| 1333 | }); | ||
| 1334 | } | ||
| 1335 | |||
| 1198 | pub fn fromIpNav(wasm: *const Wasm, ip_nav: InternPool.Nav.Index) Resolution { | 1336 | pub fn fromIpNav(wasm: *const Wasm, ip_nav: InternPool.Nav.Index) Resolution { |
| 1199 | const comp = wasm.base.comp; | 1337 | const comp = wasm.base.comp; |
| 1200 | const is_obj = comp.config.output_mode == .Obj; | 1338 | const is_obj = comp.config.output_mode == .Obj; |
| ... | @@ -1209,7 +1347,22 @@ pub const GlobalImport = extern struct { | ... | @@ -1209,7 +1347,22 @@ pub const GlobalImport = extern struct { |
| 1209 | return pack(wasm, .{ .object_global = object_global }); | 1347 | return pack(wasm, .{ .object_global = object_global }); |
| 1210 | } | 1348 | } |
| 1211 | 1349 | ||
| 1212 | pub fn name(r: Resolution, wasm: *const Wasm) ?[]const u8 { | 1350 | pub fn flags(r: Resolution, wasm: *const Wasm) SymbolFlags { |
| 1351 | return switch (unpack(r, wasm)) { | ||
| 1352 | .unresolved, | ||
| 1353 | .__heap_base, | ||
| 1354 | .__heap_end, | ||
| 1355 | .__stack_pointer, | ||
| 1356 | .__tls_align, | ||
| 1357 | .__tls_base, | ||
| 1358 | .__tls_size, | ||
| 1359 | => unreachable, | ||
| 1360 | .object_global => |i| i.ptr(wasm).flags, | ||
| 1361 | .uav_obj, .uav_exe, .nav_obj, .nav_exe => unreachable, | ||
| 1362 | }; | ||
| 1363 | } | ||
| 1364 | |||
| 1365 | pub fn name(r: Resolution, wasm: *const Wasm, buf: []u8) ?[]const u8 { | ||
| 1213 | return switch (unpack(r, wasm)) { | 1366 | return switch (unpack(r, wasm)) { |
| 1214 | .unresolved => unreachable, | 1367 | .unresolved => unreachable, |
| 1215 | .__heap_base => @tagName(Unpacked.__heap_base), | 1368 | .__heap_base => @tagName(Unpacked.__heap_base), |
| ... | @@ -1219,6 +1372,11 @@ pub const GlobalImport = extern struct { | ... | @@ -1219,6 +1372,11 @@ pub const GlobalImport = extern struct { |
| 1219 | .__tls_base => @tagName(Unpacked.__tls_base), | 1372 | .__tls_base => @tagName(Unpacked.__tls_base), |
| 1220 | .__tls_size => @tagName(Unpacked.__tls_size), | 1373 | .__tls_size => @tagName(Unpacked.__tls_size), |
| 1221 | .object_global => |i| i.name(wasm).slice(wasm), | 1374 | .object_global => |i| i.name(wasm).slice(wasm), |
| 1375 | inline .uav_obj, .uav_exe => |i| std.fmt.bufPrint( | ||
| 1376 | buf, | ||
| 1377 | "__anon_{d}", | ||
| 1378 | .{@backingInt(i.key(wasm).*)}, | ||
| 1379 | ) catch unreachable, | ||
| 1222 | .nav_obj => |i| i.name(wasm), | 1380 | .nav_obj => |i| i.name(wasm), |
| 1223 | .nav_exe => |i| i.name(wasm), | 1381 | .nav_exe => |i| i.name(wasm), |
| 1224 | }; | 1382 | }; |
| ... | @@ -1349,6 +1507,22 @@ pub const TableImport = extern struct { | ... | @@ -1349,6 +1507,22 @@ pub const TableImport = extern struct { |
| 1349 | return pack(.{ .object_table = object_table }); | 1507 | return pack(.{ .object_table = object_table }); |
| 1350 | } | 1508 | } |
| 1351 | 1509 | ||
| 1510 | pub fn name(r: Resolution, wasm: *const Wasm) ?[]const u8 { | ||
| 1511 | return switch (unpack(r)) { | ||
| 1512 | .unresolved => unreachable, | ||
| 1513 | .__indirect_function_table => @tagName(Unpacked.__indirect_function_table), | ||
| 1514 | .object_table => |i| i.ptr(wasm).name.slice(wasm), | ||
| 1515 | }; | ||
| 1516 | } | ||
| 1517 | |||
| 1518 | pub fn flags(r: Resolution, wasm: *const Wasm) SymbolFlags { | ||
| 1519 | return switch (unpack(r)) { | ||
| 1520 | .unresolved => unreachable, | ||
| 1521 | .__indirect_function_table => unreachable, | ||
| 1522 | .object_table => |i| i.ptr(wasm).flags, | ||
| 1523 | }; | ||
| 1524 | } | ||
| 1525 | |||
| 1352 | pub fn refType(r: Resolution, wasm: *const Wasm) std.wasm.RefType { | 1526 | pub fn refType(r: Resolution, wasm: *const Wasm) std.wasm.RefType { |
| 1353 | return switch (unpack(r)) { | 1527 | return switch (unpack(r)) { |
| 1354 | .unresolved => unreachable, | 1528 | .unresolved => unreachable, |
| ... | @@ -1602,6 +1776,8 @@ pub const ObjectDataImport = extern struct { | ... | @@ -1602,6 +1776,8 @@ pub const ObjectDataImport = extern struct { |
| 1602 | unresolved, | 1776 | unresolved, |
| 1603 | __zig_error_names, | 1777 | __zig_error_names, |
| 1604 | __zig_error_name_table, | 1778 | __zig_error_name_table, |
| 1779 | __zig_tag_names, | ||
| 1780 | __zig_tag_name_table, | ||
| 1605 | __heap_base, | 1781 | __heap_base, |
| 1606 | __heap_end, | 1782 | __heap_end, |
| 1607 | /// Next, an `ObjectData.Index`. | 1783 | /// Next, an `ObjectData.Index`. |
| ... | @@ -1615,6 +1791,8 @@ pub const ObjectDataImport = extern struct { | ... | @@ -1615,6 +1791,8 @@ pub const ObjectDataImport = extern struct { |
| 1615 | unresolved, | 1791 | unresolved, |
| 1616 | __zig_error_names, | 1792 | __zig_error_names, |
| 1617 | __zig_error_name_table, | 1793 | __zig_error_name_table, |
| 1794 | __zig_tag_names, | ||
| 1795 | __zig_tag_name_table, | ||
| 1618 | __heap_base, | 1796 | __heap_base, |
| 1619 | __heap_end, | 1797 | __heap_end, |
| 1620 | object: ObjectData.Index, | 1798 | object: ObjectData.Index, |
| ... | @@ -1629,6 +1807,8 @@ pub const ObjectDataImport = extern struct { | ... | @@ -1629,6 +1807,8 @@ pub const ObjectDataImport = extern struct { |
| 1629 | .unresolved => .unresolved, | 1807 | .unresolved => .unresolved, |
| 1630 | .__zig_error_names => .__zig_error_names, | 1808 | .__zig_error_names => .__zig_error_names, |
| 1631 | .__zig_error_name_table => .__zig_error_name_table, | 1809 | .__zig_error_name_table => .__zig_error_name_table, |
| 1810 | .__zig_tag_names => .__zig_tag_names, | ||
| 1811 | .__zig_tag_name_table => .__zig_tag_name_table, | ||
| 1632 | .__heap_base => .__heap_base, | 1812 | .__heap_base => .__heap_base, |
| 1633 | .__heap_end => .__heap_end, | 1813 | .__heap_end => .__heap_end, |
| 1634 | _ => { | 1814 | _ => { |
| ... | @@ -1665,6 +1845,8 @@ pub const ObjectDataImport = extern struct { | ... | @@ -1665,6 +1845,8 @@ pub const ObjectDataImport = extern struct { |
| 1665 | .unresolved => .unresolved, | 1845 | .unresolved => .unresolved, |
| 1666 | .__zig_error_names => .__zig_error_names, | 1846 | .__zig_error_names => .__zig_error_names, |
| 1667 | .__zig_error_name_table => .__zig_error_name_table, | 1847 | .__zig_error_name_table => .__zig_error_name_table, |
| 1848 | .__zig_tag_names => .__zig_tag_names, | ||
| 1849 | .__zig_tag_name_table => .__zig_tag_name_table, | ||
| 1668 | .__heap_base => .__heap_base, | 1850 | .__heap_base => .__heap_base, |
| 1669 | .__heap_end => .__heap_end, | 1851 | .__heap_end => .__heap_end, |
| 1670 | .object => |i| @fromBackingInt(@intCast(first_object + @backingInt(i))), | 1852 | .object => |i| @fromBackingInt(@intCast(first_object + @backingInt(i))), |
| ... | @@ -1678,12 +1860,32 @@ pub const ObjectDataImport = extern struct { | ... | @@ -1678,12 +1860,32 @@ pub const ObjectDataImport = extern struct { |
| 1678 | return pack(wasm, .{ .object = object_data_index }); | 1860 | return pack(wasm, .{ .object = object_data_index }); |
| 1679 | } | 1861 | } |
| 1680 | 1862 | ||
| 1863 | pub fn fromIpIndex(wasm: *const Wasm, ip_index: InternPool.Index) Resolution { | ||
| 1864 | const is_obj = wasm.base.comp.config.output_mode == .Obj; | ||
| 1865 | return pack(wasm, if (is_obj) .{ | ||
| 1866 | .uav_obj = @fromBackingInt(@intCast(wasm.uavs_obj.getIndex(ip_index).?)), | ||
| 1867 | } else .{ | ||
| 1868 | .uav_exe = @fromBackingInt(@intCast(wasm.uavs_exe.getIndex(ip_index).?)), | ||
| 1869 | }); | ||
| 1870 | } | ||
| 1871 | |||
| 1872 | pub fn fromIpNav(wasm: *const Wasm, nav_index: InternPool.Nav.Index) Resolution { | ||
| 1873 | const is_obj = wasm.base.comp.config.output_mode == .Obj; | ||
| 1874 | return pack(wasm, if (is_obj) .{ | ||
| 1875 | .nav_obj = @fromBackingInt(@intCast(wasm.navs_obj.getIndex(nav_index).?)), | ||
| 1876 | } else .{ | ||
| 1877 | .nav_exe = @fromBackingInt(@intCast(wasm.navs_exe.getIndex(nav_index).?)), | ||
| 1878 | }); | ||
| 1879 | } | ||
| 1880 | |||
| 1681 | pub fn objectDataSegment(r: Resolution, wasm: *const Wasm) ?ObjectDataSegment.Index { | 1881 | pub fn objectDataSegment(r: Resolution, wasm: *const Wasm) ?ObjectDataSegment.Index { |
| 1682 | return switch (unpack(r, wasm)) { | 1882 | return switch (unpack(r, wasm)) { |
| 1683 | .unresolved => unreachable, | 1883 | .unresolved => unreachable, |
| 1684 | .object => |i| i.ptr(wasm).segment, | 1884 | .object => |i| i.ptr(wasm).segment, |
| 1685 | .__zig_error_names, | 1885 | .__zig_error_names, |
| 1686 | .__zig_error_name_table, | 1886 | .__zig_error_name_table, |
| 1887 | .__zig_tag_names, | ||
| 1888 | .__zig_tag_name_table, | ||
| 1687 | .__heap_base, | 1889 | .__heap_base, |
| 1688 | .__heap_end, | 1890 | .__heap_end, |
| 1689 | .uav_exe, | 1891 | .uav_exe, |
| ... | @@ -1706,12 +1908,107 @@ pub const ObjectDataImport = extern struct { | ... | @@ -1706,12 +1908,107 @@ pub const ObjectDataImport = extern struct { |
| 1706 | }, | 1908 | }, |
| 1707 | .__zig_error_names => .{ .segment = .__zig_error_names, .offset = 0 }, | 1909 | .__zig_error_names => .{ .segment = .__zig_error_names, .offset = 0 }, |
| 1708 | .__zig_error_name_table => .{ .segment = .__zig_error_name_table, .offset = 0 }, | 1910 | .__zig_error_name_table => .{ .segment = .__zig_error_name_table, .offset = 0 }, |
| 1911 | .__zig_tag_names => .{ .segment = .__zig_tag_names, .offset = 0 }, | ||
| 1912 | .__zig_tag_name_table => .{ .segment = .__zig_tag_name_table, .offset = 0 }, | ||
| 1709 | .__heap_base => .{ .segment = .__heap_base, .offset = 0 }, | 1913 | .__heap_base => .{ .segment = .__heap_base, .offset = 0 }, |
| 1710 | .__heap_end => .{ .segment = .__heap_end, .offset = 0 }, | 1914 | .__heap_end => .{ .segment = .__heap_end, .offset = 0 }, |
| 1711 | .uav_exe => @panic("TODO"), | 1915 | .uav_exe => |i| .{ .segment = .pack(wasm, .{ .uav_exe = i }), .offset = 0 }, |
| 1712 | .uav_obj => @panic("TODO"), | 1916 | .uav_obj => |i| .{ .segment = .pack(wasm, .{ .uav_obj = i }), .offset = 0 }, |
| 1713 | .nav_exe => @panic("TODO"), | 1917 | .nav_exe => |i| .{ .segment = .pack(wasm, .{ .nav_exe = i }), .offset = 0 }, |
| 1714 | .nav_obj => @panic("TODO"), | 1918 | .nav_obj => |i| .{ .segment = .pack(wasm, .{ .nav_obj = i }), .offset = 0 }, |
| 1919 | }; | ||
| 1920 | } | ||
| 1921 | |||
| 1922 | pub fn flags(r: Resolution, wasm: *const Wasm) SymbolFlags { | ||
| 1923 | return switch (unpack(r, wasm)) { | ||
| 1924 | .unresolved => unreachable, | ||
| 1925 | .__zig_error_names, | ||
| 1926 | .__zig_error_name_table, | ||
| 1927 | .__zig_tag_names, | ||
| 1928 | .__zig_tag_name_table, | ||
| 1929 | => .{ .binding = .local }, | ||
| 1930 | .__heap_base, | ||
| 1931 | .__heap_end, | ||
| 1932 | => unreachable, | ||
| 1933 | .object => |i| i.ptr(wasm).flags, | ||
| 1934 | inline .nav_exe, .nav_obj => |i| { | ||
| 1935 | const zcu = wasm.base.comp.zcu.?; | ||
| 1936 | const ip = &zcu.intern_pool; | ||
| 1937 | const nav = ip.getNav(i.key(wasm).*); | ||
| 1938 | if (nav.getExtern(ip)) |ext| { | ||
| 1939 | const name_slice = ext.name.toSlice(ip); | ||
| 1940 | const name_string = wasm.getExistingString(name_slice).?; | ||
| 1941 | return .{ | ||
| 1942 | .binding = switch (ext.linkage) { | ||
| 1943 | .internal => .local, | ||
| 1944 | .strong => .strong, | ||
| 1945 | .weak => .weak, | ||
| 1946 | .link_once => @panic("TODO: COMDAT"), | ||
| 1947 | }, | ||
| 1948 | .visibility_hidden = switch (ext.visibility) { | ||
| 1949 | .default => false, | ||
| 1950 | .hidden => true, | ||
| 1951 | .protected => false, | ||
| 1952 | }, | ||
| 1953 | .undefined = false, | ||
| 1954 | .exported = wasm.missing_exports.contains(name_string), | ||
| 1955 | .explicit_name = false, | ||
| 1956 | .no_strip = false, | ||
| 1957 | .tls = ext.is_threadlocal, | ||
| 1958 | .absolute = false, | ||
| 1959 | }; | ||
| 1960 | } else { | ||
| 1961 | return .{ | ||
| 1962 | .binding = .local, | ||
| 1963 | .tls = nav.resolved.?.@"threadlocal", | ||
| 1964 | }; | ||
| 1965 | } | ||
| 1966 | }, | ||
| 1967 | .uav_exe, .uav_obj => .{ .binding = .local }, | ||
| 1968 | }; | ||
| 1969 | } | ||
| 1970 | |||
| 1971 | pub fn name(r: Resolution, wasm: *const Wasm, buf: []u8) []const u8 { | ||
| 1972 | return switch (unpack(r, wasm)) { | ||
| 1973 | .unresolved => unreachable, | ||
| 1974 | .object => |i| i.ptr(wasm).name.slice(wasm), | ||
| 1975 | .__zig_error_names => @tagName(.__zig_error_names), | ||
| 1976 | .__zig_error_name_table => @tagName(.__zig_error_name_table), | ||
| 1977 | .__zig_tag_names => @tagName(.__zig_tag_names), | ||
| 1978 | .__zig_tag_name_table => @tagName(.__zig_tag_name_table), | ||
| 1979 | .__heap_base => @tagName(.__heap_base), | ||
| 1980 | .__heap_end => @tagName(.__heap_end), | ||
| 1981 | inline .uav_exe, .uav_obj => |i| std.fmt.bufPrint( | ||
| 1982 | buf, | ||
| 1983 | "__anon_{d}", | ||
| 1984 | .{@backingInt(i.key(wasm).*)}, | ||
| 1985 | ) catch unreachable, | ||
| 1986 | inline .nav_exe, .nav_obj => |i| i.name(wasm), | ||
| 1987 | }; | ||
| 1988 | } | ||
| 1989 | |||
| 1990 | pub fn size(r: Resolution, wasm: *const Wasm) u32 { | ||
| 1991 | return switch (unpack(r, wasm)) { | ||
| 1992 | .unresolved => unreachable, | ||
| 1993 | .__zig_error_names => @intCast(wasm.error_name_bytes.items.len), | ||
| 1994 | .__zig_error_name_table => { | ||
| 1995 | const comp = wasm.base.comp; | ||
| 1996 | const zcu = comp.zcu.?; | ||
| 1997 | const errors_len = wasm.error_name_offs.items.len; | ||
| 1998 | const elem_size = Zcu.Type.slice_const_u8_sentinel_0.abiSize(zcu); | ||
| 1999 | return @intCast(errors_len * elem_size); | ||
| 2000 | }, | ||
| 2001 | .__zig_tag_names => @intCast(wasm.tag_name_bytes.items.len), | ||
| 2002 | .__zig_tag_name_table => { | ||
| 2003 | const comp = wasm.base.comp; | ||
| 2004 | const zcu = comp.zcu.?; | ||
| 2005 | const table_len = wasm.tag_name_offs.items.len; | ||
| 2006 | const elem_size = Zcu.Type.slice_const_u8_sentinel_0.abiSize(zcu); | ||
| 2007 | return @intCast(table_len * elem_size); | ||
| 2008 | }, | ||
| 2009 | .__heap_base, .__heap_end => wasm.pointerSize(), | ||
| 2010 | .object => |i| i.ptr(wasm).size, | ||
| 2011 | inline .uav_exe, .uav_obj, .nav_exe, .nav_obj => |i| i.value(wasm).code.len, | ||
| 1715 | }; | 2012 | }; |
| 1716 | } | 2013 | } |
| 1717 | }; | 2014 | }; |
| ... | @@ -1910,6 +2207,38 @@ pub const DataSegmentId = enum(u32) { | ... | @@ -1910,6 +2207,38 @@ pub const DataSegmentId = enum(u32) { |
| 1910 | }; | 2207 | }; |
| 1911 | } | 2208 | } |
| 1912 | 2209 | ||
| 2210 | pub fn isStrings(id: DataSegmentId, wasm: *const Wasm) bool { | ||
| 2211 | return switch (unpack(id, wasm)) { | ||
| 2212 | .__zig_error_names, .__zig_tag_names => true, | ||
| 2213 | |||
| 2214 | .__zig_error_name_table, | ||
| 2215 | .__zig_tag_name_table, | ||
| 2216 | .__heap_base, | ||
| 2217 | .__heap_end, | ||
| 2218 | => false, | ||
| 2219 | |||
| 2220 | .object => |i| i.ptr(wasm).flags.strings, | ||
| 2221 | .uav_exe, .uav_obj => false, | ||
| 2222 | .nav_exe, .nav_obj => false, | ||
| 2223 | }; | ||
| 2224 | } | ||
| 2225 | |||
| 2226 | pub fn isRetain(id: DataSegmentId, wasm: *const Wasm) bool { | ||
| 2227 | return switch (unpack(id, wasm)) { | ||
| 2228 | .__zig_error_names, | ||
| 2229 | .__zig_error_name_table, | ||
| 2230 | .__zig_tag_names, | ||
| 2231 | .__zig_tag_name_table, | ||
| 2232 | .__heap_base, | ||
| 2233 | .__heap_end, | ||
| 2234 | => false, | ||
| 2235 | |||
| 2236 | .object => |i| i.ptr(wasm).flags.retain, | ||
| 2237 | .uav_exe, .uav_obj => false, | ||
| 2238 | .nav_exe, .nav_obj => false, | ||
| 2239 | }; | ||
| 2240 | } | ||
| 2241 | |||
| 1913 | pub fn isBss(id: DataSegmentId, wasm: *const Wasm) bool { | 2242 | pub fn isBss(id: DataSegmentId, wasm: *const Wasm) bool { |
| 1914 | return id.category(wasm) == .zero; | 2243 | return id.category(wasm) == .zero; |
| 1915 | } | 2244 | } |
| ... | @@ -2181,6 +2510,7 @@ const PreloadedStrings = struct { | ... | @@ -2181,6 +2510,7 @@ const PreloadedStrings = struct { |
| 2181 | _initialize: String, | 2510 | _initialize: String, |
| 2182 | _start: String, | 2511 | _start: String, |
| 2183 | memory: String, | 2512 | memory: String, |
| 2513 | env: String, | ||
| 2184 | }; | 2514 | }; |
| 2185 | 2515 | ||
| 2186 | /// Index into string_bytes | 2516 | /// Index into string_bytes |
| ... | @@ -2209,14 +2539,14 @@ pub const String = enum(u32) { | ... | @@ -2209,14 +2539,14 @@ pub const String = enum(u32) { |
| 2209 | } | 2539 | } |
| 2210 | 2540 | ||
| 2211 | pub fn hash(_: @This(), adapted_key: []const u8) u64 { | 2541 | pub fn hash(_: @This(), adapted_key: []const u8) u64 { |
| 2212 | assert(mem.indexOfScalar(u8, adapted_key, 0) == null); | 2542 | assert(mem.findScalar(u8, adapted_key, 0) == null); |
| 2213 | return std.hash_map.hashString(adapted_key); | 2543 | return std.hash_map.hashString(adapted_key); |
| 2214 | } | 2544 | } |
| 2215 | }; | 2545 | }; |
| 2216 | 2546 | ||
| 2217 | pub fn slice(index: String, wasm: *const Wasm) [:0]const u8 { | 2547 | pub fn slice(index: String, wasm: *const Wasm) [:0]const u8 { |
| 2218 | const start_slice = wasm.string_bytes.items[@backingInt(index)..]; | 2548 | const start_slice = wasm.string_bytes.items[@backingInt(index)..]; |
| 2219 | return start_slice[0..mem.indexOfScalar(u8, start_slice, 0).? :0]; | 2549 | return start_slice[0..mem.findScalar(u8, start_slice, 0).? :0]; |
| 2220 | } | 2550 | } |
| 2221 | 2551 | ||
| 2222 | pub fn toOptional(i: String) OptionalString { | 2552 | pub fn toOptional(i: String) OptionalString { |
| ... | @@ -2262,6 +2592,34 @@ pub const ZcuImportIndex = enum(u32) { | ... | @@ -2262,6 +2592,34 @@ pub const ZcuImportIndex = enum(u32) { |
| 2262 | return &wasm.imports.keys()[@backingInt(index)]; | 2592 | return &wasm.imports.keys()[@backingInt(index)]; |
| 2263 | } | 2593 | } |
| 2264 | 2594 | ||
| 2595 | pub fn flags(index: ZcuImportIndex, wasm: *const Wasm) SymbolFlags { | ||
| 2596 | const zcu = wasm.base.comp.zcu.?; | ||
| 2597 | const ip = &zcu.intern_pool; | ||
| 2598 | const nav_index = index.ptr(wasm).*; | ||
| 2599 | const ext = ip.indexToKey(ip.getNav(nav_index).resolved.?.value).@"extern"; | ||
| 2600 | const name_slice = ext.name.toSlice(ip); | ||
| 2601 | const name_string = wasm.getExistingString(name_slice).?; | ||
| 2602 | return .{ | ||
| 2603 | .binding = switch (ext.linkage) { | ||
| 2604 | .internal => .local, | ||
| 2605 | .strong => .strong, | ||
| 2606 | .weak => .weak, | ||
| 2607 | .link_once => @panic("TODO: COMDAT"), | ||
| 2608 | }, | ||
| 2609 | .visibility_hidden = switch (ext.visibility) { | ||
| 2610 | .default => false, | ||
| 2611 | .hidden => true, | ||
| 2612 | .protected => false, | ||
| 2613 | }, | ||
| 2614 | .undefined = true, | ||
| 2615 | .exported = wasm.missing_exports.contains(name_string), | ||
| 2616 | .explicit_name = false, | ||
| 2617 | .no_strip = false, | ||
| 2618 | .tls = ext.is_threadlocal, | ||
| 2619 | .absolute = false, | ||
| 2620 | }; | ||
| 2621 | } | ||
| 2622 | |||
| 2265 | pub fn importName(index: ZcuImportIndex, wasm: *const Wasm) String { | 2623 | pub fn importName(index: ZcuImportIndex, wasm: *const Wasm) String { |
| 2266 | const zcu = wasm.base.comp.zcu.?; | 2624 | const zcu = wasm.base.comp.zcu.?; |
| 2267 | const ip = &zcu.intern_pool; | 2625 | const ip = &zcu.intern_pool; |
| ... | @@ -2348,6 +2706,13 @@ pub const FunctionImportId = enum(u32) { | ... | @@ -2348,6 +2706,13 @@ pub const FunctionImportId = enum(u32) { |
| 2348 | } | 2706 | } |
| 2349 | } | 2707 | } |
| 2350 | 2708 | ||
| 2709 | pub fn flags(id: FunctionImportId, wasm: *const Wasm) SymbolFlags { | ||
| 2710 | return switch (id.unpack(wasm)) { | ||
| 2711 | .object_function_import => |i| i.value(wasm).flags, | ||
| 2712 | .zcu_import => |i| i.flags(wasm), | ||
| 2713 | }; | ||
| 2714 | } | ||
| 2715 | |||
| 2351 | pub fn importName(id: FunctionImportId, wasm: *const Wasm) String { | 2716 | pub fn importName(id: FunctionImportId, wasm: *const Wasm) String { |
| 2352 | return switch (unpack(id, wasm)) { | 2717 | return switch (unpack(id, wasm)) { |
| 2353 | inline .object_function_import, .zcu_import => |i| i.importName(wasm), | 2718 | inline .object_function_import, .zcu_import => |i| i.importName(wasm), |
| ... | @@ -2385,38 +2750,61 @@ pub const FunctionImportId = enum(u32) { | ... | @@ -2385,38 +2750,61 @@ pub const FunctionImportId = enum(u32) { |
| 2385 | } | 2750 | } |
| 2386 | }; | 2751 | }; |
| 2387 | 2752 | ||
| 2388 | /// 0. Index into `object_global_imports`. | 2753 | /// 0. `__stack_pointer`. |
| 2389 | /// 1. Index into `imports`. | 2754 | /// 1. Index into `object_global_imports`. |
| 2755 | /// 2. Index into `imports`. | ||
| 2390 | pub const GlobalImportId = enum(u32) { | 2756 | pub const GlobalImportId = enum(u32) { |
| 2757 | __stack_pointer, | ||
| 2391 | _, | 2758 | _, |
| 2392 | 2759 | ||
| 2393 | pub const Unpacked = union(enum) { | 2760 | pub const Unpacked = union(enum) { |
| 2761 | __stack_pointer, | ||
| 2394 | object_global_import: GlobalImport.Index, | 2762 | object_global_import: GlobalImport.Index, |
| 2395 | zcu_import: ZcuImportIndex, | 2763 | zcu_import: ZcuImportIndex, |
| 2396 | }; | 2764 | }; |
| 2397 | 2765 | ||
| 2398 | pub fn pack(unpacked: Unpacked, wasm: *const Wasm) GlobalImportId { | 2766 | pub fn pack(unpacked: Unpacked, wasm: *const Wasm) GlobalImportId { |
| 2399 | return switch (unpacked) { | 2767 | return switch (unpacked) { |
| 2400 | .object_global_import => |i| @fromBackingInt(@intCast(@backingInt(i))), | 2768 | .__stack_pointer => .__stack_pointer, |
| 2401 | .zcu_import => |i| @fromBackingInt(@intCast(@backingInt(i) + wasm.object_global_imports.entries.len)), | 2769 | .object_global_import => |i| @fromBackingInt(@intCast(@backingInt(i) + 1)), |
| 2770 | .zcu_import => |i| @fromBackingInt(@intCast(@backingInt(i) + wasm.object_global_imports.entries.len + 1)), | ||
| 2402 | }; | 2771 | }; |
| 2403 | } | 2772 | } |
| 2404 | 2773 | ||
| 2405 | pub fn unpack(id: GlobalImportId, wasm: *const Wasm) Unpacked { | 2774 | pub fn unpack(id: GlobalImportId, wasm: *const Wasm) Unpacked { |
| 2406 | const i = @backingInt(id); | 2775 | return switch (id) { |
| 2407 | if (i < wasm.object_global_imports.entries.len) return .{ .object_global_import = @fromBackingInt(@intCast(i)) }; | 2776 | .__stack_pointer => .__stack_pointer, |
| 2408 | const zcu_import_i = i - wasm.object_global_imports.entries.len; | 2777 | _ => { |
| 2409 | return .{ .zcu_import = @fromBackingInt(@intCast(zcu_import_i)) }; | 2778 | const i = @backingInt(id) - 1; |
| 2779 | if (i < wasm.object_global_imports.entries.len) { | ||
| 2780 | return .{ .object_global_import = @fromBackingInt(@intCast(i)) }; | ||
| 2781 | } | ||
| 2782 | const zcu_import_i = i - wasm.object_global_imports.entries.len; | ||
| 2783 | return .{ .zcu_import = @fromBackingInt(@intCast(zcu_import_i)) }; | ||
| 2784 | }, | ||
| 2785 | }; | ||
| 2410 | } | 2786 | } |
| 2411 | 2787 | ||
| 2412 | pub fn fromObject(object_global_import: GlobalImport.Index, wasm: *const Wasm) GlobalImportId { | 2788 | pub fn fromObject(object_global_import: GlobalImport.Index, wasm: *const Wasm) GlobalImportId { |
| 2413 | return pack(.{ .object_global_import = object_global_import }, wasm); | 2789 | return pack(.{ .object_global_import = object_global_import }, wasm); |
| 2414 | } | 2790 | } |
| 2415 | 2791 | ||
| 2792 | pub fn flags(id: GlobalImportId, wasm: *const Wasm) SymbolFlags { | ||
| 2793 | return switch (id.unpack(wasm)) { | ||
| 2794 | .__stack_pointer => .{ | ||
| 2795 | .binding = .strong, | ||
| 2796 | .undefined = true, | ||
| 2797 | }, | ||
| 2798 | .object_global_import => |i| i.value(wasm).flags, | ||
| 2799 | .zcu_import => |i| i.flags(wasm), | ||
| 2800 | }; | ||
| 2801 | } | ||
| 2802 | |||
| 2416 | /// This function is allowed O(N) lookup because it is only called during | 2803 | /// This function is allowed O(N) lookup because it is only called during |
| 2417 | /// diagnostic generation. | 2804 | /// diagnostic generation. |
| 2418 | pub fn sourceLocation(id: GlobalImportId, wasm: *const Wasm) SourceLocation { | 2805 | pub fn sourceLocation(id: GlobalImportId, wasm: *const Wasm) SourceLocation { |
| 2419 | switch (id.unpack(wasm)) { | 2806 | switch (id.unpack(wasm)) { |
| 2807 | .__stack_pointer => return .zig_object_nofile, | ||
| 2420 | .object_global_import => |obj_global_index| { | 2808 | .object_global_import => |obj_global_index| { |
| 2421 | // TODO binary search | 2809 | // TODO binary search |
| 2422 | for (wasm.objects.items, 0..) |o, i| { | 2810 | for (wasm.objects.items, 0..) |o, i| { |
| ... | @@ -2433,18 +2821,28 @@ pub const GlobalImportId = enum(u32) { | ... | @@ -2433,18 +2821,28 @@ pub const GlobalImportId = enum(u32) { |
| 2433 | 2821 | ||
| 2434 | pub fn importName(id: GlobalImportId, wasm: *const Wasm) String { | 2822 | pub fn importName(id: GlobalImportId, wasm: *const Wasm) String { |
| 2435 | return switch (unpack(id, wasm)) { | 2823 | return switch (unpack(id, wasm)) { |
| 2824 | .__stack_pointer => wasm.preloaded_strings.__stack_pointer, | ||
| 2436 | inline .object_global_import, .zcu_import => |i| i.importName(wasm), | 2825 | inline .object_global_import, .zcu_import => |i| i.importName(wasm), |
| 2437 | }; | 2826 | }; |
| 2438 | } | 2827 | } |
| 2439 | 2828 | ||
| 2440 | pub fn moduleName(id: GlobalImportId, wasm: *const Wasm) OptionalString { | 2829 | pub fn moduleName(id: GlobalImportId, wasm: *const Wasm) OptionalString { |
| 2441 | return switch (unpack(id, wasm)) { | 2830 | return switch (unpack(id, wasm)) { |
| 2831 | .__stack_pointer => wasm.preloaded_strings.env.toOptional(), | ||
| 2442 | inline .object_global_import, .zcu_import => |i| i.moduleName(wasm), | 2832 | inline .object_global_import, .zcu_import => |i| i.moduleName(wasm), |
| 2443 | }; | 2833 | }; |
| 2444 | } | 2834 | } |
| 2445 | 2835 | ||
| 2446 | pub fn globalType(id: GlobalImportId, wasm: *Wasm) ObjectGlobal.Type { | 2836 | pub fn globalType(id: GlobalImportId, wasm: *Wasm) ObjectGlobal.Type { |
| 2447 | return switch (unpack(id, wasm)) { | 2837 | return switch (unpack(id, wasm)) { |
| 2838 | .__stack_pointer => .{ | ||
| 2839 | .valtype = switch (wasm.pointerSize()) { | ||
| 2840 | 4 => .i32, | ||
| 2841 | 8 => .i64, | ||
| 2842 | else => unreachable, | ||
| 2843 | }, | ||
| 2844 | .mutable = true, | ||
| 2845 | }, | ||
| 2448 | inline .object_global_import, .zcu_import => |i| i.globalType(wasm), | 2846 | inline .object_global_import, .zcu_import => |i| i.globalType(wasm), |
| 2449 | }; | 2847 | }; |
| 2450 | } | 2848 | } |
| ... | @@ -2482,6 +2880,13 @@ pub const DataImportId = enum(u32) { | ... | @@ -2482,6 +2880,13 @@ pub const DataImportId = enum(u32) { |
| 2482 | return pack(.{ .object_data_import = object_data_import }, wasm); | 2880 | return pack(.{ .object_data_import = object_data_import }, wasm); |
| 2483 | } | 2881 | } |
| 2484 | 2882 | ||
| 2883 | pub fn flags(id: DataImportId, wasm: *const Wasm) SymbolFlags { | ||
| 2884 | return switch (id.unpack(wasm)) { | ||
| 2885 | .object_data_import => |i| i.value(wasm).flags, | ||
| 2886 | .zcu_import => |i| i.flags(wasm), | ||
| 2887 | }; | ||
| 2888 | } | ||
| 2889 | |||
| 2485 | pub fn sourceLocation(id: DataImportId, wasm: *const Wasm) SourceLocation { | 2890 | pub fn sourceLocation(id: DataImportId, wasm: *const Wasm) SourceLocation { |
| 2486 | switch (id.unpack(wasm)) { | 2891 | switch (id.unpack(wasm)) { |
| 2487 | .object_data_import => |obj_data_index| { | 2892 | .object_data_import => |obj_data_index| { |
| ... | @@ -2499,33 +2904,42 @@ pub const DataImportId = enum(u32) { | ... | @@ -2499,33 +2904,42 @@ pub const DataImportId = enum(u32) { |
| 2499 | } | 2904 | } |
| 2500 | }; | 2905 | }; |
| 2501 | 2906 | ||
| 2502 | /// Index into `Wasm.symbol_table`. | 2907 | pub const ZcuRelocation = struct { |
| 2503 | pub const SymbolTableIndex = enum(u32) { | ||
| 2504 | _, | ||
| 2505 | |||
| 2506 | pub fn key(i: @This(), wasm: *const Wasm) *String { | ||
| 2507 | return &wasm.symbol_table.keys()[@backingInt(i)]; | ||
| 2508 | } | ||
| 2509 | }; | ||
| 2510 | |||
| 2511 | pub const OutReloc = struct { | ||
| 2512 | tag: Object.RelocationType, | 2908 | tag: Object.RelocationType, |
| 2513 | offset: u32, | 2909 | offset: u32, |
| 2514 | pointee: Pointee, | 2910 | pointee: Pointee, |
| 2515 | addend: i32, | 2911 | addend: i32, |
| 2516 | 2912 | ||
| 2517 | pub const Pointee = union { | 2913 | pub const Pointee = union(enum) { |
| 2518 | symbol_index: SymbolTableIndex, | 2914 | function_nav: InternPool.Nav.Index, |
| 2915 | function_name: String, | ||
| 2916 | tag_function: InternPool.Index, | ||
| 2917 | data_uav: InternPool.Index, | ||
| 2918 | data_nav: InternPool.Nav.Index, | ||
| 2919 | data_resolution: ObjectDataImport.Resolution, | ||
| 2920 | stack_pointer, | ||
| 2519 | type_index: FunctionType.Index, | 2921 | type_index: FunctionType.Index, |
| 2520 | }; | 2922 | }; |
| 2521 | 2923 | ||
| 2522 | pub const Slice = extern struct { | 2924 | pub const Slice = extern struct { |
| 2523 | /// Index into `out_relocs`. | 2925 | /// Index into `zcu_relocations`. |
| 2524 | off: u32, | 2926 | off: u32, |
| 2525 | len: u32, | 2927 | len: u32, |
| 2526 | 2928 | ||
| 2527 | pub fn slice(s: Slice, wasm: *const Wasm) []OutReloc { | 2929 | pub fn tags(s: Slice, wasm: *const Wasm) []const Object.RelocationType { |
| 2528 | return wasm.relocations.items[s.off..][0..s.len]; | 2930 | return wasm.zcu_relocations.items(.tag)[s.off..][0..s.len]; |
| 2931 | } | ||
| 2932 | |||
| 2933 | pub fn offsets(s: Slice, wasm: *const Wasm) []const u32 { | ||
| 2934 | return wasm.zcu_relocations.items(.offset)[s.off..][0..s.len]; | ||
| 2935 | } | ||
| 2936 | |||
| 2937 | pub fn pointees(s: Slice, wasm: *const Wasm) []const Pointee { | ||
| 2938 | return wasm.zcu_relocations.items(.pointee)[s.off..][0..s.len]; | ||
| 2939 | } | ||
| 2940 | |||
| 2941 | pub fn addends(s: Slice, wasm: *const Wasm) []const i32 { | ||
| 2942 | return wasm.zcu_relocations.items(.addend)[s.off..][0..s.len]; | ||
| 2529 | } | 2943 | } |
| 2530 | }; | 2944 | }; |
| 2531 | }; | 2945 | }; |
| ... | @@ -3137,9 +3551,9 @@ pub fn deinit(wasm: *Wasm) void { | ... | @@ -3137,9 +3551,9 @@ pub fn deinit(wasm: *Wasm) void { |
| 3137 | wasm.table_imports.deinit(gpa); | 3551 | wasm.table_imports.deinit(gpa); |
| 3138 | wasm.tables.deinit(gpa); | 3552 | wasm.tables.deinit(gpa); |
| 3139 | wasm.data_imports.deinit(gpa); | 3553 | wasm.data_imports.deinit(gpa); |
| 3554 | wasm.datas.deinit(gpa); | ||
| 3140 | wasm.data_segments.deinit(gpa); | 3555 | wasm.data_segments.deinit(gpa); |
| 3141 | wasm.symbol_table.deinit(gpa); | 3556 | wasm.zcu_relocations.deinit(gpa); |
| 3142 | wasm.out_relocs.deinit(gpa); | ||
| 3143 | wasm.uav_fixups.deinit(gpa); | 3557 | wasm.uav_fixups.deinit(gpa); |
| 3144 | wasm.nav_fixups.deinit(gpa); | 3558 | wasm.nav_fixups.deinit(gpa); |
| 3145 | wasm.func_table_fixups.deinit(gpa); | 3559 | wasm.func_table_fixups.deinit(gpa); |
| ... | @@ -3351,6 +3765,25 @@ pub fn updateExports( | ... | @@ -3351,6 +3765,25 @@ pub fn updateExports( |
| 3351 | const zcu = pt.zcu; | 3765 | const zcu = pt.zcu; |
| 3352 | const gpa = zcu.gpa; | 3766 | const gpa = zcu.gpa; |
| 3353 | const ip = &zcu.intern_pool; | 3767 | const ip = &zcu.intern_pool; |
| 3768 | const is_obj = wasm.base.comp.config.output_mode == .Obj; | ||
| 3769 | switch (exported) { | ||
| 3770 | .nav => {}, // handled in updateNav | ||
| 3771 | .uav => |uav_index| { // export may be the only reference | ||
| 3772 | const zds: ZcuDataStarts = .init(wasm); | ||
| 3773 | if (is_obj) { | ||
| 3774 | const gop = try wasm.uavs_obj.getOrPut(gpa, uav_index); | ||
| 3775 | if (!gop.found_existing) gop.value_ptr.* = undefined; | ||
| 3776 | } else { | ||
| 3777 | const gop = try wasm.uavs_exe.getOrPut(gpa, uav_index); | ||
| 3778 | if (!gop.found_existing) gop.value_ptr.* = .{ | ||
| 3779 | .code = undefined, | ||
| 3780 | .count = 0, | ||
| 3781 | }; | ||
| 3782 | gop.value_ptr.count += 1; | ||
| 3783 | } | ||
| 3784 | try zds.finish(wasm, pt); | ||
| 3785 | }, | ||
| 3786 | } | ||
| 3354 | for (export_indices) |export_idx| { | 3787 | for (export_indices) |export_idx| { |
| 3355 | const exp = export_idx.ptr(zcu); | 3788 | const exp = export_idx.ptr(zcu); |
| 3356 | const name_slice = exp.opts.name.toSlice(ip); | 3789 | const name_slice = exp.opts.name.toSlice(ip); |
| ... | @@ -3443,7 +3876,11 @@ pub fn prelink(wasm: *Wasm, prog_node: std.Progress.Node) link.Error!void { | ... | @@ -3443,7 +3876,11 @@ pub fn prelink(wasm: *Wasm, prog_node: std.Progress.Node) link.Error!void { |
| 3443 | // Zig always depends on a stack pointer global. | 3876 | // Zig always depends on a stack pointer global. |
| 3444 | // If emitting an object, it's an import. Otherwise, the linker synthesizes it. | 3877 | // If emitting an object, it's an import. Otherwise, the linker synthesizes it. |
| 3445 | if (is_obj) { | 3878 | if (is_obj) { |
| 3446 | @panic("TODO"); | 3879 | try wasm.global_imports.putNoClobber( |
| 3880 | gpa, | ||
| 3881 | wasm.preloaded_strings.__stack_pointer, | ||
| 3882 | .__stack_pointer, | ||
| 3883 | ); | ||
| 3447 | } else { | 3884 | } else { |
| 3448 | try wasm.globals.put(gpa, .__stack_pointer, {}); | 3885 | try wasm.globals.put(gpa, .__stack_pointer, {}); |
| 3449 | assert(wasm.globals.entries.len - 1 == @backingInt(GlobalIndex.stack_pointer)); | 3886 | assert(wasm.globals.entries.len - 1 == @backingInt(GlobalIndex.stack_pointer)); |
| ... | @@ -3453,7 +3890,7 @@ pub fn prelink(wasm: *Wasm, prog_node: std.Progress.Node) link.Error!void { | ... | @@ -3453,7 +3890,7 @@ pub fn prelink(wasm: *Wasm, prog_node: std.Progress.Node) link.Error!void { |
| 3453 | // These loops do both recursive marking of alive symbols well as checking for undefined symbols. | 3890 | // These loops do both recursive marking of alive symbols well as checking for undefined symbols. |
| 3454 | // At the end, output functions and globals will be populated. | 3891 | // At the end, output functions and globals will be populated. |
| 3455 | for (wasm.object_function_imports.keys(), wasm.object_function_imports.values(), 0..) |name, *import, i| { | 3892 | for (wasm.object_function_imports.keys(), wasm.object_function_imports.values(), 0..) |name, *import, i| { |
| 3456 | if (import.flags.isIncluded(rdynamic)) { | 3893 | if (import.flags.isIncluded(rdynamic, is_obj)) { |
| 3457 | try markFunctionImport(wasm, name, import, @fromBackingInt(@intCast(i))); | 3894 | try markFunctionImport(wasm, name, import, @fromBackingInt(@intCast(i))); |
| 3458 | } | 3895 | } |
| 3459 | } | 3896 | } |
| ... | @@ -3467,7 +3904,7 @@ pub fn prelink(wasm: *Wasm, prog_node: std.Progress.Node) link.Error!void { | ... | @@ -3467,7 +3904,7 @@ pub fn prelink(wasm: *Wasm, prog_node: std.Progress.Node) link.Error!void { |
| 3467 | wasm.functions_end_prelink = @intCast(wasm.functions.entries.len); | 3904 | wasm.functions_end_prelink = @intCast(wasm.functions.entries.len); |
| 3468 | 3905 | ||
| 3469 | for (wasm.object_global_imports.keys(), wasm.object_global_imports.values(), 0..) |name, *import, i| { | 3906 | for (wasm.object_global_imports.keys(), wasm.object_global_imports.values(), 0..) |name, *import, i| { |
| 3470 | if (import.flags.isIncluded(rdynamic)) { | 3907 | if (import.flags.isIncluded(rdynamic, is_obj)) { |
| 3471 | try markGlobalImport(wasm, name, import, @fromBackingInt(@intCast(i))); | 3908 | try markGlobalImport(wasm, name, import, @fromBackingInt(@intCast(i))); |
| 3472 | } | 3909 | } |
| 3473 | } | 3910 | } |
| ... | @@ -3475,13 +3912,13 @@ pub fn prelink(wasm: *Wasm, prog_node: std.Progress.Node) link.Error!void { | ... | @@ -3475,13 +3912,13 @@ pub fn prelink(wasm: *Wasm, prog_node: std.Progress.Node) link.Error!void { |
| 3475 | wasm.global_exports_len = @intCast(wasm.global_exports.items.len); | 3912 | wasm.global_exports_len = @intCast(wasm.global_exports.items.len); |
| 3476 | 3913 | ||
| 3477 | for (wasm.object_table_imports.keys(), wasm.object_table_imports.values(), 0..) |name, *import, i| { | 3914 | for (wasm.object_table_imports.keys(), wasm.object_table_imports.values(), 0..) |name, *import, i| { |
| 3478 | if (import.flags.isIncluded(rdynamic)) { | 3915 | if (import.flags.isIncluded(rdynamic, is_obj)) { |
| 3479 | try markTableImport(wasm, name, import, @fromBackingInt(@intCast(i))); | 3916 | try markTableImport(wasm, name, import, @fromBackingInt(@intCast(i))); |
| 3480 | } | 3917 | } |
| 3481 | } | 3918 | } |
| 3482 | 3919 | ||
| 3483 | for (wasm.object_data_imports.keys(), wasm.object_data_imports.values(), 0..) |name, *import, i| { | 3920 | for (wasm.object_data_imports.keys(), wasm.object_data_imports.values(), 0..) |name, *import, i| { |
| 3484 | if (import.flags.isIncluded(rdynamic)) { | 3921 | if (import.flags.isIncluded(rdynamic, is_obj)) { |
| 3485 | try markDataImport(wasm, name, import, @fromBackingInt(@intCast(i))); | 3922 | try markDataImport(wasm, name, import, @fromBackingInt(@intCast(i))); |
| 3486 | } | 3923 | } |
| 3487 | } | 3924 | } |
| ... | @@ -3512,18 +3949,23 @@ pub fn markFunctionImport( | ... | @@ -3512,18 +3949,23 @@ pub fn markFunctionImport( |
| 3512 | 3949 | ||
| 3513 | const comp = wasm.base.comp; | 3950 | const comp = wasm.base.comp; |
| 3514 | const gpa = comp.gpa; | 3951 | const gpa = comp.gpa; |
| 3952 | const is_obj = comp.config.output_mode == .Obj; | ||
| 3515 | 3953 | ||
| 3516 | try wasm.functions.ensureUnusedCapacity(gpa, 1); | 3954 | try wasm.functions.ensureUnusedCapacity(gpa, 1); |
| 3517 | 3955 | ||
| 3518 | if (import.resolution == .unresolved) { | 3956 | if (import.resolution == .unresolved) { |
| 3519 | if (name == wasm.preloaded_strings.__wasm_init_memory) { | 3957 | if (!is_obj) { |
| 3520 | try wasm.resolveFunctionSynthetic(import, .__wasm_init_memory, &.{}, &.{}); | 3958 | if (name == wasm.preloaded_strings.__wasm_init_memory) { |
| 3521 | } else if (name == wasm.preloaded_strings.__wasm_apply_global_tls_relocs) { | 3959 | try wasm.resolveFunctionSynthetic(import, .__wasm_init_memory, &.{}, &.{}); |
| 3522 | try wasm.resolveFunctionSynthetic(import, .__wasm_apply_global_tls_relocs, &.{}, &.{}); | 3960 | } else if (name == wasm.preloaded_strings.__wasm_apply_global_tls_relocs) { |
| 3523 | } else if (name == wasm.preloaded_strings.__wasm_call_ctors) { | 3961 | try wasm.resolveFunctionSynthetic(import, .__wasm_apply_global_tls_relocs, &.{}, &.{}); |
| 3524 | try wasm.resolveFunctionSynthetic(import, .__wasm_call_ctors, &.{}, &.{}); | 3962 | } else if (name == wasm.preloaded_strings.__wasm_call_ctors) { |
| 3525 | } else if (name == wasm.preloaded_strings.__wasm_init_tls) { | 3963 | try wasm.resolveFunctionSynthetic(import, .__wasm_call_ctors, &.{}, &.{}); |
| 3526 | try wasm.resolveFunctionSynthetic(import, .__wasm_init_tls, &.{.i32}, &.{}); | 3964 | } else if (name == wasm.preloaded_strings.__wasm_init_tls) { |
| 3965 | try wasm.resolveFunctionSynthetic(import, .__wasm_init_tls, &.{.i32}, &.{}); | ||
| 3966 | } else { | ||
| 3967 | try wasm.function_imports.put(gpa, name, .fromObject(func_index, wasm)); | ||
| 3968 | } | ||
| 3527 | } else { | 3969 | } else { |
| 3528 | try wasm.function_imports.put(gpa, name, .fromObject(func_index, wasm)); | 3970 | try wasm.function_imports.put(gpa, name, .fromObject(func_index, wasm)); |
| 3529 | } | 3971 | } |
| ... | @@ -3576,28 +4018,33 @@ fn markGlobalImport( | ... | @@ -3576,28 +4018,33 @@ fn markGlobalImport( |
| 3576 | 4018 | ||
| 3577 | const comp = wasm.base.comp; | 4019 | const comp = wasm.base.comp; |
| 3578 | const gpa = comp.gpa; | 4020 | const gpa = comp.gpa; |
| 4021 | const is_obj = comp.config.output_mode == .Obj; | ||
| 3579 | 4022 | ||
| 3580 | try wasm.globals.ensureUnusedCapacity(gpa, 1); | 4023 | try wasm.globals.ensureUnusedCapacity(gpa, 1); |
| 3581 | 4024 | ||
| 3582 | if (import.resolution == .unresolved) { | 4025 | if (import.resolution == .unresolved) { |
| 3583 | if (name == wasm.preloaded_strings.__heap_base) { | 4026 | if (!is_obj) { |
| 3584 | import.resolution = .__heap_base; | 4027 | if (name == wasm.preloaded_strings.__heap_base) { |
| 3585 | wasm.globals.putAssumeCapacity(.__heap_base, {}); | 4028 | import.resolution = .__heap_base; |
| 3586 | } else if (name == wasm.preloaded_strings.__heap_end) { | 4029 | wasm.globals.putAssumeCapacity(.__heap_base, {}); |
| 3587 | import.resolution = .__heap_end; | 4030 | } else if (name == wasm.preloaded_strings.__heap_end) { |
| 3588 | wasm.globals.putAssumeCapacity(.__heap_end, {}); | 4031 | import.resolution = .__heap_end; |
| 3589 | } else if (name == wasm.preloaded_strings.__stack_pointer) { | 4032 | wasm.globals.putAssumeCapacity(.__heap_end, {}); |
| 3590 | import.resolution = .__stack_pointer; | 4033 | } else if (name == wasm.preloaded_strings.__stack_pointer) { |
| 3591 | wasm.globals.putAssumeCapacity(.__stack_pointer, {}); | 4034 | import.resolution = .__stack_pointer; |
| 3592 | } else if (name == wasm.preloaded_strings.__tls_align) { | 4035 | wasm.globals.putAssumeCapacity(.__stack_pointer, {}); |
| 3593 | import.resolution = .__tls_align; | 4036 | } else if (name == wasm.preloaded_strings.__tls_align) { |
| 3594 | wasm.globals.putAssumeCapacity(.__tls_align, {}); | 4037 | import.resolution = .__tls_align; |
| 3595 | } else if (name == wasm.preloaded_strings.__tls_base) { | 4038 | wasm.globals.putAssumeCapacity(.__tls_align, {}); |
| 3596 | import.resolution = .__tls_base; | 4039 | } else if (name == wasm.preloaded_strings.__tls_base) { |
| 3597 | wasm.globals.putAssumeCapacity(.__tls_base, {}); | 4040 | import.resolution = .__tls_base; |
| 3598 | } else if (name == wasm.preloaded_strings.__tls_size) { | 4041 | wasm.globals.putAssumeCapacity(.__tls_base, {}); |
| 3599 | import.resolution = .__tls_size; | 4042 | } else if (name == wasm.preloaded_strings.__tls_size) { |
| 3600 | wasm.globals.putAssumeCapacity(.__tls_size, {}); | 4043 | import.resolution = .__tls_size; |
| 4044 | wasm.globals.putAssumeCapacity(.__tls_size, {}); | ||
| 4045 | } else { | ||
| 4046 | try wasm.global_imports.put(gpa, name, .fromObject(global_index, wasm)); | ||
| 4047 | } | ||
| 3601 | } else { | 4048 | } else { |
| 3602 | try wasm.global_imports.put(gpa, name, .fromObject(global_index, wasm)); | 4049 | try wasm.global_imports.put(gpa, name, .fromObject(global_index, wasm)); |
| 3603 | } | 4050 | } |
| ... | @@ -3625,7 +4072,7 @@ fn markGlobal(wasm: *Wasm, i: ObjectGlobalIndex, override_export: bool) link.Err | ... | @@ -3625,7 +4072,7 @@ fn markGlobal(wasm: *Wasm, i: ObjectGlobalIndex, override_export: bool) link.Err |
| 3625 | try wasm.markRelocations(global.relocations(wasm)); | 4072 | try wasm.markRelocations(global.relocations(wasm)); |
| 3626 | } | 4073 | } |
| 3627 | 4074 | ||
| 3628 | fn markTableImport( | 4075 | pub fn markTableImport( |
| 3629 | wasm: *Wasm, | 4076 | wasm: *Wasm, |
| 3630 | name: String, | 4077 | name: String, |
| 3631 | import: *TableImport, | 4078 | import: *TableImport, |
| ... | @@ -3636,13 +4083,18 @@ fn markTableImport( | ... | @@ -3636,13 +4083,18 @@ fn markTableImport( |
| 3636 | 4083 | ||
| 3637 | const comp = wasm.base.comp; | 4084 | const comp = wasm.base.comp; |
| 3638 | const gpa = comp.gpa; | 4085 | const gpa = comp.gpa; |
| 4086 | const is_obj = comp.config.output_mode == .Obj; | ||
| 3639 | 4087 | ||
| 3640 | try wasm.tables.ensureUnusedCapacity(gpa, 1); | 4088 | try wasm.tables.ensureUnusedCapacity(gpa, 1); |
| 3641 | 4089 | ||
| 3642 | if (import.resolution == .unresolved) { | 4090 | if (import.resolution == .unresolved) { |
| 3643 | if (name == wasm.preloaded_strings.__indirect_function_table) { | 4091 | if (!is_obj) { |
| 3644 | import.resolution = .__indirect_function_table; | 4092 | if (name == wasm.preloaded_strings.__indirect_function_table) { |
| 3645 | wasm.tables.putAssumeCapacity(.__indirect_function_table, {}); | 4093 | import.resolution = .__indirect_function_table; |
| 4094 | wasm.tables.putAssumeCapacity(.__indirect_function_table, {}); | ||
| 4095 | } else { | ||
| 4096 | try wasm.table_imports.put(gpa, name, table_index); | ||
| 4097 | } | ||
| 3646 | } else { | 4098 | } else { |
| 3647 | try wasm.table_imports.put(gpa, name, table_index); | 4099 | try wasm.table_imports.put(gpa, name, table_index); |
| 3648 | } | 4100 | } |
| ... | @@ -3676,22 +4128,38 @@ pub fn markDataImport( | ... | @@ -3676,22 +4128,38 @@ pub fn markDataImport( |
| 3676 | 4128 | ||
| 3677 | const comp = wasm.base.comp; | 4129 | const comp = wasm.base.comp; |
| 3678 | const gpa = comp.gpa; | 4130 | const gpa = comp.gpa; |
| 4131 | const is_obj = comp.config.output_mode == .Obj; | ||
| 4132 | |||
| 4133 | try wasm.data_segments.ensureUnusedCapacity(gpa, 1); | ||
| 3679 | 4134 | ||
| 3680 | if (import.resolution == .unresolved) { | 4135 | if (import.resolution == .unresolved) { |
| 3681 | if (name == wasm.preloaded_strings.__heap_base) { | 4136 | if (!is_obj) { |
| 3682 | import.resolution = .__heap_base; | 4137 | if (name == wasm.preloaded_strings.__heap_base) { |
| 3683 | wasm.data_segments.putAssumeCapacity(.__heap_base, {}); | 4138 | import.resolution = .__heap_base; |
| 3684 | } else if (name == wasm.preloaded_strings.__heap_end) { | 4139 | wasm.data_segments.putAssumeCapacity(.__heap_base, {}); |
| 3685 | import.resolution = .__heap_end; | 4140 | } else if (name == wasm.preloaded_strings.__heap_end) { |
| 3686 | wasm.data_segments.putAssumeCapacity(.__heap_end, {}); | 4141 | import.resolution = .__heap_end; |
| 4142 | wasm.data_segments.putAssumeCapacity(.__heap_end, {}); | ||
| 4143 | } else { | ||
| 4144 | try wasm.data_imports.put(gpa, name, .fromObject(data_index, wasm)); | ||
| 4145 | } | ||
| 3687 | } else { | 4146 | } else { |
| 3688 | try wasm.data_imports.put(gpa, name, .fromObject(data_index, wasm)); | 4147 | try wasm.data_imports.put(gpa, name, .fromObject(data_index, wasm)); |
| 3689 | } | 4148 | } |
| 3690 | } else if (import.resolution.objectDataSegment(wasm)) |segment_index| { | 4149 | } else switch (import.resolution.unpack(wasm)) { |
| 3691 | try markDataSegment(wasm, segment_index); | 4150 | .object => |object_data_index| try markData(wasm, object_data_index), |
| 4151 | else => {}, | ||
| 3692 | } | 4152 | } |
| 3693 | } | 4153 | } |
| 3694 | 4154 | ||
| 4155 | fn markData(wasm: *Wasm, i: ObjectData.Index) link.Error!void { | ||
| 4156 | const gpa = wasm.base.comp.gpa; | ||
| 4157 | const gop = try wasm.datas.getOrPut(gpa, .fromObjectDataIndex(wasm, i)); | ||
| 4158 | if (gop.found_existing) return; | ||
| 4159 | |||
| 4160 | try markDataSegment(wasm, i.ptr(wasm).segment); | ||
| 4161 | } | ||
| 4162 | |||
| 3695 | fn markRelocations(wasm: *Wasm, relocs: ObjectRelocation.IterableSlice) link.Error!void { | 4163 | fn markRelocations(wasm: *Wasm, relocs: ObjectRelocation.IterableSlice) link.Error!void { |
| 3696 | const gpa = wasm.base.comp.gpa; | 4164 | const gpa = wasm.base.comp.gpa; |
| 3697 | for (relocs.slice.tags(wasm), relocs.slice.pointees(wasm), relocs.slice.offsets(wasm)) |tag, pointee, offset| { | 4165 | for (relocs.slice.tags(wasm), relocs.slice.pointees(wasm), relocs.slice.offsets(wasm)) |tag, pointee, offset| { |
| ... | @@ -3782,7 +4250,7 @@ fn markRelocations(wasm: *Wasm, relocs: ObjectRelocation.IterableSlice) link.Err | ... | @@ -3782,7 +4250,7 @@ fn markRelocations(wasm: *Wasm, relocs: ObjectRelocation.IterableSlice) link.Err |
| 3782 | .memory_addr_tls_sleb, | 4250 | .memory_addr_tls_sleb, |
| 3783 | .memory_addr_locrel_i32, | 4251 | .memory_addr_locrel_i32, |
| 3784 | .memory_addr_tls_sleb64, | 4252 | .memory_addr_tls_sleb64, |
| 3785 | => try markDataSegment(wasm, pointee.data.ptr(wasm).segment), | 4253 | => try markData(wasm, pointee.data), |
| 3786 | 4254 | ||
| 3787 | .type_index_leb => continue, | 4255 | .type_index_leb => continue, |
| 3788 | } | 4256 | } |
| ... | @@ -3829,7 +4297,13 @@ pub fn flush( | ... | @@ -3829,7 +4297,13 @@ pub fn flush( |
| 3829 | const hidden_function_exports_end_zcu: u32 = @intCast(wasm.hidden_function_exports.entries.len); | 4297 | const hidden_function_exports_end_zcu: u32 = @intCast(wasm.hidden_function_exports.entries.len); |
| 3830 | defer wasm.hidden_function_exports.shrinkRetainingCapacity(hidden_function_exports_end_zcu); | 4298 | defer wasm.hidden_function_exports.shrinkRetainingCapacity(hidden_function_exports_end_zcu); |
| 3831 | 4299 | ||
| 4300 | const global_exports_end_zcu: u32 = @intCast(wasm.global_exports.items.len); | ||
| 4301 | defer wasm.global_exports.shrinkRetainingCapacity(global_exports_end_zcu); | ||
| 4302 | |||
| 3832 | wasm.flush_buffer.clear(); | 4303 | wasm.flush_buffer.clear(); |
| 4304 | wasm.tag_name_bytes.clearRetainingCapacity(); | ||
| 4305 | wasm.tag_name_offs.clearRetainingCapacity(); | ||
| 4306 | wasm.tag_name_table_ref_count = 0; | ||
| 3833 | try wasm.flush_buffer.missing_exports.reinit(gpa, wasm.missing_exports.keys(), &.{}); | 4307 | try wasm.flush_buffer.missing_exports.reinit(gpa, wasm.missing_exports.keys(), &.{}); |
| 3834 | try wasm.flush_buffer.function_imports.reinit(gpa, wasm.function_imports.keys(), wasm.function_imports.values()); | 4308 | try wasm.flush_buffer.function_imports.reinit(gpa, wasm.function_imports.keys(), wasm.function_imports.values()); |
| 3835 | try wasm.flush_buffer.global_imports.reinit(gpa, wasm.global_imports.keys(), wasm.global_imports.values()); | 4309 | try wasm.flush_buffer.global_imports.reinit(gpa, wasm.global_imports.keys(), wasm.global_imports.values()); |
| ... | @@ -3858,7 +4332,7 @@ pub fn internOptionalString(wasm: *Wasm, optional_bytes: ?[]const u8) Allocator. | ... | @@ -3858,7 +4332,7 @@ pub fn internOptionalString(wasm: *Wasm, optional_bytes: ?[]const u8) Allocator. |
| 3858 | } | 4332 | } |
| 3859 | 4333 | ||
| 3860 | pub fn internString(wasm: *Wasm, bytes: []const u8) Allocator.Error!String { | 4334 | pub fn internString(wasm: *Wasm, bytes: []const u8) Allocator.Error!String { |
| 3861 | assert(mem.indexOfScalar(u8, bytes, 0) == null); | 4335 | assert(mem.findScalar(u8, bytes, 0) == null); |
| 3862 | wasm.string_bytes_lock.lock(); | 4336 | wasm.string_bytes_lock.lock(); |
| 3863 | defer wasm.string_bytes_lock.unlock(); | 4337 | defer wasm.string_bytes_lock.unlock(); |
| 3864 | const gpa = wasm.base.comp.gpa; | 4338 | const gpa = wasm.base.comp.gpa; |
| ... | @@ -3889,7 +4363,7 @@ pub fn internStringFmt(wasm: *Wasm, comptime format: []const u8, args: anytype) | ... | @@ -3889,7 +4363,7 @@ pub fn internStringFmt(wasm: *Wasm, comptime format: []const u8, args: anytype) |
| 3889 | } | 4363 | } |
| 3890 | 4364 | ||
| 3891 | pub fn getExistingString(wasm: *const Wasm, bytes: []const u8) ?String { | 4365 | pub fn getExistingString(wasm: *const Wasm, bytes: []const u8) ?String { |
| 3892 | assert(mem.indexOfScalar(u8, bytes, 0) == null); | 4366 | assert(mem.findScalar(u8, bytes, 0) == null); |
| 3893 | return wasm.string_table.getKeyAdapted(bytes, @as(String.TableIndexAdapter, .{ | 4367 | return wasm.string_table.getKeyAdapted(bytes, @as(String.TableIndexAdapter, .{ |
| 3894 | .bytes = wasm.string_bytes.items, | 4368 | .bytes = wasm.string_bytes.items, |
| 3895 | })); | 4369 | })); |
| ... | @@ -3953,6 +4427,255 @@ pub fn getExistingFunctionType( | ... | @@ -3953,6 +4427,255 @@ pub fn getExistingFunctionType( |
| 3953 | }); | 4427 | }); |
| 3954 | } | 4428 | } |
| 3955 | 4429 | ||
| 4430 | fn internIntrinsicType( | ||
| 4431 | wasm: *Wasm, | ||
| 4432 | params: []const InternPool.Index, | ||
| 4433 | return_type: Zcu.Type, | ||
| 4434 | ) Allocator.Error!FunctionType.Index { | ||
| 4435 | const target = &wasm.base.comp.root_mod.resolved_target.result; | ||
| 4436 | return wasm.internFunctionType(.{ .wasm_mvp = .{} }, params, return_type, false, target); | ||
| 4437 | } | ||
| 4438 | |||
| 4439 | pub fn intrinsicFunctionType(wasm: *Wasm, intrinsic: Mir.Intrinsic) Allocator.Error!FunctionType.Index { | ||
| 4440 | return switch (intrinsic) { | ||
| 4441 | .__addhf3 => internIntrinsicType(wasm, &.{ .f16_type, .f16_type }, .f16), | ||
| 4442 | .__addtf3 => internIntrinsicType(wasm, &.{ .f128_type, .f128_type }, .f128), | ||
| 4443 | .__addxf3 => internIntrinsicType(wasm, &.{ .f80_type, .f80_type }, .f80), | ||
| 4444 | .__ashlti3 => internIntrinsicType(wasm, &.{ .i128_type, .i32_type }, .i128), | ||
| 4445 | .__ashrti3 => internIntrinsicType(wasm, &.{ .i128_type, .i32_type }, .i128), | ||
| 4446 | .__bitreversedi2 => internIntrinsicType(wasm, &.{.u64_type}, .u64), | ||
| 4447 | .__bitreversesi2 => internIntrinsicType(wasm, &.{.u32_type}, .u32), | ||
| 4448 | .__bswapdi2 => internIntrinsicType(wasm, &.{.u64_type}, .u64), | ||
| 4449 | .__bswapsi2 => internIntrinsicType(wasm, &.{.u32_type}, .u32), | ||
| 4450 | .__ceilh => internIntrinsicType(wasm, &.{.f16_type}, .f16), | ||
| 4451 | .__ceilx => internIntrinsicType(wasm, &.{.f80_type}, .f80), | ||
| 4452 | .__cosh => internIntrinsicType(wasm, &.{.f16_type}, .f16), | ||
| 4453 | .__cosx => internIntrinsicType(wasm, &.{.f80_type}, .f80), | ||
| 4454 | .__divei5 => internIntrinsicType(wasm, &.{ .usize_type, .usize_type, .usize_type, .usize_type, .usize_type }, .void), | ||
| 4455 | .__divhf3 => internIntrinsicType(wasm, &.{ .f16_type, .f16_type }, .f16), | ||
| 4456 | .__divtf3 => internIntrinsicType(wasm, &.{ .f128_type, .f128_type }, .f128), | ||
| 4457 | .__divti3 => internIntrinsicType(wasm, &.{ .i128_type, .i128_type }, .i128), | ||
| 4458 | .__divxf3 => internIntrinsicType(wasm, &.{ .f80_type, .f80_type }, .f80), | ||
| 4459 | .__eqtf2 => internIntrinsicType(wasm, &.{ .f128_type, .f128_type }, .bool), | ||
| 4460 | .__eqxf2 => internIntrinsicType(wasm, &.{ .f80_type, .f80_type }, .bool), | ||
| 4461 | .__exp2h => internIntrinsicType(wasm, &.{.f16_type}, .f16), | ||
| 4462 | .__exp2x => internIntrinsicType(wasm, &.{.f80_type}, .f80), | ||
| 4463 | .__exph => internIntrinsicType(wasm, &.{.f16_type}, .f16), | ||
| 4464 | .__expx => internIntrinsicType(wasm, &.{.f80_type}, .f80), | ||
| 4465 | .__extenddftf2 => internIntrinsicType(wasm, &.{.f64_type}, .f128), | ||
| 4466 | .__extenddfxf2 => internIntrinsicType(wasm, &.{.f64_type}, .f80), | ||
| 4467 | .__extendhfsf2 => internIntrinsicType(wasm, &.{.f16_type}, .f32), | ||
| 4468 | .__extendhftf2 => internIntrinsicType(wasm, &.{.f16_type}, .f128), | ||
| 4469 | .__extendhfxf2 => internIntrinsicType(wasm, &.{.f16_type}, .f80), | ||
| 4470 | .__extendsftf2 => internIntrinsicType(wasm, &.{.f32_type}, .f128), | ||
| 4471 | .__extendsfxf2 => internIntrinsicType(wasm, &.{.f32_type}, .f80), | ||
| 4472 | .__extendxftf2 => internIntrinsicType(wasm, &.{.f80_type}, .f128), | ||
| 4473 | .__fabsh => internIntrinsicType(wasm, &.{.f16_type}, .f16), | ||
| 4474 | .__fabsx => internIntrinsicType(wasm, &.{.f80_type}, .f80), | ||
| 4475 | .__fixdfdi => internIntrinsicType(wasm, &.{.f64_type}, .i64), | ||
| 4476 | .__fixdfei => internIntrinsicType(wasm, &.{ .usize_type, .usize_type, .f64_type }, .void), | ||
| 4477 | .__fixdfsi => internIntrinsicType(wasm, &.{.f64_type}, .i32), | ||
| 4478 | .__fixdfti => internIntrinsicType(wasm, &.{.f64_type}, .i128), | ||
| 4479 | .__fixhfdi => internIntrinsicType(wasm, &.{.f16_type}, .i64), | ||
| 4480 | .__fixhfei => internIntrinsicType(wasm, &.{ .usize_type, .usize_type, .f16_type }, .void), | ||
| 4481 | .__fixhfsi => internIntrinsicType(wasm, &.{.f16_type}, .i32), | ||
| 4482 | .__fixhfti => internIntrinsicType(wasm, &.{.f16_type}, .i128), | ||
| 4483 | .__fixsfdi => internIntrinsicType(wasm, &.{.f32_type}, .i64), | ||
| 4484 | .__fixsfei => internIntrinsicType(wasm, &.{ .usize_type, .usize_type, .f32_type }, .void), | ||
| 4485 | .__fixsfsi => internIntrinsicType(wasm, &.{.f32_type}, .i32), | ||
| 4486 | .__fixsfti => internIntrinsicType(wasm, &.{.f32_type}, .i128), | ||
| 4487 | .__fixtfdi => internIntrinsicType(wasm, &.{.f128_type}, .i64), | ||
| 4488 | .__fixtfei => internIntrinsicType(wasm, &.{ .usize_type, .usize_type, .f128_type }, .void), | ||
| 4489 | .__fixtfsi => internIntrinsicType(wasm, &.{.f128_type}, .i32), | ||
| 4490 | .__fixtfti => internIntrinsicType(wasm, &.{.f128_type}, .i128), | ||
| 4491 | .__fixunsdfdi => internIntrinsicType(wasm, &.{.f64_type}, .u64), | ||
| 4492 | .__fixunsdfei => internIntrinsicType(wasm, &.{ .usize_type, .usize_type, .f64_type }, .void), | ||
| 4493 | .__fixunsdfsi => internIntrinsicType(wasm, &.{.f64_type}, .u32), | ||
| 4494 | .__fixunsdfti => internIntrinsicType(wasm, &.{.f64_type}, .u128), | ||
| 4495 | .__fixunshfdi => internIntrinsicType(wasm, &.{.f16_type}, .u64), | ||
| 4496 | .__fixunshfei => internIntrinsicType(wasm, &.{ .usize_type, .usize_type, .f16_type }, .void), | ||
| 4497 | .__fixunshfsi => internIntrinsicType(wasm, &.{.f16_type}, .u32), | ||
| 4498 | .__fixunshfti => internIntrinsicType(wasm, &.{.f16_type}, .u128), | ||
| 4499 | .__fixunssfdi => internIntrinsicType(wasm, &.{.f32_type}, .u64), | ||
| 4500 | .__fixunssfei => internIntrinsicType(wasm, &.{ .usize_type, .usize_type, .f32_type }, .void), | ||
| 4501 | .__fixunssfsi => internIntrinsicType(wasm, &.{.f32_type}, .u32), | ||
| 4502 | .__fixunssfti => internIntrinsicType(wasm, &.{.f32_type}, .u128), | ||
| 4503 | .__fixunstfdi => internIntrinsicType(wasm, &.{.f128_type}, .u64), | ||
| 4504 | .__fixunstfei => internIntrinsicType(wasm, &.{ .usize_type, .usize_type, .f128_type }, .void), | ||
| 4505 | .__fixunstfsi => internIntrinsicType(wasm, &.{.f128_type}, .u32), | ||
| 4506 | .__fixunstfti => internIntrinsicType(wasm, &.{.f128_type}, .u128), | ||
| 4507 | .__fixunsxfdi => internIntrinsicType(wasm, &.{.f80_type}, .u64), | ||
| 4508 | .__fixunsxfei => internIntrinsicType(wasm, &.{ .usize_type, .usize_type, .f80_type }, .void), | ||
| 4509 | .__fixunsxfsi => internIntrinsicType(wasm, &.{.f80_type}, .u32), | ||
| 4510 | .__fixunsxfti => internIntrinsicType(wasm, &.{.f80_type}, .u128), | ||
| 4511 | .__fixxfdi => internIntrinsicType(wasm, &.{.f80_type}, .i64), | ||
| 4512 | .__fixxfei => internIntrinsicType(wasm, &.{ .usize_type, .usize_type, .f80_type }, .void), | ||
| 4513 | .__fixxfsi => internIntrinsicType(wasm, &.{.f80_type}, .i32), | ||
| 4514 | .__fixxfti => internIntrinsicType(wasm, &.{.f80_type}, .i128), | ||
| 4515 | .__floatdidf => internIntrinsicType(wasm, &.{.i64_type}, .f64), | ||
| 4516 | .__floatdihf => internIntrinsicType(wasm, &.{.i64_type}, .f16), | ||
| 4517 | .__floatdisf => internIntrinsicType(wasm, &.{.i64_type}, .f32), | ||
| 4518 | .__floatditf => internIntrinsicType(wasm, &.{.i64_type}, .f128), | ||
| 4519 | .__floatdixf => internIntrinsicType(wasm, &.{.i64_type}, .f80), | ||
| 4520 | .__floateidf => internIntrinsicType(wasm, &.{ .usize_type, .usize_type }, .f64), | ||
| 4521 | .__floateihf => internIntrinsicType(wasm, &.{ .usize_type, .usize_type }, .f16), | ||
| 4522 | .__floateisf => internIntrinsicType(wasm, &.{ .usize_type, .usize_type }, .f32), | ||
| 4523 | .__floateitf => internIntrinsicType(wasm, &.{ .usize_type, .usize_type }, .f128), | ||
| 4524 | .__floateixf => internIntrinsicType(wasm, &.{ .usize_type, .usize_type }, .f80), | ||
| 4525 | .__floatsidf => internIntrinsicType(wasm, &.{.i32_type}, .f64), | ||
| 4526 | .__floatsihf => internIntrinsicType(wasm, &.{.i32_type}, .f16), | ||
| 4527 | .__floatsisf => internIntrinsicType(wasm, &.{.i32_type}, .f32), | ||
| 4528 | .__floatsitf => internIntrinsicType(wasm, &.{.i32_type}, .f128), | ||
| 4529 | .__floatsixf => internIntrinsicType(wasm, &.{.i32_type}, .f80), | ||
| 4530 | .__floattidf => internIntrinsicType(wasm, &.{.i128_type}, .f64), | ||
| 4531 | .__floattihf => internIntrinsicType(wasm, &.{.i128_type}, .f16), | ||
| 4532 | .__floattisf => internIntrinsicType(wasm, &.{.i128_type}, .f32), | ||
| 4533 | .__floattitf => internIntrinsicType(wasm, &.{.i128_type}, .f128), | ||
| 4534 | .__floattixf => internIntrinsicType(wasm, &.{.i128_type}, .f80), | ||
| 4535 | .__floatundidf => internIntrinsicType(wasm, &.{.u64_type}, .f64), | ||
| 4536 | .__floatundihf => internIntrinsicType(wasm, &.{.u64_type}, .f16), | ||
| 4537 | .__floatundisf => internIntrinsicType(wasm, &.{.u64_type}, .f32), | ||
| 4538 | .__floatunditf => internIntrinsicType(wasm, &.{.u64_type}, .f128), | ||
| 4539 | .__floatundixf => internIntrinsicType(wasm, &.{.u64_type}, .f80), | ||
| 4540 | .__floatuneidf => internIntrinsicType(wasm, &.{ .usize_type, .usize_type }, .f64), | ||
| 4541 | .__floatuneihf => internIntrinsicType(wasm, &.{ .usize_type, .usize_type }, .f16), | ||
| 4542 | .__floatuneisf => internIntrinsicType(wasm, &.{ .usize_type, .usize_type }, .f32), | ||
| 4543 | .__floatuneitf => internIntrinsicType(wasm, &.{ .usize_type, .usize_type }, .f128), | ||
| 4544 | .__floatuneixf => internIntrinsicType(wasm, &.{ .usize_type, .usize_type }, .f80), | ||
| 4545 | .__floatunsidf => internIntrinsicType(wasm, &.{.u32_type}, .f64), | ||
| 4546 | .__floatunsihf => internIntrinsicType(wasm, &.{.u32_type}, .f16), | ||
| 4547 | .__floatunsisf => internIntrinsicType(wasm, &.{.u32_type}, .f32), | ||
| 4548 | .__floatunsitf => internIntrinsicType(wasm, &.{.u32_type}, .f128), | ||
| 4549 | .__floatunsixf => internIntrinsicType(wasm, &.{.u32_type}, .f80), | ||
| 4550 | .__floatuntidf => internIntrinsicType(wasm, &.{.u128_type}, .f64), | ||
| 4551 | .__floatuntihf => internIntrinsicType(wasm, &.{.u128_type}, .f16), | ||
| 4552 | .__floatuntisf => internIntrinsicType(wasm, &.{.u128_type}, .f32), | ||
| 4553 | .__floatuntitf => internIntrinsicType(wasm, &.{.u128_type}, .f128), | ||
| 4554 | .__floatuntixf => internIntrinsicType(wasm, &.{.u128_type}, .f80), | ||
| 4555 | .__floorh => internIntrinsicType(wasm, &.{.f16_type}, .f16), | ||
| 4556 | .__floorx => internIntrinsicType(wasm, &.{.f80_type}, .f80), | ||
| 4557 | .__fmah => internIntrinsicType(wasm, &.{ .f16_type, .f16_type, .f16_type }, .f16), | ||
| 4558 | .__fmax => internIntrinsicType(wasm, &.{ .f80_type, .f80_type, .f80_type }, .f80), | ||
| 4559 | .__fmaxh => internIntrinsicType(wasm, &.{ .f16_type, .f16_type }, .f16), | ||
| 4560 | .__fmaxx => internIntrinsicType(wasm, &.{ .f80_type, .f80_type }, .f80), | ||
| 4561 | .__fminh => internIntrinsicType(wasm, &.{ .f16_type, .f16_type }, .f16), | ||
| 4562 | .__fminx => internIntrinsicType(wasm, &.{ .f80_type, .f80_type }, .f80), | ||
| 4563 | .__fmodh => internIntrinsicType(wasm, &.{ .f16_type, .f16_type }, .f16), | ||
| 4564 | .__fmodx => internIntrinsicType(wasm, &.{ .f80_type, .f80_type }, .f80), | ||
| 4565 | .__getf2 => internIntrinsicType(wasm, &.{ .f128_type, .f128_type }, .bool), | ||
| 4566 | .__gexf2 => internIntrinsicType(wasm, &.{ .f80_type, .f80_type }, .bool), | ||
| 4567 | .__gttf2 => internIntrinsicType(wasm, &.{ .f128_type, .f128_type }, .bool), | ||
| 4568 | .__gtxf2 => internIntrinsicType(wasm, &.{ .f80_type, .f80_type }, .bool), | ||
| 4569 | .__letf2 => internIntrinsicType(wasm, &.{ .f128_type, .f128_type }, .bool), | ||
| 4570 | .__lexf2 => internIntrinsicType(wasm, &.{ .f80_type, .f80_type }, .bool), | ||
| 4571 | .__log10h => internIntrinsicType(wasm, &.{.f16_type}, .f16), | ||
| 4572 | .__log10x => internIntrinsicType(wasm, &.{.f80_type}, .f80), | ||
| 4573 | .__log2h => internIntrinsicType(wasm, &.{.f16_type}, .f16), | ||
| 4574 | .__log2x => internIntrinsicType(wasm, &.{.f80_type}, .f80), | ||
| 4575 | .__logh => internIntrinsicType(wasm, &.{.f16_type}, .f16), | ||
| 4576 | .__logx => internIntrinsicType(wasm, &.{.f80_type}, .f80), | ||
| 4577 | .__lshrti3 => internIntrinsicType(wasm, &.{ .i128_type, .i32_type }, .i128), | ||
| 4578 | .__lttf2 => internIntrinsicType(wasm, &.{ .f128_type, .f128_type }, .bool), | ||
| 4579 | .__ltxf2 => internIntrinsicType(wasm, &.{ .f80_type, .f80_type }, .bool), | ||
| 4580 | .__modei5 => internIntrinsicType(wasm, &.{ .usize_type, .usize_type, .usize_type, .usize_type, .usize_type }, .void), | ||
| 4581 | .__modti3 => internIntrinsicType(wasm, &.{ .i128_type, .i128_type }, .i128), | ||
| 4582 | .__mulhf3 => internIntrinsicType(wasm, &.{ .f16_type, .f16_type }, .f16), | ||
| 4583 | .__mulodi4 => internIntrinsicType(wasm, &.{ .i64_type, .i64_type, .usize_type }, .i64), | ||
| 4584 | .__muloti4 => internIntrinsicType(wasm, &.{ .i128_type, .i128_type, .usize_type }, .i128), | ||
| 4585 | .__multf3 => internIntrinsicType(wasm, &.{ .f128_type, .f128_type }, .f128), | ||
| 4586 | .__multi3 => internIntrinsicType(wasm, &.{ .i128_type, .i128_type }, .i128), | ||
| 4587 | .__mulxf3 => internIntrinsicType(wasm, &.{ .f80_type, .f80_type }, .f80), | ||
| 4588 | .__netf2 => internIntrinsicType(wasm, &.{ .f128_type, .f128_type }, .bool), | ||
| 4589 | .__nexf2 => internIntrinsicType(wasm, &.{ .f80_type, .f80_type }, .bool), | ||
| 4590 | .__roundh => internIntrinsicType(wasm, &.{.f16_type}, .f16), | ||
| 4591 | .__roundx => internIntrinsicType(wasm, &.{.f80_type}, .f80), | ||
| 4592 | .__sinh => internIntrinsicType(wasm, &.{.f16_type}, .f16), | ||
| 4593 | .__sinx => internIntrinsicType(wasm, &.{.f80_type}, .f80), | ||
| 4594 | .__sqrth => internIntrinsicType(wasm, &.{.f16_type}, .f16), | ||
| 4595 | .__sqrtx => internIntrinsicType(wasm, &.{.f80_type}, .f80), | ||
| 4596 | .__subhf3 => internIntrinsicType(wasm, &.{ .f16_type, .f16_type }, .f16), | ||
| 4597 | .__subtf3 => internIntrinsicType(wasm, &.{ .f128_type, .f128_type }, .f128), | ||
| 4598 | .__subxf3 => internIntrinsicType(wasm, &.{ .f80_type, .f80_type }, .f80), | ||
| 4599 | .__tanh => internIntrinsicType(wasm, &.{.f16_type}, .f16), | ||
| 4600 | .__tanx => internIntrinsicType(wasm, &.{.f80_type}, .f80), | ||
| 4601 | .__trunch => internIntrinsicType(wasm, &.{.f16_type}, .f16), | ||
| 4602 | .__truncsfhf2 => internIntrinsicType(wasm, &.{.f32_type}, .f16), | ||
| 4603 | .__trunctfdf2 => internIntrinsicType(wasm, &.{.f128_type}, .f64), | ||
| 4604 | .__trunctfhf2 => internIntrinsicType(wasm, &.{.f128_type}, .f16), | ||
| 4605 | .__trunctfsf2 => internIntrinsicType(wasm, &.{.f128_type}, .f32), | ||
| 4606 | .__trunctfxf2 => internIntrinsicType(wasm, &.{.f128_type}, .f80), | ||
| 4607 | .__truncx => internIntrinsicType(wasm, &.{.f80_type}, .f80), | ||
| 4608 | .__truncxfdf2 => internIntrinsicType(wasm, &.{.f80_type}, .f64), | ||
| 4609 | .__truncxfhf2 => internIntrinsicType(wasm, &.{.f80_type}, .f16), | ||
| 4610 | .__truncxfsf2 => internIntrinsicType(wasm, &.{.f80_type}, .f32), | ||
| 4611 | .__udivei5 => internIntrinsicType(wasm, &.{ .usize_type, .usize_type, .usize_type, .usize_type, .usize_type }, .void), | ||
| 4612 | .__udivti3 => internIntrinsicType(wasm, &.{ .u128_type, .u128_type }, .u128), | ||
| 4613 | .__umodei5 => internIntrinsicType(wasm, &.{ .usize_type, .usize_type, .usize_type, .usize_type, .usize_type }, .void), | ||
| 4614 | .__umodti3 => internIntrinsicType(wasm, &.{ .u128_type, .u128_type }, .u128), | ||
| 4615 | .ceilf128 => internIntrinsicType(wasm, &.{.f128_type}, .f128), | ||
| 4616 | .cos => internIntrinsicType(wasm, &.{.f64_type}, .f64), | ||
| 4617 | .cosf => internIntrinsicType(wasm, &.{.f32_type}, .f32), | ||
| 4618 | .cosf128 => internIntrinsicType(wasm, &.{.f128_type}, .f128), | ||
| 4619 | .exp => internIntrinsicType(wasm, &.{.f64_type}, .f64), | ||
| 4620 | .exp2 => internIntrinsicType(wasm, &.{.f64_type}, .f64), | ||
| 4621 | .exp2f => internIntrinsicType(wasm, &.{.f32_type}, .f32), | ||
| 4622 | .exp2f128 => internIntrinsicType(wasm, &.{.f128_type}, .f128), | ||
| 4623 | .expf => internIntrinsicType(wasm, &.{.f32_type}, .f32), | ||
| 4624 | .expf128 => internIntrinsicType(wasm, &.{.f128_type}, .f128), | ||
| 4625 | .fabsf128 => internIntrinsicType(wasm, &.{.f128_type}, .f128), | ||
| 4626 | .floorf128 => internIntrinsicType(wasm, &.{.f128_type}, .f128), | ||
| 4627 | .fma => internIntrinsicType(wasm, &.{ .f64_type, .f64_type, .f64_type }, .f64), | ||
| 4628 | .fmaf => internIntrinsicType(wasm, &.{ .f32_type, .f32_type, .f32_type }, .f32), | ||
| 4629 | .fmaf128 => internIntrinsicType(wasm, &.{ .f128_type, .f128_type, .f128_type }, .f128), | ||
| 4630 | .fmax => internIntrinsicType(wasm, &.{ .f64_type, .f64_type }, .f64), | ||
| 4631 | .fmaxf => internIntrinsicType(wasm, &.{ .f32_type, .f32_type }, .f32), | ||
| 4632 | .fmaxf128 => internIntrinsicType(wasm, &.{ .f128_type, .f128_type }, .f128), | ||
| 4633 | .fmin => internIntrinsicType(wasm, &.{ .f64_type, .f64_type }, .f64), | ||
| 4634 | .fminf => internIntrinsicType(wasm, &.{ .f32_type, .f32_type }, .f32), | ||
| 4635 | .fminf128 => internIntrinsicType(wasm, &.{ .f128_type, .f128_type }, .f128), | ||
| 4636 | .fmod => internIntrinsicType(wasm, &.{ .f64_type, .f64_type }, .f64), | ||
| 4637 | .fmodf => internIntrinsicType(wasm, &.{ .f32_type, .f32_type }, .f32), | ||
| 4638 | .fmodf128 => internIntrinsicType(wasm, &.{ .f128_type, .f128_type }, .f128), | ||
| 4639 | .log => internIntrinsicType(wasm, &.{.f64_type}, .f64), | ||
| 4640 | .log10 => internIntrinsicType(wasm, &.{.f64_type}, .f64), | ||
| 4641 | .log10f => internIntrinsicType(wasm, &.{.f32_type}, .f32), | ||
| 4642 | .log10f128 => internIntrinsicType(wasm, &.{.f128_type}, .f128), | ||
| 4643 | .log2 => internIntrinsicType(wasm, &.{.f64_type}, .f64), | ||
| 4644 | .log2f => internIntrinsicType(wasm, &.{.f32_type}, .f32), | ||
| 4645 | .log2f128 => internIntrinsicType(wasm, &.{.f128_type}, .f128), | ||
| 4646 | .logf => internIntrinsicType(wasm, &.{.f32_type}, .f32), | ||
| 4647 | .logf128 => internIntrinsicType(wasm, &.{.f128_type}, .f128), | ||
| 4648 | .roundf128 => internIntrinsicType(wasm, &.{.f128_type}, .f128), | ||
| 4649 | .sin => internIntrinsicType(wasm, &.{.f64_type}, .f64), | ||
| 4650 | .sinf => internIntrinsicType(wasm, &.{.f32_type}, .f32), | ||
| 4651 | .sinf128 => internIntrinsicType(wasm, &.{.f128_type}, .f128), | ||
| 4652 | .sqrtf128 => internIntrinsicType(wasm, &.{.f128_type}, .f128), | ||
| 4653 | .tan => internIntrinsicType(wasm, &.{.f64_type}, .f64), | ||
| 4654 | .tanf => internIntrinsicType(wasm, &.{.f32_type}, .f32), | ||
| 4655 | .tanf128 => internIntrinsicType(wasm, &.{.f128_type}, .f128), | ||
| 4656 | .truncf128 => internIntrinsicType(wasm, &.{.f128_type}, .f128), | ||
| 4657 | .memcpy => internIntrinsicType(wasm, &.{ .usize_type, .usize_type, .usize_type }, .usize), | ||
| 4658 | .memmove => internIntrinsicType(wasm, &.{ .usize_type, .usize_type, .usize_type }, .usize), | ||
| 4659 | .memset => internIntrinsicType(wasm, &.{ .usize_type, .i32_type, .usize_type }, .usize), | ||
| 4660 | .__addo_limb64 => internIntrinsicType(wasm, &.{ .usize_type, .usize_type, .usize_type, .bool_type, .u16_type }, .bool), | ||
| 4661 | .__subo_limb64 => internIntrinsicType(wasm, &.{ .usize_type, .usize_type, .usize_type, .bool_type, .u16_type }, .bool), | ||
| 4662 | .__cmp_limb64 => internIntrinsicType(wasm, &.{ .usize_type, .usize_type, .bool_type, .u16_type }, .i8), | ||
| 4663 | .__and_limb64 => internIntrinsicType(wasm, &.{ .usize_type, .usize_type, .usize_type, .u16_type }, .void), | ||
| 4664 | .__or_limb64 => internIntrinsicType(wasm, &.{ .usize_type, .usize_type, .usize_type, .u16_type }, .void), | ||
| 4665 | .__xor_limb64 => internIntrinsicType(wasm, &.{ .usize_type, .usize_type, .usize_type, .u16_type }, .void), | ||
| 4666 | .__not_limb64 => internIntrinsicType(wasm, &.{ .usize_type, .usize_type, .bool_type, .u16_type }, .void), | ||
| 4667 | .__shlo_limb64 => internIntrinsicType(wasm, &.{ .usize_type, .usize_type, .u16_type, .bool_type, .u16_type }, .bool), | ||
| 4668 | .__shr_limb64 => internIntrinsicType(wasm, &.{ .usize_type, .usize_type, .u16_type, .bool_type, .u16_type }, .void), | ||
| 4669 | .__clz_limb64 => internIntrinsicType(wasm, &.{ .usize_type, .u16_type }, .u16), | ||
| 4670 | .__ctz_limb64 => internIntrinsicType(wasm, &.{ .usize_type, .u16_type }, .u16), | ||
| 4671 | .__popcount_limb64 => internIntrinsicType(wasm, &.{ .usize_type, .u16_type }, .u16), | ||
| 4672 | .__bitreverse_limb64 => internIntrinsicType(wasm, &.{ .usize_type, .usize_type, .bool_type, .u16_type }, .void), | ||
| 4673 | .__byteswap_limb64 => internIntrinsicType(wasm, &.{ .usize_type, .usize_type, .bool_type, .u16_type }, .void), | ||
| 4674 | .__mulo_limb64 => internIntrinsicType(wasm, &.{ .usize_type, .usize_type, .usize_type, .bool_type, .u16_type }, .bool), | ||
| 4675 | .__abs_limb64 => internIntrinsicType(wasm, &.{ .usize_type, .usize_type, .u16_type }, .void), | ||
| 4676 | }; | ||
| 4677 | } | ||
| 4678 | |||
| 3956 | pub fn addExpr(wasm: *Wasm, bytes: []const u8) Allocator.Error!Expr { | 4679 | pub fn addExpr(wasm: *Wasm, bytes: []const u8) Allocator.Error!Expr { |
| 3957 | const gpa = wasm.base.comp.gpa; | 4680 | const gpa = wasm.base.comp.gpa; |
| 3958 | // We can't use string table deduplication here since these expressions can | 4681 | // We can't use string table deduplication here since these expressions can |
| ... | @@ -3972,64 +4695,63 @@ pub fn addRelocatableDataPayload(wasm: *Wasm, bytes: []const u8) Allocator.Error | ... | @@ -3972,64 +4695,63 @@ pub fn addRelocatableDataPayload(wasm: *Wasm, bytes: []const u8) Allocator.Error |
| 3972 | }; | 4695 | }; |
| 3973 | } | 4696 | } |
| 3974 | 4697 | ||
| 3975 | pub fn uavSymbolIndex(wasm: *Wasm, ip_index: InternPool.Index) Allocator.Error!SymbolTableIndex { | 4698 | pub fn addNavReloc( |
| 3976 | const comp = wasm.base.comp; | 4699 | wasm: *Wasm, |
| 3977 | assert(comp.config.output_mode == .Obj); | 4700 | reloc_offset: usize, |
| 3978 | const gpa = comp.gpa; | 4701 | nav_index: InternPool.Nav.Index, |
| 3979 | const name = try wasm.internStringFmt("__anon_{d}", .{@backingInt(ip_index)}); | 4702 | nav_ty: Zcu.Type, |
| 3980 | const gop = try wasm.symbol_table.getOrPut(gpa, name); | 4703 | addend: u32, |
| 3981 | gop.value_ptr.* = {}; | 4704 | ) !void { |
| 3982 | return @fromBackingInt(@intCast(gop.index)); | ||
| 3983 | } | ||
| 3984 | |||
| 3985 | pub fn navSymbolIndex(wasm: *Wasm, nav_index: InternPool.Nav.Index) Allocator.Error!SymbolTableIndex { | ||
| 3986 | const comp = wasm.base.comp; | 4705 | const comp = wasm.base.comp; |
| 3987 | assert(comp.config.output_mode == .Obj); | ||
| 3988 | const zcu = comp.zcu.?; | 4706 | const zcu = comp.zcu.?; |
| 3989 | const ip = &zcu.intern_pool; | 4707 | const ip = &zcu.intern_pool; |
| 3990 | const gpa = comp.gpa; | 4708 | const gpa = comp.gpa; |
| 3991 | const nav = ip.getNav(nav_index); | ||
| 3992 | const name = try wasm.internString(nav.fqn.toSlice(ip)); | ||
| 3993 | const gop = try wasm.symbol_table.getOrPut(gpa, name); | ||
| 3994 | gop.value_ptr.* = {}; | ||
| 3995 | return @fromBackingInt(@intCast(gop.index)); | ||
| 3996 | } | ||
| 3997 | |||
| 3998 | pub fn errorNameTableSymbolIndex(wasm: *Wasm) Allocator.Error!SymbolTableIndex { | ||
| 3999 | const comp = wasm.base.comp; | ||
| 4000 | assert(comp.config.output_mode == .Obj); | ||
| 4001 | const gpa = comp.gpa; | ||
| 4002 | const gop = try wasm.symbol_table.getOrPut(gpa, wasm.preloaded_strings.__zig_error_name_table); | ||
| 4003 | gop.value_ptr.* = {}; | ||
| 4004 | return @fromBackingInt(@intCast(gop.index)); | ||
| 4005 | } | ||
| 4006 | |||
| 4007 | pub fn stackPointerSymbolIndex(wasm: *Wasm) Allocator.Error!SymbolTableIndex { | ||
| 4008 | const comp = wasm.base.comp; | ||
| 4009 | assert(comp.config.output_mode == .Obj); | ||
| 4010 | const gpa = comp.gpa; | ||
| 4011 | const gop = try wasm.symbol_table.getOrPut(gpa, wasm.preloaded_strings.__stack_pointer); | ||
| 4012 | gop.value_ptr.* = {}; | ||
| 4013 | return @fromBackingInt(@intCast(gop.index)); | ||
| 4014 | } | ||
| 4015 | 4709 | ||
| 4016 | pub fn tagTableIndexSymbolIndex(wasm: *Wasm, ip_index: InternPool.Index) Allocator.Error!SymbolTableIndex { | 4710 | const is_obj = comp.config.output_mode == .Obj; |
| 4017 | const comp = wasm.base.comp; | ||
| 4018 | assert(comp.config.output_mode == .Obj); | ||
| 4019 | const gpa = comp.gpa; | ||
| 4020 | const name = try wasm.internStringFmt("__zig_tag_name_{d}", .{ip_index}); | ||
| 4021 | const gop = try wasm.symbol_table.getOrPut(gpa, name); | ||
| 4022 | gop.value_ptr.* = {}; | ||
| 4023 | return @fromBackingInt(@intCast(gop.index)); | ||
| 4024 | } | ||
| 4025 | 4711 | ||
| 4026 | pub fn symbolNameIndex(wasm: *Wasm, name: String) Allocator.Error!SymbolTableIndex { | 4712 | if (nav_ty.zigTypeTag(zcu) == .@"fn") { |
| 4027 | const comp = wasm.base.comp; | 4713 | const gop = try wasm.zcu_indirect_function_set.getOrPut(gpa, nav_index); |
| 4028 | assert(comp.config.output_mode == .Obj); | 4714 | if (!gop.found_existing) gop.value_ptr.* = {}; |
| 4029 | const gpa = comp.gpa; | 4715 | if (is_obj) { |
| 4030 | const gop = try wasm.symbol_table.getOrPut(gpa, name); | 4716 | assert(addend == 0); |
| 4031 | gop.value_ptr.* = {}; | 4717 | try wasm.zcu_relocations.append(gpa, .{ |
| 4032 | return @fromBackingInt(@intCast(gop.index)); | 4718 | .offset = @intCast(reloc_offset), |
| 4719 | .pointee = .{ .function_nav = nav_index }, | ||
| 4720 | .tag = switch (wasm.pointerSize()) { | ||
| 4721 | 4 => .table_index_i32, | ||
| 4722 | 8 => .table_index_i64, | ||
| 4723 | else => unreachable, | ||
| 4724 | }, | ||
| 4725 | .addend = 0, | ||
| 4726 | }); | ||
| 4727 | } else { | ||
| 4728 | try wasm.func_table_fixups.append(gpa, .{ | ||
| 4729 | .nav_index = nav_index, | ||
| 4730 | .offset = @intCast(reloc_offset), | ||
| 4731 | }); | ||
| 4732 | } | ||
| 4733 | } else { | ||
| 4734 | if (is_obj) { | ||
| 4735 | if (ip.getNav(nav_index).getExtern(ip) == null) _ = try wasm.refNavObj(nav_index); | ||
| 4736 | try wasm.zcu_relocations.append(gpa, .{ | ||
| 4737 | .offset = @intCast(reloc_offset), | ||
| 4738 | .pointee = .{ .data_nav = nav_index }, | ||
| 4739 | .tag = switch (wasm.pointerSize()) { | ||
| 4740 | 4 => .memory_addr_i32, | ||
| 4741 | 8 => .memory_addr_i64, | ||
| 4742 | else => unreachable, | ||
| 4743 | }, | ||
| 4744 | .addend = @intCast(addend), | ||
| 4745 | }); | ||
| 4746 | } else { | ||
| 4747 | try wasm.nav_fixups.ensureUnusedCapacity(gpa, 1); | ||
| 4748 | wasm.nav_fixups.appendAssumeCapacity(.{ | ||
| 4749 | .nav_index = nav_index, | ||
| 4750 | .offset = @intCast(reloc_offset), | ||
| 4751 | .addend = addend, | ||
| 4752 | }); | ||
| 4753 | } | ||
| 4754 | } | ||
| 4033 | } | 4755 | } |
| 4034 | 4756 | ||
| 4035 | pub fn addUavReloc( | 4757 | pub fn addUavReloc( |
| ... | @@ -4057,12 +4779,12 @@ pub fn addUavReloc( | ... | @@ -4057,12 +4779,12 @@ pub fn addUavReloc( |
| 4057 | if (comp.config.output_mode == .Obj) { | 4779 | if (comp.config.output_mode == .Obj) { |
| 4058 | const gop = try wasm.uavs_obj.getOrPut(gpa, uav_val); | 4780 | const gop = try wasm.uavs_obj.getOrPut(gpa, uav_val); |
| 4059 | if (!gop.found_existing) gop.value_ptr.* = undefined; // to avoid recursion, `ZcuDataStarts` will lower the value later | 4781 | if (!gop.found_existing) gop.value_ptr.* = undefined; // to avoid recursion, `ZcuDataStarts` will lower the value later |
| 4060 | try wasm.out_relocs.append(gpa, .{ | 4782 | try wasm.zcu_relocations.append(gpa, .{ |
| 4061 | .offset = @intCast(reloc_offset), | 4783 | .offset = @intCast(reloc_offset), |
| 4062 | .pointee = .{ .symbol_index = try wasm.uavSymbolIndex(uav_val) }, | 4784 | .pointee = .{ .data_uav = uav_val }, |
| 4063 | .tag = switch (wasm.pointerSize()) { | 4785 | .tag = switch (wasm.pointerSize()) { |
| 4064 | 32 => .memory_addr_i32, | 4786 | 4 => .memory_addr_i32, |
| 4065 | 64 => .memory_addr_i64, | 4787 | 8 => .memory_addr_i64, |
| 4066 | else => unreachable, | 4788 | else => unreachable, |
| 4067 | }, | 4789 | }, |
| 4068 | .addend = @intCast(addend), | 4790 | .addend = @intCast(addend), |
| ... | @@ -4085,7 +4807,7 @@ pub fn addUavReloc( | ... | @@ -4085,7 +4807,7 @@ pub fn addUavReloc( |
| 4085 | pub fn refNavObj(wasm: *Wasm, nav_index: InternPool.Nav.Index) !NavsObjIndex { | 4807 | pub fn refNavObj(wasm: *Wasm, nav_index: InternPool.Nav.Index) !NavsObjIndex { |
| 4086 | const comp = wasm.base.comp; | 4808 | const comp = wasm.base.comp; |
| 4087 | const gpa = comp.gpa; | 4809 | const gpa = comp.gpa; |
| 4088 | assert(comp.config.output_mode != .Obj); | 4810 | assert(comp.config.output_mode == .Obj); |
| 4089 | const gop = try wasm.navs_obj.getOrPut(gpa, nav_index); | 4811 | const gop = try wasm.navs_obj.getOrPut(gpa, nav_index); |
| 4090 | if (!gop.found_existing) gop.value_ptr.* = .{ | 4812 | if (!gop.found_existing) gop.value_ptr.* = .{ |
| 4091 | // Lowering the value is delayed to avoid recursion. | 4813 | // Lowering the value is delayed to avoid recursion. |
| ... | @@ -4113,7 +4835,7 @@ pub fn refNavExe(wasm: *Wasm, nav_index: InternPool.Nav.Index) !NavsExeIndex { | ... | @@ -4113,7 +4835,7 @@ pub fn refNavExe(wasm: *Wasm, nav_index: InternPool.Nav.Index) !NavsExeIndex { |
| 4113 | } | 4835 | } |
| 4114 | 4836 | ||
| 4115 | /// Asserts it is called after `Flush.data_segments` is fully populated and sorted. | 4837 | /// Asserts it is called after `Flush.data_segments` is fully populated and sorted. |
| 4116 | pub fn uavAddr(wasm: *Wasm, ip_index: InternPool.Index) u32 { | 4838 | pub fn uavAddr(wasm: *const Wasm, ip_index: InternPool.Index) u32 { |
| 4117 | assert(wasm.flush_buffer.memory_layout_finished); | 4839 | assert(wasm.flush_buffer.memory_layout_finished); |
| 4118 | const comp = wasm.base.comp; | 4840 | const comp = wasm.base.comp; |
| 4119 | assert(comp.config.output_mode != .Obj); | 4841 | assert(comp.config.output_mode != .Obj); |
| ... | @@ -4123,7 +4845,7 @@ pub fn uavAddr(wasm: *Wasm, ip_index: InternPool.Index) u32 { | ... | @@ -4123,7 +4845,7 @@ pub fn uavAddr(wasm: *Wasm, ip_index: InternPool.Index) u32 { |
| 4123 | } | 4845 | } |
| 4124 | 4846 | ||
| 4125 | /// Asserts it is called after `Flush.data_segments` is fully populated and sorted. | 4847 | /// Asserts it is called after `Flush.data_segments` is fully populated and sorted. |
| 4126 | pub fn navAddr(wasm: *Wasm, nav_index: InternPool.Nav.Index) u32 { | 4848 | pub fn navAddr(wasm: *const Wasm, nav_index: InternPool.Nav.Index) u32 { |
| 4127 | assert(wasm.flush_buffer.memory_layout_finished); | 4849 | assert(wasm.flush_buffer.memory_layout_finished); |
| 4128 | const comp = wasm.base.comp; | 4850 | const comp = wasm.base.comp; |
| 4129 | assert(comp.config.output_mode != .Obj); | 4851 | assert(comp.config.output_mode != .Obj); |
| ... | @@ -4139,23 +4861,34 @@ pub fn navAddr(wasm: *Wasm, nav_index: InternPool.Nav.Index) u32 { | ... | @@ -4139,23 +4861,34 @@ pub fn navAddr(wasm: *Wasm, nav_index: InternPool.Nav.Index) u32 { |
| 4139 | .@"extern" => |ext| if (wasm.getExistingString(ext.name.toSlice(ip))) |symbol_name| { | 4861 | .@"extern" => |ext| if (wasm.getExistingString(ext.name.toSlice(ip))) |symbol_name| { |
| 4140 | if (wasm.object_data_imports.getPtr(symbol_name)) |import| { | 4862 | if (wasm.object_data_imports.getPtr(symbol_name)) |import| { |
| 4141 | switch (import.resolution.unpack(wasm)) { | 4863 | switch (import.resolution.unpack(wasm)) { |
| 4142 | .unresolved => unreachable, | 4864 | .unresolved => {}, |
| 4143 | .object => |object_data_index| { | 4865 | .object => |object_data_index| { |
| 4144 | const object_data = object_data_index.ptr(wasm); | 4866 | const object_data = object_data_index.ptr(wasm); |
| 4145 | const ds_id: DataSegmentId = .fromObjectDataSegment(wasm, object_data.segment); | 4867 | const ds_id: DataSegmentId = .fromObjectDataSegment(wasm, object_data.segment); |
| 4146 | const segment_base_addr = wasm.flush_buffer.data_segments.get(ds_id).?; | 4868 | const segment_base_addr = wasm.flush_buffer.data_segments.get(ds_id).?; |
| 4147 | return segment_base_addr + object_data.offset; | 4869 | return segment_base_addr + object_data.offset; |
| 4148 | }, | 4870 | }, |
| 4149 | .__zig_error_names => @panic("TODO"), | 4871 | .__heap_base, |
| 4150 | .__zig_error_name_table => @panic("TODO"), | 4872 | .__heap_end, |
| 4151 | .__heap_base => @panic("TODO"), | 4873 | .uav_exe, |
| 4152 | .__heap_end => @panic("TODO"), | 4874 | .nav_exe, |
| 4153 | .uav_exe => @panic("TODO"), | 4875 | => { |
| 4154 | .uav_obj => @panic("TODO"), | 4876 | const data_loc = import.resolution.dataLoc(wasm); |
| 4155 | .nav_exe => @panic("TODO"), | 4877 | return wasm.flush_buffer.data_segments.get(data_loc.segment).? + data_loc.offset; |
| 4156 | .nav_obj => @panic("TODO"), | 4878 | }, |
| 4879 | .__zig_error_names, | ||
| 4880 | .__zig_error_name_table, | ||
| 4881 | .__zig_tag_names, | ||
| 4882 | .__zig_tag_name_table, | ||
| 4883 | .uav_obj, | ||
| 4884 | .nav_obj, | ||
| 4885 | => unreachable, | ||
| 4157 | } | 4886 | } |
| 4158 | } | 4887 | } |
| 4888 | if (wasm.flush_buffer.data_exports.get(symbol_name)) |symbol| { | ||
| 4889 | const data_loc = symbol.resolution.dataLoc(wasm); | ||
| 4890 | return wasm.flush_buffer.data_segments.get(data_loc.segment).? + data_loc.offset; | ||
| 4891 | } | ||
| 4159 | }, | 4892 | }, |
| 4160 | else => {}, | 4893 | else => {}, |
| 4161 | } | 4894 | } |
| ... | @@ -4177,8 +4910,12 @@ pub fn tagIndexTableAddr(wasm: *Wasm, ip_index: InternPool.Index) u32 { | ... | @@ -4177,8 +4910,12 @@ pub fn tagIndexTableAddr(wasm: *Wasm, ip_index: InternPool.Index) u32 { |
| 4177 | assert(comp.config.output_mode != .Obj); | 4910 | assert(comp.config.output_mode != .Obj); |
| 4178 | const f = &wasm.flush_buffer; | 4911 | const f = &wasm.flush_buffer; |
| 4179 | const table_base_addr = f.data_segments.get(.__zig_tag_name_table).?; | 4912 | const table_base_addr = f.data_segments.get(.__zig_tag_name_table).?; |
| 4180 | const table_index = f.enum_tag_name_table.get(ip_index).?; | 4913 | return table_base_addr + wasm.tagIndexTableOffset(ip_index); |
| 4181 | return table_base_addr + table_index * 8; | 4914 | } |
| 4915 | |||
| 4916 | pub fn tagIndexTableOffset(wasm: *const Wasm, ip_index: InternPool.Index) u32 { | ||
| 4917 | const table_index = wasm.flush_buffer.enum_tag_name_table.get(ip_index).?; | ||
| 4918 | return table_index * wasm.pointerSize() * 2; | ||
| 4182 | } | 4919 | } |
| 4183 | 4920 | ||
| 4184 | fn convertZcuFnType( | 4921 | fn convertZcuFnType( |
| ... | @@ -4201,12 +4938,15 @@ fn convertZcuFnType( | ... | @@ -4201,12 +4938,15 @@ fn convertZcuFnType( |
| 4201 | try params_buffer.append(gpa, .i32); // memory address is always a 32-bit handle | 4938 | try params_buffer.append(gpa, .i32); // memory address is always a 32-bit handle |
| 4202 | } else if (return_type.hasRuntimeBits(zcu)) { | 4939 | } else if (return_type.hasRuntimeBits(zcu)) { |
| 4203 | if (cc == .wasm_mvp) { | 4940 | if (cc == .wasm_mvp) { |
| 4204 | switch (abi.classifyType(return_type, zcu)) { | 4941 | switch (abi.classifyType(return_type, zcu, target)) { |
| 4205 | .direct => |scalar_ty| { | 4942 | .direct => |scalar_type| { |
| 4206 | assert(!abi.lowerAsDoubleI64(scalar_ty, zcu)); | 4943 | try returns_buffer.append(gpa, CodeGen.typeToValtype(scalar_type, zcu, target)); |
| 4207 | try returns_buffer.append(gpa, CodeGen.typeToValtype(scalar_ty, zcu, target)); | 4944 | }, |
| 4945 | .double_i64, .indirect => unreachable, | ||
| 4946 | .unrolled => |vector| { | ||
| 4947 | assert(vector.len == 1); | ||
| 4948 | try returns_buffer.append(gpa, CodeGen.typeToValtype(vector.elem_type, zcu, target)); | ||
| 4208 | }, | 4949 | }, |
| 4209 | .indirect => unreachable, | ||
| 4210 | } | 4950 | } |
| 4211 | } else { | 4951 | } else { |
| 4212 | try returns_buffer.append(gpa, CodeGen.typeToValtype(return_type, zcu, target)); | 4952 | try returns_buffer.append(gpa, CodeGen.typeToValtype(return_type, zcu, target)); |
| ... | @@ -4222,16 +4962,22 @@ fn convertZcuFnType( | ... | @@ -4222,16 +4962,22 @@ fn convertZcuFnType( |
| 4222 | 4962 | ||
| 4223 | switch (cc) { | 4963 | switch (cc) { |
| 4224 | .wasm_mvp => { | 4964 | .wasm_mvp => { |
| 4225 | switch (abi.classifyType(param_type, zcu)) { | 4965 | switch (abi.classifyType(param_type, zcu, target)) { |
| 4226 | .direct => |scalar_ty| { | 4966 | .direct => |scalar_type| { |
| 4227 | if (!abi.lowerAsDoubleI64(scalar_ty, zcu)) { | 4967 | try params_buffer.append(gpa, CodeGen.typeToValtype(scalar_type, zcu, target)); |
| 4228 | try params_buffer.append(gpa, CodeGen.typeToValtype(scalar_ty, zcu, target)); | 4968 | }, |
| 4229 | } else { | 4969 | .double_i64 => { |
| 4230 | try params_buffer.append(gpa, .i64); | 4970 | try params_buffer.append(gpa, .i64); |
| 4231 | try params_buffer.append(gpa, .i64); | 4971 | try params_buffer.append(gpa, .i64); |
| 4972 | }, | ||
| 4973 | .indirect => { | ||
| 4974 | try params_buffer.append(gpa, CodeGen.typeToValtype(param_type, zcu, target)); | ||
| 4975 | }, | ||
| 4976 | .unrolled => |vector| { | ||
| 4977 | for (0..vector.len) |_| { | ||
| 4978 | try params_buffer.append(gpa, CodeGen.typeToValtype(vector.elem_type, zcu, target)); | ||
| 4232 | } | 4979 | } |
| 4233 | }, | 4980 | }, |
| 4234 | .indirect => try params_buffer.append(gpa, CodeGen.typeToValtype(param_type, zcu, target)), | ||
| 4235 | } | 4981 | } |
| 4236 | }, | 4982 | }, |
| 4237 | else => try params_buffer.append(gpa, CodeGen.typeToValtype(param_type, zcu, target)), | 4983 | else => try params_buffer.append(gpa, CodeGen.typeToValtype(param_type, zcu, target)), |
| ... | @@ -4255,7 +5001,7 @@ pub fn isBss(wasm: *const Wasm, optional_name: OptionalString) bool { | ... | @@ -4255,7 +5001,7 @@ pub fn isBss(wasm: *const Wasm, optional_name: OptionalString) bool { |
| 4255 | /// those entries. | 5001 | /// those entries. |
| 4256 | fn lowerZcuData(wasm: *Wasm, pt: Zcu.PerThread, ip_index: InternPool.Index) !ZcuDataObj { | 5002 | fn lowerZcuData(wasm: *Wasm, pt: Zcu.PerThread, ip_index: InternPool.Index) !ZcuDataObj { |
| 4257 | const code_start: u32 = @intCast(wasm.string_bytes.items.len); | 5003 | const code_start: u32 = @intCast(wasm.string_bytes.items.len); |
| 4258 | const relocs_start: u32 = @intCast(wasm.out_relocs.len); | 5004 | const relocs_start: u32 = @intCast(wasm.zcu_relocations.len); |
| 4259 | const uav_fixups_start: u32 = @intCast(wasm.uav_fixups.items.len); | 5005 | const uav_fixups_start: u32 = @intCast(wasm.uav_fixups.items.len); |
| 4260 | const nav_fixups_start: u32 = @intCast(wasm.nav_fixups.items.len); | 5006 | const nav_fixups_start: u32 = @intCast(wasm.nav_fixups.items.len); |
| 4261 | const func_table_fixups_start: u32 = @intCast(wasm.func_table_fixups.items.len); | 5007 | const func_table_fixups_start: u32 = @intCast(wasm.func_table_fixups.items.len); |
| ... | @@ -4271,8 +5017,9 @@ fn lowerZcuData(wasm: *Wasm, pt: Zcu.PerThread, ip_index: InternPool.Index) !Zcu | ... | @@ -4271,8 +5017,9 @@ fn lowerZcuData(wasm: *Wasm, pt: Zcu.PerThread, ip_index: InternPool.Index) !Zcu |
| 4271 | } | 5017 | } |
| 4272 | 5018 | ||
| 4273 | const code_len: u32 = @intCast(wasm.string_bytes.items.len - code_start); | 5019 | const code_len: u32 = @intCast(wasm.string_bytes.items.len - code_start); |
| 4274 | const relocs_len: u32 = @intCast(wasm.out_relocs.len - relocs_start); | 5020 | const relocs_len: u32 = @intCast(wasm.zcu_relocations.len - relocs_start); |
| 4275 | const any_fixups = | 5021 | const any_fixups = |
| 5022 | relocs_len != 0 or | ||
| 4276 | uav_fixups_start != wasm.uav_fixups.items.len or | 5023 | uav_fixups_start != wasm.uav_fixups.items.len or |
| 4277 | nav_fixups_start != wasm.nav_fixups.items.len or | 5024 | nav_fixups_start != wasm.nav_fixups.items.len or |
| 4278 | func_table_fixups_start != wasm.func_table_fixups.items.len; | 5025 | func_table_fixups_start != wasm.func_table_fixups.items.len; |
src/link/Wasm/Archive.zig+1-1| ... | @@ -45,7 +45,7 @@ const Header = extern struct { | ... | @@ -45,7 +45,7 @@ const Header = extern struct { |
| 45 | 45 | ||
| 46 | fn nameOrIndex(archive: Header) !NameOrIndex { | 46 | fn nameOrIndex(archive: Header) !NameOrIndex { |
| 47 | const value = getValue(&archive.name); | 47 | const value = getValue(&archive.name); |
| 48 | const slash_index = mem.indexOfScalar(u8, value, '/') orelse return error.MalformedArchive; | 48 | const slash_index = mem.findScalar(u8, value, '/') orelse return error.MalformedArchive; |
| 49 | const len = value.len; | 49 | const len = value.len; |
| 50 | if (slash_index == len - 1) { | 50 | if (slash_index == len - 1) { |
| 51 | // Name stored directly | 51 | // Name stored directly |
src/link/Wasm/Flush.zig+1148-137| ... | @@ -7,7 +7,6 @@ const Object = @import("Object.zig"); | ... | @@ -7,7 +7,6 @@ const Object = @import("Object.zig"); |
| 7 | const Zcu = @import("../../Zcu.zig"); | 7 | const Zcu = @import("../../Zcu.zig"); |
| 8 | const Alignment = Wasm.Alignment; | 8 | const Alignment = Wasm.Alignment; |
| 9 | const String = Wasm.String; | 9 | const String = Wasm.String; |
| 10 | const Relocation = Wasm.Relocation; | ||
| 11 | const InternPool = @import("../../InternPool.zig"); | 10 | const InternPool = @import("../../InternPool.zig"); |
| 12 | const Mir = @import("../../codegen/wasm/Mir.zig"); | 11 | const Mir = @import("../../codegen/wasm/Mir.zig"); |
| 13 | 12 | ||
| ... | @@ -33,8 +32,13 @@ data_segment_groups: ArrayList(DataSegmentGroup) = .empty, | ... | @@ -33,8 +32,13 @@ data_segment_groups: ArrayList(DataSegmentGroup) = .empty, |
| 33 | binary_bytes: ArrayList(u8) = .empty, | 32 | binary_bytes: ArrayList(u8) = .empty, |
| 34 | missing_exports: std.array_hash_map.Auto(String, void) = .empty, | 33 | missing_exports: std.array_hash_map.Auto(String, void) = .empty, |
| 35 | function_imports: std.array_hash_map.Auto(String, Wasm.FunctionImportId) = .empty, | 34 | function_imports: std.array_hash_map.Auto(String, Wasm.FunctionImportId) = .empty, |
| 35 | intrinsic_function_imports: std.array_hash_map.Auto(String, Wasm.FunctionType.Index) = .empty, | ||
| 36 | /// Function aliases emitted after function symbols. | ||
| 37 | function_export_symbols: std.array_hash_map.Auto(String, FunctionExportSymbol) = .empty, | ||
| 36 | global_imports: std.array_hash_map.Auto(String, Wasm.GlobalImportId) = .empty, | 38 | global_imports: std.array_hash_map.Auto(String, Wasm.GlobalImportId) = .empty, |
| 37 | data_imports: std.array_hash_map.Auto(String, Wasm.DataImportId) = .empty, | 39 | data_imports: std.array_hash_map.Auto(String, Wasm.DataImportId) = .empty, |
| 40 | /// Data aliases emitted after data symbols. | ||
| 41 | data_exports: std.array_hash_map.Auto(String, DataExportSymbol) = .empty, | ||
| 38 | 42 | ||
| 39 | indirect_function_table: std.array_hash_map.Auto(Wasm.OutputFunctionIndex, void) = .empty, | 43 | indirect_function_table: std.array_hash_map.Auto(Wasm.OutputFunctionIndex, void) = .empty, |
| 40 | 44 | ||
| ... | @@ -43,6 +47,9 @@ func_types: std.array_hash_map.Auto(Wasm.FunctionType.Index, void) = .empty, | ... | @@ -43,6 +47,9 @@ func_types: std.array_hash_map.Auto(Wasm.FunctionType.Index, void) = .empty, |
| 43 | 47 | ||
| 44 | enum_tag_name_table: std.array_hash_map.Auto(InternPool.Index, u32) = .empty, | 48 | enum_tag_name_table: std.array_hash_map.Auto(InternPool.Index, u32) = .empty, |
| 45 | 49 | ||
| 50 | code_relocs: std.ArrayList(Relocation) = .empty, | ||
| 51 | data_relocs: std.ArrayList(Relocation) = .empty, | ||
| 52 | |||
| 46 | /// For debug purposes only. | 53 | /// For debug purposes only. |
| 47 | memory_layout_finished: bool = false, | 54 | memory_layout_finished: bool = false, |
| 48 | 55 | ||
| ... | @@ -55,6 +62,74 @@ pub const FuncTypeIndex = enum(u32) { | ... | @@ -55,6 +62,74 @@ pub const FuncTypeIndex = enum(u32) { |
| 55 | } | 62 | } |
| 56 | }; | 63 | }; |
| 57 | 64 | ||
| 65 | /// Index into SYMTAB_FUNCTION. | ||
| 66 | const FunctionSymbolIndex = enum(u32) { | ||
| 67 | _, | ||
| 68 | |||
| 69 | fn fromOutputFunctionIndex(i: Wasm.OutputFunctionIndex) FunctionSymbolIndex { | ||
| 70 | return @fromBackingInt(@backingInt(i)); | ||
| 71 | } | ||
| 72 | |||
| 73 | fn fromObjectFunctionHandlingWeak(wasm: *const Wasm, index: Wasm.ObjectFunctionIndex) FunctionSymbolIndex { | ||
| 74 | return fromOutputFunctionIndex(.fromObjectFunctionHandlingWeak(wasm, index)); | ||
| 75 | } | ||
| 76 | |||
| 77 | fn fromIpNav(wasm: *const Wasm, nav_index: InternPool.Nav.Index) FunctionSymbolIndex { | ||
| 78 | return fromOutputFunctionIndex(.fromIpNav(wasm, nav_index)); | ||
| 79 | } | ||
| 80 | |||
| 81 | fn fromTagIndexType(wasm: *const Wasm, ip_index: InternPool.Index) FunctionSymbolIndex { | ||
| 82 | return fromOutputFunctionIndex(.fromTagIndexType(wasm, ip_index)); | ||
| 83 | } | ||
| 84 | |||
| 85 | fn fromSymbolName(wasm: *const Wasm, name: String) FunctionSymbolIndex { | ||
| 86 | const f = &wasm.flush_buffer; | ||
| 87 | if (f.function_imports.getIndex(name)) |i| return @fromBackingInt(@intCast(i)); | ||
| 88 | if (f.intrinsic_function_imports.getIndex(name)) |i| return @fromBackingInt(@intCast( | ||
| 89 | f.function_imports.entries.len + i, | ||
| 90 | )); | ||
| 91 | if (f.function_export_symbols.getIndex(name)) |i| return @fromBackingInt(@intCast( | ||
| 92 | f.function_imports.entries.len + f.intrinsic_function_imports.entries.len + | ||
| 93 | wasm.functions.entries.len + i, | ||
| 94 | )); | ||
| 95 | return fromOutputFunctionIndex(.fromSymbolName(wasm, name)); | ||
| 96 | } | ||
| 97 | }; | ||
| 98 | |||
| 99 | /// Index into SYMTAB_DATA. | ||
| 100 | const DataSymbolIndex = enum(u32) { | ||
| 101 | _, | ||
| 102 | |||
| 103 | fn fromOutputDataIndex(i: Wasm.OutputDataIndex) DataSymbolIndex { | ||
| 104 | return @fromBackingInt(@backingInt(i)); | ||
| 105 | } | ||
| 106 | |||
| 107 | fn fromResolution(wasm: *const Wasm, resolution: Wasm.ObjectDataImport.Resolution) DataSymbolIndex { | ||
| 108 | return fromOutputDataIndex(Wasm.OutputDataIndex.fromResolution(wasm, resolution).?); | ||
| 109 | } | ||
| 110 | |||
| 111 | fn fromObjectData(wasm: *const Wasm, index: Wasm.ObjectData.Index) DataSymbolIndex { | ||
| 112 | return fromOutputDataIndex(.fromObjectData(wasm, index)); | ||
| 113 | } | ||
| 114 | |||
| 115 | fn fromUav(wasm: *const Wasm, ip_index: InternPool.Index) DataSymbolIndex { | ||
| 116 | return fromOutputDataIndex(.fromUav(wasm, ip_index)); | ||
| 117 | } | ||
| 118 | |||
| 119 | fn fromNav(wasm: *const Wasm, nav_index: InternPool.Nav.Index) DataSymbolIndex { | ||
| 120 | return fromOutputDataIndex(.fromNav(wasm, nav_index)); | ||
| 121 | } | ||
| 122 | |||
| 123 | fn fromSymbolName(wasm: *const Wasm, name: String) DataSymbolIndex { | ||
| 124 | const f = &wasm.flush_buffer; | ||
| 125 | if (f.data_imports.getIndex(name)) |i| return @fromBackingInt(@intCast(i)); | ||
| 126 | if (f.data_exports.getIndex(name)) |i| return @fromBackingInt(@intCast( | ||
| 127 | f.data_imports.entries.len + wasm.datas.entries.len + i, | ||
| 128 | )); | ||
| 129 | return fromOutputDataIndex(.fromSymbolName(wasm, name)); | ||
| 130 | } | ||
| 131 | }; | ||
| 132 | |||
| 58 | /// Index into `indirect_function_table`. | 133 | /// Index into `indirect_function_table`. |
| 59 | const IndirectFunctionTableIndex = enum(u32) { | 134 | const IndirectFunctionTableIndex = enum(u32) { |
| 60 | _, | 135 | _, |
| ... | @@ -71,9 +146,8 @@ const IndirectFunctionTableIndex = enum(u32) { | ... | @@ -71,9 +146,8 @@ const IndirectFunctionTableIndex = enum(u32) { |
| 71 | return @fromBackingInt(@intCast(f.indirect_function_table.getIndex(i).?)); | 146 | return @fromBackingInt(@intCast(f.indirect_function_table.getIndex(i).?)); |
| 72 | } | 147 | } |
| 73 | 148 | ||
| 74 | fn fromZcuIndirectFunctionSetIndex(i: Wasm.ZcuIndirectFunctionSetIndex) IndirectFunctionTableIndex { | 149 | fn fromIpNav(wasm: *const Wasm, nav_index: InternPool.Nav.Index) IndirectFunctionTableIndex { |
| 75 | // These are the same since those are added to the table first. | 150 | return fromOutputFunctionIndex(&wasm.flush_buffer, .fromIpNav(wasm, nav_index)); |
| 76 | return @fromBackingInt(@intCast(@backingInt(i))); | ||
| 77 | } | 151 | } |
| 78 | 152 | ||
| 79 | fn toAbi(i: IndirectFunctionTableIndex) u32 { | 153 | fn toAbi(i: IndirectFunctionTableIndex) u32 { |
| ... | @@ -81,6 +155,39 @@ const IndirectFunctionTableIndex = enum(u32) { | ... | @@ -81,6 +155,39 @@ const IndirectFunctionTableIndex = enum(u32) { |
| 81 | } | 155 | } |
| 82 | }; | 156 | }; |
| 83 | 157 | ||
| 158 | const SymbolTableOffsets = struct { | ||
| 159 | function: u32, | ||
| 160 | data: u32, | ||
| 161 | global: u32, | ||
| 162 | table: u32, | ||
| 163 | }; | ||
| 164 | |||
| 165 | const FunctionExportSymbol = struct { | ||
| 166 | function_index: Wasm.FunctionIndex, | ||
| 167 | flags: Wasm.SymbolFlags, | ||
| 168 | }; | ||
| 169 | |||
| 170 | const DataExportSymbol = struct { | ||
| 171 | resolution: Wasm.ObjectDataImport.Resolution, | ||
| 172 | flags: Wasm.SymbolFlags, | ||
| 173 | }; | ||
| 174 | |||
| 175 | const Relocation = struct { | ||
| 176 | tag: Object.RelocationType, | ||
| 177 | offset: u32, | ||
| 178 | pointee: Pointee, | ||
| 179 | addend: i32, | ||
| 180 | |||
| 181 | const Pointee = union { | ||
| 182 | data: DataSymbolIndex, | ||
| 183 | type_index: FuncTypeIndex, | ||
| 184 | section: Wasm.ObjectSectionIndex, | ||
| 185 | function: FunctionSymbolIndex, | ||
| 186 | global: Wasm.GlobalIndex, | ||
| 187 | table: Wasm.TableIndex, | ||
| 188 | }; | ||
| 189 | }; | ||
| 190 | |||
| 84 | const DataSegmentGroup = struct { | 191 | const DataSegmentGroup = struct { |
| 85 | first_segment: Wasm.DataSegmentId, | 192 | first_segment: Wasm.DataSegmentId, |
| 86 | end_addr: u32, | 193 | end_addr: u32, |
| ... | @@ -90,9 +197,14 @@ pub fn clear(f: *Flush) void { | ... | @@ -90,9 +197,14 @@ pub fn clear(f: *Flush) void { |
| 90 | f.data_segments.clearRetainingCapacity(); | 197 | f.data_segments.clearRetainingCapacity(); |
| 91 | f.data_segment_groups.clearRetainingCapacity(); | 198 | f.data_segment_groups.clearRetainingCapacity(); |
| 92 | f.binary_bytes.clearRetainingCapacity(); | 199 | f.binary_bytes.clearRetainingCapacity(); |
| 200 | f.intrinsic_function_imports.clearRetainingCapacity(); | ||
| 201 | f.function_export_symbols.clearRetainingCapacity(); | ||
| 202 | f.data_exports.clearRetainingCapacity(); | ||
| 93 | f.indirect_function_table.clearRetainingCapacity(); | 203 | f.indirect_function_table.clearRetainingCapacity(); |
| 94 | f.func_types.clearRetainingCapacity(); | 204 | f.func_types.clearRetainingCapacity(); |
| 95 | f.enum_tag_name_table.clearRetainingCapacity(); | 205 | f.enum_tag_name_table.clearRetainingCapacity(); |
| 206 | f.code_relocs.clearRetainingCapacity(); | ||
| 207 | f.data_relocs.clearRetainingCapacity(); | ||
| 96 | f.memory_layout_finished = false; | 208 | f.memory_layout_finished = false; |
| 97 | } | 209 | } |
| 98 | 210 | ||
| ... | @@ -102,11 +214,16 @@ pub fn deinit(f: *Flush, gpa: Allocator) void { | ... | @@ -102,11 +214,16 @@ pub fn deinit(f: *Flush, gpa: Allocator) void { |
| 102 | f.binary_bytes.deinit(gpa); | 214 | f.binary_bytes.deinit(gpa); |
| 103 | f.missing_exports.deinit(gpa); | 215 | f.missing_exports.deinit(gpa); |
| 104 | f.function_imports.deinit(gpa); | 216 | f.function_imports.deinit(gpa); |
| 217 | f.intrinsic_function_imports.deinit(gpa); | ||
| 218 | f.function_export_symbols.deinit(gpa); | ||
| 105 | f.global_imports.deinit(gpa); | 219 | f.global_imports.deinit(gpa); |
| 106 | f.data_imports.deinit(gpa); | 220 | f.data_imports.deinit(gpa); |
| 221 | f.data_exports.deinit(gpa); | ||
| 107 | f.indirect_function_table.deinit(gpa); | 222 | f.indirect_function_table.deinit(gpa); |
| 108 | f.func_types.deinit(gpa); | 223 | f.func_types.deinit(gpa); |
| 109 | f.enum_tag_name_table.deinit(gpa); | 224 | f.enum_tag_name_table.deinit(gpa); |
| 225 | f.code_relocs.deinit(gpa); | ||
| 226 | f.data_relocs.deinit(gpa); | ||
| 110 | f.* = undefined; | 227 | f.* = undefined; |
| 111 | } | 228 | } |
| 112 | 229 | ||
| ... | @@ -131,51 +248,12 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -131,51 +248,12 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 131 | 248 | ||
| 132 | if (comp.zcu) |zcu| { | 249 | if (comp.zcu) |zcu| { |
| 133 | const ip: *const InternPool = &zcu.intern_pool; // No mutations allowed! | 250 | const ip: *const InternPool = &zcu.intern_pool; // No mutations allowed! |
| 251 | const function_imports_start = wasm.function_imports.entries.len; | ||
| 252 | const global_imports_start = wasm.global_imports.entries.len; | ||
| 253 | const data_imports_start = wasm.data_imports.entries.len; | ||
| 134 | 254 | ||
| 135 | log.debug("total MIR instructions: {d}", .{wasm.mir_instructions.len}); | 255 | log.debug("total MIR instructions: {d}", .{wasm.mir_instructions.len}); |
| 136 | 256 | ||
| 137 | // Detect any intrinsics that were called; they need to have dependencies on the symbols marked. | ||
| 138 | // Likewise detect `@tagName` calls so those functions can be included in the output and synthesized. | ||
| 139 | for (wasm.mir_instructions.items(.tag), wasm.mir_instructions.items(.data)) |tag, *data| switch (tag) { | ||
| 140 | .call_intrinsic => { | ||
| 141 | const symbol_name = try wasm.internString(@tagName(data.intrinsic)); | ||
| 142 | const i: Wasm.FunctionImport.Index = @fromBackingInt(@intCast(wasm.object_function_imports.getIndex(symbol_name) orelse { | ||
| 143 | return diags.fail("missing compiler runtime intrinsic '{t}' (undefined linker symbol)", .{ | ||
| 144 | data.intrinsic, | ||
| 145 | }); | ||
| 146 | })); | ||
| 147 | try wasm.markFunctionImport(symbol_name, i.value(wasm), i); | ||
| 148 | log.debug("markFunctionImport intrinsic {d}={t}", .{ i, data.intrinsic }); | ||
| 149 | }, | ||
| 150 | .call_tag_index => { | ||
| 151 | assert(ip.indexToKey(data.ip_index) == .enum_type); | ||
| 152 | const gop = try wasm.zcu_funcs.getOrPut(gpa, data.ip_index); | ||
| 153 | if (!gop.found_existing) { | ||
| 154 | const int_tag_ty = Zcu.Type.fromInterned(data.ip_index).backingIntType(zcu); | ||
| 155 | gop.value_ptr.* = .{ .tag_name = .{ | ||
| 156 | .symbol_name = try wasm.internStringFmt("__zig_tag_index_{d}", .{data.ip_index}), | ||
| 157 | .type_index = try wasm.internFunctionType(.auto, &.{int_tag_ty.ip_index}, .u32, false, target), | ||
| 158 | } }; | ||
| 159 | } | ||
| 160 | try wasm.functions.put(gpa, .fromZcuFunc(wasm, @fromBackingInt(@intCast(gop.index))), {}); | ||
| 161 | }, | ||
| 162 | .enum_tag_name_table_ref => { | ||
| 163 | assert(ip.indexToKey(data.ip_index) == .enum_type); | ||
| 164 | const gop = try f.enum_tag_name_table.getOrPut(gpa, data.ip_index); | ||
| 165 | if (!gop.found_existing) { | ||
| 166 | wasm.tag_name_table_ref_count += 1; | ||
| 167 | gop.value_ptr.* = @intCast(wasm.tag_name_offs.items.len); | ||
| 168 | const tag_names = ip.loadEnumType(data.ip_index).field_names; | ||
| 169 | for (tag_names.get(ip)) |tag_name| { | ||
| 170 | const slice = tag_name.toSlice(ip); | ||
| 171 | try wasm.tag_name_offs.append(gpa, @intCast(wasm.tag_name_bytes.items.len)); | ||
| 172 | try wasm.tag_name_bytes.appendSlice(gpa, slice[0 .. slice.len + 1]); | ||
| 173 | } | ||
| 174 | } | ||
| 175 | }, | ||
| 176 | else => continue, | ||
| 177 | }; | ||
| 178 | |||
| 179 | { | 257 | { |
| 180 | var i = wasm.function_imports_len_prelink; | 258 | var i = wasm.function_imports_len_prelink; |
| 181 | while (i < f.function_imports.entries.len) { | 259 | while (i < f.function_imports.entries.len) { |
| ... | @@ -225,10 +303,24 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -225,10 +303,24 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 225 | log.debug("flush export '{s}' nav={d}", .{ nav_export.name.slice(wasm), nav_export.nav_index }); | 303 | log.debug("flush export '{s}' nav={d}", .{ nav_export.name.slice(wasm), nav_export.nav_index }); |
| 226 | const function_index = Wasm.FunctionIndex.fromIpNav(wasm, nav_export.nav_index).?; | 304 | const function_index = Wasm.FunctionIndex.fromIpNav(wasm, nav_export.nav_index).?; |
| 227 | const explicit = f.missing_exports.swapRemove(nav_export.name); | 305 | const explicit = f.missing_exports.swapRemove(nav_export.name); |
| 228 | const is_hidden = !explicit and switch (export_index.ptr(zcu).opts.visibility) { | 306 | const opts = export_index.ptr(zcu).opts; |
| 307 | const is_hidden = !explicit and switch (opts.visibility) { | ||
| 229 | .hidden => true, | 308 | .hidden => true, |
| 230 | .default, .protected => false, | 309 | .default, .protected => false, |
| 231 | }; | 310 | }; |
| 311 | if (is_obj) try f.function_export_symbols.put(gpa, nav_export.name, .{ | ||
| 312 | .function_index = function_index, | ||
| 313 | .flags = .{ | ||
| 314 | .binding = switch (opts.linkage) { | ||
| 315 | .internal => .local, | ||
| 316 | .strong => .strong, | ||
| 317 | .weak => .weak, | ||
| 318 | .link_once => @panic("TODO: COMDAT"), | ||
| 319 | }, | ||
| 320 | .visibility_hidden = is_hidden, | ||
| 321 | .exported = !is_hidden, | ||
| 322 | }, | ||
| 323 | }); | ||
| 232 | if (is_hidden) { | 324 | if (is_hidden) { |
| 233 | try wasm.hidden_function_exports.put(gpa, nav_export.name, function_index); | 325 | try wasm.hidden_function_exports.put(gpa, nav_export.name, function_index); |
| 234 | } else { | 326 | } else { |
| ... | @@ -239,17 +331,170 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -239,17 +331,170 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 239 | if (nav_export.name.toOptional() == entry_name) | 331 | if (nav_export.name.toOptional() == entry_name) |
| 240 | wasm.entry_resolution = .fromIpNav(wasm, nav_export.nav_index); | 332 | wasm.entry_resolution = .fromIpNav(wasm, nav_export.nav_index); |
| 241 | } else { | 333 | } else { |
| 242 | // This is a data export because Zcu currently has no way to | 334 | // data exports are linker symbols |
| 243 | // export wasm globals. | 335 | // explicit exports become address globals |
| 244 | _ = f.missing_exports.swapRemove(nav_export.name); | 336 | const explicit = f.missing_exports.swapRemove(nav_export.name); |
| 337 | const opts = export_index.ptr(zcu).opts; | ||
| 338 | try f.data_exports.put(gpa, nav_export.name, .{ | ||
| 339 | .resolution = .fromIpNav(wasm, nav_export.nav_index), | ||
| 340 | .flags = if (is_obj) .{ | ||
| 341 | .binding = switch (opts.linkage) { | ||
| 342 | .internal => .local, | ||
| 343 | .strong => .strong, | ||
| 344 | .weak => .weak, | ||
| 345 | .link_once => @panic("TODO: COMDAT"), | ||
| 346 | }, | ||
| 347 | .visibility_hidden = !explicit and switch (opts.visibility) { | ||
| 348 | .default => false, | ||
| 349 | .hidden => true, | ||
| 350 | .protected => false, | ||
| 351 | }, | ||
| 352 | .exported = explicit, | ||
| 353 | .tls = ip.getNav(nav_export.nav_index).resolved.?.@"threadlocal", | ||
| 354 | } else .{}, | ||
| 355 | }); | ||
| 245 | _ = f.data_imports.swapRemove(nav_export.name); | 356 | _ = f.data_imports.swapRemove(nav_export.name); |
| 246 | if (!is_obj) { | 357 | if (explicit and !is_obj) { |
| 247 | diags.addError("unable to export data symbol '{s}'; not emitting a relocatable", .{ | 358 | const global_resolution: Wasm.GlobalImport.Resolution = .fromIpNav( |
| 248 | nav_export.name.slice(wasm), | 359 | wasm, |
| 360 | nav_export.nav_index, | ||
| 361 | ); | ||
| 362 | try wasm.globals.put(gpa, global_resolution, {}); | ||
| 363 | try wasm.global_exports.append(gpa, .{ | ||
| 364 | .name = nav_export.name, | ||
| 365 | .global_index = Wasm.GlobalIndex.fromResolution(wasm, global_resolution).?, | ||
| 249 | }); | 366 | }); |
| 250 | } | 367 | } |
| 251 | } | 368 | } |
| 252 | } | 369 | } |
| 370 | // handle exported values without navs | ||
| 371 | for (wasm.uav_exports.keys(), wasm.uav_exports.values()) |uav_export, export_index| { | ||
| 372 | assert(!ip.isFunctionType(ip.typeOf(uav_export.uav_index))); | ||
| 373 | const explicit = f.missing_exports.swapRemove(uav_export.name); | ||
| 374 | const opts = export_index.ptr(zcu).opts; | ||
| 375 | try f.data_exports.put(gpa, uav_export.name, .{ | ||
| 376 | .resolution = .fromIpIndex(wasm, uav_export.uav_index), | ||
| 377 | .flags = if (is_obj) .{ | ||
| 378 | .binding = switch (opts.linkage) { | ||
| 379 | .internal => .local, | ||
| 380 | .strong => .strong, | ||
| 381 | .weak => .weak, | ||
| 382 | .link_once => @panic("TODO: COMDAT"), | ||
| 383 | }, | ||
| 384 | .visibility_hidden = !explicit and switch (opts.visibility) { | ||
| 385 | .default => false, | ||
| 386 | .hidden => true, | ||
| 387 | .protected => false, | ||
| 388 | }, | ||
| 389 | .exported = explicit, | ||
| 390 | } else .{}, | ||
| 391 | }); | ||
| 392 | _ = f.data_imports.swapRemove(uav_export.name); | ||
| 393 | if (explicit and !is_obj) { | ||
| 394 | const global_resolution: Wasm.GlobalImport.Resolution = .fromIpIndex( | ||
| 395 | wasm, | ||
| 396 | uav_export.uav_index, | ||
| 397 | ); | ||
| 398 | try wasm.globals.put(gpa, global_resolution, {}); | ||
| 399 | try wasm.global_exports.append(gpa, .{ | ||
| 400 | .name = uav_export.name, | ||
| 401 | .global_index = Wasm.GlobalIndex.fromResolution(wasm, global_resolution).?, | ||
| 402 | }); | ||
| 403 | } | ||
| 404 | } | ||
| 405 | |||
| 406 | // Detect any intrinsics that were called; they need to have dependencies on the symbols marked. | ||
| 407 | // Likewise detect `@tagName` calls so those functions can be included in the output and synthesized. | ||
| 408 | for (wasm.mir_instructions.items(.tag), wasm.mir_instructions.items(.data)) |tag, *data| switch (tag) { | ||
| 409 | .call_intrinsic => { | ||
| 410 | const symbol_name = try wasm.internString(@tagName(data.intrinsic)); | ||
| 411 | if (Wasm.FunctionIndex.fromSymbolName(wasm, symbol_name) == null and | ||
| 412 | !f.function_imports.contains(symbol_name)) | ||
| 413 | { | ||
| 414 | if (wasm.object_function_imports.getIndex(symbol_name)) |object_import_index| { | ||
| 415 | const i: Wasm.FunctionImport.Index = @fromBackingInt(@intCast(object_import_index)); | ||
| 416 | try wasm.markFunctionImport(symbol_name, i.value(wasm), i); | ||
| 417 | if (Wasm.FunctionIndex.fromSymbolName(wasm, symbol_name) == null) { | ||
| 418 | try f.function_imports.put(gpa, symbol_name, .fromObject(i, wasm)); | ||
| 419 | } | ||
| 420 | } else if (is_obj) { | ||
| 421 | const gop = try f.intrinsic_function_imports.getOrPut(gpa, symbol_name); | ||
| 422 | if (!gop.found_existing) gop.value_ptr.* = try wasm.intrinsicFunctionType(data.intrinsic); | ||
| 423 | } else { | ||
| 424 | return diags.fail("missing compiler runtime intrinsic '{t}' (undefined linker symbol)", .{ | ||
| 425 | data.intrinsic, | ||
| 426 | }); | ||
| 427 | } | ||
| 428 | } | ||
| 429 | }, | ||
| 430 | .call_indirect => { | ||
| 431 | const fn_info = zcu.typeToFunc(.fromInterned(data.ip_index)).?; | ||
| 432 | const type_index = wasm.getExistingFunctionType( | ||
| 433 | fn_info.cc, | ||
| 434 | fn_info.param_types.get(ip), | ||
| 435 | .fromInterned(fn_info.return_type), | ||
| 436 | fn_info.is_var_args, | ||
| 437 | target, | ||
| 438 | ).?; | ||
| 439 | try f.func_types.put(gpa, type_index, {}); | ||
| 440 | }, | ||
| 441 | .call_tag_index => { | ||
| 442 | assert(ip.indexToKey(data.ip_index) == .enum_type); | ||
| 443 | const gop = try wasm.zcu_funcs.getOrPut(gpa, data.ip_index); | ||
| 444 | if (!gop.found_existing) { | ||
| 445 | const int_tag_ty = Zcu.Type.fromInterned(data.ip_index).backingIntType(zcu); | ||
| 446 | gop.value_ptr.* = .{ .tag_name = .{ | ||
| 447 | .symbol_name = try wasm.internStringFmt("__zig_tag_index_{d}", .{data.ip_index}), | ||
| 448 | .type_index = try wasm.internFunctionType(.auto, &.{int_tag_ty.ip_index}, .u32, false, target), | ||
| 449 | } }; | ||
| 450 | } | ||
| 451 | try wasm.functions.put(gpa, .fromZcuFunc(wasm, @fromBackingInt(@intCast(gop.index))), {}); | ||
| 452 | }, | ||
| 453 | .enum_tag_name_table_ref => { | ||
| 454 | assert(ip.indexToKey(data.ip_index) == .enum_type); | ||
| 455 | const gop = try f.enum_tag_name_table.getOrPut(gpa, data.ip_index); | ||
| 456 | if (!gop.found_existing) { | ||
| 457 | wasm.tag_name_table_ref_count += 1; | ||
| 458 | gop.value_ptr.* = @intCast(wasm.tag_name_offs.items.len); | ||
| 459 | const tag_names = ip.loadEnumType(data.ip_index).field_names; | ||
| 460 | for (tag_names.get(ip)) |tag_name| { | ||
| 461 | const slice = tag_name.toSlice(ip); | ||
| 462 | try wasm.tag_name_offs.append(gpa, @intCast(wasm.tag_name_bytes.items.len)); | ||
| 463 | try wasm.tag_name_bytes.appendSlice(gpa, slice[0 .. slice.len + 1]); | ||
| 464 | } | ||
| 465 | } | ||
| 466 | }, | ||
| 467 | else => continue, | ||
| 468 | }; | ||
| 469 | |||
| 470 | // marking above may discover additional imports | ||
| 471 | try f.function_imports.ensureUnusedCapacity(gpa, wasm.function_imports.entries.len - function_imports_start); | ||
| 472 | for ( | ||
| 473 | wasm.function_imports.keys()[function_imports_start..], | ||
| 474 | wasm.function_imports.values()[function_imports_start..], | ||
| 475 | ) |name, id| { | ||
| 476 | if (!f.function_imports.contains(name) and Wasm.FunctionIndex.fromSymbolName(wasm, name) == null) { | ||
| 477 | f.function_imports.putAssumeCapacity(name, id); | ||
| 478 | } | ||
| 479 | } | ||
| 480 | |||
| 481 | try f.global_imports.ensureUnusedCapacity(gpa, wasm.global_imports.entries.len - global_imports_start); | ||
| 482 | for ( | ||
| 483 | wasm.global_imports.keys()[global_imports_start..], | ||
| 484 | wasm.global_imports.values()[global_imports_start..], | ||
| 485 | ) |name, id| { | ||
| 486 | if (!f.global_imports.contains(name)) f.global_imports.putAssumeCapacity(name, id); | ||
| 487 | } | ||
| 488 | |||
| 489 | try f.data_imports.ensureUnusedCapacity(gpa, wasm.data_imports.entries.len - data_imports_start); | ||
| 490 | for ( | ||
| 491 | wasm.data_imports.keys()[data_imports_start..], | ||
| 492 | wasm.data_imports.values()[data_imports_start..], | ||
| 493 | ) |name, id| { | ||
| 494 | if (!f.data_imports.contains(name) and !f.data_exports.contains(name)) { | ||
| 495 | f.data_imports.putAssumeCapacity(name, id); | ||
| 496 | } | ||
| 497 | } | ||
| 253 | 498 | ||
| 254 | for (f.missing_exports.keys()) |exp_name| { | 499 | for (f.missing_exports.keys()) |exp_name| { |
| 255 | diags.addError("manually specified export name '{s}' undefined", .{exp_name.slice(wasm)}); | 500 | diags.addError("manually specified export name '{s}' undefined", .{exp_name.slice(wasm)}); |
| ... | @@ -300,7 +545,27 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -300,7 +545,27 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 300 | if (wasm.object_init_funcs.items.len > 0) { | 545 | if (wasm.object_init_funcs.items.len > 0) { |
| 301 | // Zig has no constructors so these are only for object file inputs. | 546 | // Zig has no constructors so these are only for object file inputs. |
| 302 | mem.sortUnstable(Wasm.InitFunc, wasm.object_init_funcs.items, {}, Wasm.InitFunc.lessThan); | 547 | mem.sortUnstable(Wasm.InitFunc, wasm.object_init_funcs.items, {}, Wasm.InitFunc.lessThan); |
| 303 | try wasm.functions.put(gpa, .__wasm_call_ctors, {}); | 548 | if (!is_obj) try wasm.functions.put(gpa, .__wasm_call_ctors, {}); |
| 549 | } | ||
| 550 | |||
| 551 | if (is_obj) { | ||
| 552 | try wasm.datas.ensureUnusedCapacity(gpa, wasm.uavs_obj.entries.len + wasm.navs_obj.entries.len + 4); | ||
| 553 | for (0..wasm.uavs_obj.entries.len) |i| wasm.datas.putAssumeCapacity( | ||
| 554 | .pack(wasm, .{ .uav_obj = @fromBackingInt(@intCast(i)) }), | ||
| 555 | {}, | ||
| 556 | ); | ||
| 557 | for (0..wasm.navs_obj.entries.len) |i| wasm.datas.putAssumeCapacity( | ||
| 558 | .pack(wasm, .{ .nav_obj = @fromBackingInt(@intCast(i)) }), | ||
| 559 | {}, | ||
| 560 | ); | ||
| 561 | if (wasm.error_name_table_ref_count > 0) { | ||
| 562 | wasm.datas.putAssumeCapacity(.__zig_error_names, {}); | ||
| 563 | wasm.datas.putAssumeCapacity(.__zig_error_name_table, {}); | ||
| 564 | } | ||
| 565 | if (wasm.tag_name_table_ref_count > 0) { | ||
| 566 | wasm.datas.putAssumeCapacity(.__zig_tag_names, {}); | ||
| 567 | wasm.datas.putAssumeCapacity(.__zig_tag_name_table, {}); | ||
| 568 | } | ||
| 304 | } | 569 | } |
| 305 | 570 | ||
| 306 | // Merge and order the data segments. Depends on garbage collection so that | 571 | // Merge and order the data segments. Depends on garbage collection so that |
| ... | @@ -341,14 +606,33 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -341,14 +606,33 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 341 | // dropped in __wasm_init_memory, which is registered as the start function | 606 | // dropped in __wasm_init_memory, which is registered as the start function |
| 342 | // We also initialize bss segments (using memory.fill) as part of this | 607 | // We also initialize bss segments (using memory.fill) as part of this |
| 343 | // function. | 608 | // function. |
| 344 | if (wasm.any_passive_inits) { | 609 | if (!is_obj and wasm.any_passive_inits) { |
| 345 | try wasm.addFunction(.__wasm_init_memory, &.{}, &.{}); | 610 | try wasm.addFunction(.__wasm_init_memory, &.{}, &.{}); |
| 346 | } | 611 | } |
| 347 | 612 | ||
| 348 | try wasm.tables.ensureUnusedCapacity(gpa, 1); | 613 | try wasm.tables.ensureUnusedCapacity(gpa, 1); |
| 349 | 614 | ||
| 350 | if (f.indirect_function_table.entries.len > 0) { | 615 | if (f.indirect_function_table.entries.len > 0) { |
| 351 | wasm.tables.putAssumeCapacity(.__indirect_function_table, {}); | 616 | if (is_obj) { |
| 617 | const name = wasm.preloaded_strings.__indirect_function_table; | ||
| 618 | const gop = try wasm.object_table_imports.getOrPut(gpa, name); | ||
| 619 | if (!gop.found_existing) gop.value_ptr.* = .{ | ||
| 620 | .flags = .{ | ||
| 621 | .undefined = true, | ||
| 622 | .no_strip = true, | ||
| 623 | }, | ||
| 624 | .module_name = wasm.preloaded_strings.env, | ||
| 625 | .name = name, | ||
| 626 | .source_location = .zig_object_nofile, | ||
| 627 | .resolution = .unresolved, | ||
| 628 | .limits_min = 1, | ||
| 629 | .limits_max = 0, | ||
| 630 | }; | ||
| 631 | const import_index: Wasm.TableImport.Index = @fromBackingInt(@intCast(gop.index)); | ||
| 632 | try wasm.markTableImport(name, gop.value_ptr, import_index); | ||
| 633 | } else { | ||
| 634 | wasm.tables.putAssumeCapacity(.__indirect_function_table, {}); | ||
| 635 | } | ||
| 352 | } | 636 | } |
| 353 | 637 | ||
| 354 | // Sort order: | 638 | // Sort order: |
| ... | @@ -449,7 +733,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -449,7 +733,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 449 | const start_addr = alignment.forward(memory_ptr); | 733 | const start_addr = alignment.forward(memory_ptr); |
| 450 | 734 | ||
| 451 | const want_new_segment = b: { | 735 | const want_new_segment = b: { |
| 452 | if (is_obj) break :b false; | 736 | if (is_obj) break :b i != 0; |
| 453 | switch (seen_tls) { | 737 | switch (seen_tls) { |
| 454 | .before => switch (category) { | 738 | .before => switch (category) { |
| 455 | .tls => { | 739 | .tls => { |
| ... | @@ -489,7 +773,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -489,7 +773,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 489 | log.debug("0x{x} {d} {s}", .{ start_addr, @backingInt(segment_id), segment_id.name(wasm) }); | 773 | log.debug("0x{x} {d} {s}", .{ start_addr, @backingInt(segment_id), segment_id.name(wasm) }); |
| 490 | memory_ptr = start_addr + size; | 774 | memory_ptr = start_addr + size; |
| 491 | } | 775 | } |
| 492 | if (category != .zero) try f.data_segment_groups.append(gpa, .{ | 776 | if (is_obj or category != .zero) try f.data_segment_groups.append(gpa, .{ |
| 493 | .first_segment = first_segment, | 777 | .first_segment = first_segment, |
| 494 | .end_addr = @intCast(memory_ptr), | 778 | .end_addr = @intCast(memory_ptr), |
| 495 | }); | 779 | }); |
| ... | @@ -555,7 +839,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -555,7 +839,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 555 | 839 | ||
| 556 | // When we have TLS GOT entries and shared memory is enabled, we must | 840 | // When we have TLS GOT entries and shared memory is enabled, we must |
| 557 | // perform runtime relocations or else we don't create the function. | 841 | // perform runtime relocations or else we don't create the function. |
| 558 | if (shared_memory and virtual_addrs.tls_base != null) { | 842 | if (!is_obj and shared_memory and virtual_addrs.tls_base != null) { |
| 559 | // This logic that checks `any_tls_relocs` is missing the part where it | 843 | // This logic that checks `any_tls_relocs` is missing the part where it |
| 560 | // also notices threadlocal globals from Zcu code. | 844 | // also notices threadlocal globals from Zcu code. |
| 561 | if (wasm.any_tls_relocs) try wasm.addFunction(.__wasm_apply_global_tls_relocs, &.{}, &.{}); | 845 | if (wasm.any_tls_relocs) try wasm.addFunction(.__wasm_apply_global_tls_relocs, &.{}, &.{}); |
| ... | @@ -582,6 +866,9 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -582,6 +866,9 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 582 | for (f.function_imports.values()) |id| { | 866 | for (f.function_imports.values()) |id| { |
| 583 | try f.func_types.put(gpa, id.functionType(wasm), {}); | 867 | try f.func_types.put(gpa, id.functionType(wasm), {}); |
| 584 | } | 868 | } |
| 869 | for (f.intrinsic_function_imports.values()) |type_index| { | ||
| 870 | try f.func_types.put(gpa, type_index, {}); | ||
| 871 | } | ||
| 585 | for (wasm.functions.keys()) |function| { | 872 | for (wasm.functions.keys()) |function| { |
| 586 | try f.func_types.put(gpa, function.typeIndex(wasm), {}); | 873 | try f.func_types.put(gpa, function.typeIndex(wasm), {}); |
| 587 | } | 874 | } |
| ... | @@ -617,7 +904,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -617,7 +904,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 617 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); | 904 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); |
| 618 | 905 | ||
| 619 | for (f.function_imports.values()) |id| { | 906 | for (f.function_imports.values()) |id| { |
| 620 | const module_name = id.moduleName(wasm).slice(wasm).?; | 907 | const module_name = (id.moduleName(wasm).unwrap() orelse wasm.preloaded_strings.env).slice(wasm); |
| 621 | try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(module_name.len))); | 908 | try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(module_name.len))); |
| 622 | try binary_bytes.appendSlice(gpa, module_name); | 909 | try binary_bytes.appendSlice(gpa, module_name); |
| 623 | 910 | ||
| ... | @@ -631,6 +918,20 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -631,6 +918,20 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 631 | } | 918 | } |
| 632 | total_imports += f.function_imports.entries.len; | 919 | total_imports += f.function_imports.entries.len; |
| 633 | 920 | ||
| 921 | for (f.intrinsic_function_imports.keys(), f.intrinsic_function_imports.values()) |name_string, type_index| { | ||
| 922 | const module_name = wasm.preloaded_strings.env.slice(wasm); | ||
| 923 | try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(module_name.len))); | ||
| 924 | try binary_bytes.appendSlice(gpa, module_name); | ||
| 925 | |||
| 926 | const name = name_string.slice(wasm); | ||
| 927 | try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(name.len))); | ||
| 928 | try binary_bytes.appendSlice(gpa, name); | ||
| 929 | |||
| 930 | try binary_bytes.append(gpa, @backingInt(std.wasm.ExternalKind.function)); | ||
| 931 | try appendLeb128(gpa, binary_bytes, @backingInt(FuncTypeIndex.fromTypeIndex(type_index, f))); | ||
| 932 | } | ||
| 933 | total_imports += f.intrinsic_function_imports.entries.len; | ||
| 934 | |||
| 634 | for (wasm.table_imports.values()) |id| { | 935 | for (wasm.table_imports.values()) |id| { |
| 635 | const table_import = id.value(wasm); | 936 | const table_import = id.value(wasm); |
| 636 | const module_name = table_import.module_name.slice(wasm); | 937 | const module_name = table_import.module_name.slice(wasm); |
| ... | @@ -662,7 +963,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -662,7 +963,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 662 | } | 963 | } |
| 663 | 964 | ||
| 664 | for (f.global_imports.values()) |id| { | 965 | for (f.global_imports.values()) |id| { |
| 665 | const module_name = id.moduleName(wasm).slice(wasm).?; | 966 | const module_name = (id.moduleName(wasm).unwrap() orelse wasm.preloaded_strings.env).slice(wasm); |
| 666 | try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(module_name.len))); | 967 | try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(module_name.len))); |
| 667 | try binary_bytes.appendSlice(gpa, module_name); | 968 | try binary_bytes.appendSlice(gpa, module_name); |
| 668 | 969 | ||
| ... | @@ -726,12 +1027,12 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -726,12 +1027,12 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 726 | for (wasm.globals.keys()) |global_resolution| { | 1027 | for (wasm.globals.keys()) |global_resolution| { |
| 727 | switch (global_resolution.unpack(wasm)) { | 1028 | switch (global_resolution.unpack(wasm)) { |
| 728 | .unresolved => unreachable, | 1029 | .unresolved => unreachable, |
| 729 | .__heap_base => try appendGlobal(gpa, binary_bytes, 0, virtual_addrs.heap_base), | 1030 | .__heap_base => try appendGlobal(gpa, binary_bytes, 0, virtual_addrs.heap_base, is64), |
| 730 | .__heap_end => try appendGlobal(gpa, binary_bytes, 0, virtual_addrs.heap_end), | 1031 | .__heap_end => try appendGlobal(gpa, binary_bytes, 0, virtual_addrs.heap_end, is64), |
| 731 | .__stack_pointer => try appendGlobal(gpa, binary_bytes, 1, virtual_addrs.stack_pointer), | 1032 | .__stack_pointer => try appendGlobal(gpa, binary_bytes, 1, virtual_addrs.stack_pointer, is64), |
| 732 | .__tls_align => try appendGlobal(gpa, binary_bytes, 0, @intCast(virtual_addrs.tls_align.toByteUnits().?)), | 1033 | .__tls_align => try appendGlobal(gpa, binary_bytes, 0, @intCast(virtual_addrs.tls_align.toByteUnits().?), is64), |
| 733 | .__tls_base => try appendGlobal(gpa, binary_bytes, 1, virtual_addrs.tls_base.?), | 1034 | .__tls_base => try appendGlobal(gpa, binary_bytes, 1, virtual_addrs.tls_base.?, is64), |
| 734 | .__tls_size => try appendGlobal(gpa, binary_bytes, 0, virtual_addrs.tls_size.?), | 1035 | .__tls_size => try appendGlobal(gpa, binary_bytes, 0, virtual_addrs.tls_size.?, is64), |
| 735 | .object_global => |i| { | 1036 | .object_global => |i| { |
| 736 | const global = i.ptr(wasm); | 1037 | const global = i.ptr(wasm); |
| 737 | try binary_bytes.appendSlice(gpa, &.{ | 1038 | try binary_bytes.appendSlice(gpa, &.{ |
| ... | @@ -740,8 +1041,9 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -740,8 +1041,9 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 740 | }); | 1041 | }); |
| 741 | try emitExpr(wasm, binary_bytes, global.expr); | 1042 | try emitExpr(wasm, binary_bytes, global.expr); |
| 742 | }, | 1043 | }, |
| 743 | .nav_exe => unreachable, // Zig source code currently cannot represent this. | 1044 | .uav_exe => |i| try appendGlobal(gpa, binary_bytes, 0, wasm.uavAddr(i.key(wasm).*), is64), |
| 744 | .nav_obj => unreachable, // Zig source code currently cannot represent this. | 1045 | .nav_exe => |i| try appendGlobal(gpa, binary_bytes, 0, wasm.navAddr(i.key(wasm).*), is64), |
| 1046 | .uav_obj, .nav_obj => unreachable, | ||
| 745 | } | 1047 | } |
| 746 | } | 1048 | } |
| 747 | 1049 | ||
| ... | @@ -766,7 +1068,8 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -766,7 +1068,8 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 766 | 1068 | ||
| 767 | if (wasm.export_table and f.indirect_function_table.entries.len > 0) { | 1069 | if (wasm.export_table and f.indirect_function_table.entries.len > 0) { |
| 768 | const name = "__indirect_function_table"; | 1070 | const name = "__indirect_function_table"; |
| 769 | const index: u32 = @intCast(wasm.tables.getIndex(.__indirect_function_table).?); | 1071 | const index: u32 = @intCast(wasm.table_imports.entries.len + |
| 1072 | wasm.tables.getIndex(.__indirect_function_table).?); | ||
| 770 | try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(name.len))); | 1073 | try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(name.len))); |
| 771 | try binary_bytes.appendSlice(gpa, name); | 1074 | try binary_bytes.appendSlice(gpa, name); |
| 772 | try binary_bytes.append(gpa, @backingInt(std.wasm.ExternalKind.table)); | 1075 | try binary_bytes.append(gpa, @backingInt(std.wasm.ExternalKind.table)); |
| ... | @@ -803,16 +1106,18 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -803,16 +1106,18 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 803 | // start section | 1106 | // start section |
| 804 | if (wasm.functions.getIndex(.__wasm_init_memory)) |func_index| { | 1107 | if (wasm.functions.getIndex(.__wasm_init_memory)) |func_index| { |
| 805 | try emitStartSection(gpa, binary_bytes, .fromFunctionIndex(wasm, @fromBackingInt(@intCast(func_index)))); | 1108 | try emitStartSection(gpa, binary_bytes, .fromFunctionIndex(wasm, @fromBackingInt(@intCast(func_index)))); |
| 806 | } else if (Wasm.OutputFunctionIndex.fromResolution(wasm, wasm.entry_resolution)) |func_index| { | 1109 | section_index += 1; |
| 807 | try emitStartSection(gpa, binary_bytes, func_index); | ||
| 808 | } | 1110 | } |
| 809 | 1111 | ||
| 810 | // element section | 1112 | // element section |
| 811 | if (f.indirect_function_table.entries.len > 0) { | 1113 | if (!is_obj and f.indirect_function_table.entries.len > 0) { |
| 812 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); | 1114 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); |
| 813 | 1115 | ||
| 814 | // indirect function table elements | 1116 | // indirect function table elements |
| 815 | const table_index: u32 = @intCast(wasm.tables.getIndex(.__indirect_function_table).?); | 1117 | const table_index: u32 = @intCast( |
| 1118 | wasm.table_imports.getIndex(wasm.preloaded_strings.__indirect_function_table) orelse | ||
| 1119 | wasm.table_imports.entries.len + wasm.tables.getIndex(.__indirect_function_table).?, | ||
| 1120 | ); | ||
| 816 | // passive with implicit 0-index table or set table index manually | 1121 | // passive with implicit 0-index table or set table index manually |
| 817 | const flags: u32 = if (table_index == 0) 0x0 else 0x02; | 1122 | const flags: u32 = if (table_index == 0) 0x0 else 0x02; |
| 818 | try appendLeb128(gpa, binary_bytes, flags); | 1123 | try appendLeb128(gpa, binary_bytes, flags); |
| ... | @@ -841,11 +1146,13 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -841,11 +1146,13 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 841 | if (f.data_segment_groups.items.len > 0) { | 1146 | if (f.data_segment_groups.items.len > 0) { |
| 842 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); | 1147 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); |
| 843 | replaceVecSectionHeader(binary_bytes, header_offset, .data_count, @intCast(f.data_segment_groups.items.len)); | 1148 | replaceVecSectionHeader(binary_bytes, header_offset, .data_count, @intCast(f.data_segment_groups.items.len)); |
| 1149 | section_index += 1; | ||
| 844 | } | 1150 | } |
| 845 | 1151 | ||
| 846 | // Code section. | 1152 | // Code section. |
| 847 | if (wasm.functions.count() != 0) { | 1153 | if (wasm.functions.count() != 0) { |
| 848 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); | 1154 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); |
| 1155 | const section_offset = binary_bytes.items.len - uleb128size(@intCast(wasm.functions.count())); | ||
| 849 | 1156 | ||
| 850 | for (wasm.functions.keys()) |resolution| switch (resolution.unpack(wasm)) { | 1157 | for (wasm.functions.keys()) |resolution| switch (resolution.unpack(wasm)) { |
| 851 | .unresolved => unreachable, | 1158 | .unresolved => unreachable, |
| ... | @@ -870,10 +1177,22 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -870,10 +1177,22 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 870 | const code = ptr.code.slice(wasm); | 1177 | const code = ptr.code.slice(wasm); |
| 871 | try appendLeb128(gpa, binary_bytes, code.len); | 1178 | try appendLeb128(gpa, binary_bytes, code.len); |
| 872 | const code_start = binary_bytes.items.len; | 1179 | const code_start = binary_bytes.items.len; |
| 1180 | const output_offset: u32 = @intCast(binary_bytes.items.len - section_offset); | ||
| 873 | try binary_bytes.appendSlice(gpa, code); | 1181 | try binary_bytes.appendSlice(gpa, code); |
| 874 | if (!is_obj) applyRelocs(binary_bytes.items[code_start..], ptr.offset, ptr.relocations(wasm), wasm); | 1182 | if (is_obj) { |
| 1183 | try processRelocs( | ||
| 1184 | wasm, | ||
| 1185 | &f.code_relocs, | ||
| 1186 | output_offset, | ||
| 1187 | ptr.offset, | ||
| 1188 | ptr.relocations(wasm), | ||
| 1189 | ); | ||
| 1190 | } else { | ||
| 1191 | applyRelocs(binary_bytes.items[code_start..], ptr.offset, ptr.relocations(wasm), wasm); | ||
| 1192 | } | ||
| 875 | }, | 1193 | }, |
| 876 | .zcu_func => |i| { | 1194 | .zcu_func => |i| { |
| 1195 | const function_offset: u32 = @intCast(binary_bytes.items.len - section_offset); | ||
| 877 | const code_start = try reserveSize(gpa, binary_bytes); | 1196 | const code_start = try reserveSize(gpa, binary_bytes); |
| 878 | defer replaceSize(binary_bytes, code_start); | 1197 | defer replaceSize(binary_bytes, code_start); |
| 879 | 1198 | ||
| ... | @@ -899,7 +1218,22 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -899,7 +1218,22 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 899 | .func_tys = undefined, | 1218 | .func_tys = undefined, |
| 900 | .error_name_table_ref_count = undefined, | 1219 | .error_name_table_ref_count = undefined, |
| 901 | }; | 1220 | }; |
| 1221 | const body_start: u32 = @intCast(binary_bytes.items.len); | ||
| 1222 | const relocs_start: u32 = @intCast(wasm.zcu_relocations.len); | ||
| 1223 | defer wasm.zcu_relocations.shrinkRetainingCapacity(relocs_start); | ||
| 902 | try mir.lower(wasm, binary_bytes); | 1224 | try mir.lower(wasm, binary_bytes); |
| 1225 | const relocs_len: u32 = @intCast(wasm.zcu_relocations.len - relocs_start); | ||
| 1226 | if (is_obj) { | ||
| 1227 | const body_len: u32 = @intCast(binary_bytes.items.len - @as(usize, body_start)); | ||
| 1228 | const output_offset = function_offset + uleb128size(body_len); | ||
| 1229 | try processZcuRelocs( | ||
| 1230 | wasm, | ||
| 1231 | &f.code_relocs, | ||
| 1232 | output_offset, | ||
| 1233 | body_start, | ||
| 1234 | .{ .off = relocs_start, .len = relocs_len }, | ||
| 1235 | ); | ||
| 1236 | } | ||
| 903 | }, | 1237 | }, |
| 904 | } | 1238 | } |
| 905 | }, | 1239 | }, |
| ... | @@ -921,8 +1255,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -921,8 +1255,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 921 | } | 1255 | } |
| 922 | } | 1256 | } |
| 923 | for (wasm.nav_fixups.items) |nav_fixup| { | 1257 | for (wasm.nav_fixups.items) |nav_fixup| { |
| 924 | const ds_id: Wasm.DataSegmentId = .pack(wasm, .{ .nav_exe = nav_fixup.navs_exe_index }); | 1258 | const vaddr = wasm.navAddr(nav_fixup.nav_index) + nav_fixup.addend; |
| 925 | const vaddr = f.data_segments.get(ds_id).? + nav_fixup.addend; | ||
| 926 | if (!is64) { | 1259 | if (!is64) { |
| 927 | mem.writeInt(u32, wasm.string_bytes.items[nav_fixup.offset..][0..4], vaddr, .little); | 1260 | mem.writeInt(u32, wasm.string_bytes.items[nav_fixup.offset..][0..4], vaddr, .little); |
| 928 | } else { | 1261 | } else { |
| ... | @@ -930,7 +1263,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -930,7 +1263,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 930 | } | 1263 | } |
| 931 | } | 1264 | } |
| 932 | for (wasm.func_table_fixups.items) |fixup| { | 1265 | for (wasm.func_table_fixups.items) |fixup| { |
| 933 | const table_index: IndirectFunctionTableIndex = .fromZcuIndirectFunctionSetIndex(fixup.table_index); | 1266 | const table_index: IndirectFunctionTableIndex = .fromIpNav(wasm, fixup.nav_index); |
| 934 | if (!is64) { | 1267 | if (!is64) { |
| 935 | mem.writeInt(u32, wasm.string_bytes.items[fixup.offset..][0..4], table_index.toAbi(), .little); | 1268 | mem.writeInt(u32, wasm.string_bytes.items[fixup.offset..][0..4], table_index.toAbi(), .little); |
| 936 | } else { | 1269 | } else { |
| ... | @@ -942,6 +1275,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -942,6 +1275,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 942 | // Data section. | 1275 | // Data section. |
| 943 | if (f.data_segment_groups.items.len != 0) { | 1276 | if (f.data_segment_groups.items.len != 0) { |
| 944 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); | 1277 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); |
| 1278 | const section_offset = binary_bytes.items.len - uleb128size(@intCast(f.data_segment_groups.items.len)); | ||
| 945 | 1279 | ||
| 946 | var group_index: u32 = 0; | 1280 | var group_index: u32 = 0; |
| 947 | var segment_offset: u32 = 0; | 1281 | var segment_offset: u32 = 0; |
| ... | @@ -976,7 +1310,11 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -976,7 +1310,11 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 976 | try appendLeb128(gpa, binary_bytes, group_size); | 1310 | try appendLeb128(gpa, binary_bytes, group_size); |
| 977 | } | 1311 | } |
| 978 | if (segment_id.isEmpty(wasm)) { | 1312 | if (segment_id.isEmpty(wasm)) { |
| 979 | // It counted for virtual memory but it does not go into the binary. | 1313 | if (is_obj) { |
| 1314 | const group_size = group_end_addr - group_start_addr; | ||
| 1315 | try binary_bytes.appendNTimes(gpa, 0, group_size - segment_offset); | ||
| 1316 | segment_offset = group_size; | ||
| 1317 | } | ||
| 980 | continue; | 1318 | continue; |
| 981 | } | 1319 | } |
| 982 | 1320 | ||
| ... | @@ -986,6 +1324,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -986,6 +1324,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 986 | segment_offset = needed_offset; | 1324 | segment_offset = needed_offset; |
| 987 | 1325 | ||
| 988 | const code_start = binary_bytes.items.len; | 1326 | const code_start = binary_bytes.items.len; |
| 1327 | const output_offset: u32 = @intCast(binary_bytes.items.len - section_offset); | ||
| 989 | append: { | 1328 | append: { |
| 990 | const code = switch (segment_id.unpack(wasm)) { | 1329 | const code = switch (segment_id.unpack(wasm)) { |
| 991 | .__heap_base => { | 1330 | .__heap_base => { |
| ... | @@ -1001,12 +1340,19 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -1001,12 +1340,19 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 1001 | break :append; | 1340 | break :append; |
| 1002 | }, | 1341 | }, |
| 1003 | .__zig_error_name_table => { | 1342 | .__zig_error_name_table => { |
| 1004 | if (is_obj) @panic("TODO error name table reloc"); | 1343 | if (is_obj) { |
| 1005 | const base = f.data_segments.get(.__zig_error_names).?; | 1344 | try emitRelocatableNameTable( |
| 1006 | if (!is64) { | 1345 | wasm, |
| 1007 | try emitTagNameTable(gpa, binary_bytes, wasm.error_name_offs.items, wasm.error_name_bytes.items, base, u32); | 1346 | binary_bytes, |
| 1347 | &f.data_relocs, | ||
| 1348 | output_offset, | ||
| 1349 | wasm.error_name_offs.items, | ||
| 1350 | wasm.error_name_bytes.items, | ||
| 1351 | .__zig_error_names, | ||
| 1352 | ); | ||
| 1008 | } else { | 1353 | } else { |
| 1009 | try emitTagNameTable(gpa, binary_bytes, wasm.error_name_offs.items, wasm.error_name_bytes.items, base, u64); | 1354 | const base = f.data_segments.get(.__zig_error_names).?; |
| 1355 | try emitTagNameTable(wasm, binary_bytes, wasm.error_name_offs.items, wasm.error_name_bytes.items, base, is64); | ||
| 1010 | } | 1356 | } |
| 1011 | break :append; | 1357 | break :append; |
| 1012 | }, | 1358 | }, |
| ... | @@ -1015,22 +1361,51 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -1015,22 +1361,51 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 1015 | break :append; | 1361 | break :append; |
| 1016 | }, | 1362 | }, |
| 1017 | .__zig_tag_name_table => { | 1363 | .__zig_tag_name_table => { |
| 1018 | if (is_obj) @panic("TODO tag name table reloc"); | 1364 | if (is_obj) { |
| 1019 | const base = f.data_segments.get(.__zig_tag_names).?; | 1365 | try emitRelocatableNameTable( |
| 1020 | if (!is64) { | 1366 | wasm, |
| 1021 | try emitTagNameTable(gpa, binary_bytes, wasm.tag_name_offs.items, wasm.tag_name_bytes.items, base, u32); | 1367 | binary_bytes, |
| 1368 | &f.data_relocs, | ||
| 1369 | output_offset, | ||
| 1370 | wasm.tag_name_offs.items, | ||
| 1371 | wasm.tag_name_bytes.items, | ||
| 1372 | .__zig_tag_names, | ||
| 1373 | ); | ||
| 1022 | } else { | 1374 | } else { |
| 1023 | try emitTagNameTable(gpa, binary_bytes, wasm.tag_name_offs.items, wasm.tag_name_bytes.items, base, u64); | 1375 | const base = f.data_segments.get(.__zig_tag_names).?; |
| 1376 | try emitTagNameTable(wasm, binary_bytes, wasm.tag_name_offs.items, wasm.tag_name_bytes.items, base, is64); | ||
| 1024 | } | 1377 | } |
| 1025 | break :append; | 1378 | break :append; |
| 1026 | }, | 1379 | }, |
| 1027 | .object => |i| { | 1380 | .object => |i| { |
| 1028 | const ptr = i.ptr(wasm); | 1381 | const ptr = i.ptr(wasm); |
| 1029 | try binary_bytes.appendSlice(gpa, ptr.payload.slice(wasm)); | 1382 | try binary_bytes.appendSlice(gpa, ptr.payload.slice(wasm)); |
| 1030 | if (!is_obj) applyRelocs(binary_bytes.items[code_start..], ptr.offset, ptr.relocations(wasm), wasm); | 1383 | if (is_obj) { |
| 1384 | try processRelocs( | ||
| 1385 | wasm, | ||
| 1386 | &f.data_relocs, | ||
| 1387 | output_offset, | ||
| 1388 | ptr.offset, | ||
| 1389 | ptr.relocations(wasm), | ||
| 1390 | ); | ||
| 1391 | } else { | ||
| 1392 | applyRelocs(binary_bytes.items[code_start..], ptr.offset, ptr.relocations(wasm), wasm); | ||
| 1393 | } | ||
| 1031 | break :append; | 1394 | break :append; |
| 1032 | }, | 1395 | }, |
| 1033 | inline .uav_exe, .uav_obj, .nav_exe, .nav_obj => |i| i.value(wasm).code, | 1396 | inline .uav_obj, .nav_obj => |i| { |
| 1397 | const zcu_data = i.value(wasm); | ||
| 1398 | try binary_bytes.appendSlice(gpa, zcu_data.code.slice(wasm)); | ||
| 1399 | try processZcuRelocs( | ||
| 1400 | wasm, | ||
| 1401 | &f.data_relocs, | ||
| 1402 | output_offset, | ||
| 1403 | zcu_data.code.off.unwrap().?, | ||
| 1404 | zcu_data.relocs, | ||
| 1405 | ); | ||
| 1406 | break :append; | ||
| 1407 | }, | ||
| 1408 | inline .uav_exe, .nav_exe => |i| i.value(wasm).code, | ||
| 1034 | }; | 1409 | }; |
| 1035 | try binary_bytes.appendSlice(gpa, code.slice(wasm)); | 1410 | try binary_bytes.appendSlice(gpa, code.slice(wasm)); |
| 1036 | } | 1411 | } |
| ... | @@ -1043,7 +1418,274 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -1043,7 +1418,274 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 1043 | } | 1418 | } |
| 1044 | 1419 | ||
| 1045 | if (is_obj) { | 1420 | if (is_obj) { |
| 1046 | @panic("TODO emit link section for object file and emit modified relocations"); | 1421 | var symbol_table_offsets: SymbolTableOffsets = undefined; |
| 1422 | { | ||
| 1423 | const header_offset = try reserveCustomSectionHeader(gpa, binary_bytes); | ||
| 1424 | defer writeCustomSectionHeader(binary_bytes, header_offset); | ||
| 1425 | |||
| 1426 | const linking_name = "linking"; | ||
| 1427 | try appendLeb128(gpa, binary_bytes, @as(u32, linking_name.len)); | ||
| 1428 | try binary_bytes.appendSlice(gpa, linking_name); | ||
| 1429 | |||
| 1430 | try appendLeb128(gpa, binary_bytes, @as(u32, 2)); | ||
| 1431 | |||
| 1432 | // WASM_SEGMENT_INFO | ||
| 1433 | { | ||
| 1434 | const sub_offset = try reserveCustomSectionHeader(gpa, binary_bytes); | ||
| 1435 | defer replaceHeader(binary_bytes, sub_offset, @backingInt(Object.SubsectionType.segment_info)); | ||
| 1436 | |||
| 1437 | const total_data_segments: u32 = @intCast(f.data_segment_groups.items.len); | ||
| 1438 | try appendLeb128(gpa, binary_bytes, total_data_segments); | ||
| 1439 | |||
| 1440 | for (f.data_segment_groups.items) |group| { | ||
| 1441 | const segment = group.first_segment; | ||
| 1442 | const name, _ = splitSegmentName(segment.name(wasm)); | ||
| 1443 | try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(name.len))); | ||
| 1444 | try binary_bytes.appendSlice(gpa, name); | ||
| 1445 | |||
| 1446 | try appendLeb128(gpa, binary_bytes, @as(u32, segment.alignment(wasm).toLog2Units())); | ||
| 1447 | |||
| 1448 | var flags: u32 = 0; | ||
| 1449 | if (segment.isStrings(wasm)) flags |= 1; | ||
| 1450 | if (segment.isTls(wasm)) flags |= 2; | ||
| 1451 | if (segment.isRetain(wasm)) flags |= 4; | ||
| 1452 | try appendLeb128(gpa, binary_bytes, flags); | ||
| 1453 | } | ||
| 1454 | } | ||
| 1455 | |||
| 1456 | // WASM_SYMBOL_TABLE | ||
| 1457 | { | ||
| 1458 | const sub_offset = try reserveCustomSectionHeader(gpa, binary_bytes); | ||
| 1459 | defer replaceHeader(binary_bytes, sub_offset, @backingInt(Object.SubsectionType.symbol_table)); | ||
| 1460 | |||
| 1461 | const total_symbols: u32 = @intCast( | ||
| 1462 | f.function_imports.entries.len + f.intrinsic_function_imports.entries.len + | ||
| 1463 | wasm.functions.entries.len + | ||
| 1464 | f.function_export_symbols.entries.len + | ||
| 1465 | f.data_imports.entries.len + wasm.datas.entries.len + f.data_exports.entries.len + | ||
| 1466 | f.global_imports.entries.len + wasm.globals.entries.len + | ||
| 1467 | wasm.table_imports.entries.len + wasm.tables.entries.len, | ||
| 1468 | ); | ||
| 1469 | try appendLeb128(gpa, binary_bytes, total_symbols); | ||
| 1470 | var symbol_count: u32 = 0; | ||
| 1471 | |||
| 1472 | // SYMTAB_FUNCTION | ||
| 1473 | { | ||
| 1474 | symbol_table_offsets.function = symbol_count; | ||
| 1475 | for (f.function_imports.values(), 0..) |i, function_index| { | ||
| 1476 | try binary_bytes.append(gpa, @backingInt(Object.Symbol.Tag.function)); | ||
| 1477 | const flags = i.flags(wasm); | ||
| 1478 | assert(flags.undefined); | ||
| 1479 | try appendLeb128(gpa, binary_bytes, flags.toAbiInteger()); | ||
| 1480 | try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(function_index))); | ||
| 1481 | if (flags.explicit_name) { | ||
| 1482 | unreachable; // never set | ||
| 1483 | } | ||
| 1484 | symbol_count += 1; | ||
| 1485 | } | ||
| 1486 | const intrinsic_flags: Wasm.SymbolFlags = .{ .undefined = true }; | ||
| 1487 | for (f.intrinsic_function_imports.keys(), f.function_imports.entries.len..) |_, function_index| { | ||
| 1488 | try binary_bytes.append(gpa, @backingInt(Object.Symbol.Tag.function)); | ||
| 1489 | try appendLeb128(gpa, binary_bytes, intrinsic_flags.toAbiInteger()); | ||
| 1490 | try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(function_index))); | ||
| 1491 | symbol_count += 1; | ||
| 1492 | } | ||
| 1493 | for ( | ||
| 1494 | wasm.functions.keys(), | ||
| 1495 | f.function_imports.entries.len + f.intrinsic_function_imports.entries.len.., | ||
| 1496 | ) |resolution, function_index| { | ||
| 1497 | const name = resolution.name(wasm).?; | ||
| 1498 | const flags = resolution.flags(wasm); | ||
| 1499 | try binary_bytes.append(gpa, @backingInt(Object.Symbol.Tag.function)); | ||
| 1500 | assert(!flags.undefined); | ||
| 1501 | try appendLeb128(gpa, binary_bytes, flags.toAbiInteger()); | ||
| 1502 | try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(function_index))); | ||
| 1503 | try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(name.len))); | ||
| 1504 | try binary_bytes.appendSlice(gpa, name); | ||
| 1505 | symbol_count += 1; | ||
| 1506 | } | ||
| 1507 | for ( | ||
| 1508 | f.function_export_symbols.keys(), | ||
| 1509 | f.function_export_symbols.values(), | ||
| 1510 | ) |name_string, symbol| { | ||
| 1511 | const name = name_string.slice(wasm); | ||
| 1512 | const function_index: Wasm.OutputFunctionIndex = .fromFunctionIndex( | ||
| 1513 | wasm, | ||
| 1514 | symbol.function_index, | ||
| 1515 | ); | ||
| 1516 | try binary_bytes.append(gpa, @backingInt(Object.Symbol.Tag.function)); | ||
| 1517 | try appendLeb128(gpa, binary_bytes, symbol.flags.toAbiInteger()); | ||
| 1518 | try appendLeb128(gpa, binary_bytes, @backingInt(function_index)); | ||
| 1519 | try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(name.len))); | ||
| 1520 | try binary_bytes.appendSlice(gpa, name); | ||
| 1521 | symbol_count += 1; | ||
| 1522 | } | ||
| 1523 | } | ||
| 1524 | |||
| 1525 | // SYMTAB_DATA | ||
| 1526 | { | ||
| 1527 | symbol_table_offsets.data = symbol_count; | ||
| 1528 | for (f.data_imports.keys(), f.data_imports.values()) |name_string, data_index| { | ||
| 1529 | const name = name_string.slice(wasm); | ||
| 1530 | try binary_bytes.append(gpa, @backingInt(Object.Symbol.Tag.data)); | ||
| 1531 | const flags = data_index.flags(wasm); | ||
| 1532 | assert(flags.undefined); | ||
| 1533 | try appendLeb128(gpa, binary_bytes, flags.toAbiInteger()); | ||
| 1534 | try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(name.len))); | ||
| 1535 | try binary_bytes.appendSlice(gpa, name); | ||
| 1536 | symbol_count += 1; | ||
| 1537 | } | ||
| 1538 | for (wasm.datas.keys()) |resolution| { | ||
| 1539 | var buf: [32]u8 = undefined; | ||
| 1540 | const name = resolution.name(wasm, &buf); | ||
| 1541 | try binary_bytes.append(gpa, @backingInt(Object.Symbol.Tag.data)); | ||
| 1542 | const flags = resolution.flags(wasm); | ||
| 1543 | assert(!flags.undefined); | ||
| 1544 | try appendLeb128(gpa, binary_bytes, flags.toAbiInteger()); | ||
| 1545 | |||
| 1546 | const data_loc = resolution.dataLoc(wasm); | ||
| 1547 | try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(name.len))); | ||
| 1548 | try binary_bytes.appendSlice(gpa, name); | ||
| 1549 | |||
| 1550 | const segment_index = f.data_segments.getIndex(data_loc.segment).?; | ||
| 1551 | try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(segment_index))); | ||
| 1552 | try appendLeb128(gpa, binary_bytes, data_loc.offset); | ||
| 1553 | try appendLeb128(gpa, binary_bytes, resolution.size(wasm)); | ||
| 1554 | symbol_count += 1; | ||
| 1555 | } | ||
| 1556 | for (f.data_exports.keys(), f.data_exports.values()) |name_string, symbol| { | ||
| 1557 | const name = name_string.slice(wasm); | ||
| 1558 | try binary_bytes.append(gpa, @backingInt(Object.Symbol.Tag.data)); | ||
| 1559 | try appendLeb128(gpa, binary_bytes, symbol.flags.toAbiInteger()); | ||
| 1560 | try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(name.len))); | ||
| 1561 | try binary_bytes.appendSlice(gpa, name); | ||
| 1562 | |||
| 1563 | const data_loc = symbol.resolution.dataLoc(wasm); | ||
| 1564 | const segment_index = f.data_segments.getIndex(data_loc.segment).?; | ||
| 1565 | try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(segment_index))); | ||
| 1566 | try appendLeb128(gpa, binary_bytes, data_loc.offset); | ||
| 1567 | try appendLeb128(gpa, binary_bytes, symbol.resolution.size(wasm)); | ||
| 1568 | symbol_count += 1; | ||
| 1569 | } | ||
| 1570 | } | ||
| 1571 | |||
| 1572 | // SYMTAB_GLOBAL | ||
| 1573 | { | ||
| 1574 | symbol_table_offsets.global = symbol_count; | ||
| 1575 | for (f.global_imports.values(), 0..) |i, global_index| { | ||
| 1576 | try binary_bytes.append(gpa, @backingInt(Object.Symbol.Tag.global)); | ||
| 1577 | const flags = i.flags(wasm); | ||
| 1578 | assert(flags.undefined); | ||
| 1579 | try appendLeb128(gpa, binary_bytes, flags.toAbiInteger()); | ||
| 1580 | try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(global_index))); | ||
| 1581 | if (flags.explicit_name) { | ||
| 1582 | unreachable; // never set | ||
| 1583 | } | ||
| 1584 | symbol_count += 1; | ||
| 1585 | } | ||
| 1586 | for (wasm.globals.keys(), f.global_imports.entries.len..) |resolution, global_index| { | ||
| 1587 | var buf: [32]u8 = undefined; | ||
| 1588 | const name = resolution.name(wasm, &buf).?; | ||
| 1589 | try binary_bytes.append(gpa, @backingInt(Object.Symbol.Tag.global)); | ||
| 1590 | const flags = resolution.flags(wasm); | ||
| 1591 | assert(!flags.undefined); | ||
| 1592 | try appendLeb128(gpa, binary_bytes, flags.toAbiInteger()); | ||
| 1593 | try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(global_index))); | ||
| 1594 | try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(name.len))); | ||
| 1595 | try binary_bytes.appendSlice(gpa, name); | ||
| 1596 | symbol_count += 1; | ||
| 1597 | } | ||
| 1598 | } | ||
| 1599 | |||
| 1600 | // SYMTAB_EVENT | ||
| 1601 | { | ||
| 1602 | // TODO not parsed yet | ||
| 1603 | } | ||
| 1604 | |||
| 1605 | // SYMTAB_SECTION | ||
| 1606 | { | ||
| 1607 | // TODO not parsed correctly yet | ||
| 1608 | } | ||
| 1609 | |||
| 1610 | // SYMTAB_TABLE | ||
| 1611 | { | ||
| 1612 | symbol_table_offsets.table = symbol_count; | ||
| 1613 | for (wasm.table_imports.values(), 0..) |i, table_index| { | ||
| 1614 | try binary_bytes.append(gpa, @backingInt(Object.Symbol.Tag.table)); | ||
| 1615 | const flags = i.value(wasm).flags; | ||
| 1616 | assert(flags.undefined); | ||
| 1617 | try appendLeb128(gpa, binary_bytes, flags.toAbiInteger()); | ||
| 1618 | try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(table_index))); | ||
| 1619 | if (flags.explicit_name) { | ||
| 1620 | unreachable; // never set | ||
| 1621 | } | ||
| 1622 | symbol_count += 1; | ||
| 1623 | } | ||
| 1624 | for (wasm.tables.keys(), wasm.table_imports.entries.len..) |resolution, table_index| { | ||
| 1625 | const name = resolution.name(wasm).?; | ||
| 1626 | try binary_bytes.append(gpa, @backingInt(Object.Symbol.Tag.table)); | ||
| 1627 | const flags = resolution.flags(wasm); | ||
| 1628 | assert(!flags.undefined); | ||
| 1629 | try appendLeb128(gpa, binary_bytes, flags.toAbiInteger()); | ||
| 1630 | try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(table_index))); | ||
| 1631 | try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(name.len))); | ||
| 1632 | try binary_bytes.appendSlice(gpa, name); | ||
| 1633 | symbol_count += 1; | ||
| 1634 | } | ||
| 1635 | } | ||
| 1636 | assert(symbol_count == total_symbols); | ||
| 1637 | } | ||
| 1638 | |||
| 1639 | // WASM_INIT_FUNCS | ||
| 1640 | { | ||
| 1641 | const sub_offset = try reserveCustomSectionHeader(gpa, binary_bytes); | ||
| 1642 | defer replaceHeader(binary_bytes, sub_offset, @backingInt(Object.SubsectionType.init_funcs)); | ||
| 1643 | |||
| 1644 | const init_funcs = wasm.object_init_funcs.items; | ||
| 1645 | const total_functions: u32 = b: { | ||
| 1646 | var cnt: u32 = 0; | ||
| 1647 | for (init_funcs) |init_func| { | ||
| 1648 | const func = init_func.function_index.ptr(wasm); | ||
| 1649 | if (!func.object_index.ptr(wasm).is_included) continue; | ||
| 1650 | cnt += 1; | ||
| 1651 | } | ||
| 1652 | break :b cnt; | ||
| 1653 | }; | ||
| 1654 | try appendLeb128(gpa, binary_bytes, total_functions); | ||
| 1655 | |||
| 1656 | for (init_funcs) |init_func| { | ||
| 1657 | const func = init_func.function_index.ptr(wasm); | ||
| 1658 | if (!func.object_index.ptr(wasm).is_included) continue; | ||
| 1659 | |||
| 1660 | try appendLeb128(gpa, binary_bytes, init_func.priority); | ||
| 1661 | const out_index: Wasm.OutputFunctionIndex = .fromObjectFunction(wasm, init_func.function_index); | ||
| 1662 | const symbol_index: u32 = symbol_table_offsets.function + @backingInt(out_index); | ||
| 1663 | try appendLeb128(gpa, binary_bytes, symbol_index); | ||
| 1664 | } | ||
| 1665 | } | ||
| 1666 | |||
| 1667 | // WASM_COMDAT_INFO | ||
| 1668 | { | ||
| 1669 | // TODO | ||
| 1670 | } | ||
| 1671 | } | ||
| 1672 | |||
| 1673 | if (f.code_relocs.items.len != 0) try emitRelocSection( | ||
| 1674 | wasm, | ||
| 1675 | binary_bytes, | ||
| 1676 | code_section_index.?, | ||
| 1677 | "reloc.CODE", | ||
| 1678 | f.code_relocs.items, | ||
| 1679 | symbol_table_offsets, | ||
| 1680 | ); | ||
| 1681 | if (f.data_relocs.items.len != 0) try emitRelocSection( | ||
| 1682 | wasm, | ||
| 1683 | binary_bytes, | ||
| 1684 | data_section_index.?, | ||
| 1685 | "reloc.DATA", | ||
| 1686 | f.data_relocs.items, | ||
| 1687 | symbol_table_offsets, | ||
| 1688 | ); | ||
| 1047 | } else if (comp.config.debug_format != .strip) { | 1689 | } else if (comp.config.debug_format != .strip) { |
| 1048 | try emitNameSection(wasm, f.data_segment_groups.items, binary_bytes); | 1690 | try emitNameSection(wasm, f.data_segment_groups.items, binary_bytes); |
| 1049 | } | 1691 | } |
| ... | @@ -1121,7 +1763,10 @@ fn emitNameSection( | ... | @@ -1121,7 +1763,10 @@ fn emitNameSection( |
| 1121 | const sub_offset = try reserveCustomSectionHeader(gpa, binary_bytes); | 1763 | const sub_offset = try reserveCustomSectionHeader(gpa, binary_bytes); |
| 1122 | defer replaceHeader(binary_bytes, sub_offset, @backingInt(std.wasm.NameSubsection.function)); | 1764 | defer replaceHeader(binary_bytes, sub_offset, @backingInt(std.wasm.NameSubsection.function)); |
| 1123 | 1765 | ||
| 1124 | const total_functions: u32 = @intCast(f.function_imports.entries.len + wasm.functions.entries.len); | 1766 | const total_functions: u32 = @intCast( |
| 1767 | f.function_imports.entries.len + f.intrinsic_function_imports.entries.len + | ||
| 1768 | wasm.functions.entries.len, | ||
| 1769 | ); | ||
| 1125 | try appendLeb128(gpa, binary_bytes, total_functions); | 1770 | try appendLeb128(gpa, binary_bytes, total_functions); |
| 1126 | 1771 | ||
| 1127 | for (f.function_imports.keys(), 0..) |name_index, function_index| { | 1772 | for (f.function_imports.keys(), 0..) |name_index, function_index| { |
| ... | @@ -1130,7 +1775,16 @@ fn emitNameSection( | ... | @@ -1130,7 +1775,16 @@ fn emitNameSection( |
| 1130 | try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(name.len))); | 1775 | try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(name.len))); |
| 1131 | try binary_bytes.appendSlice(gpa, name); | 1776 | try binary_bytes.appendSlice(gpa, name); |
| 1132 | } | 1777 | } |
| 1133 | for (wasm.functions.keys(), f.function_imports.entries.len..) |resolution, function_index| { | 1778 | for (f.intrinsic_function_imports.keys(), f.function_imports.entries.len..) |name_index, function_index| { |
| 1779 | const name = name_index.slice(wasm); | ||
| 1780 | try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(function_index))); | ||
| 1781 | try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(name.len))); | ||
| 1782 | try binary_bytes.appendSlice(gpa, name); | ||
| 1783 | } | ||
| 1784 | for ( | ||
| 1785 | wasm.functions.keys(), | ||
| 1786 | f.function_imports.entries.len + f.intrinsic_function_imports.entries.len.., | ||
| 1787 | ) |resolution, function_index| { | ||
| 1134 | const name = resolution.name(wasm).?; | 1788 | const name = resolution.name(wasm).?; |
| 1135 | try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(function_index))); | 1789 | try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(function_index))); |
| 1136 | try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(name.len))); | 1790 | try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(name.len))); |
| ... | @@ -1152,7 +1806,8 @@ fn emitNameSection( | ... | @@ -1152,7 +1806,8 @@ fn emitNameSection( |
| 1152 | try binary_bytes.appendSlice(gpa, name); | 1806 | try binary_bytes.appendSlice(gpa, name); |
| 1153 | } | 1807 | } |
| 1154 | for (wasm.globals.keys(), f.global_imports.entries.len..) |resolution, global_index| { | 1808 | for (wasm.globals.keys(), f.global_imports.entries.len..) |resolution, global_index| { |
| 1155 | const name = resolution.name(wasm).?; | 1809 | var buf: [32]u8 = undefined; |
| 1810 | const name = resolution.name(wasm, &buf).?; | ||
| 1156 | try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(global_index))); | 1811 | try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(global_index))); |
| 1157 | try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(name.len))); | 1812 | try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(name.len))); |
| 1158 | try binary_bytes.appendSlice(gpa, name); | 1813 | try binary_bytes.appendSlice(gpa, name); |
| ... | @@ -1270,7 +1925,7 @@ fn emitProducerSection(gpa: Allocator, binary_bytes: *ArrayList(u8)) !void { | ... | @@ -1270,7 +1925,7 @@ fn emitProducerSection(gpa: Allocator, binary_bytes: *ArrayList(u8)) !void { |
| 1270 | 1925 | ||
| 1271 | fn splitSegmentName(name: []const u8) struct { []const u8, []const u8 } { | 1926 | fn splitSegmentName(name: []const u8) struct { []const u8, []const u8 } { |
| 1272 | const start = @intFromBool(name.len >= 1 and name[0] == '.'); | 1927 | const start = @intFromBool(name.len >= 1 and name[0] == '.'); |
| 1273 | const pivot = mem.indexOfScalarPos(u8, name, start, '.') orelse name.len; | 1928 | const pivot = mem.findScalarPos(u8, name, start, '.') orelse name.len; |
| 1274 | return .{ name[0..pivot], name[pivot..] }; | 1929 | return .{ name[0..pivot], name[pivot..] }; |
| 1275 | } | 1930 | } |
| 1276 | 1931 | ||
| ... | @@ -1418,29 +2073,6 @@ pub fn emitExpr(wasm: *const Wasm, binary_bytes: *ArrayList(u8), expr: Wasm.Expr | ... | @@ -1418,29 +2073,6 @@ pub fn emitExpr(wasm: *const Wasm, binary_bytes: *ArrayList(u8), expr: Wasm.Expr |
| 1418 | try binary_bytes.appendSlice(gpa, slice[0 .. slice.len + 1]); // +1 to include end opcode | 2073 | try binary_bytes.appendSlice(gpa, slice[0 .. slice.len + 1]); // +1 to include end opcode |
| 1419 | } | 2074 | } |
| 1420 | 2075 | ||
| 1421 | fn emitSegmentInfo(wasm: *Wasm, binary_bytes: *std.array_list.Managed(u8)) !void { | ||
| 1422 | const gpa = wasm.base.comp.gpa; | ||
| 1423 | try appendLeb128(gpa, binary_bytes, @backingInt(Wasm.SubsectionType.segment_info)); | ||
| 1424 | const segment_offset = binary_bytes.items.len; | ||
| 1425 | |||
| 1426 | try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(wasm.segment_info.count()))); | ||
| 1427 | for (wasm.segment_info.values()) |segment_info| { | ||
| 1428 | log.debug("Emit segment: {s} align({d}) flags({b})", .{ | ||
| 1429 | segment_info.name, | ||
| 1430 | segment_info.alignment, | ||
| 1431 | segment_info.flags, | ||
| 1432 | }); | ||
| 1433 | try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(segment_info.name.len))); | ||
| 1434 | try binary_bytes.appendSlice(gpa, segment_info.name); | ||
| 1435 | try appendLeb128(gpa, binary_bytes, segment_info.alignment.toLog2Units()); | ||
| 1436 | try appendLeb128(gpa, binary_bytes, segment_info.flags); | ||
| 1437 | } | ||
| 1438 | |||
| 1439 | var buf: [5]u8 = undefined; | ||
| 1440 | leb.writeUnsignedFixed(5, &buf, @as(u32, @intCast(binary_bytes.items.len - segment_offset))); | ||
| 1441 | try binary_bytes.insertSlice(segment_offset, &buf); | ||
| 1442 | } | ||
| 1443 | |||
| 1444 | fn uleb128size(x: u32) u32 { | 2076 | fn uleb128size(x: u32) u32 { |
| 1445 | var value = x; | 2077 | var value = x; |
| 1446 | var size: u32 = 0; | 2078 | var size: u32 = 0; |
| ... | @@ -1449,22 +2081,395 @@ fn uleb128size(x: u32) u32 { | ... | @@ -1449,22 +2081,395 @@ fn uleb128size(x: u32) u32 { |
| 1449 | } | 2081 | } |
| 1450 | 2082 | ||
| 1451 | fn emitTagNameTable( | 2083 | fn emitTagNameTable( |
| 1452 | gpa: Allocator, | 2084 | wasm: *const Wasm, |
| 1453 | code: *ArrayList(u8), | 2085 | code: *ArrayList(u8), |
| 1454 | tag_name_offs: []const u32, | 2086 | tag_name_offs: []const u32, |
| 1455 | tag_name_bytes: []const u8, | 2087 | tag_name_bytes: []const u8, |
| 1456 | base: u32, | 2088 | base: u32, |
| 1457 | comptime Int: type, | 2089 | is64: bool, |
| 1458 | ) error{OutOfMemory}!void { | 2090 | ) error{OutOfMemory}!void { |
| 1459 | const ptr_size_bytes = @divExact(@bitSizeOf(Int), 8); | 2091 | const gpa = wasm.base.comp.gpa; |
| 2092 | const ptr_size_bytes: usize = if (is64) 8 else 4; | ||
| 1460 | try code.ensureUnusedCapacity(gpa, ptr_size_bytes * 2 * tag_name_offs.len); | 2093 | try code.ensureUnusedCapacity(gpa, ptr_size_bytes * 2 * tag_name_offs.len); |
| 1461 | for (tag_name_offs) |off| { | 2094 | for (tag_name_offs) |off| { |
| 1462 | const name_len: u32 = @intCast(mem.indexOfScalar(u8, tag_name_bytes[off..], 0).?); | 2095 | const name_len: u32 = @intCast(mem.findScalar(u8, tag_name_bytes[off..], 0).?); |
| 1463 | mem.writeInt(Int, code.addManyAsArrayAssumeCapacity(ptr_size_bytes), base + off, .little); | 2096 | if (is64) { |
| 1464 | mem.writeInt(Int, code.addManyAsArrayAssumeCapacity(ptr_size_bytes), name_len, .little); | 2097 | mem.writeInt(u64, code.addManyAsArrayAssumeCapacity(8), base + off, .little); |
| 2098 | mem.writeInt(u64, code.addManyAsArrayAssumeCapacity(8), name_len, .little); | ||
| 2099 | } else { | ||
| 2100 | mem.writeInt(u32, code.addManyAsArrayAssumeCapacity(4), base + off, .little); | ||
| 2101 | mem.writeInt(u32, code.addManyAsArrayAssumeCapacity(4), name_len, .little); | ||
| 2102 | } | ||
| 2103 | } | ||
| 2104 | } | ||
| 2105 | |||
| 2106 | fn emitRelocatableNameTable( | ||
| 2107 | wasm: *const Wasm, | ||
| 2108 | code: *ArrayList(u8), | ||
| 2109 | relocs: *ArrayList(Relocation), | ||
| 2110 | output_offset: u32, | ||
| 2111 | name_offs: []const u32, | ||
| 2112 | name_bytes: []const u8, | ||
| 2113 | names_resolution: Wasm.ObjectDataImport.Resolution, | ||
| 2114 | ) error{OutOfMemory}!void { | ||
| 2115 | const gpa = wasm.base.comp.gpa; | ||
| 2116 | const ptr_size = @divExact(wasm.base.comp.root_mod.resolved_target.result.ptrBitWidth(), 8); | ||
| 2117 | const table_start = code.items.len; | ||
| 2118 | const data_index: DataSymbolIndex = .fromResolution(wasm, names_resolution); | ||
| 2119 | try code.ensureUnusedCapacity(gpa, @as(usize, ptr_size) * 2 * name_offs.len); | ||
| 2120 | try relocs.ensureUnusedCapacity(gpa, name_offs.len); | ||
| 2121 | for (name_offs) |off| { | ||
| 2122 | const name_len: u32 = @intCast(mem.findScalar(u8, name_bytes[off..], 0).?); | ||
| 2123 | const reloc_offset = output_offset + @as(u32, @intCast(code.items.len - table_start)); | ||
| 2124 | switch (ptr_size) { | ||
| 2125 | 4 => { | ||
| 2126 | @memset(code.addManyAsArrayAssumeCapacity(4), 0); | ||
| 2127 | mem.writeInt(u32, code.addManyAsArrayAssumeCapacity(4), name_len, .little); | ||
| 2128 | }, | ||
| 2129 | 8 => { | ||
| 2130 | @memset(code.addManyAsArrayAssumeCapacity(8), 0); | ||
| 2131 | mem.writeInt(u64, code.addManyAsArrayAssumeCapacity(8), @intCast(name_len), .little); | ||
| 2132 | }, | ||
| 2133 | else => unreachable, | ||
| 2134 | } | ||
| 2135 | relocs.appendAssumeCapacity(.{ | ||
| 2136 | .tag = if (ptr_size == 4) .memory_addr_i32 else .memory_addr_i64, | ||
| 2137 | .offset = reloc_offset, | ||
| 2138 | .pointee = .{ .data = data_index }, | ||
| 2139 | .addend = @intCast(off), | ||
| 2140 | }); | ||
| 2141 | } | ||
| 2142 | } | ||
| 2143 | |||
| 2144 | fn emitRelocSection( | ||
| 2145 | wasm: *const Wasm, | ||
| 2146 | binary_bytes: *ArrayList(u8), | ||
| 2147 | section_index: u32, | ||
| 2148 | reloc_name: []const u8, | ||
| 2149 | relocs: []const Relocation, | ||
| 2150 | symbol_table_offsets: SymbolTableOffsets, | ||
| 2151 | ) !void { | ||
| 2152 | const comp = wasm.base.comp; | ||
| 2153 | const gpa = comp.gpa; | ||
| 2154 | |||
| 2155 | const header_offset = try reserveCustomSectionHeader(gpa, binary_bytes); | ||
| 2156 | defer writeCustomSectionHeader(binary_bytes, header_offset); | ||
| 2157 | |||
| 2158 | try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(reloc_name.len))); | ||
| 2159 | try binary_bytes.appendSlice(gpa, reloc_name); | ||
| 2160 | |||
| 2161 | try appendLeb128(gpa, binary_bytes, section_index); | ||
| 2162 | try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(relocs.len))); | ||
| 2163 | |||
| 2164 | for (relocs) |r| { | ||
| 2165 | try binary_bytes.append(gpa, @backingInt(r.tag)); | ||
| 2166 | try appendLeb128(gpa, binary_bytes, r.offset); | ||
| 2167 | switch (r.tag) { | ||
| 2168 | .memory_addr_leb, | ||
| 2169 | .memory_addr_sleb, | ||
| 2170 | .memory_addr_i32, | ||
| 2171 | .memory_addr_rel_sleb, | ||
| 2172 | .memory_addr_leb64, | ||
| 2173 | .memory_addr_sleb64, | ||
| 2174 | .memory_addr_i64, | ||
| 2175 | .memory_addr_rel_sleb64, | ||
| 2176 | .memory_addr_tls_sleb, | ||
| 2177 | .memory_addr_locrel_i32, | ||
| 2178 | .memory_addr_tls_sleb64, | ||
| 2179 | => { | ||
| 2180 | const symbol_index: u32 = symbol_table_offsets.data + @backingInt(r.pointee.data); | ||
| 2181 | try appendLeb128(gpa, binary_bytes, symbol_index); | ||
| 2182 | }, | ||
| 2183 | .section_offset_i32 => { | ||
| 2184 | @panic("TODO"); | ||
| 2185 | }, | ||
| 2186 | .type_index_leb => { | ||
| 2187 | try appendLeb128(gpa, binary_bytes, @backingInt(r.pointee.type_index)); | ||
| 2188 | }, | ||
| 2189 | .function_offset_i32, | ||
| 2190 | .function_offset_i64, | ||
| 2191 | .function_index_leb, | ||
| 2192 | .function_index_i32, | ||
| 2193 | .table_index_sleb, | ||
| 2194 | .table_index_i32, | ||
| 2195 | .table_index_sleb64, | ||
| 2196 | .table_index_i64, | ||
| 2197 | .table_index_rel_sleb, | ||
| 2198 | .table_index_rel_sleb64, | ||
| 2199 | => { | ||
| 2200 | const symbol_index: u32 = symbol_table_offsets.function + @backingInt(r.pointee.function); | ||
| 2201 | try appendLeb128(gpa, binary_bytes, symbol_index); | ||
| 2202 | }, | ||
| 2203 | .global_index_leb, .global_index_i32 => { | ||
| 2204 | const symbol_index: u32 = symbol_table_offsets.global + @backingInt(r.pointee.global); | ||
| 2205 | try appendLeb128(gpa, binary_bytes, symbol_index); | ||
| 2206 | }, | ||
| 2207 | .table_number_leb => { | ||
| 2208 | const symbol_index: u32 = symbol_table_offsets.table + @backingInt(r.pointee.table); | ||
| 2209 | try appendLeb128(gpa, binary_bytes, symbol_index); | ||
| 2210 | }, | ||
| 2211 | .event_index_leb => @panic("TODO"), | ||
| 2212 | } | ||
| 2213 | switch (r.tag) { | ||
| 2214 | .memory_addr_leb, | ||
| 2215 | .memory_addr_sleb, | ||
| 2216 | .memory_addr_i32, | ||
| 2217 | .memory_addr_rel_sleb, | ||
| 2218 | .memory_addr_leb64, | ||
| 2219 | .memory_addr_sleb64, | ||
| 2220 | .memory_addr_i64, | ||
| 2221 | .memory_addr_rel_sleb64, | ||
| 2222 | .memory_addr_tls_sleb, | ||
| 2223 | .memory_addr_locrel_i32, | ||
| 2224 | .memory_addr_tls_sleb64, | ||
| 2225 | .function_offset_i32, | ||
| 2226 | .function_offset_i64, | ||
| 2227 | .section_offset_i32, | ||
| 2228 | => { | ||
| 2229 | try appendLeb128(gpa, binary_bytes, r.addend); | ||
| 2230 | }, | ||
| 2231 | else => {}, | ||
| 2232 | } | ||
| 2233 | } | ||
| 2234 | } | ||
| 2235 | |||
| 2236 | fn processZcuRelocs( | ||
| 2237 | wasm: *const Wasm, | ||
| 2238 | out: *ArrayList(Relocation), | ||
| 2239 | output_offset: u32, | ||
| 2240 | input_offset: u32, | ||
| 2241 | relocs: Wasm.ZcuRelocation.Slice, | ||
| 2242 | ) !void { | ||
| 2243 | const gpa = wasm.base.comp.gpa; | ||
| 2244 | for ( | ||
| 2245 | relocs.tags(wasm), | ||
| 2246 | relocs.pointees(wasm), | ||
| 2247 | relocs.offsets(wasm), | ||
| 2248 | relocs.addends(wasm), | ||
| 2249 | ) |tag, pointee, offset, addend| { | ||
| 2250 | const output_pointee: Relocation.Pointee = switch (pointee) { | ||
| 2251 | .function_nav => |nav_index| .{ .function = .fromIpNav(wasm, nav_index) }, | ||
| 2252 | .function_name => |name| .{ .function = .fromSymbolName(wasm, name) }, | ||
| 2253 | .tag_function => |ip_index| .{ .function = .fromTagIndexType(wasm, ip_index) }, | ||
| 2254 | .data_uav => |ip_index| .{ .data = .fromUav(wasm, ip_index) }, | ||
| 2255 | .data_nav => |nav_index| .{ .data = .fromNav(wasm, nav_index) }, | ||
| 2256 | .data_resolution => |resolution| .{ .data = .fromResolution(wasm, resolution) }, | ||
| 2257 | .stack_pointer => .{ .global = .fromSymbolName(wasm, wasm.preloaded_strings.__stack_pointer) }, | ||
| 2258 | .type_index => |type_index| .{ .type_index = .fromTypeIndex(type_index, &wasm.flush_buffer) }, | ||
| 2259 | }; | ||
| 2260 | try out.append(gpa, .{ | ||
| 2261 | .tag = tag, | ||
| 2262 | .offset = output_offset + (offset - input_offset), | ||
| 2263 | .pointee = output_pointee, | ||
| 2264 | .addend = addend, | ||
| 2265 | }); | ||
| 1465 | } | 2266 | } |
| 1466 | } | 2267 | } |
| 1467 | 2268 | ||
| 2269 | fn processRelocs( | ||
| 2270 | wasm: *const Wasm, | ||
| 2271 | out: *ArrayList(Relocation), | ||
| 2272 | output_offset: u32, | ||
| 2273 | input_offset: u32, | ||
| 2274 | relocs: Wasm.ObjectRelocation.IterableSlice, | ||
| 2275 | ) !void { | ||
| 2276 | const gpa = wasm.base.comp.gpa; | ||
| 2277 | for ( | ||
| 2278 | relocs.slice.tags(wasm), | ||
| 2279 | relocs.slice.pointees(wasm), | ||
| 2280 | relocs.slice.offsets(wasm), | ||
| 2281 | relocs.slice.addends(wasm), | ||
| 2282 | ) |tag, pointee, offset, addend| { | ||
| 2283 | if (offset >= relocs.end) break; | ||
| 2284 | const rebased_offset = output_offset + (offset - input_offset); | ||
| 2285 | try out.ensureUnusedCapacity(gpa, 1); | ||
| 2286 | switch (tag) { | ||
| 2287 | .function_index_i32 => out.appendAssumeCapacity(.{ | ||
| 2288 | .tag = .function_index_i32, | ||
| 2289 | .offset = rebased_offset, | ||
| 2290 | .pointee = .{ .function = .fromObjectFunctionHandlingWeak(wasm, pointee.function) }, | ||
| 2291 | .addend = addend, | ||
| 2292 | }), | ||
| 2293 | .function_index_leb => out.appendAssumeCapacity(.{ | ||
| 2294 | .tag = .function_index_leb, | ||
| 2295 | .offset = rebased_offset, | ||
| 2296 | .pointee = .{ .function = .fromObjectFunctionHandlingWeak(wasm, pointee.function) }, | ||
| 2297 | .addend = addend, | ||
| 2298 | }), | ||
| 2299 | .function_offset_i32 => @panic("TODO this value is not known yet"), | ||
| 2300 | .function_offset_i64 => @panic("TODO this value is not known yet"), | ||
| 2301 | .table_index_i32 => out.appendAssumeCapacity(.{ | ||
| 2302 | .tag = .table_index_i32, | ||
| 2303 | .offset = rebased_offset, | ||
| 2304 | .pointee = .{ .function = .fromObjectFunctionHandlingWeak(wasm, pointee.function) }, | ||
| 2305 | .addend = addend, | ||
| 2306 | }), | ||
| 2307 | .table_index_i64 => out.appendAssumeCapacity(.{ | ||
| 2308 | .tag = .table_index_i64, | ||
| 2309 | .offset = rebased_offset, | ||
| 2310 | .pointee = .{ .function = .fromObjectFunctionHandlingWeak(wasm, pointee.function) }, | ||
| 2311 | .addend = addend, | ||
| 2312 | }), | ||
| 2313 | .table_index_rel_sleb => @panic("TODO what does this reloc tag mean?"), | ||
| 2314 | .table_index_rel_sleb64 => @panic("TODO what does this reloc tag mean?"), | ||
| 2315 | .table_index_sleb => out.appendAssumeCapacity(.{ | ||
| 2316 | .tag = .table_index_sleb, | ||
| 2317 | .offset = rebased_offset, | ||
| 2318 | .pointee = .{ .function = .fromObjectFunctionHandlingWeak(wasm, pointee.function) }, | ||
| 2319 | .addend = addend, | ||
| 2320 | }), | ||
| 2321 | .table_index_sleb64 => out.appendAssumeCapacity(.{ | ||
| 2322 | .tag = .table_index_sleb64, | ||
| 2323 | .offset = rebased_offset, | ||
| 2324 | .pointee = .{ .function = .fromObjectFunctionHandlingWeak(wasm, pointee.function) }, | ||
| 2325 | .addend = addend, | ||
| 2326 | }), | ||
| 2327 | |||
| 2328 | .function_import_index_i32 => out.appendAssumeCapacity(.{ | ||
| 2329 | .tag = .function_index_i32, | ||
| 2330 | .offset = rebased_offset, | ||
| 2331 | .pointee = .{ .function = .fromSymbolName(wasm, pointee.symbol_name) }, | ||
| 2332 | .addend = addend, | ||
| 2333 | }), | ||
| 2334 | .function_import_index_leb => out.appendAssumeCapacity(.{ | ||
| 2335 | .tag = .function_index_leb, | ||
| 2336 | .offset = rebased_offset, | ||
| 2337 | .pointee = .{ .function = .fromSymbolName(wasm, pointee.symbol_name) }, | ||
| 2338 | .addend = addend, | ||
| 2339 | }), | ||
| 2340 | .function_import_offset_i32 => @panic("TODO this value is not known yet"), | ||
| 2341 | .function_import_offset_i64 => @panic("TODO this value is not known yet"), | ||
| 2342 | .table_import_index_i32 => out.appendAssumeCapacity(.{ | ||
| 2343 | .tag = .table_index_i32, | ||
| 2344 | .offset = rebased_offset, | ||
| 2345 | .pointee = .{ .function = .fromSymbolName(wasm, pointee.symbol_name) }, | ||
| 2346 | .addend = addend, | ||
| 2347 | }), | ||
| 2348 | .table_import_index_i64 => out.appendAssumeCapacity(.{ | ||
| 2349 | .tag = .table_index_i64, | ||
| 2350 | .offset = rebased_offset, | ||
| 2351 | .pointee = .{ .function = .fromSymbolName(wasm, pointee.symbol_name) }, | ||
| 2352 | .addend = addend, | ||
| 2353 | }), | ||
| 2354 | .table_import_index_rel_sleb => @panic("TODO what does this reloc tag mean?"), | ||
| 2355 | .table_import_index_rel_sleb64 => @panic("TODO what does this reloc tag mean?"), | ||
| 2356 | .table_import_index_sleb => out.appendAssumeCapacity(.{ | ||
| 2357 | .tag = .table_index_sleb, | ||
| 2358 | .offset = rebased_offset, | ||
| 2359 | .pointee = .{ .function = .fromSymbolName(wasm, pointee.symbol_name) }, | ||
| 2360 | .addend = addend, | ||
| 2361 | }), | ||
| 2362 | .table_import_index_sleb64 => out.appendAssumeCapacity(.{ | ||
| 2363 | .tag = .table_index_sleb64, | ||
| 2364 | .offset = rebased_offset, | ||
| 2365 | .pointee = .{ .function = .fromSymbolName(wasm, pointee.symbol_name) }, | ||
| 2366 | .addend = addend, | ||
| 2367 | }), | ||
| 2368 | |||
| 2369 | .global_index_i32 => out.appendAssumeCapacity(.{ | ||
| 2370 | .tag = .global_index_i32, | ||
| 2371 | .offset = rebased_offset, | ||
| 2372 | .pointee = .{ .global = .fromObjectGlobalHandlingWeak(wasm, pointee.global) }, | ||
| 2373 | .addend = addend, | ||
| 2374 | }), | ||
| 2375 | .global_index_leb => out.appendAssumeCapacity(.{ | ||
| 2376 | .tag = .global_index_leb, | ||
| 2377 | .offset = rebased_offset, | ||
| 2378 | .pointee = .{ .global = .fromObjectGlobalHandlingWeak(wasm, pointee.global) }, | ||
| 2379 | .addend = addend, | ||
| 2380 | }), | ||
| 2381 | |||
| 2382 | .global_import_index_i32 => out.appendAssumeCapacity(.{ | ||
| 2383 | .tag = .global_index_i32, | ||
| 2384 | .offset = rebased_offset, | ||
| 2385 | .pointee = .{ .global = .fromSymbolName(wasm, pointee.symbol_name) }, | ||
| 2386 | .addend = addend, | ||
| 2387 | }), | ||
| 2388 | .global_import_index_leb => out.appendAssumeCapacity(.{ | ||
| 2389 | .tag = .global_index_leb, | ||
| 2390 | .offset = rebased_offset, | ||
| 2391 | .pointee = .{ .global = .fromSymbolName(wasm, pointee.symbol_name) }, | ||
| 2392 | .addend = addend, | ||
| 2393 | }), | ||
| 2394 | |||
| 2395 | .memory_addr_i32, | ||
| 2396 | .memory_addr_i64, | ||
| 2397 | .memory_addr_leb, | ||
| 2398 | .memory_addr_leb64, | ||
| 2399 | .memory_addr_sleb, | ||
| 2400 | .memory_addr_sleb64, | ||
| 2401 | .memory_addr_tls_sleb, | ||
| 2402 | .memory_addr_tls_sleb64, | ||
| 2403 | => out.appendAssumeCapacity(.{ | ||
| 2404 | .tag = memoryRelocationType(tag), | ||
| 2405 | .offset = rebased_offset, | ||
| 2406 | .pointee = .{ .data = .fromObjectData(wasm, pointee.data) }, | ||
| 2407 | .addend = addend, | ||
| 2408 | }), | ||
| 2409 | .memory_addr_locrel_i32 => @panic("TODO implement relocation memory_addr_locrel_i32"), | ||
| 2410 | .memory_addr_rel_sleb => @panic("TODO implement relocation memory_addr_rel_sleb"), | ||
| 2411 | .memory_addr_rel_sleb64 => @panic("TODO implement relocation memory_addr_rel_sleb64"), | ||
| 2412 | |||
| 2413 | .memory_addr_import_i32, | ||
| 2414 | .memory_addr_import_i64, | ||
| 2415 | .memory_addr_import_leb, | ||
| 2416 | .memory_addr_import_leb64, | ||
| 2417 | .memory_addr_import_sleb, | ||
| 2418 | .memory_addr_import_sleb64, | ||
| 2419 | => out.appendAssumeCapacity(.{ | ||
| 2420 | .tag = memoryRelocationType(tag), | ||
| 2421 | .offset = rebased_offset, | ||
| 2422 | .pointee = .{ .data = .fromSymbolName(wasm, pointee.symbol_name) }, | ||
| 2423 | .addend = addend, | ||
| 2424 | }), | ||
| 2425 | .memory_addr_import_locrel_i32 => @panic("TODO implement relocation memory_addr_import_locrel_i32"), | ||
| 2426 | .memory_addr_import_rel_sleb => @panic("TODO implement relocation memory_addr_import_rel_sleb"), | ||
| 2427 | .memory_addr_import_rel_sleb64 => @panic("TODO implement memory_addr_import_rel_sleb64"), | ||
| 2428 | .memory_addr_import_tls_sleb => @panic("TODO"), | ||
| 2429 | .memory_addr_import_tls_sleb64 => @panic("TODO"), | ||
| 2430 | |||
| 2431 | .section_offset_i32 => @panic("TODO this value is not known yet"), | ||
| 2432 | |||
| 2433 | .table_number_leb => out.appendAssumeCapacity(.{ | ||
| 2434 | .tag = .table_number_leb, | ||
| 2435 | .offset = rebased_offset, | ||
| 2436 | .pointee = .{ .table = .fromObjectTable(wasm, pointee.table) }, | ||
| 2437 | .addend = addend, | ||
| 2438 | }), | ||
| 2439 | .table_import_number_leb => out.appendAssumeCapacity(.{ | ||
| 2440 | .tag = .table_number_leb, | ||
| 2441 | .offset = rebased_offset, | ||
| 2442 | .pointee = .{ .table = .fromSymbolName(wasm, pointee.symbol_name) }, | ||
| 2443 | .addend = addend, | ||
| 2444 | }), | ||
| 2445 | |||
| 2446 | .type_index_leb => out.appendAssumeCapacity(.{ | ||
| 2447 | .tag = .type_index_leb, | ||
| 2448 | .offset = rebased_offset, | ||
| 2449 | .pointee = .{ .type_index = .fromTypeIndex(pointee.type_index, &wasm.flush_buffer) }, | ||
| 2450 | .addend = addend, | ||
| 2451 | }), | ||
| 2452 | } | ||
| 2453 | } | ||
| 2454 | } | ||
| 2455 | |||
| 2456 | fn memoryRelocationType(tag: Wasm.ObjectRelocation.Tag) Object.RelocationType { | ||
| 2457 | return switch (tag) { | ||
| 2458 | .memory_addr_i32, .memory_addr_import_i32 => .memory_addr_i32, | ||
| 2459 | .memory_addr_i64, .memory_addr_import_i64 => .memory_addr_i64, | ||
| 2460 | .memory_addr_leb, .memory_addr_import_leb => .memory_addr_leb, | ||
| 2461 | .memory_addr_leb64, .memory_addr_import_leb64 => .memory_addr_leb64, | ||
| 2462 | .memory_addr_locrel_i32, .memory_addr_import_locrel_i32 => .memory_addr_locrel_i32, | ||
| 2463 | .memory_addr_rel_sleb, .memory_addr_import_rel_sleb => .memory_addr_rel_sleb, | ||
| 2464 | .memory_addr_rel_sleb64, .memory_addr_import_rel_sleb64 => .memory_addr_rel_sleb64, | ||
| 2465 | .memory_addr_sleb, .memory_addr_import_sleb => .memory_addr_sleb, | ||
| 2466 | .memory_addr_sleb64, .memory_addr_import_sleb64 => .memory_addr_sleb64, | ||
| 2467 | .memory_addr_tls_sleb, .memory_addr_import_tls_sleb => .memory_addr_tls_sleb, | ||
| 2468 | .memory_addr_tls_sleb64, .memory_addr_import_tls_sleb64 => .memory_addr_tls_sleb64, | ||
| 2469 | else => unreachable, | ||
| 2470 | }; | ||
| 2471 | } | ||
| 2472 | |||
| 1468 | fn applyRelocs(code: []u8, code_offset: u32, relocs: Wasm.ObjectRelocation.IterableSlice, wasm: *const Wasm) void { | 2473 | fn applyRelocs(code: []u8, code_offset: u32, relocs: Wasm.ObjectRelocation.IterableSlice, wasm: *const Wasm) void { |
| 1469 | for ( | 2474 | for ( |
| 1470 | relocs.slice.tags(wasm), | 2475 | relocs.slice.tags(wasm), |
| ... | @@ -1579,12 +2584,17 @@ const RelocAddr = struct { | ... | @@ -1579,12 +2584,17 @@ const RelocAddr = struct { |
| 1579 | fn fromSymbolName(wasm: *const Wasm, name: String, addend: i32) RelocAddr { | 2584 | fn fromSymbolName(wasm: *const Wasm, name: String, addend: i32) RelocAddr { |
| 1580 | const flush = &wasm.flush_buffer; | 2585 | const flush = &wasm.flush_buffer; |
| 1581 | if (wasm.object_data_imports.getPtr(name)) |import| { | 2586 | if (wasm.object_data_imports.getPtr(name)) |import| { |
| 1582 | return fromDataLoc(flush, import.resolution.dataLoc(wasm), addend); | 2587 | if (import.resolution != .unresolved) { |
| 1583 | } else if (wasm.data_imports.get(name)) |id| { | 2588 | return fromDataLoc(flush, import.resolution.dataLoc(wasm), addend); |
| 2589 | } | ||
| 2590 | } | ||
| 2591 | if (flush.data_exports.get(name)) |symbol| { | ||
| 2592 | return fromDataLoc(flush, symbol.resolution.dataLoc(wasm), addend); | ||
| 2593 | } | ||
| 2594 | if (wasm.data_imports.get(name)) |id| { | ||
| 1584 | return fromDataLoc(flush, .fromDataImportId(wasm, id), addend); | 2595 | return fromDataLoc(flush, .fromDataImportId(wasm, id), addend); |
| 1585 | } else { | ||
| 1586 | unreachable; | ||
| 1587 | } | 2596 | } |
| 2597 | unreachable; | ||
| 1588 | } | 2598 | } |
| 1589 | 2599 | ||
| 1590 | fn fromDataLoc(flush: *const Flush, data_loc: Wasm.DataLoc, addend: i32) RelocAddr { | 2600 | fn fromDataLoc(flush: *const Flush, data_loc: Wasm.DataLoc, addend: i32) RelocAddr { |
| ... | @@ -1702,13 +2712,11 @@ fn emitInitMemoryFunction( | ... | @@ -1702,13 +2712,11 @@ fn emitInitMemoryFunction( |
| 1702 | } | 2712 | } |
| 1703 | 2713 | ||
| 1704 | const segment_groups = wasm.flush_buffer.data_segment_groups.items; | 2714 | const segment_groups = wasm.flush_buffer.data_segment_groups.items; |
| 1705 | var prev_end: u32 = 0; | ||
| 1706 | for (segment_groups, 0..) |group, segment_index| { | 2715 | for (segment_groups, 0..) |group, segment_index| { |
| 1707 | defer prev_end = group.end_addr; | ||
| 1708 | const segment = group.first_segment; | 2716 | const segment = group.first_segment; |
| 1709 | if (!segment.isPassive(wasm)) continue; | 2717 | if (!segment.isPassive(wasm)) continue; |
| 1710 | 2718 | ||
| 1711 | const start_addr: u32 = @intCast(segment.alignment(wasm).forward(prev_end)); | 2719 | const start_addr = wasm.flush_buffer.data_segments.get(segment).?; |
| 1712 | const segment_size: u32 = group.end_addr - start_addr; | 2720 | const segment_size: u32 = group.end_addr - start_addr; |
| 1713 | 2721 | ||
| 1714 | try binary_bytes.ensureUnusedCapacity(gpa, 6 + 6 + 1 + 5 + 6 + 6 + 1 + 6 * 2 + 1 + 1); | 2722 | try binary_bytes.ensureUnusedCapacity(gpa, 6 + 6 + 1 + 5 + 6 + 6 + 1 + 6 * 2 + 1 + 1); |
| ... | @@ -2028,12 +3036,15 @@ fn appendReservedUleb32(bytes: *ArrayList(u8), val: u32) void { | ... | @@ -2028,12 +3036,15 @@ fn appendReservedUleb32(bytes: *ArrayList(u8), val: u32) void { |
| 2028 | }; | 3036 | }; |
| 2029 | } | 3037 | } |
| 2030 | 3038 | ||
| 2031 | fn appendGlobal(gpa: Allocator, bytes: *ArrayList(u8), mutable: u8, val: u32) Allocator.Error!void { | 3039 | fn appendGlobal(gpa: Allocator, bytes: *ArrayList(u8), mutable: u8, val: u64, is64: bool) Allocator.Error!void { |
| 2032 | try bytes.ensureUnusedCapacity(gpa, 9); | 3040 | try bytes.ensureUnusedCapacity(gpa, if (is64) 14 else 9); |
| 2033 | bytes.appendAssumeCapacity(@backingInt(std.wasm.Valtype.i32)); | 3041 | bytes.appendAssumeCapacity(@backingInt(@as(std.wasm.Valtype, if (is64) .i64 else .i32))); |
| 2034 | bytes.appendAssumeCapacity(mutable); | 3042 | bytes.appendAssumeCapacity(mutable); |
| 2035 | bytes.appendAssumeCapacity(@backingInt(std.wasm.Opcode.i32_const)); | 3043 | if (is64) { |
| 2036 | appendReservedUleb32(bytes, val); | 3044 | appendReservedI64Const(bytes, val); |
| 3045 | } else { | ||
| 3046 | appendReservedI32Const(bytes, @intCast(val)); | ||
| 3047 | } | ||
| 2037 | bytes.appendAssumeCapacity(@backingInt(std.wasm.Opcode.end)); | 3048 | bytes.appendAssumeCapacity(@backingInt(std.wasm.Opcode.end)); |
| 2038 | } | 3049 | } |
| 2039 | 3050 |
src/link/Wasm/Object.zig+2-2| ... | @@ -146,7 +146,7 @@ pub const Symbol = struct { | ... | @@ -146,7 +146,7 @@ pub const Symbol = struct { |
| 146 | pointee: Pointee, | 146 | pointee: Pointee, |
| 147 | 147 | ||
| 148 | /// https://github.com/WebAssembly/tool-conventions/blob/df8d737539eb8a8f446ba5eab9dc670c40dfb81e/Linking.md#symbol-table-subsection | 148 | /// https://github.com/WebAssembly/tool-conventions/blob/df8d737539eb8a8f446ba5eab9dc670c40dfb81e/Linking.md#symbol-table-subsection |
| 149 | const Tag = enum(u8) { | 149 | pub const Tag = enum(u8) { |
| 150 | function, | 150 | function, |
| 151 | data, | 151 | data, |
| 152 | global, | 152 | global, |
| ... | @@ -856,7 +856,7 @@ pub fn parse( | ... | @@ -856,7 +856,7 @@ pub fn parse( |
| 856 | start_function = @fromBackingInt(@intCast(functions_start + index)); | 856 | start_function = @fromBackingInt(@intCast(functions_start + index)); |
| 857 | }, | 857 | }, |
| 858 | .element => { | 858 | .element => { |
| 859 | log.warn("unimplemented: element section in {f} {?s}", .{ path, archive_member_name }); | 859 | // element section is not needed for linking, validating it serves no purpose |
| 860 | pos = section_end; | 860 | pos = section_end; |
| 861 | }, | 861 | }, |
| 862 | .code => { | 862 | .code => { |
src/main.zig+40-54| ... | @@ -44,9 +44,9 @@ pub const std_options: std.Options = .{ | ... | @@ -44,9 +44,9 @@ pub const std_options: std.Options = .{ |
| 44 | .logFn = log, | 44 | .logFn = log, |
| 45 | 45 | ||
| 46 | .log_level = switch (builtin.mode) { | 46 | .log_level = switch (builtin.mode) { |
| 47 | .Debug => .debug, | 47 | .debug => .debug, |
| 48 | .ReleaseSafe, .ReleaseFast => .info, | 48 | .safe, .fast => .info, |
| 49 | .ReleaseSmall => .err, | 49 | .small => .err, |
| 50 | }, | 50 | }, |
| 51 | }; | 51 | }; |
| 52 | pub const std_options_cwd = if (native_os == .wasi) wasi_cwd else null; | 52 | pub const std_options_cwd = if (native_os == .wasi) wasi_cwd else null; |
| ... | @@ -158,8 +158,8 @@ pub fn log( | ... | @@ -158,8 +158,8 @@ pub fn log( |
| 158 | 158 | ||
| 159 | const use_safe_allocator = build_options.debug_gpa or | 159 | const use_safe_allocator = build_options.debug_gpa or |
| 160 | (native_os != .wasi and !builtin.link_libc and switch (builtin.mode) { | 160 | (native_os != .wasi and !builtin.link_libc and switch (builtin.mode) { |
| 161 | .Debug, .ReleaseSafe => true, | 161 | .debug, .safe => true, |
| 162 | .ReleaseFast, .ReleaseSmall => false, | 162 | .fast, .small => false, |
| 163 | }); | 163 | }); |
| 164 | 164 | ||
| 165 | var safe_allocator: std.heap.SafeAllocator = .init(std.heap.page_allocator, .{ | 165 | var safe_allocator: std.heap.SafeAllocator = .init(std.heap.page_allocator, .{ |
| ... | @@ -359,8 +359,7 @@ fn mainArgs( | ... | @@ -359,8 +359,7 @@ fn mainArgs( |
| 359 | .prepend_global_cache_path = true, | 359 | .prepend_global_cache_path = true, |
| 360 | .prepend_zig_exe_path = true, | 360 | .prepend_zig_exe_path = true, |
| 361 | .prepend_seed = true, | 361 | .prepend_seed = true, |
| 362 | .debug_env_var = .ZIG_DEBUG_MAKER, | 362 | .release_mode = .safe, |
| 363 | .release_mode = .ReleaseSafe, | ||
| 364 | }); | 363 | }); |
| 365 | }, | 364 | }, |
| 366 | .clang, .@"-cc1", .@"-cc1as" => { | 365 | .clang, .@"-cc1", .@"-cc1as" => { |
| ... | @@ -557,10 +556,6 @@ const usage_build_generic = | ... | @@ -557,10 +556,6 @@ const usage_build_generic = |
| 557 | \\ -fno-function-sections All functions go into same section | 556 | \\ -fno-function-sections All functions go into same section |
| 558 | \\ -fdata-sections Places each data in a separate section | 557 | \\ -fdata-sections Places each data in a separate section |
| 559 | \\ -fno-data-sections All data go into same section | 558 | \\ -fno-data-sections All data go into same section |
| 560 | \\ -fformatted-panics Enable formatted safety panics | ||
| 561 | \\ -fno-formatted-panics Disable formatted safety panics | ||
| 562 | \\ -fstructured-cfg (SPIR-V) force SPIR-V kernels to use structured control flow | ||
| 563 | \\ -fno-structured-cfg (SPIR-V) force SPIR-V kernels to not use structured control flow | ||
| 564 | \\ -mexec-model=[value] (WASI) Execution model | 559 | \\ -mexec-model=[value] (WASI) Execution model |
| 565 | \\ -municode (Windows) Use wmain/wWinMain as entry point | 560 | \\ -municode (Windows) Use wmain/wWinMain as entry point |
| 566 | \\ --time-report Send timing diagnostics to '--listen' clients | 561 | \\ --time-report Send timing diagnostics to '--listen' clients |
| ... | @@ -568,10 +563,10 @@ const usage_build_generic = | ... | @@ -568,10 +563,10 @@ const usage_build_generic = |
| 568 | \\Per-Module Compile Options: | 563 | \\Per-Module Compile Options: |
| 569 | \\ -target [name] <arch><sub>-<os>-<abi> see the targets command | 564 | \\ -target [name] <arch><sub>-<os>-<abi> see the targets command |
| 570 | \\ -O [mode] Choose what to optimize for | 565 | \\ -O [mode] Choose what to optimize for |
| 571 | \\ Debug (default) Optimizations off, safety on | 566 | \\ debug (default) Prioritize bug detection, accurate debug info, compilation speed |
| 572 | \\ ReleaseFast Optimize for performance, safety off | 567 | \\ fast Prioritize runtime performance. Safety checks off. |
| 573 | \\ ReleaseSafe Optimize for performance, safety on | 568 | \\ safe Enable both safety checks and machine code optimizations |
| 574 | \\ ReleaseSmall Optimize for small binary, safety off | 569 | \\ small Prioritize small binary size. Safety checks off. |
| 575 | \\ -ofmt=[fmt] Override target object format | 570 | \\ -ofmt=[fmt] Override target object format |
| 576 | \\ elf Executable and Linking Format | 571 | \\ elf Executable and Linking Format |
| 577 | \\ c C source code | 572 | \\ c C source code |
| ... | @@ -994,7 +989,7 @@ fn buildOutputType( | ... | @@ -994,7 +989,7 @@ fn buildOutputType( |
| 994 | var minor_subsystem_version: ?u16 = null; | 989 | var minor_subsystem_version: ?u16 = null; |
| 995 | var mingw_unicode_entry_point: bool = false; | 990 | var mingw_unicode_entry_point: bool = false; |
| 996 | var enable_link_snapshots: bool = false; | 991 | var enable_link_snapshots: bool = false; |
| 997 | var debug_compiler_runtime_libs: ?std.lang.OptimizeMode = null; | 992 | var debug_compiler_runtime_libs: ?std.lang.Optimize = null; |
| 998 | var install_name: ?[]const u8 = null; | 993 | var install_name: ?[]const u8 = null; |
| 999 | var hash_style: link.File.Lld.Elf.HashStyle = .both; | 994 | var hash_style: link.File.Lld.Elf.HashStyle = .both; |
| 1000 | var entitlements: ?[]const u8 = null; | 995 | var entitlements: ?[]const u8 = null; |
| ... | @@ -1200,10 +1195,6 @@ fn buildOutputType( | ... | @@ -1200,10 +1195,6 @@ fn buildOutputType( |
| 1200 | if (mem.eql(u8, next_arg, "--")) break; | 1195 | if (mem.eql(u8, next_arg, "--")) break; |
| 1201 | try extra_rcflags.append(arena, next_arg); | 1196 | try extra_rcflags.append(arena, next_arg); |
| 1202 | } | 1197 | } |
| 1203 | } else if (mem.eql(u8, arg, "-fstructured-cfg")) { | ||
| 1204 | mod_opts.structured_cfg = true; | ||
| 1205 | } else if (mem.eql(u8, arg, "-fno-structured-cfg")) { | ||
| 1206 | mod_opts.structured_cfg = false; | ||
| 1207 | } else if (mem.eql(u8, arg, "--color")) { | 1198 | } else if (mem.eql(u8, arg, "--color")) { |
| 1208 | const next_arg = args_iter.next() orelse { | 1199 | const next_arg = args_iter.next() orelse { |
| 1209 | fatal("expected [auto|on|off] after --color", .{}); | 1200 | fatal("expected [auto|on|off] after --color", .{}); |
| ... | @@ -1433,7 +1424,7 @@ fn buildOutputType( | ... | @@ -1433,7 +1424,7 @@ fn buildOutputType( |
| 1433 | enable_link_snapshots = true; | 1424 | enable_link_snapshots = true; |
| 1434 | } | 1425 | } |
| 1435 | } else if (mem.eql(u8, arg, "--debug-rt")) { | 1426 | } else if (mem.eql(u8, arg, "--debug-rt")) { |
| 1436 | debug_compiler_runtime_libs = .Debug; | 1427 | debug_compiler_runtime_libs = .debug; |
| 1437 | } else if (mem.cutPrefix(u8, arg, "--debug-rt=")) |rest| { | 1428 | } else if (mem.cutPrefix(u8, arg, "--debug-rt=")) |rest| { |
| 1438 | debug_compiler_runtime_libs = parseOptimizeMode(rest); | 1429 | debug_compiler_runtime_libs = parseOptimizeMode(rest); |
| 1439 | } else if (mem.eql(u8, arg, "--debug-incremental")) { | 1430 | } else if (mem.eql(u8, arg, "--debug-incremental")) { |
| ... | @@ -1650,12 +1641,6 @@ fn buildOutputType( | ... | @@ -1650,12 +1641,6 @@ fn buildOutputType( |
| 1650 | create_module.opts.debug_format = .{ .dwarf = .@"32" }; | 1641 | create_module.opts.debug_format = .{ .dwarf = .@"32" }; |
| 1651 | } else if (mem.eql(u8, arg, "-gdwarf64")) { | 1642 | } else if (mem.eql(u8, arg, "-gdwarf64")) { |
| 1652 | create_module.opts.debug_format = .{ .dwarf = .@"64" }; | 1643 | create_module.opts.debug_format = .{ .dwarf = .@"64" }; |
| 1653 | } else if (mem.eql(u8, arg, "-fformatted-panics")) { | ||
| 1654 | // Remove this after 0.15.0 is tagged. | ||
| 1655 | warn("-fformatted-panics is deprecated and does nothing", .{}); | ||
| 1656 | } else if (mem.eql(u8, arg, "-fno-formatted-panics")) { | ||
| 1657 | // Remove this after 0.15.0 is tagged. | ||
| 1658 | warn("-fno-formatted-panics is deprecated and does nothing", .{}); | ||
| 1659 | } else if (mem.eql(u8, arg, "-fsingle-threaded")) { | 1644 | } else if (mem.eql(u8, arg, "-fsingle-threaded")) { |
| 1660 | mod_opts.single_threaded = true; | 1645 | mod_opts.single_threaded = true; |
| 1661 | } else if (mem.eql(u8, arg, "-fno-single-threaded")) { | 1646 | } else if (mem.eql(u8, arg, "-fno-single-threaded")) { |
| ... | @@ -2162,7 +2147,7 @@ fn buildOutputType( | ... | @@ -2162,7 +2147,7 @@ fn buildOutputType( |
| 2162 | preprocessor_arg[0] == '-' and | 2147 | preprocessor_arg[0] == '-' and |
| 2163 | preprocessor_arg[2] != '-') | 2148 | preprocessor_arg[2] != '-') |
| 2164 | { | 2149 | { |
| 2165 | if (mem.indexOfScalar(u8, preprocessor_arg, '=')) |equals_pos| { | 2150 | if (mem.findScalar(u8, preprocessor_arg, '=')) |equals_pos| { |
| 2166 | const key = preprocessor_arg[0..equals_pos]; | 2151 | const key = preprocessor_arg[0..equals_pos]; |
| 2167 | const value = preprocessor_arg[equals_pos + 1 ..]; | 2152 | const value = preprocessor_arg[equals_pos + 1 ..]; |
| 2168 | try preprocessor_args.append(key); | 2153 | try preprocessor_args.append(key); |
| ... | @@ -2184,7 +2169,7 @@ fn buildOutputType( | ... | @@ -2184,7 +2169,7 @@ fn buildOutputType( |
| 2184 | linker_arg[0] == '-' and | 2169 | linker_arg[0] == '-' and |
| 2185 | linker_arg[2] != '-') | 2170 | linker_arg[2] != '-') |
| 2186 | { | 2171 | { |
| 2187 | if (mem.indexOfScalar(u8, linker_arg, '=')) |equals_pos| { | 2172 | if (mem.findScalar(u8, linker_arg, '=')) |equals_pos| { |
| 2188 | const key = linker_arg[0..equals_pos]; | 2173 | const key = linker_arg[0..equals_pos]; |
| 2189 | const value = linker_arg[equals_pos + 1 ..]; | 2174 | const value = linker_arg[equals_pos + 1 ..]; |
| 2190 | 2175 | ||
| ... | @@ -2271,18 +2256,18 @@ fn buildOutputType( | ... | @@ -2271,18 +2256,18 @@ fn buildOutputType( |
| 2271 | if (mem.eql(u8, level, "s") or | 2256 | if (mem.eql(u8, level, "s") or |
| 2272 | mem.eql(u8, level, "z")) | 2257 | mem.eql(u8, level, "z")) |
| 2273 | { | 2258 | { |
| 2274 | mod_opts.optimize_mode = .ReleaseSmall; | 2259 | mod_opts.optimize_mode = .small; |
| 2275 | } else if (mem.eql(u8, level, "1") or | 2260 | } else if (mem.eql(u8, level, "1") or |
| 2276 | mem.eql(u8, level, "2") or | 2261 | mem.eql(u8, level, "2") or |
| 2277 | mem.eql(u8, level, "3") or | 2262 | mem.eql(u8, level, "3") or |
| 2278 | mem.eql(u8, level, "4") or | 2263 | mem.eql(u8, level, "4") or |
| 2279 | mem.eql(u8, level, "fast")) | 2264 | mem.eql(u8, level, "fast")) |
| 2280 | { | 2265 | { |
| 2281 | mod_opts.optimize_mode = .ReleaseFast; | 2266 | mod_opts.optimize_mode = .fast; |
| 2282 | } else if (mem.eql(u8, level, "g") or | 2267 | } else if (mem.eql(u8, level, "g") or |
| 2283 | mem.eql(u8, level, "0")) | 2268 | mem.eql(u8, level, "0")) |
| 2284 | { | 2269 | { |
| 2285 | mod_opts.optimize_mode = .Debug; | 2270 | mod_opts.optimize_mode = .debug; |
| 2286 | } else { | 2271 | } else { |
| 2287 | try cc_argv.appendSlice(arena, it.other_args); | 2272 | try cc_argv.appendSlice(arena, it.other_args); |
| 2288 | } | 2273 | } |
| ... | @@ -2356,9 +2341,9 @@ fn buildOutputType( | ... | @@ -2356,9 +2341,9 @@ fn buildOutputType( |
| 2356 | // `sanitize_c` will resolve to! So we either have to pick `off` or `full`. | 2341 | // `sanitize_c` will resolve to! So we either have to pick `off` or `full`. |
| 2357 | // | 2342 | // |
| 2358 | // `full` has the potential to be problematic if `optimize_mode` turns out to | 2343 | // `full` has the potential to be problematic if `optimize_mode` turns out to |
| 2359 | // be `ReleaseFast`/`ReleaseSmall` because the user will get a slower and larger | 2344 | // be `fast`/`small` because the user will get a slower and larger |
| 2360 | // binary than expected. On the other hand, if `optimize_mode` turns out to be | 2345 | // binary than expected. On the other hand, if `optimize_mode` turns out to be |
| 2361 | // `Debug`/`ReleaseSafe`, `off` would mean UBSan would unexpectedly be disabled. | 2346 | // `debug`/`safe`, `off` would mean UBSan would unexpectedly be disabled. |
| 2362 | // | 2347 | // |
| 2363 | // `off` seems very slightly less bad, so let's go with that. | 2348 | // `off` seems very slightly less bad, so let's go with that. |
| 2364 | mod_opts.sanitize_c = .off; | 2349 | mod_opts.sanitize_c = .off; |
| ... | @@ -2392,7 +2377,7 @@ fn buildOutputType( | ... | @@ -2392,7 +2377,7 @@ fn buildOutputType( |
| 2392 | // Handle joined args like `--dependency-file=foo.d`. | 2377 | // Handle joined args like `--dependency-file=foo.d`. |
| 2393 | // Must be prefixed with 1 or 2 dashes. | 2378 | // Must be prefixed with 1 or 2 dashes. |
| 2394 | if (it.only_arg.len >= 3 and it.only_arg[0] == '-' and it.only_arg[2] != '-') { | 2379 | if (it.only_arg.len >= 3 and it.only_arg[0] == '-' and it.only_arg[2] != '-') { |
| 2395 | if (mem.indexOfScalar(u8, it.only_arg, '=')) |equals_pos| { | 2380 | if (mem.findScalar(u8, it.only_arg, '=')) |equals_pos| { |
| 2396 | const key = it.only_arg[0..equals_pos]; | 2381 | const key = it.only_arg[0..equals_pos]; |
| 2397 | const value = it.only_arg[equals_pos + 1 ..]; | 2382 | const value = it.only_arg[equals_pos + 1 ..]; |
| 2398 | 2383 | ||
| ... | @@ -2972,8 +2957,8 @@ fn buildOutputType( | ... | @@ -2972,8 +2957,8 @@ fn buildOutputType( |
| 2972 | } | 2957 | } |
| 2973 | 2958 | ||
| 2974 | if (mod_opts.sanitize_c) |wsc| { | 2959 | if (mod_opts.sanitize_c) |wsc| { |
| 2975 | if (wsc != .off and mod_opts.optimize_mode == .ReleaseFast) { | 2960 | if (wsc != .off and mod_opts.optimize_mode == .fast) { |
| 2976 | mod_opts.optimize_mode = .ReleaseSafe; | 2961 | mod_opts.optimize_mode = .safe; |
| 2977 | } | 2962 | } |
| 2978 | } | 2963 | } |
| 2979 | 2964 | ||
| ... | @@ -3835,11 +3820,17 @@ fn buildOutputType( | ... | @@ -3835,11 +3820,17 @@ fn buildOutputType( |
| 3835 | 3820 | ||
| 3836 | var prev_has_cflags = false; | 3821 | var prev_has_cflags = false; |
| 3837 | var prev_has_rcflags = false; | 3822 | var prev_has_rcflags = false; |
| 3838 | if (dirs.zig_lib.path) |zig_lib_path| { | 3823 | { |
| 3839 | try test_exec_args.appendSlice(arena, &.{ "-cflags", "-I", zig_lib_path, "--" }); | 3824 | if (dirs.zig_lib.path) |zig_lib_path| { |
| 3840 | prev_has_cflags = true; | 3825 | try test_exec_args.appendSlice(arena, &.{ "-cflags", "-I", zig_lib_path, "--" }); |
| 3826 | prev_has_cflags = true; | ||
| 3827 | } | ||
| 3828 | const emit_ext: Compilation.FileExt = .c; | ||
| 3829 | const need_lang = if (comp.emit_bin) |comp_emit_bin| Compilation.classifyFileExt(comp_emit_bin) != emit_ext else true; | ||
| 3830 | if (need_lang) try test_exec_args.appendSlice(arena, &.{ "-x", emit_ext.toLang() }); | ||
| 3831 | try test_exec_args.append(arena, null); | ||
| 3832 | if (need_lang) try test_exec_args.appendSlice(arena, &.{ "-x", "none" }); | ||
| 3841 | } | 3833 | } |
| 3842 | try test_exec_args.append(arena, null); | ||
| 3843 | for (create_module.modules.keys(), create_module.modules.values()) |mod_name, mod| { | 3834 | for (create_module.modules.keys(), create_module.modules.values()) |mod_name, mod| { |
| 3844 | for (create_module.c_source_files.items[mod.c_source_files_start..mod.c_source_files_end]) |c_source_file| { | 3835 | for (create_module.c_source_files.items[mod.c_source_files_start..mod.c_source_files_end]) |c_source_file| { |
| 3845 | const cflags_len = c_source_file.extra_flags.len + c_source_file.cache_exempt_flags.len; | 3836 | const cflags_len = c_source_file.extra_flags.len + c_source_file.cache_exempt_flags.len; |
| ... | @@ -4305,11 +4296,8 @@ fn serve( | ... | @@ -4305,11 +4296,8 @@ fn serve( |
| 4305 | const gpa = comp.gpa; | 4296 | const gpa = comp.gpa; |
| 4306 | const io = comp.io; | 4297 | const io = comp.io; |
| 4307 | 4298 | ||
| 4308 | var server = try Server.init(.{ | 4299 | var server: Server = .{ .in = in, .out = out }; |
| 4309 | .in = in, | 4300 | try server.serveStringMessage(.zig_version, build_options.version); |
| 4310 | .out = out, | ||
| 4311 | .zig_version = build_options.version, | ||
| 4312 | }); | ||
| 4313 | 4301 | ||
| 4314 | var child_pid: ?std.process.Child.Id = null; | 4302 | var child_pid: ?std.process.Child.Id = null; |
| 4315 | 4303 | ||
| ... | @@ -4874,8 +4862,7 @@ const JitCmdOptions = struct { | ... | @@ -4874,8 +4862,7 @@ const JitCmdOptions = struct { |
| 4874 | capture: ?*[]u8 = null, | 4862 | capture: ?*[]u8 = null, |
| 4875 | /// Send error bundles via std.zig.Server over stdout | 4863 | /// Send error bundles via std.zig.Server over stdout |
| 4876 | server: bool = false, | 4864 | server: bool = false, |
| 4877 | debug_env_var: EnvVar = .ZIG_DEBUG_CMD, | 4865 | release_mode: std.lang.Optimize = .fast, |
| 4878 | release_mode: std.lang.OptimizeMode = .ReleaseFast, | ||
| 4879 | }; | 4866 | }; |
| 4880 | 4867 | ||
| 4881 | fn jitCmd( | 4868 | fn jitCmd( |
| ... | @@ -4926,11 +4913,11 @@ fn jitCmdInner( | ... | @@ -4926,11 +4913,11 @@ fn jitCmdInner( |
| 4926 | const self_exe_path = process.executablePathAlloc(io, arena) catch |err| | 4913 | const self_exe_path = process.executablePathAlloc(io, arena) catch |err| |
| 4927 | fatal("unable to find self exe path: {t}", .{err}); | 4914 | fatal("unable to find self exe path: {t}", .{err}); |
| 4928 | 4915 | ||
| 4929 | const optimize_mode: std.lang.OptimizeMode = if (options.debug_env_var.isSet(environ_map)) | 4916 | const optimize_mode: std.lang.Optimize = if (EnvVar.ZIG_DEBUG_CMD.isSet(environ_map)) |
| 4930 | .Debug | 4917 | .debug |
| 4931 | else | 4918 | else |
| 4932 | options.release_mode; | 4919 | options.release_mode; |
| 4933 | const strip = optimize_mode != .Debug; | 4920 | const strip = optimize_mode != .debug; |
| 4934 | var override_lib_dir: ?[]const u8 = EnvVar.ZIG_LIB_DIR.get(environ_map); | 4921 | var override_lib_dir: ?[]const u8 = EnvVar.ZIG_LIB_DIR.get(environ_map); |
| 4935 | const override_global_cache_dir: ?[]const u8 = EnvVar.ZIG_GLOBAL_CACHE_DIR.get(environ_map); | 4922 | const override_global_cache_dir: ?[]const u8 = EnvVar.ZIG_GLOBAL_CACHE_DIR.get(environ_map); |
| 4936 | 4923 | ||
| ... | @@ -6008,9 +5995,8 @@ fn parseRcIncludes(arg: []const u8) std.zig.RcIncludes { | ... | @@ -6008,9 +5995,8 @@ fn parseRcIncludes(arg: []const u8) std.zig.RcIncludes { |
| 6008 | fatal("unsupported rc includes type: {q}", .{arg}); | 5995 | fatal("unsupported rc includes type: {q}", .{arg}); |
| 6009 | } | 5996 | } |
| 6010 | 5997 | ||
| 6011 | fn parseOptimizeMode(s: []const u8) std.lang.OptimizeMode { | 5998 | fn parseOptimizeMode(s: []const u8) std.lang.Optimize { |
| 6012 | return stringToEnum(std.lang.OptimizeMode, s) orelse | 5999 | return std.lang.Optimize.fromString(s) orelse fatal("unrecognized optimization mode: {q}", .{s}); |
| 6013 | fatal("unrecognized optimization mode: {q}", .{s}); | ||
| 6014 | } | 6000 | } |
| 6015 | 6001 | ||
| 6016 | fn parseWasiExecModel(s: []const u8) std.lang.WasiExecModel { | 6002 | fn parseWasiExecModel(s: []const u8) std.lang.WasiExecModel { |
src/print_targets.zig+3-3| ... | @@ -43,9 +43,9 @@ pub fn cmdTargets( | ... | @@ -43,9 +43,9 @@ pub fn cmdTargets( |
| 43 | { | 43 | { |
| 44 | var root_obj = try serializer.beginStruct(.{}); | 44 | var root_obj = try serializer.beginStruct(.{}); |
| 45 | 45 | ||
| 46 | try root_obj.field("arch", meta.fieldNames(Target.Cpu.Arch), .{}); | 46 | try root_obj.field("arch", @typeInfo(Target.Cpu.Arch).@"enum".field_names, .{}); |
| 47 | try root_obj.field("os", meta.fieldNames(Target.Os.Tag), .{}); | 47 | try root_obj.field("os", @typeInfo(Target.Os.Tag).@"enum".field_names, .{}); |
| 48 | try root_obj.field("abi", meta.fieldNames(Target.Abi), .{}); | 48 | try root_obj.field("abi", @typeInfo(Target.Abi).@"enum".field_names, .{}); |
| 49 | 49 | ||
| 50 | { | 50 | { |
| 51 | var libc_obj = try root_obj.beginTupleField("libc", .{}); | 51 | var libc_obj = try root_obj.beginTupleField("libc", .{}); |
src/target.zig+12-17| ... | @@ -12,7 +12,6 @@ pub const default_stack_protector_buffer_size = 4; | ... | @@ -12,7 +12,6 @@ pub const default_stack_protector_buffer_size = 4; |
| 12 | 12 | ||
| 13 | pub fn canDynamicLink(target: *const std.Target) bool { | 13 | pub fn canDynamicLink(target: *const std.Target) bool { |
| 14 | return switch (target.cpu.arch) { | 14 | return switch (target.cpu.arch) { |
| 15 | .amdgcn, | ||
| 16 | .bpfeb, | 15 | .bpfeb, |
| 17 | .bpfel, | 16 | .bpfel, |
| 18 | .nvptx, | 17 | .nvptx, |
| ... | @@ -119,10 +118,6 @@ pub fn defaultSingleThreaded(target: *const std.Target) bool { | ... | @@ -119,10 +118,6 @@ pub fn defaultSingleThreaded(target: *const std.Target) bool { |
| 119 | .wasm32, .wasm64 => return true, | 118 | .wasm32, .wasm64 => return true, |
| 120 | else => {}, | 119 | else => {}, |
| 121 | } | 120 | } |
| 122 | switch (target.os.tag) { | ||
| 123 | .haiku => return true, | ||
| 124 | else => {}, | ||
| 125 | } | ||
| 126 | return false; | 121 | return false; |
| 127 | } | 122 | } |
| 128 | 123 | ||
| ... | @@ -357,12 +352,12 @@ pub fn libcProvidesStackProtector(target: *const std.Target) bool { | ... | @@ -357,12 +352,12 @@ pub fn libcProvidesStackProtector(target: *const std.Target) bool { |
| 357 | 352 | ||
| 358 | /// Returns true if `@returnAddress()` is supported by the target and has a | 353 | /// Returns true if `@returnAddress()` is supported by the target and has a |
| 359 | /// reasonably performant implementation for the requested optimization mode. | 354 | /// reasonably performant implementation for the requested optimization mode. |
| 360 | pub fn supportsReturnAddress(target: *const std.Target, optimize: std.lang.OptimizeMode) bool { | 355 | pub fn supportsReturnAddress(target: *const std.Target, optimize: std.lang.Optimize) bool { |
| 361 | return switch (target.cpu.arch) { | 356 | return switch (target.cpu.arch) { |
| 362 | // Emscripten currently implements `emscripten_return_address()` by calling | 357 | // Emscripten currently implements `emscripten_return_address()` by calling |
| 363 | // out into JavaScript and parsing a stack trace, which introduces significant | 358 | // out into JavaScript and parsing a stack trace, which introduces significant |
| 364 | // overhead that we would prefer to avoid in release builds. | 359 | // overhead that we would prefer to avoid in release builds. |
| 365 | .wasm32, .wasm64 => target.os.tag == .emscripten and optimize == .Debug, | 360 | .wasm32, .wasm64 => target.os.tag == .emscripten and optimize == .debug, |
| 366 | .bpfel, .bpfeb => false, | 361 | .bpfel, .bpfeb => false, |
| 367 | .spirv32, .spirv64 => false, | 362 | .spirv32, .spirv64 => false, |
| 368 | else => true, | 363 | else => true, |
| ... | @@ -417,11 +412,11 @@ pub fn hasDebugInfo(target: *const std.Target) bool { | ... | @@ -417,11 +412,11 @@ pub fn hasDebugInfo(target: *const std.Target) bool { |
| 417 | }; | 412 | }; |
| 418 | } | 413 | } |
| 419 | 414 | ||
| 420 | pub fn defaultCompilerRtOptimizeMode(target: *const std.Target) std.lang.OptimizeMode { | 415 | pub fn defaultCompilerRtOptimizeMode(target: *const std.Target) std.lang.Optimize { |
| 421 | if (target.cpu.arch.isWasm() and target.os.tag == .freestanding) { | 416 | if (target.cpu.arch.isWasm() and target.os.tag == .freestanding) { |
| 422 | return .ReleaseSmall; | 417 | return .small; |
| 423 | } else { | 418 | } else { |
| 424 | return .ReleaseFast; | 419 | return .fast; |
| 425 | } | 420 | } |
| 426 | } | 421 | } |
| 427 | 422 | ||
| ... | @@ -437,7 +432,7 @@ pub fn canBuildLibCompilerRt(target: *const std.Target) enum { no, yes, llvm_onl | ... | @@ -437,7 +432,7 @@ pub fn canBuildLibCompilerRt(target: *const std.Target) enum { no, yes, llvm_onl |
| 437 | else => {}, | 432 | else => {}, |
| 438 | } | 433 | } |
| 439 | return switch (zigBackend(target, false)) { | 434 | return switch (zigBackend(target, false)) { |
| 440 | .stage2_aarch64, .stage2_x86_64 => .yes, | 435 | .stage2_aarch64, .stage2_wasm, .stage2_x86_64 => .yes, |
| 441 | else => .llvm_only, | 436 | else => .llvm_only, |
| 442 | }; | 437 | }; |
| 443 | } | 438 | } |
| ... | @@ -450,7 +445,7 @@ pub fn canBuildLibUbsanRt(target: *const std.Target) enum { no, yes, llvm_only, | ... | @@ -450,7 +445,7 @@ pub fn canBuildLibUbsanRt(target: *const std.Target) enum { no, yes, llvm_only, |
| 450 | else => {}, | 445 | else => {}, |
| 451 | } | 446 | } |
| 452 | return switch (zigBackend(target, false)) { | 447 | return switch (zigBackend(target, false)) { |
| 453 | .stage2_wasm => .llvm_lld_only, | 448 | .stage2_wasm => .yes, |
| 454 | .stage2_x86_64 => .yes, | 449 | .stage2_x86_64 => .yes, |
| 455 | else => .llvm_only, | 450 | else => .llvm_only, |
| 456 | }; | 451 | }; |
| ... | @@ -681,14 +676,14 @@ pub fn isDynamicAMDGCNFeature(target: *const std.Target, feature: std.Target.Cpu | ... | @@ -681,14 +676,14 @@ pub fn isDynamicAMDGCNFeature(target: *const std.Target, feature: std.Target.Cpu |
| 681 | const feature_tag: std.Target.amdgcn.Feature = @fromBackingInt(@intCast(feature.index)); | 676 | const feature_tag: std.Target.amdgcn.Feature = @fromBackingInt(@intCast(feature.index)); |
| 682 | 677 | ||
| 683 | if (feature_tag == .sramecc) { | 678 | if (feature_tag == .sramecc) { |
| 684 | if (std.mem.indexOfScalar( | 679 | if (std.mem.findScalar( |
| 685 | *const std.Target.Cpu.Model, | 680 | *const std.Target.Cpu.Model, |
| 686 | sramecc_only ++ xnack_or_sramecc, | 681 | sramecc_only ++ xnack_or_sramecc, |
| 687 | target.cpu.model, | 682 | target.cpu.model, |
| 688 | )) |_| return true; | 683 | )) |_| return true; |
| 689 | } | 684 | } |
| 690 | if (feature_tag == .xnack) { | 685 | if (feature_tag == .xnack) { |
| 691 | if (std.mem.indexOfScalar( | 686 | if (std.mem.findScalar( |
| 692 | *const std.Target.Cpu.Model, | 687 | *const std.Target.Cpu.Model, |
| 693 | xnack_or_sramecc, | 688 | xnack_or_sramecc, |
| 694 | target.cpu.model, | 689 | target.cpu.model, |
| ... | @@ -876,18 +871,18 @@ pub fn libcFloatSuffix(float_bits: u16) []const u8 { | ... | @@ -876,18 +871,18 @@ pub fn libcFloatSuffix(float_bits: u16) []const u8 { |
| 876 | 32 => "f", | 871 | 32 => "f", |
| 877 | 64 => "", | 872 | 64 => "", |
| 878 | 80 => "x", // Non-standard | 873 | 80 => "x", // Non-standard |
| 879 | 128 => "q", // Non-standard (mimics convention in GCC libquadmath) | 874 | 128 => "f128", |
| 880 | else => unreachable, | 875 | else => unreachable, |
| 881 | }; | 876 | }; |
| 882 | } | 877 | } |
| 883 | 878 | ||
| 884 | pub fn compilerRtFloatAbbrev(float_bits: u16) []const u8 { | 879 | pub fn compilerRtFloatAbbrev(target: *const std.Target, float_bits: u16) []const u8 { |
| 885 | return switch (float_bits) { | 880 | return switch (float_bits) { |
| 886 | 16 => "h", | 881 | 16 => "h", |
| 887 | 32 => "s", | 882 | 32 => "s", |
| 888 | 64 => "d", | 883 | 64 => "d", |
| 889 | 80 => "x", | 884 | 80 => "x", |
| 890 | 128 => "t", | 885 | 128 => if (target.cpu.arch.isPowerPC()) "k" else "t", |
| 891 | else => unreachable, | 886 | else => unreachable, |
| 892 | }; | 887 | }; |
| 893 | } | 888 | } |
src/zig_llvm.cpp+16-3| ... | @@ -473,19 +473,32 @@ void ZigLLVMParseCommandLineOptions(size_t argc, const char *const *argv) { | ... | @@ -473,19 +473,32 @@ void ZigLLVMParseCommandLineOptions(size_t argc, const char *const *argv) { |
| 473 | } | 473 | } |
| 474 | 474 | ||
| 475 | bool ZigLLVMWriteArchive(const char *archive_name, const char **file_names, size_t file_name_count, | 475 | bool ZigLLVMWriteArchive(const char *archive_name, const char **file_names, size_t file_name_count, |
| 476 | ZigLLVMArchiveKind archive_kind) | 476 | ZigLLVMArchiveKind archive_kind, size_t *err_file_index_out, char **err_msg_out) |
| 477 | { | 477 | { |
| 478 | SmallVector<NewArchiveMember, 4> new_members; | 478 | SmallVector<NewArchiveMember, 4> new_members; |
| 479 | for (size_t i = 0; i < file_name_count; i += 1) { | 479 | for (size_t i = 0; i < file_name_count; i += 1) { |
| 480 | Expected<NewArchiveMember> new_member = NewArchiveMember::getFile(file_names[i], true); | 480 | Expected<NewArchiveMember> new_member = NewArchiveMember::getFile(file_names[i], true); |
| 481 | Error err = new_member.takeError(); | 481 | Error err = new_member.takeError(); |
| 482 | if (err) return true; | 482 | if (err) { |
| 483 | *err_file_index_out = i; | ||
| 484 | const std::string msg = toString(std::move(err)); | ||
| 485 | *err_msg_out = (char *)malloc(msg.length() + 1); | ||
| 486 | strcpy(*err_msg_out, msg.c_str()); | ||
| 487 | return true; | ||
| 488 | } | ||
| 483 | new_members.push_back(std::move(*new_member)); | 489 | new_members.push_back(std::move(*new_member)); |
| 484 | } | 490 | } |
| 485 | Error err = writeArchive(archive_name, new_members, | 491 | Error err = writeArchive(archive_name, new_members, |
| 486 | SymtabWritingMode::NormalSymtab, static_cast<object::Archive::Kind>(archive_kind), true, false, nullptr); | 492 | SymtabWritingMode::NormalSymtab, static_cast<object::Archive::Kind>(archive_kind), true, false, nullptr); |
| 487 | 493 | ||
| 488 | if (err) return true; | 494 | if (err) { |
| 495 | *err_file_index_out = file_name_count; | ||
| 496 | const std::string msg = toString(std::move(err)); | ||
| 497 | *err_msg_out = (char *)malloc(msg.length() + 1); | ||
| 498 | strcpy(*err_msg_out, msg.c_str()); | ||
| 499 | return true; | ||
| 500 | } | ||
| 501 | |||
| 489 | return false; | 502 | return false; |
| 490 | } | 503 | } |
| 491 | 504 |
src/zig_llvm.h+6-1| ... | @@ -121,7 +121,12 @@ ZIG_EXTERN_C bool ZigLLDLinkCOFF(int argc, const char **argv, bool can_exit_earl | ... | @@ -121,7 +121,12 @@ ZIG_EXTERN_C bool ZigLLDLinkCOFF(int argc, const char **argv, bool can_exit_earl |
| 121 | ZIG_EXTERN_C bool ZigLLDLinkELF(int argc, const char **argv, bool can_exit_early, bool disable_output); | 121 | ZIG_EXTERN_C bool ZigLLDLinkELF(int argc, const char **argv, bool can_exit_early, bool disable_output); |
| 122 | ZIG_EXTERN_C bool ZigLLDLinkWasm(int argc, const char **argv, bool can_exit_early, bool disable_output); | 122 | ZIG_EXTERN_C bool ZigLLDLinkWasm(int argc, const char **argv, bool can_exit_early, bool disable_output); |
| 123 | 123 | ||
| 124 | // On error, populates `*err_file_index_out` and `*err_msg_out` and returns `true`. The caller is | ||
| 125 | // responsible for freeing `*err_msg_out` using `free`. | ||
| 126 | // | ||
| 127 | // If an error occurs reading an input file, `*err_file_index_out` is set to the index of that input | ||
| 128 | // file in `file_names`. Otherwise, `*err_file_index_out` is set to `file_name_count`. | ||
| 124 | ZIG_EXTERN_C bool ZigLLVMWriteArchive(const char *archive_name, const char **file_names, size_t file_name_count, | 129 | ZIG_EXTERN_C bool ZigLLVMWriteArchive(const char *archive_name, const char **file_names, size_t file_name_count, |
| 125 | ZigLLVMArchiveKind archive_kind); | 130 | ZigLLVMArchiveKind archive_kind, size_t *err_file_index_out, char **err_msg_out); |
| 126 | 131 | ||
| 127 | #endif | 132 | #endif |
stage1/FuncGen.h+3-3| ... | @@ -52,17 +52,17 @@ static void FuncGen_free(struct FuncGen *self) { | ... | @@ -52,17 +52,17 @@ static void FuncGen_free(struct FuncGen *self) { |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | static void FuncGen_outdent(struct FuncGen *self, FILE *out) { | 54 | static void FuncGen_outdent(struct FuncGen *self, FILE *out) { |
| 55 | for (uint32_t i = 0; i < self->block_i; i += 1) fputs(" ", out); | 55 | for (uint32_t i = 0; i < self->block_i; i += 1) fputs(" ", out); |
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | static void FuncGen_indent(struct FuncGen *self, FILE *out) { | 58 | static void FuncGen_indent(struct FuncGen *self, FILE *out) { |
| 59 | FuncGen_outdent(self, out); | 59 | FuncGen_outdent(self, out); |
| 60 | fputs(" ", out); | 60 | fputs(" ", out); |
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | static void FuncGen_cont(struct FuncGen *self, FILE *out) { | 63 | static void FuncGen_cont(struct FuncGen *self, FILE *out) { |
| 64 | FuncGen_indent(self, out); | 64 | FuncGen_indent(self, out); |
| 65 | fputs(" ", out); | 65 | fputs(" ", out); |
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | static uint32_t FuncGen_localAlloc(struct FuncGen *self, int8_t type) { | 68 | static uint32_t FuncGen_localAlloc(struct FuncGen *self, int8_t type) { |
stage1/wasm2c.c+9-9| ... | @@ -518,8 +518,8 @@ int main(int argc, char **argv) { | ... | @@ -518,8 +518,8 @@ int main(int argc, char **argv) { |
| 518 | } | 518 | } |
| 519 | fprintf(out, | 519 | fprintf(out, |
| 520 | ") {\n" | 520 | ") {\n" |
| 521 | " init();\n" | 521 | " init();\n" |
| 522 | " %sf%" PRIu32 "(", | 522 | " %sf%" PRIu32 "(", |
| 523 | func_type->result->len > 0 ? "return " : "", idx - imports_len); | 523 | func_type->result->len > 0 ? "return " : "", idx - imports_len); |
| 524 | for (uint32_t param_i = 0; param_i < func_type->param->len; param_i += 1) { | 524 | for (uint32_t param_i = 0; param_i < func_type->param->len; param_i += 1) { |
| 525 | if (param_i > 0) fputs(", ", out); | 525 | if (param_i > 0) fputs(", ", out); |
| ... | @@ -552,7 +552,7 @@ int main(int argc, char **argv) { | ... | @@ -552,7 +552,7 @@ int main(int argc, char **argv) { |
| 552 | uint32_t segment_len = InputStream_readLeb128_u32(&in); | 552 | uint32_t segment_len = InputStream_readLeb128_u32(&in); |
| 553 | for (uint32_t i = 0; i < segment_len; i += 1) { | 553 | for (uint32_t i = 0; i < segment_len; i += 1) { |
| 554 | uint32_t func_id = InputStream_readLeb128_u32(&in); | 554 | uint32_t func_id = InputStream_readLeb128_u32(&in); |
| 555 | fprintf(out, " t%" PRIu32 "[UINT32_C(%" PRIu32 ")] = (void (*)(void))&", | 555 | fprintf(out, " t%" PRIu32 "[UINT32_C(%" PRIu32 ")] = (void (*)(void))&", |
| 556 | table_idx, offset + i); | 556 | table_idx, offset + i); |
| 557 | if (func_id < imports_len) | 557 | if (func_id < imports_len) |
| 558 | fprintf(out, "%s_%s", imports[func_id].mod, imports[func_id].name); | 558 | fprintf(out, "%s_%s", imports[func_id].mod, imports[func_id].name); |
| ... | @@ -2260,9 +2260,9 @@ int main(int argc, char **argv) { | ... | @@ -2260,9 +2260,9 @@ int main(int argc, char **argv) { |
| 2260 | uint32_t len = InputStream_readLeb128_u32(&in); | 2260 | uint32_t len = InputStream_readLeb128_u32(&in); |
| 2261 | fputs("static void init_data(void) {\n", out); | 2261 | fputs("static void init_data(void) {\n", out); |
| 2262 | for (uint32_t i = 0; i < mems_len; i += 1) | 2262 | for (uint32_t i = 0; i < mems_len; i += 1) |
| 2263 | fprintf(out, " p%" PRIu32 " = UINT32_C(%" PRIu32 ");\n" | 2263 | fprintf(out, " p%" PRIu32 " = UINT32_C(%" PRIu32 ");\n" |
| 2264 | " c%" PRIu32 " = p%" PRIu32 ";\n" | 2264 | " c%" PRIu32 " = p%" PRIu32 ";\n" |
| 2265 | " m%" PRIu32 " = calloc(c%" PRIu32 ", UINT32_C(1) << 16);\n", | 2265 | " m%" PRIu32 " = calloc(c%" PRIu32 ", UINT32_C(1) << 16);\n", |
| 2266 | i, mems[i].limits.min, i, i, i, i); | 2266 | i, mems[i].limits.min, i, i, i, i); |
| 2267 | for (uint32_t segment_i = 0; segment_i < len; segment_i += 1) { | 2267 | for (uint32_t segment_i = 0; segment_i < len; segment_i += 1) { |
| 2268 | uint32_t mem_idx; | 2268 | uint32_t mem_idx; |
| ... | @@ -2280,15 +2280,15 @@ int main(int argc, char **argv) { | ... | @@ -2280,15 +2280,15 @@ int main(int argc, char **argv) { |
| 2280 | uint32_t offset = evalExpr(&in); | 2280 | uint32_t offset = evalExpr(&in); |
| 2281 | uint32_t segment_len = InputStream_readLeb128_u32(&in); | 2281 | uint32_t segment_len = InputStream_readLeb128_u32(&in); |
| 2282 | fputc('\n', out); | 2282 | fputc('\n', out); |
| 2283 | fprintf(out, " static const uint8_t s%" PRIu32 "[UINT32_C(%" PRIu32 ")] = {", | 2283 | fprintf(out, " static const uint8_t s%" PRIu32 "[UINT32_C(%" PRIu32 ")] = {", |
| 2284 | segment_i, segment_len); | 2284 | segment_i, segment_len); |
| 2285 | for (uint32_t i = 0; i < segment_len; i += 1) { | 2285 | for (uint32_t i = 0; i < segment_len; i += 1) { |
| 2286 | if (i % 32 == 0) fputs("\n ", out); | 2286 | if (i % 32 == 0) fputs("\n ", out); |
| 2287 | fprintf(out, " 0x%02hhX,", InputStream_readByte(&in)); | 2287 | fprintf(out, " 0x%02hhX,", InputStream_readByte(&in)); |
| 2288 | } | 2288 | } |
| 2289 | fprintf(out, "\n" | 2289 | fprintf(out, "\n" |
| 2290 | " };\n" | 2290 | " };\n" |
| 2291 | " memcpy(&m%" PRIu32 "[UINT32_C(0x%" PRIX32 ")], s%" PRIu32 ", UINT32_C(%" PRIu32 "));\n", | 2291 | " memcpy(&m%" PRIu32 "[UINT32_C(0x%" PRIX32 ")], s%" PRIu32 ", UINT32_C(%" PRIu32 "));\n", |
| 2292 | mem_idx, offset, segment_i, segment_len); | 2292 | mem_idx, offset, segment_i, segment_len); |
| 2293 | } | 2293 | } |
| 2294 | fputs("}\n", out); | 2294 | fputs("}\n", out); |
stage1/zig.h+3079-991| ... | @@ -166,6 +166,12 @@ | ... | @@ -166,6 +166,12 @@ |
| 166 | #endif | 166 | #endif |
| 167 | #define zig_expand_has_builtin(b) zig_has_builtin(b) | 167 | #define zig_expand_has_builtin(b) zig_has_builtin(b) |
| 168 | 168 | ||
| 169 | #if defined(__has_feature) | ||
| 170 | #define zig_has_feature(feature) __has_feature(feature) | ||
| 171 | #else | ||
| 172 | #define zig_has_feature(feature) 0 | ||
| 173 | #endif | ||
| 174 | |||
| 169 | #if defined(__has_attribute) | 175 | #if defined(__has_attribute) |
| 170 | #define zig_has_attribute(attribute) __has_attribute(attribute) | 176 | #define zig_has_attribute(attribute) __has_attribute(attribute) |
| 171 | #else | 177 | #else |
| ... | @@ -175,9 +181,9 @@ | ... | @@ -175,9 +181,9 @@ |
| 175 | #if __STDC_VERSION__ >= 201112L | 181 | #if __STDC_VERSION__ >= 201112L |
| 176 | #define zig_static_assert(cond, msg) _Static_assert(cond, msg) | 182 | #define zig_static_assert(cond, msg) _Static_assert(cond, msg) |
| 177 | #elif zig_has_attribute(unused) | 183 | #elif zig_has_attribute(unused) |
| 178 | #define zig_static_assert(cond, _) typedef char zig_expand_concat(zig_static_assert_fail_, __LINE__)[!!(cond)] __attribute__((unused)) | 184 | #define zig_static_assert(cond, msg) typedef char zig_expand_concat(zig_static_assert_fail_, __LINE__)[(cond) ? 1 : -1] __attribute__((unused)) |
| 179 | #else | 185 | #else |
| 180 | #define zig_static_assert(cond, _) typedef char zig_expand_concat(zig_static_assert_fail_, __LINE__)[!!(cond)] | 186 | #define zig_static_assert(cond, msg) typedef char zig_expand_concat(zig_static_assert_fail_, __LINE__)[(cond) ? 1 : -1] |
| 181 | #endif | 187 | #endif |
| 182 | 188 | ||
| 183 | #if __STDC_VERSION__ >= 202311L | 189 | #if __STDC_VERSION__ >= 202311L |
| ... | @@ -193,10 +199,8 @@ | ... | @@ -193,10 +199,8 @@ |
| 193 | #endif | 199 | #endif |
| 194 | 200 | ||
| 195 | #if defined(zig_msvc) | 201 | #if defined(zig_msvc) |
| 196 | #define zig_const_arr | ||
| 197 | #define zig_callconv(c) __##c | 202 | #define zig_callconv(c) __##c |
| 198 | #else | 203 | #else |
| 199 | #define zig_const_arr static const | ||
| 200 | #define zig_callconv(c) __attribute__((c)) | 204 | #define zig_callconv(c) __attribute__((c)) |
| 201 | #endif | 205 | #endif |
| 202 | 206 | ||
| ... | @@ -267,12 +271,20 @@ | ... | @@ -267,12 +271,20 @@ |
| 267 | 271 | ||
| 268 | #if __STDC_VERSION__ >= 202311L | 272 | #if __STDC_VERSION__ >= 202311L |
| 269 | #define zig_align(alignment) alignas(alignment) | 273 | #define zig_align(alignment) alignas(alignment) |
| 270 | #elif __STDC_VERSION__ >= 201112L | 274 | #elif __STDC_VERSION__ >= 201112L || zig_has_feature(c_alignas) |
| 271 | #define zig_align(alignment) _Alignas(alignment) | 275 | #define zig_align(alignment) _Alignas(alignment) |
| 272 | #else | 276 | #else |
| 273 | #define zig_align(alignment) zig_under_align(alignment) | 277 | #define zig_align(alignment) zig_under_align(alignment) |
| 274 | #endif | 278 | #endif |
| 275 | 279 | ||
| 280 | #if __STDC_VERSION__ >= 202311L | ||
| 281 | #define zig_alignOf(Type) alignof(Type) | ||
| 282 | #elif __STDC_VERSION__ >= 201112L || zig_has_feature(c_alignof) | ||
| 283 | #define zig_alignOf(Type) _Alignof(Type) | ||
| 284 | #else | ||
| 285 | #define zig_alignOf(Type) (sizeof(struct { char c; Type t; }) - sizeof(Type)) | ||
| 286 | #endif | ||
| 287 | |||
| 276 | #if zig_has_attribute(aligned) || defined(zig_tinyc) | 288 | #if zig_has_attribute(aligned) || defined(zig_tinyc) |
| 277 | #define zig_align_fn(alignment) __attribute__((aligned(alignment))) | 289 | #define zig_align_fn(alignment) __attribute__((aligned(alignment))) |
| 278 | #elif defined(zig_msvc) | 290 | #elif defined(zig_msvc) |
| ... | @@ -350,11 +362,9 @@ | ... | @@ -350,11 +362,9 @@ |
| 350 | #define zig_export(symbol, name) __attribute__((alias(symbol))) | 362 | #define zig_export(symbol, name) __attribute__((alias(symbol))) |
| 351 | #else | 363 | #else |
| 352 | #define zig_export(symbol, name) ; \ | 364 | #define zig_export(symbol, name) ; \ |
| 353 | __asm(zig_mangle_c(name) " = " zig_mangle_c(symbol)) | 365 | __asm("\t.globl\t" zig_mangle_c(name) "\n" zig_mangle_c(name) " = " zig_mangle_c(symbol)) |
| 354 | #endif | 366 | #endif |
| 355 | 367 | ||
| 356 | #define zig_mangled_tentative zig_mangled | ||
| 357 | #define zig_mangled_final zig_mangled | ||
| 358 | #if defined(zig_msvc) | 368 | #if defined(zig_msvc) |
| 359 | #define zig_mangled(mangled, unmangled) ; \ | 369 | #define zig_mangled(mangled, unmangled) ; \ |
| 360 | zig_export(#mangled, unmangled) | 370 | zig_export(#mangled, unmangled) |
| ... | @@ -364,7 +374,7 @@ | ... | @@ -364,7 +374,7 @@ |
| 364 | #else /* zig_msvc */ | 374 | #else /* zig_msvc */ |
| 365 | #define zig_mangled(mangled, unmangled) __asm(zig_mangle_c(unmangled)) | 375 | #define zig_mangled(mangled, unmangled) __asm(zig_mangle_c(unmangled)) |
| 366 | #define zig_mangled_export(mangled, unmangled, symbol) \ | 376 | #define zig_mangled_export(mangled, unmangled, symbol) \ |
| 367 | zig_mangled_final(mangled, unmangled) \ | 377 | zig_mangled(mangled, unmangled) \ |
| 368 | zig_export(symbol, unmangled) | 378 | zig_export(symbol, unmangled) |
| 369 | #endif /* zig_msvc */ | 379 | #endif /* zig_msvc */ |
| 370 | 380 | ||
| ... | @@ -550,6 +560,9 @@ | ... | @@ -550,6 +560,9 @@ |
| 550 | #define zig_noreturn | 560 | #define zig_noreturn |
| 551 | #endif | 561 | #endif |
| 552 | 562 | ||
| 563 | #define zig_has_always 1 | ||
| 564 | #define zig_has_never 0 | ||
| 565 | |||
| 553 | #define zig_compiler_rt_abbrev_uint32_t si | 566 | #define zig_compiler_rt_abbrev_uint32_t si |
| 554 | #define zig_compiler_rt_abbrev_int32_t si | 567 | #define zig_compiler_rt_abbrev_int32_t si |
| 555 | #define zig_compiler_rt_abbrev_uint64_t di | 568 | #define zig_compiler_rt_abbrev_uint64_t di |
| ... | @@ -560,7 +573,11 @@ | ... | @@ -560,7 +573,11 @@ |
| 560 | #define zig_compiler_rt_abbrev_zig_f32 sf | 573 | #define zig_compiler_rt_abbrev_zig_f32 sf |
| 561 | #define zig_compiler_rt_abbrev_zig_f64 df | 574 | #define zig_compiler_rt_abbrev_zig_f64 df |
| 562 | #define zig_compiler_rt_abbrev_zig_f80 xf | 575 | #define zig_compiler_rt_abbrev_zig_f80 xf |
| 576 | #ifdef zig_powerpc | ||
| 577 | #define zig_compiler_rt_abbrev_zig_f128 kf | ||
| 578 | #else | ||
| 563 | #define zig_compiler_rt_abbrev_zig_f128 tf | 579 | #define zig_compiler_rt_abbrev_zig_f128 tf |
| 580 | #endif | ||
| 564 | 581 | ||
| 565 | zig_extern void *memcpy (void *zig_restrict, void const *zig_restrict, size_t); | 582 | zig_extern void *memcpy (void *zig_restrict, void const *zig_restrict, size_t); |
| 566 | zig_extern void *memset (void *, int, size_t); | 583 | zig_extern void *memset (void *, int, size_t); |
| ... | @@ -645,16 +662,6 @@ typedef signed long long int16_t; | ... | @@ -645,16 +662,6 @@ typedef signed long long int16_t; |
| 645 | #define INT16_MAX ( INT16_C(0x7FFF)) | 662 | #define INT16_MAX ( INT16_C(0x7FFF)) |
| 646 | #define UINT16_MAX ( INT16_C(0xFFFF)) | 663 | #define UINT16_MAX ( INT16_C(0xFFFF)) |
| 647 | 664 | ||
| 648 | #if defined(zig_ez80) | ||
| 649 | typedef unsigned int uint24_t; | ||
| 650 | typedef signed int int24_t; | ||
| 651 | #define INT24_C(c) c | ||
| 652 | #define UINT24_C(c) c##U | ||
| 653 | #endif | ||
| 654 | #define INT24_MIN (~INT24_C(0x7FFF)) | ||
| 655 | #define INT24_MAX ( INT24_C(0x7FFF)) | ||
| 656 | #define UINT24_MAX ( INT24_C(0xFFFF)) | ||
| 657 | |||
| 658 | #if SCHAR_MIN == ~0x7FFFFFFF && SCHAR_MAX == 0x7FFFFFFF && UCHAR_MAX == 0xFFFFFFFF | 665 | #if SCHAR_MIN == ~0x7FFFFFFF && SCHAR_MAX == 0x7FFFFFFF && UCHAR_MAX == 0xFFFFFFFF |
| 659 | typedef unsigned char uint32_t; | 666 | typedef unsigned char uint32_t; |
| 660 | typedef signed char int32_t; | 667 | typedef signed char int32_t; |
| ... | @@ -685,17 +692,6 @@ typedef signed long long int32_t; | ... | @@ -685,17 +692,6 @@ typedef signed long long int32_t; |
| 685 | #define INT32_MAX ( INT32_C(0x7FFFFFFF)) | 692 | #define INT32_MAX ( INT32_C(0x7FFFFFFF)) |
| 686 | #define UINT32_MAX ( INT32_C(0xFFFFFFFF)) | 693 | #define UINT32_MAX ( INT32_C(0xFFFFFFFF)) |
| 687 | 694 | ||
| 688 | #if defined(zig_ez80) | ||
| 689 | typedef unsigned __int48 uint48_t; | ||
| 690 | typedef signed __int48 int48_t; | ||
| 691 | #define INT48_C(c) c | ||
| 692 | /* no suffix */ | ||
| 693 | #define UINT48_C(c) ((uint48_t)(c)) | ||
| 694 | #endif | ||
| 695 | #define INT48_MIN (~INT48_C(0x7FFFFFFFFFFF)) | ||
| 696 | #define INT48_MAX ( INT48_C(0x7FFFFFFFFFFF)) | ||
| 697 | #define UINT48_MAX ( INT48_C(0xFFFFFFFFFFFF)) | ||
| 698 | |||
| 699 | #if SCHAR_MIN == ~0x7FFFFFFFFFFFFFFF && SCHAR_MAX == 0x7FFFFFFFFFFFFFFF && UCHAR_MAX == 0xFFFFFFFFFFFFFFFF | 695 | #if SCHAR_MIN == ~0x7FFFFFFFFFFFFFFF && SCHAR_MAX == 0x7FFFFFFFFFFFFFFF && UCHAR_MAX == 0xFFFFFFFFFFFFFFFF |
| 700 | typedef unsigned char uint64_t; | 696 | typedef unsigned char uint64_t; |
| 701 | typedef signed char int64_t; | 697 | typedef signed char int64_t; |
| ... | @@ -726,6 +722,27 @@ typedef signed long long int64_t; | ... | @@ -726,6 +722,27 @@ typedef signed long long int64_t; |
| 726 | #define INT64_MAX ( INT64_C(0x7FFFFFFFFFFFFFFF)) | 722 | #define INT64_MAX ( INT64_C(0x7FFFFFFFFFFFFFFF)) |
| 727 | #define UINT64_MAX ( INT64_C(0xFFFFFFFFFFFFFFFF)) | 723 | #define UINT64_MAX ( INT64_C(0xFFFFFFFFFFFFFFFF)) |
| 728 | 724 | ||
| 725 | #if defined(zig_ez80) | ||
| 726 | |||
| 727 | typedef unsigned int uint24_t; | ||
| 728 | typedef signed int int24_t; | ||
| 729 | #define INT24_C(c) c | ||
| 730 | #define UINT24_C(c) c##U | ||
| 731 | #define INT24_MIN (~INT24_C(0x7FFF)) | ||
| 732 | #define INT24_MAX ( INT24_C(0x7FFF)) | ||
| 733 | #define UINT24_MAX ( INT24_C(0xFFFF)) | ||
| 734 | |||
| 735 | typedef unsigned __int48 uint48_t; | ||
| 736 | typedef signed __int48 int48_t; | ||
| 737 | #define INT48_C(c) c | ||
| 738 | /* no suffix */ | ||
| 739 | #define UINT48_C(c) ((uint48_t)(c)) | ||
| 740 | #define INT48_MIN (~INT48_C(0x7FFFFFFFFFFF)) | ||
| 741 | #define INT48_MAX ( INT48_C(0x7FFFFFFFFFFF)) | ||
| 742 | #define UINT48_MAX ( INT48_C(0xFFFFFFFFFFFF)) | ||
| 743 | |||
| 744 | #endif | ||
| 745 | |||
| 729 | typedef size_t uintptr_t; | 746 | typedef size_t uintptr_t; |
| 730 | typedef ptrdiff_t intptr_t; | 747 | typedef ptrdiff_t intptr_t; |
| 731 | 748 | ||
| ... | @@ -739,23 +756,145 @@ typedef ptrdiff_t intptr_t; | ... | @@ -739,23 +756,145 @@ typedef ptrdiff_t intptr_t; |
| 739 | #define zig_maxInt_i16 INT16_MAX | 756 | #define zig_maxInt_i16 INT16_MAX |
| 740 | #define zig_minInt_u16 UINT16_C(0) | 757 | #define zig_minInt_u16 UINT16_C(0) |
| 741 | #define zig_maxInt_u16 UINT16_MAX | 758 | #define zig_maxInt_u16 UINT16_MAX |
| 742 | #define zig_minInt_i24 INT24_MIN | ||
| 743 | #define zig_maxInt_i24 INT24_MAX | ||
| 744 | #define zig_minInt_u24 UINT24_C(0) | ||
| 745 | #define zig_maxInt_u24 UINT24_MAX | ||
| 746 | #define zig_minInt_i32 INT32_MIN | 759 | #define zig_minInt_i32 INT32_MIN |
| 747 | #define zig_maxInt_i32 INT32_MAX | 760 | #define zig_maxInt_i32 INT32_MAX |
| 748 | #define zig_minInt_u32 UINT32_C(0) | 761 | #define zig_minInt_u32 UINT32_C(0) |
| 749 | #define zig_maxInt_u32 UINT32_MAX | 762 | #define zig_maxInt_u32 UINT32_MAX |
| 750 | #define zig_minInt_i48 INT48_MIN | ||
| 751 | #define zig_maxInt_i48 INT48_MAX | ||
| 752 | #define zig_minInt_u48 UINT48_C(0) | ||
| 753 | #define zig_maxInt_u48 UINT48_MAX | ||
| 754 | #define zig_minInt_i64 INT64_MIN | 763 | #define zig_minInt_i64 INT64_MIN |
| 755 | #define zig_maxInt_i64 INT64_MAX | 764 | #define zig_maxInt_i64 INT64_MAX |
| 756 | #define zig_minInt_u64 UINT64_C(0) | 765 | #define zig_minInt_u64 UINT64_C(0) |
| 757 | #define zig_maxInt_u64 UINT64_MAX | 766 | #define zig_maxInt_u64 UINT64_MAX |
| 758 | 767 | ||
| 768 | // zig_promoted_T implements C integral promotions except with signedness preserved, which | ||
| 769 | // allows wrapping operations to avoid the ub that would be caused by the normal promotion. | ||
| 770 | |||
| 771 | #if INT8_MAX <= INT_MAX | ||
| 772 | typedef unsigned int zig_promoted_i8; | ||
| 773 | #elif INT8_MAX <= LONG_MAX | ||
| 774 | typedef unsigned long zig_promoted_i8; | ||
| 775 | #elif INT8_MAX <= LLONG_MAX | ||
| 776 | typedef unsigned long long zig_promoted_i8; | ||
| 777 | #else | ||
| 778 | typedef int8_t zig_promoted_i8; | ||
| 779 | #endif | ||
| 780 | #if UINT8_MAX <= UINT_MAX | ||
| 781 | typedef unsigned int zig_promoted_u8; | ||
| 782 | #elif UINT8_MAX <= ULONG_MAX | ||
| 783 | typedef unsigned long zig_promoted_u8; | ||
| 784 | #elif UINT8_MAX <= ULLONG_MAX | ||
| 785 | typedef unsigned long long zig_promoted_u8; | ||
| 786 | #else | ||
| 787 | typedef uint8_t zig_promoted_u8; | ||
| 788 | #endif | ||
| 789 | |||
| 790 | #if INT16_MAX <= INT_MAX | ||
| 791 | typedef unsigned int zig_promoted_i16; | ||
| 792 | #elif INT16_MAX <= LONG_MAX | ||
| 793 | typedef unsigned long zig_promoted_i16; | ||
| 794 | #elif INT16_MAX <= LLONG_MAX | ||
| 795 | typedef unsigned long long zig_promoted_i16; | ||
| 796 | #else | ||
| 797 | typedef int16_t zig_promoted_i16; | ||
| 798 | #endif | ||
| 799 | #if UINT16_MAX <= UINT_MAX | ||
| 800 | typedef unsigned int zig_promoted_u16; | ||
| 801 | #elif UINT16_MAX <= ULONG_MAX | ||
| 802 | typedef unsigned long zig_promoted_u16; | ||
| 803 | #elif UINT16_MAX <= ULLONG_MAX | ||
| 804 | typedef unsigned long long zig_promoted_u16; | ||
| 805 | #else | ||
| 806 | typedef uint16_t zig_promoted_u16; | ||
| 807 | #endif | ||
| 808 | |||
| 809 | #if INT32_MAX <= INT_MAX | ||
| 810 | typedef unsigned int zig_promoted_i32; | ||
| 811 | #elif INT32_MAX <= LONG_MAX | ||
| 812 | typedef unsigned long zig_promoted_i32; | ||
| 813 | #elif INT32_MAX <= LLONG_MAX | ||
| 814 | typedef unsigned long long zig_promoted_i32; | ||
| 815 | #else | ||
| 816 | typedef int32_t zig_promoted_i32; | ||
| 817 | #endif | ||
| 818 | #if UINT32_MAX <= UINT_MAX | ||
| 819 | typedef unsigned int zig_promoted_u32; | ||
| 820 | #elif UINT32_MAX <= ULONG_MAX | ||
| 821 | typedef unsigned long zig_promoted_u32; | ||
| 822 | #elif UINT32_MAX <= ULLONG_MAX | ||
| 823 | typedef unsigned long long zig_promoted_u32; | ||
| 824 | #else | ||
| 825 | typedef uint32_t zig_promoted_u32; | ||
| 826 | #endif | ||
| 827 | |||
| 828 | #if INT64_MAX <= INT_MAX | ||
| 829 | typedef unsigned int zig_promoted_i64; | ||
| 830 | #elif INT64_MAX <= LONG_MAX | ||
| 831 | typedef unsigned long zig_promoted_i64; | ||
| 832 | #elif INT64_MAX <= LLONG_MAX | ||
| 833 | typedef unsigned long long zig_promoted_i64; | ||
| 834 | #else | ||
| 835 | typedef int64_t zig_promoted_i64; | ||
| 836 | #endif | ||
| 837 | #if UINT64_MAX <= UINT_MAX | ||
| 838 | typedef unsigned int zig_promoted_u64; | ||
| 839 | #elif UINT64_MAX <= ULONG_MAX | ||
| 840 | typedef unsigned long zig_promoted_u64; | ||
| 841 | #elif UINT64_MAX <= ULLONG_MAX | ||
| 842 | typedef unsigned long long zig_promoted_u64; | ||
| 843 | #else | ||
| 844 | typedef uint64_t zig_promoted_u64; | ||
| 845 | #endif | ||
| 846 | |||
| 847 | #ifdef zig_ez80 | ||
| 848 | |||
| 849 | #define zig_minInt_i24 INT24_MIN | ||
| 850 | #define zig_maxInt_i24 INT24_MAX | ||
| 851 | #define zig_minInt_u24 UINT24_C(0) | ||
| 852 | #define zig_maxInt_u24 UINT24_MAX | ||
| 853 | #define zig_minInt_i48 INT48_MIN | ||
| 854 | #define zig_maxInt_i48 INT48_MAX | ||
| 855 | #define zig_minInt_u48 UINT48_C(0) | ||
| 856 | #define zig_maxInt_u48 UINT48_MAX | ||
| 857 | |||
| 858 | #if INT24_MAX <= INT_MAX | ||
| 859 | typedef unsigned int zig_promoted_i24; | ||
| 860 | #elif INT24_MAX <= LONG_MAX | ||
| 861 | typedef unsigned long zig_promoted_i24; | ||
| 862 | #elif INT24_MAX <= LLONG_MAX | ||
| 863 | typedef unsigned long long zig_promoted_i24; | ||
| 864 | #else | ||
| 865 | typedef int24_t zig_promoted_i24; | ||
| 866 | #endif | ||
| 867 | #if UINT24_MAX <= UINT_MAX | ||
| 868 | typedef unsigned int zig_promoted_u24; | ||
| 869 | #elif UINT24_MAX <= ULONG_MAX | ||
| 870 | typedef unsigned long zig_promoted_u24; | ||
| 871 | #elif UINT24_MAX <= ULLONG_MAX | ||
| 872 | typedef unsigned long long zig_promoted_u24; | ||
| 873 | #else | ||
| 874 | typedef uint24_t zig_promoted_u24; | ||
| 875 | #endif | ||
| 876 | |||
| 877 | #if INT48_MAX <= INT_MAX | ||
| 878 | typedef unsigned int zig_promoted_i48; | ||
| 879 | #elif INT48_MAX <= LONG_MAX | ||
| 880 | typedef unsigned long zig_promoted_i48; | ||
| 881 | #elif INT48_MAX <= LLONG_MAX | ||
| 882 | typedef unsigned long long zig_promoted_i48; | ||
| 883 | #else | ||
| 884 | typedef int48_t zig_promoted_i48; | ||
| 885 | #endif | ||
| 886 | #if UINT48_MAX <= UINT_MAX | ||
| 887 | typedef unsigned int zig_promoted_u48; | ||
| 888 | #elif UINT48_MAX <= ULONG_MAX | ||
| 889 | typedef unsigned long zig_promoted_u48; | ||
| 890 | #elif UINT48_MAX <= ULLONG_MAX | ||
| 891 | typedef unsigned long long zig_promoted_u48; | ||
| 892 | #else | ||
| 893 | typedef uint48_t zig_promoted_u48; | ||
| 894 | #endif | ||
| 895 | |||
| 896 | #endif | ||
| 897 | |||
| 759 | #define zig_intLimit(s, w, limit, bits) zig_shr_##s##w(zig_##limit##Int_##s##w, w - (bits)) | 898 | #define zig_intLimit(s, w, limit, bits) zig_shr_##s##w(zig_##limit##Int_##s##w, w - (bits)) |
| 760 | #define zig_minInt_i(w, bits) zig_intLimit(i, w, min, bits) | 899 | #define zig_minInt_i(w, bits) zig_intLimit(i, w, min, bits) |
| 761 | #define zig_maxInt_i(w, bits) zig_intLimit(i, w, max, bits) | 900 | #define zig_maxInt_i(w, bits) zig_intLimit(i, w, max, bits) |
| ... | @@ -770,7 +909,33 @@ typedef ptrdiff_t intptr_t; | ... | @@ -770,7 +909,33 @@ typedef ptrdiff_t intptr_t; |
| 770 | zig_operator(Type, Type, operation, operator) | 909 | zig_operator(Type, Type, operation, operator) |
| 771 | #define zig_shift_operator(Type, operation, operator) \ | 910 | #define zig_shift_operator(Type, operation, operator) \ |
| 772 | zig_operator(Type, uint8_t, operation, operator) | 911 | zig_operator(Type, uint8_t, operation, operator) |
| 773 | #define zig_int_helpers(w, PromotedUnsigned) \ | 912 | |
| 913 | #define zig_int_casts_common(bw, sw) \ | ||
| 914 | static inline uint##bw##_t zig_u##bw##_intCast_u##sw(uint##sw##_t arg) { \ | ||
| 915 | return arg; \ | ||
| 916 | } \ | ||
| 917 | \ | ||
| 918 | static inline uint##bw##_t zig_u##bw##_intCast_i##sw(int##sw##_t arg) { \ | ||
| 919 | return (uint##bw##_t)arg; \ | ||
| 920 | } \ | ||
| 921 | \ | ||
| 922 | static inline int##bw##_t zig_i##bw##_intCast_u##sw(uint##sw##_t arg) { \ | ||
| 923 | return arg; \ | ||
| 924 | } \ | ||
| 925 | \ | ||
| 926 | static inline int##bw##_t zig_i##bw##_intCast_i##sw(int##sw##_t arg) { \ | ||
| 927 | return arg; \ | ||
| 928 | } \ | ||
| 929 | \ | ||
| 930 | static inline uint##sw##_t zig_u##sw##_truncate_u##bw(uint##bw##_t arg, uint8_t bits) { \ | ||
| 931 | return (uint##sw##_t)arg & zig_maxInt_u(sw, bits); \ | ||
| 932 | } \ | ||
| 933 | \ | ||
| 934 | static inline int##sw##_t zig_i##sw##_truncate_i##bw(int##bw##_t arg, uint8_t bits) { \ | ||
| 935 | return ((uint##sw##_t)arg & UINT##sw##_C(1) << (bits - UINT8_C(1))) != UINT##sw##_C(0) \ | ||
| 936 | ? (int##sw##_t)arg | zig_minInt_i(sw, bits) : (int##sw##_t)arg & zig_maxInt_i(sw, bits); \ | ||
| 937 | } | ||
| 938 | #define zig_int_operators(w) \ | ||
| 774 | zig_basic_operator(uint##w##_t, and_u##w, &) \ | 939 | zig_basic_operator(uint##w##_t, and_u##w, &) \ |
| 775 | zig_basic_operator( int##w##_t, and_i##w, &) \ | 940 | zig_basic_operator( int##w##_t, and_i##w, &) \ |
| 776 | zig_basic_operator(uint##w##_t, or_u##w, |) \ | 941 | zig_basic_operator(uint##w##_t, or_u##w, |) \ |
| ... | @@ -786,44 +951,48 @@ typedef ptrdiff_t intptr_t; | ... | @@ -786,44 +951,48 @@ typedef ptrdiff_t intptr_t; |
| 786 | return ((lhs ^ sign_mask) >> rhs) ^ sign_mask; \ | 951 | return ((lhs ^ sign_mask) >> rhs) ^ sign_mask; \ |
| 787 | } \ | 952 | } \ |
| 788 | \ | 953 | \ |
| 789 | static inline uint##w##_t zig_not_u##w(uint##w##_t val, uint8_t bits) { \ | 954 | static inline uint##w##_t zig_not_u##w(uint##w##_t arg, uint8_t bits) { \ |
| 790 | return val ^ zig_maxInt_u(w, bits); \ | 955 | return arg ^ zig_maxInt_u(w, bits); \ |
| 791 | } \ | 956 | } \ |
| 792 | \ | 957 | \ |
| 793 | static inline int##w##_t zig_not_i##w(int##w##_t val, uint8_t bits) { \ | 958 | static inline int##w##_t zig_not_i##w(int##w##_t arg, uint8_t bits) { \ |
| 794 | (void)bits; \ | 959 | (void)bits; \ |
| 795 | return ~val; \ | 960 | return ~arg; \ |
| 796 | } \ | 961 | } \ |
| 797 | \ | 962 | \ |
| 798 | static inline uint##w##_t zig_wrap_u##w(uint##w##_t val, uint8_t bits) { \ | 963 | zig_basic_operator(uint##w##_t, divFloor_u##w, /) \ |
| 799 | return val & zig_maxInt_u(w, bits); \ | 964 | \ |
| 965 | static inline int##w##_t zig_divFloor_i##w(int##w##_t lhs, int##w##_t rhs) { \ | ||
| 966 | return lhs / rhs + (lhs % rhs != INT##w##_C(0) ? zig_shr_i##w(lhs ^ rhs, UINT8_C(w) - UINT8_C(1)) : INT##w##_C(0)); \ | ||
| 800 | } \ | 967 | } \ |
| 801 | \ | 968 | \ |
| 802 | static inline int##w##_t zig_wrap_i##w(int##w##_t val, uint8_t bits) { \ | 969 | static inline uint##w##_t zig_divCeil_u##w(uint##w##_t lhs, uint##w##_t rhs) { \ |
| 803 | return (val & UINT##w##_C(1) << (bits - UINT8_C(1))) != 0 \ | 970 | return lhs / rhs + (lhs % rhs != UINT##w##_C(0) ? UINT##w##_C(1) : UINT##w##_C(0)); \ |
| 804 | ? val | zig_minInt_i(w, bits) : val & zig_maxInt_i(w, bits); \ | ||
| 805 | } \ | 971 | } \ |
| 806 | \ | 972 | \ |
| 807 | static inline uint##w##_t zig_abs_i##w(int##w##_t val) { \ | 973 | static inline int##w##_t zig_divCeil_i##w(int##w##_t lhs, int##w##_t rhs) { \ |
| 808 | return (val < 0) ? -(uint##w##_t)val : (uint##w##_t)val; \ | 974 | return lhs / rhs + (lhs % rhs != INT##w##_C(0) \ |
| 975 | ? zig_shr_i##w(lhs ^ rhs, UINT8_C(w) - UINT8_C(1)) + INT##w##_C(1) : INT##w##_C(0)); \ | ||
| 809 | } \ | 976 | } \ |
| 810 | \ | 977 | \ |
| 811 | zig_basic_operator(uint##w##_t, div_floor_u##w, /) \ | 978 | zig_basic_operator(uint##w##_t, mod_u##w, %) \ |
| 979 | zig_int_casts_common(w, w) \ | ||
| 812 | \ | 980 | \ |
| 813 | static inline int##w##_t zig_div_floor_i##w(int##w##_t lhs, int##w##_t rhs) { \ | 981 | static inline uint##w##_t zig_u##w##_bitCast_u##w(uint##w##_t arg, uint8_t bits) { \ |
| 814 | return lhs / rhs + (lhs % rhs != INT##w##_C(0) ? zig_shr_i##w(lhs ^ rhs, UINT8_C(w) - UINT8_C(1)) : INT##w##_C(0)); \ | 982 | return zig_u##w##_truncate_u##w(arg, bits); \ |
| 815 | } \ | 983 | } \ |
| 816 | \ | 984 | \ |
| 817 | static inline uint##w##_t zig_div_ceil_u##w(uint##w##_t lhs, uint##w##_t rhs) { \ | 985 | static inline uint##w##_t zig_u##w##_bitCast_i##w(int##w##_t arg, uint8_t bits) { \ |
| 818 | return lhs / rhs + (lhs % rhs != UINT##w##_C(0) ? UINT##w##_C(1) : UINT##w##_C(0)); \ | 986 | return zig_u##w##_bitCast_u##w((uint##w##_t)arg, bits); \ |
| 819 | } \ | 987 | } \ |
| 820 | \ | 988 | \ |
| 821 | static inline int##w##_t zig_div_ceil_i##w(int##w##_t lhs, int##w##_t rhs) { \ | 989 | static inline int##w##_t zig_i##w##_bitCast_i##w(int##w##_t arg, uint8_t bits) { \ |
| 822 | return lhs / rhs + (lhs % rhs != INT##w##_C(0) \ | 990 | return zig_i##w##_truncate_i##w(arg, bits); \ |
| 823 | ? zig_shr_i##w(lhs ^ rhs, UINT8_C(w) - UINT8_C(1)) + INT##w##_C(1) : INT##w##_C(0)); \ | ||
| 824 | } \ | 991 | } \ |
| 825 | \ | 992 | \ |
| 826 | zig_basic_operator(uint##w##_t, mod_u##w, %) \ | 993 | static inline int##w##_t zig_i##w##_bitCast_u##w(uint##w##_t arg, uint8_t bits) { \ |
| 994 | return zig_i##w##_bitCast_i##w((int##w##_t)arg, bits); \ | ||
| 995 | } \ | ||
| 827 | \ | 996 | \ |
| 828 | static inline int##w##_t zig_mod_i##w(int##w##_t lhs, int##w##_t rhs) { \ | 997 | static inline int##w##_t zig_mod_i##w(int##w##_t lhs, int##w##_t rhs) { \ |
| 829 | int##w##_t rem = lhs % rhs; \ | 998 | int##w##_t rem = lhs % rhs; \ |
| ... | @@ -831,100 +1000,102 @@ typedef ptrdiff_t intptr_t; | ... | @@ -831,100 +1000,102 @@ typedef ptrdiff_t intptr_t; |
| 831 | } \ | 1000 | } \ |
| 832 | \ | 1001 | \ |
| 833 | static inline uint##w##_t zig_shlw_u##w(uint##w##_t lhs, uint8_t rhs, uint8_t bits) { \ | 1002 | static inline uint##w##_t zig_shlw_u##w(uint##w##_t lhs, uint8_t rhs, uint8_t bits) { \ |
| 834 | return zig_wrap_u##w(zig_shl_u##w(lhs, rhs), bits); \ | 1003 | return zig_u##w##_truncate_u##w(zig_shl_u##w(lhs, rhs), bits); \ |
| 835 | } \ | 1004 | } \ |
| 836 | \ | 1005 | \ |
| 837 | static inline int##w##_t zig_shlw_i##w(int##w##_t lhs, uint8_t rhs, uint8_t bits) { \ | 1006 | static inline int##w##_t zig_shlw_i##w(int##w##_t lhs, uint8_t rhs, uint8_t bits) { \ |
| 838 | return zig_wrap_i##w((int##w##_t)zig_shl_u##w((uint##w##_t)lhs, rhs), bits); \ | 1007 | return zig_i##w##_bitCast_u##w(zig_shl_u##w(zig_u##w##_bitCast_i##w(lhs, bits), rhs), bits); \ |
| 839 | } \ | 1008 | } \ |
| 840 | \ | 1009 | \ |
| 841 | static inline uint##w##_t zig_addw_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \ | 1010 | static inline uint##w##_t zig_addw_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \ |
| 842 | return zig_wrap_u##w(lhs + rhs, bits); \ | 1011 | return zig_u##w##_truncate_u##w((zig_promoted_u##w)lhs + rhs, bits); \ |
| 843 | } \ | 1012 | } \ |
| 844 | \ | 1013 | \ |
| 845 | static inline int##w##_t zig_addw_i##w(int##w##_t lhs, int##w##_t rhs, uint8_t bits) { \ | 1014 | static inline int##w##_t zig_addw_i##w(int##w##_t lhs, int##w##_t rhs, uint8_t bits) { \ |
| 846 | return zig_wrap_i##w((int##w##_t)((uint##w##_t)lhs + (uint##w##_t)rhs), bits); \ | 1015 | return zig_i##w##_bitCast_u##w(zig_addw_u##w(zig_u##w##_bitCast_i##w(lhs, bits), zig_u##w##_bitCast_i##w(rhs, bits), bits), bits); \ |
| 847 | } \ | 1016 | } \ |
| 848 | \ | 1017 | \ |
| 849 | static inline uint##w##_t zig_subw_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \ | 1018 | static inline uint##w##_t zig_subw_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \ |
| 850 | return zig_wrap_u##w(lhs - rhs, bits); \ | 1019 | return zig_u##w##_truncate_u##w((zig_promoted_u##w)lhs - rhs, bits); \ |
| 851 | } \ | 1020 | } \ |
| 852 | \ | 1021 | \ |
| 853 | static inline int##w##_t zig_subw_i##w(int##w##_t lhs, int##w##_t rhs, uint8_t bits) { \ | 1022 | static inline int##w##_t zig_subw_i##w(int##w##_t lhs, int##w##_t rhs, uint8_t bits) { \ |
| 854 | return zig_wrap_i##w((int##w##_t)((uint##w##_t)lhs - (uint##w##_t)rhs), bits); \ | 1023 | return zig_i##w##_bitCast_u##w(zig_subw_u##w(zig_u##w##_bitCast_i##w(lhs, bits), zig_u##w##_bitCast_i##w(rhs, bits), bits), bits); \ |
| 855 | } \ | 1024 | } \ |
| 856 | \ | 1025 | \ |
| 857 | static inline uint##w##_t zig_mulw_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \ | 1026 | static inline uint##w##_t zig_mulw_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \ |
| 858 | return zig_wrap_u##w((PromotedUnsigned)lhs * rhs, bits); \ | 1027 | return zig_u##w##_truncate_u##w((zig_promoted_u##w)lhs * rhs, bits); \ |
| 859 | } \ | 1028 | } \ |
| 860 | \ | 1029 | \ |
| 861 | static inline int##w##_t zig_mulw_i##w(int##w##_t lhs, int##w##_t rhs, uint8_t bits) { \ | 1030 | static inline int##w##_t zig_mulw_i##w(int##w##_t lhs, int##w##_t rhs, uint8_t bits) { \ |
| 862 | return zig_wrap_i##w((int##w##_t)((uint##w##_t)lhs * (uint##w##_t)rhs), bits); \ | 1031 | return zig_i##w##_bitCast_u##w(zig_mulw_u##w(zig_u##w##_bitCast_i##w(lhs, bits), zig_u##w##_bitCast_i##w(rhs, bits), bits), bits); \ |
| 1032 | } \ | ||
| 1033 | \ | ||
| 1034 | static inline uint##w##_t zig_abs_i##w(int##w##_t arg) { \ | ||
| 1035 | int##w##_t tmp = zig_shr_i##w(arg, UINT8_C(w) - UINT8_C(1)); \ | ||
| 1036 | return zig_u##w##_bitCast_i##w(zig_subw_i##w(zig_xor_i##w(arg, tmp), tmp, UINT8_C(w)), UINT8_C(w)); \ | ||
| 1037 | } \ | ||
| 1038 | \ | ||
| 1039 | static inline uint##w##_t zig_min_u##w(uint##w##_t lhs, uint##w##_t rhs) { \ | ||
| 1040 | return lhs < rhs ? lhs : rhs; \ | ||
| 1041 | } \ | ||
| 1042 | \ | ||
| 1043 | static inline int##w##_t zig_min_i##w(int##w##_t lhs, int##w##_t rhs) { \ | ||
| 1044 | return lhs < rhs ? lhs : rhs; \ | ||
| 1045 | } \ | ||
| 1046 | \ | ||
| 1047 | static inline uint##w##_t zig_max_u##w(uint##w##_t lhs, uint##w##_t rhs) { \ | ||
| 1048 | return lhs >= rhs ? lhs : rhs; \ | ||
| 1049 | } \ | ||
| 1050 | \ | ||
| 1051 | static inline int##w##_t zig_max_i##w(int##w##_t lhs, int##w##_t rhs) { \ | ||
| 1052 | return lhs >= rhs ? lhs : rhs; \ | ||
| 863 | } | 1053 | } |
| 864 | #if UINT8_MAX <= UINT_MAX | 1054 | zig_int_operators(8) |
| 865 | zig_int_helpers(8, unsigned int) | 1055 | zig_int_operators(16) |
| 866 | #elif UINT8_MAX <= ULONG_MAX | 1056 | zig_int_operators(32) |
| 867 | zig_int_helpers(8, unsigned long) | 1057 | zig_int_operators(64) |
| 868 | #elif UINT8_MAX <= ULLONG_MAX | 1058 | #ifdef zig_ez80 |
| 869 | zig_int_helpers(8, unsigned long long) | 1059 | zig_int_operators(24) |
| 870 | #else | 1060 | zig_int_operators(48) |
| 871 | zig_int_helpers(8, uint8_t) | 1061 | #endif |
| 872 | #endif | 1062 | |
| 873 | #if UINT16_MAX <= UINT_MAX | 1063 | #define zig_int_casts(bw, sw) \ |
| 874 | zig_int_helpers(16, unsigned int) | 1064 | static inline uint##sw##_t zig_u##sw##_intCast_u##bw(uint##bw##_t arg) { \ |
| 875 | #elif UINT16_MAX <= ULONG_MAX | 1065 | return (uint##sw##_t)arg; \ |
| 876 | zig_int_helpers(16, unsigned long) | 1066 | } \ |
| 877 | #elif UINT16_MAX <= ULLONG_MAX | 1067 | \ |
| 878 | zig_int_helpers(16, unsigned long long) | 1068 | static inline uint##sw##_t zig_u##sw##_intCast_i##bw(int##bw##_t arg) { \ |
| 879 | #else | 1069 | return (uint##sw##_t)arg; \ |
| 880 | zig_int_helpers(16, uint16_t) | 1070 | } \ |
| 881 | #endif | 1071 | \ |
| 882 | #if defined(zig_ez80) | 1072 | static inline int##sw##_t zig_i##sw##_intCast_u##bw(uint##bw##_t arg) { \ |
| 883 | #if UINT24_MAX <= UINT_MAX | 1073 | return (int##sw##_t)arg; \ |
| 884 | zig_int_helpers(24, unsigned int) | 1074 | } \ |
| 885 | #elif UINT24_MAX <= ULONG_MAX | 1075 | \ |
| 886 | zig_int_helpers(24, unsigned long) | 1076 | static inline int##sw##_t zig_i##sw##_intCast_i##bw(int##bw##_t arg) { \ |
| 887 | #elif UINT24_MAX <= ULLONG_MAX | 1077 | return (int##sw##_t)arg; \ |
| 888 | zig_int_helpers(24, unsigned long long) | 1078 | } \ |
| 889 | #else | 1079 | \ |
| 890 | zig_int_helpers(24, uint24_t) | 1080 | zig_int_casts_common(bw, sw) |
| 891 | #endif | 1081 | zig_int_casts(16, 8) |
| 892 | #endif | 1082 | zig_int_casts(32, 8) |
| 893 | #if UINT32_MAX <= UINT_MAX | 1083 | zig_int_casts(64, 8) |
| 894 | zig_int_helpers(32, unsigned int) | 1084 | zig_int_casts(32, 16) |
| 895 | #elif UINT32_MAX <= ULONG_MAX | 1085 | zig_int_casts(64, 16) |
| 896 | zig_int_helpers(32, unsigned long) | 1086 | zig_int_casts(64, 32) |
| 897 | #elif UINT32_MAX <= ULLONG_MAX | 1087 | #ifdef zig_ez80 |
| 898 | zig_int_helpers(32, unsigned long long) | 1088 | zig_int_casts(32, 24) |
| 899 | #else | 1089 | zig_int_casts(48, 24) |
| 900 | zig_int_helpers(32, uint32_t) | 1090 | zig_int_casts(64, 24) |
| 901 | #endif | 1091 | zig_int_casts(64, 48) |
| 902 | #if defined(zig_ez80) | ||
| 903 | #if UINT24_MAX <= UINT_MAX | ||
| 904 | zig_int_helpers(48, unsigned int) | ||
| 905 | #elif UINT24_MAX <= ULONG_MAX | ||
| 906 | zig_int_helpers(48, unsigned long) | ||
| 907 | #elif UINT24_MAX <= ULLONG_MAX | ||
| 908 | zig_int_helpers(48, unsigned long long) | ||
| 909 | #else | ||
| 910 | zig_int_helpers(48, uint48_t) | ||
| 911 | #endif | ||
| 912 | #endif | ||
| 913 | #if UINT64_MAX <= UINT_MAX | ||
| 914 | zig_int_helpers(64, unsigned int) | ||
| 915 | #elif UINT64_MAX <= ULONG_MAX | ||
| 916 | zig_int_helpers(64, unsigned long) | ||
| 917 | #elif UINT64_MAX <= ULLONG_MAX | ||
| 918 | zig_int_helpers(64, unsigned long long) | ||
| 919 | #else | ||
| 920 | zig_int_helpers(64, uint64_t) | ||
| 921 | #endif | 1092 | #endif |
| 922 | 1093 | ||
| 923 | static inline bool zig_addo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) { | 1094 | static inline bool zig_addo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) { |
| 924 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) | 1095 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) |
| 925 | uint32_t full_res; | 1096 | uint32_t full_res; |
| 926 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); | 1097 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); |
| 927 | *res = zig_wrap_u32(full_res, bits); | 1098 | *res = zig_u32_truncate_u32(full_res, bits); |
| 928 | return overflow || full_res < zig_minInt_u(32, bits) || full_res > zig_maxInt_u(32, bits); | 1099 | return overflow || full_res < zig_minInt_u(32, bits) || full_res > zig_maxInt_u(32, bits); |
| 929 | #else | 1100 | #else |
| 930 | *res = zig_addw_u32(lhs, rhs, bits); | 1101 | *res = zig_addw_u32(lhs, rhs, bits); |
| ... | @@ -936,19 +1107,19 @@ static inline bool zig_addo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t | ... | @@ -936,19 +1107,19 @@ static inline bool zig_addo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t |
| 936 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) | 1107 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) |
| 937 | int32_t full_res; | 1108 | int32_t full_res; |
| 938 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); | 1109 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); |
| 1110 | *res = zig_i32_truncate_i32(full_res, bits); | ||
| 1111 | return overflow || full_res < zig_minInt_i(32, bits) || full_res > zig_maxInt_i(32, bits); | ||
| 939 | #else | 1112 | #else |
| 940 | int32_t full_res = (int32_t)((uint32_t)lhs + (uint32_t)rhs); | 1113 | *res = zig_addw_i32(lhs, rhs, bits); |
| 941 | bool overflow = ((full_res ^ lhs) & (full_res ^ rhs)) < 0; | 1114 | return ((*res ^ lhs) & (*res ^ rhs)) < INT32_C(0); |
| 942 | #endif | 1115 | #endif |
| 943 | *res = zig_wrap_i32(full_res, bits); | ||
| 944 | return overflow || full_res < zig_minInt_i(32, bits) || full_res > zig_maxInt_i(32, bits); | ||
| 945 | } | 1116 | } |
| 946 | 1117 | ||
| 947 | static inline bool zig_addo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8_t bits) { | 1118 | static inline bool zig_addo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8_t bits) { |
| 948 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) | 1119 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) |
| 949 | uint64_t full_res; | 1120 | uint64_t full_res; |
| 950 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); | 1121 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); |
| 951 | *res = zig_wrap_u64(full_res, bits); | 1122 | *res = zig_u64_truncate_u64(full_res, bits); |
| 952 | return overflow || full_res < zig_minInt_u(64, bits) || full_res > zig_maxInt_u(64, bits); | 1123 | return overflow || full_res < zig_minInt_u(64, bits) || full_res > zig_maxInt_u(64, bits); |
| 953 | #else | 1124 | #else |
| 954 | *res = zig_addw_u64(lhs, rhs, bits); | 1125 | *res = zig_addw_u64(lhs, rhs, bits); |
| ... | @@ -960,24 +1131,24 @@ static inline bool zig_addo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t | ... | @@ -960,24 +1131,24 @@ static inline bool zig_addo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t |
| 960 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) | 1131 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) |
| 961 | int64_t full_res; | 1132 | int64_t full_res; |
| 962 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); | 1133 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); |
| 1134 | *res = zig_i64_truncate_i64(full_res, bits); | ||
| 1135 | return overflow || full_res < zig_minInt_i(64, bits) || full_res > zig_maxInt_i(64, bits); | ||
| 963 | #else | 1136 | #else |
| 964 | int64_t full_res = (int64_t)((uint64_t)lhs + (uint64_t)rhs); | 1137 | *res = zig_addw_i64(lhs, rhs, bits); |
| 965 | bool overflow = ((full_res ^ lhs) & (full_res ^ rhs)) < 0; | 1138 | return ((*res ^ lhs) & (*res ^ rhs)) < INT64_C(0); |
| 966 | #endif | 1139 | #endif |
| 967 | *res = zig_wrap_i64(full_res, bits); | ||
| 968 | return overflow || full_res < zig_minInt_i(64, bits) || full_res > zig_maxInt_i(64, bits); | ||
| 969 | } | 1140 | } |
| 970 | 1141 | ||
| 971 | static inline bool zig_addo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t bits) { | 1142 | static inline bool zig_addo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t bits) { |
| 972 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) | 1143 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) |
| 973 | uint8_t full_res; | 1144 | uint8_t full_res; |
| 974 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); | 1145 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); |
| 975 | *res = zig_wrap_u8(full_res, bits); | 1146 | *res = zig_u8_truncate_u8(full_res, bits); |
| 976 | return overflow || full_res < zig_minInt_u(8, bits) || full_res > zig_maxInt_u(8, bits); | 1147 | return overflow || full_res < zig_minInt_u(8, bits) || full_res > zig_maxInt_u(8, bits); |
| 977 | #else | 1148 | #else |
| 978 | uint32_t full_res; | 1149 | uint32_t full_res; |
| 979 | bool overflow = zig_addo_u32(&full_res, lhs, rhs, bits); | 1150 | bool overflow = zig_addo_u32(&full_res, lhs, rhs, bits); |
| 980 | *res = (uint8_t)full_res; | 1151 | *res = zig_u8_intCast_u32(full_res); |
| 981 | return overflow; | 1152 | return overflow; |
| 982 | #endif | 1153 | #endif |
| 983 | } | 1154 | } |
| ... | @@ -986,12 +1157,12 @@ static inline bool zig_addo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits | ... | @@ -986,12 +1157,12 @@ static inline bool zig_addo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits |
| 986 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) | 1157 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) |
| 987 | int8_t full_res; | 1158 | int8_t full_res; |
| 988 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); | 1159 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); |
| 989 | *res = zig_wrap_i8(full_res, bits); | 1160 | *res = zig_i8_truncate_i8(full_res, bits); |
| 990 | return overflow || full_res < zig_minInt_i(8, bits) || full_res > zig_maxInt_i(8, bits); | 1161 | return overflow || full_res < zig_minInt_i(8, bits) || full_res > zig_maxInt_i(8, bits); |
| 991 | #else | 1162 | #else |
| 992 | int32_t full_res; | 1163 | int32_t full_res; |
| 993 | bool overflow = zig_addo_i32(&full_res, lhs, rhs, bits); | 1164 | bool overflow = zig_addo_i32(&full_res, lhs, rhs, bits); |
| 994 | *res = (int8_t)full_res; | 1165 | *res = zig_i8_intCast_i32(full_res); |
| 995 | return overflow; | 1166 | return overflow; |
| 996 | #endif | 1167 | #endif |
| 997 | } | 1168 | } |
| ... | @@ -1000,12 +1171,12 @@ static inline bool zig_addo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8 | ... | @@ -1000,12 +1171,12 @@ static inline bool zig_addo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8 |
| 1000 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) | 1171 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) |
| 1001 | uint16_t full_res; | 1172 | uint16_t full_res; |
| 1002 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); | 1173 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); |
| 1003 | *res = zig_wrap_u16(full_res, bits); | 1174 | *res = zig_u16_truncate_u16(full_res, bits); |
| 1004 | return overflow || full_res < zig_minInt_u(16, bits) || full_res > zig_maxInt_u(16, bits); | 1175 | return overflow || full_res < zig_minInt_u(16, bits) || full_res > zig_maxInt_u(16, bits); |
| 1005 | #else | 1176 | #else |
| 1006 | uint32_t full_res; | 1177 | uint32_t full_res; |
| 1007 | bool overflow = zig_addo_u32(&full_res, lhs, rhs, bits); | 1178 | bool overflow = zig_addo_u32(&full_res, lhs, rhs, bits); |
| 1008 | *res = (uint16_t)full_res; | 1179 | *res = zig_u16_intCast_u32(full_res); |
| 1009 | return overflow; | 1180 | return overflow; |
| 1010 | #endif | 1181 | #endif |
| 1011 | } | 1182 | } |
| ... | @@ -1014,27 +1185,28 @@ static inline bool zig_addo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t | ... | @@ -1014,27 +1185,28 @@ static inline bool zig_addo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t |
| 1014 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) | 1185 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) |
| 1015 | int16_t full_res; | 1186 | int16_t full_res; |
| 1016 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); | 1187 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); |
| 1017 | *res = zig_wrap_i16(full_res, bits); | 1188 | *res = zig_i16_truncate_i16(full_res, bits); |
| 1018 | return overflow || full_res < zig_minInt_i(16, bits) || full_res > zig_maxInt_i(16, bits); | 1189 | return overflow || full_res < zig_minInt_i(16, bits) || full_res > zig_maxInt_i(16, bits); |
| 1019 | #else | 1190 | #else |
| 1020 | int32_t full_res; | 1191 | int32_t full_res; |
| 1021 | bool overflow = zig_addo_i32(&full_res, lhs, rhs, bits); | 1192 | bool overflow = zig_addo_i32(&full_res, lhs, rhs, bits); |
| 1022 | *res = (int16_t)full_res; | 1193 | *res = zig_i16_intCast_i32(full_res); |
| 1023 | return overflow; | 1194 | return overflow; |
| 1024 | #endif | 1195 | #endif |
| 1025 | } | 1196 | } |
| 1026 | 1197 | ||
| 1027 | #if defined(zig_ez80) | 1198 | #if defined(zig_ez80) |
| 1199 | |||
| 1028 | static inline bool zig_addo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) { | 1200 | static inline bool zig_addo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) { |
| 1029 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) | 1201 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) |
| 1030 | uint24_t full_res; | 1202 | uint24_t full_res; |
| 1031 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); | 1203 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); |
| 1032 | *res = zig_wrap_u24(full_res, bits); | 1204 | *res = zig_u24_truncate_u24(full_res, bits); |
| 1033 | return overflow || full_res < zig_minInt_u(24, bits) || full_res > zig_maxInt_u(24, bits); | 1205 | return overflow || full_res < zig_minInt_u(24, bits) || full_res > zig_maxInt_u(24, bits); |
| 1034 | #else | 1206 | #else |
| 1035 | uint32_t full_res; | 1207 | uint32_t full_res; |
| 1036 | bool overflow = zig_addo_u32(&full_res, lhs, rhs, bits); | 1208 | bool overflow = zig_addo_u32(&full_res, lhs, rhs, bits); |
| 1037 | *res = (uint24_t)full_res; | 1209 | *res = zig_u24_intCast_u32(full_res); |
| 1038 | return overflow; | 1210 | return overflow; |
| 1039 | #endif | 1211 | #endif |
| 1040 | } | 1212 | } |
| ... | @@ -1043,28 +1215,26 @@ static inline bool zig_addo_i24(int24_t *res, int24_t lhs, int24_t rhs, uint8_t | ... | @@ -1043,28 +1215,26 @@ static inline bool zig_addo_i24(int24_t *res, int24_t lhs, int24_t rhs, uint8_t |
| 1043 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) | 1215 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) |
| 1044 | int24_t full_res; | 1216 | int24_t full_res; |
| 1045 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); | 1217 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); |
| 1046 | *res = zig_wrap_i24(full_res, bits); | 1218 | *res = zig_i24_truncate_i24(full_res, bits); |
| 1047 | return overflow || full_res < zig_minInt_i(24, bits) || full_res > zig_maxInt_i(24, bits); | 1219 | return overflow || full_res < zig_minInt_i(24, bits) || full_res > zig_maxInt_i(24, bits); |
| 1048 | #else | 1220 | #else |
| 1049 | int32_t full_res; | 1221 | int32_t full_res; |
| 1050 | bool overflow = zig_addo_i32(&full_res, lhs, rhs, bits); | 1222 | bool overflow = zig_addo_i32(&full_res, lhs, rhs, bits); |
| 1051 | *res = (int24_t)full_res; | 1223 | *res = zig_i24_intCast_i32(full_res); |
| 1052 | return overflow; | 1224 | return overflow; |
| 1053 | #endif | 1225 | #endif |
| 1054 | } | 1226 | } |
| 1055 | #endif | ||
| 1056 | 1227 | ||
| 1057 | #if defined(zig_ez80) | ||
| 1058 | static inline bool zig_addo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) { | 1228 | static inline bool zig_addo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) { |
| 1059 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) | 1229 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) |
| 1060 | uint48_t full_res; | 1230 | uint48_t full_res; |
| 1061 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); | 1231 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); |
| 1062 | *res = zig_wrap_u48(full_res, bits); | 1232 | *res = zig_u48_truncate_u48(full_res, bits); |
| 1063 | return overflow || full_res < zig_minInt_u(48, bits) || full_res > zig_maxInt_u(48, bits); | 1233 | return overflow || full_res < zig_minInt_u(48, bits) || full_res > zig_maxInt_u(48, bits); |
| 1064 | #else | 1234 | #else |
| 1065 | uint64_t full_res; | 1235 | uint64_t full_res; |
| 1066 | bool overflow = zig_addo_u64(&full_res, lhs, rhs, bits); | 1236 | bool overflow = zig_addo_u64(&full_res, lhs, rhs, bits); |
| 1067 | *res = (uint48_t)full_res; | 1237 | *res = zig_u48_intCast_u64(full_res); |
| 1068 | return overflow; | 1238 | return overflow; |
| 1069 | #endif | 1239 | #endif |
| 1070 | } | 1240 | } |
| ... | @@ -1073,22 +1243,23 @@ static inline bool zig_addo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t | ... | @@ -1073,22 +1243,23 @@ static inline bool zig_addo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t |
| 1073 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) | 1243 | #if zig_has_builtin(add_overflow) || defined(zig_gcc) |
| 1074 | int48_t full_res; | 1244 | int48_t full_res; |
| 1075 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); | 1245 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); |
| 1076 | *res = zig_wrap_i48(full_res, bits); | 1246 | *res = zig_i48_truncate_i48(full_res, bits); |
| 1077 | return overflow || full_res < zig_minInt_i(48, bits) || full_res > zig_maxInt_i(48, bits); | 1247 | return overflow || full_res < zig_minInt_i(48, bits) || full_res > zig_maxInt_i(48, bits); |
| 1078 | #else | 1248 | #else |
| 1079 | int64_t full_res; | 1249 | int64_t full_res; |
| 1080 | bool overflow = zig_addo_i64(&full_res, lhs, rhs, bits); | 1250 | bool overflow = zig_addo_i64(&full_res, lhs, rhs, bits); |
| 1081 | *res = (int48_t)full_res; | 1251 | *res = zig_i48_intCast_i64(full_res); |
| 1082 | return overflow; | 1252 | return overflow; |
| 1083 | #endif | 1253 | #endif |
| 1084 | } | 1254 | } |
| 1255 | |||
| 1085 | #endif | 1256 | #endif |
| 1086 | 1257 | ||
| 1087 | static inline bool zig_subo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) { | 1258 | static inline bool zig_subo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) { |
| 1088 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) | 1259 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) |
| 1089 | uint32_t full_res; | 1260 | uint32_t full_res; |
| 1090 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); | 1261 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); |
| 1091 | *res = zig_wrap_u32(full_res, bits); | 1262 | *res = zig_u32_truncate_u32(full_res, bits); |
| 1092 | return overflow || full_res < zig_minInt_u(32, bits) || full_res > zig_maxInt_u(32, bits); | 1263 | return overflow || full_res < zig_minInt_u(32, bits) || full_res > zig_maxInt_u(32, bits); |
| 1093 | #else | 1264 | #else |
| 1094 | *res = zig_subw_u32(lhs, rhs, bits); | 1265 | *res = zig_subw_u32(lhs, rhs, bits); |
| ... | @@ -1100,20 +1271,19 @@ static inline bool zig_subo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t | ... | @@ -1100,20 +1271,19 @@ static inline bool zig_subo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t |
| 1100 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) | 1271 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) |
| 1101 | int32_t full_res; | 1272 | int32_t full_res; |
| 1102 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); | 1273 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); |
| 1274 | *res = zig_i32_truncate_i32(full_res, bits); | ||
| 1275 | return overflow || full_res < zig_minInt_i(32, bits) || full_res > zig_maxInt_i(32, bits); | ||
| 1103 | #else | 1276 | #else |
| 1104 | int32_t full_res = (int32_t)((uint32_t)lhs - (uint32_t)rhs); | 1277 | *res = zig_subw_i32(lhs, rhs, bits); |
| 1105 | bool overflow = ((lhs ^ rhs) & (full_res ^ lhs)) < 0; | 1278 | return ((lhs ^ rhs) & (*res ^ lhs)) < INT32_C(0); |
| 1106 | #endif | 1279 | #endif |
| 1107 | *res = zig_wrap_i32(full_res, bits); | ||
| 1108 | return overflow || full_res < zig_minInt_i(32, bits) || full_res > zig_maxInt_i(32, bits); | ||
| 1109 | } | 1280 | } |
| 1110 | 1281 | ||
| 1111 | |||
| 1112 | static inline bool zig_subo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8_t bits) { | 1282 | static inline bool zig_subo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8_t bits) { |
| 1113 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) | 1283 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) |
| 1114 | uint64_t full_res; | 1284 | uint64_t full_res; |
| 1115 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); | 1285 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); |
| 1116 | *res = zig_wrap_u64(full_res, bits); | 1286 | *res = zig_u64_truncate_u64(full_res, bits); |
| 1117 | return overflow || full_res < zig_minInt_u(64, bits) || full_res > zig_maxInt_u(64, bits); | 1287 | return overflow || full_res < zig_minInt_u(64, bits) || full_res > zig_maxInt_u(64, bits); |
| 1118 | #else | 1288 | #else |
| 1119 | *res = zig_subw_u64(lhs, rhs, bits); | 1289 | *res = zig_subw_u64(lhs, rhs, bits); |
| ... | @@ -1125,24 +1295,24 @@ static inline bool zig_subo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t | ... | @@ -1125,24 +1295,24 @@ static inline bool zig_subo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t |
| 1125 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) | 1295 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) |
| 1126 | int64_t full_res; | 1296 | int64_t full_res; |
| 1127 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); | 1297 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); |
| 1298 | *res = zig_i64_truncate_i64(full_res, bits); | ||
| 1299 | return overflow || full_res < zig_minInt_i(64, bits) || full_res > zig_maxInt_i(64, bits); | ||
| 1128 | #else | 1300 | #else |
| 1129 | int64_t full_res = (int64_t)((uint64_t)lhs - (uint64_t)rhs); | 1301 | *res = zig_subw_i64(lhs, rhs, bits); |
| 1130 | bool overflow = ((lhs ^ rhs) & (full_res ^ lhs)) < 0; | 1302 | return ((lhs ^ rhs) & (*res ^ lhs)) < INT64_C(0); |
| 1131 | #endif | 1303 | #endif |
| 1132 | *res = zig_wrap_i64(full_res, bits); | ||
| 1133 | return overflow || full_res < zig_minInt_i(64, bits) || full_res > zig_maxInt_i(64, bits); | ||
| 1134 | } | 1304 | } |
| 1135 | 1305 | ||
| 1136 | static inline bool zig_subo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t bits) { | 1306 | static inline bool zig_subo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t bits) { |
| 1137 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) | 1307 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) |
| 1138 | uint8_t full_res; | 1308 | uint8_t full_res; |
| 1139 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); | 1309 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); |
| 1140 | *res = zig_wrap_u8(full_res, bits); | 1310 | *res = zig_u8_truncate_u8(full_res, bits); |
| 1141 | return overflow || full_res < zig_minInt_u(8, bits) || full_res > zig_maxInt_u(8, bits); | 1311 | return overflow || full_res < zig_minInt_u(8, bits) || full_res > zig_maxInt_u(8, bits); |
| 1142 | #else | 1312 | #else |
| 1143 | uint32_t full_res; | 1313 | uint32_t full_res; |
| 1144 | bool overflow = zig_subo_u32(&full_res, lhs, rhs, bits); | 1314 | bool overflow = zig_subo_u32(&full_res, lhs, rhs, bits); |
| 1145 | *res = (uint8_t)full_res; | 1315 | *res = zig_u8_intCast_u32(full_res); |
| 1146 | return overflow; | 1316 | return overflow; |
| 1147 | #endif | 1317 | #endif |
| 1148 | } | 1318 | } |
| ... | @@ -1151,12 +1321,12 @@ static inline bool zig_subo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits | ... | @@ -1151,12 +1321,12 @@ static inline bool zig_subo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits |
| 1151 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) | 1321 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) |
| 1152 | int8_t full_res; | 1322 | int8_t full_res; |
| 1153 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); | 1323 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); |
| 1154 | *res = zig_wrap_i8(full_res, bits); | 1324 | *res = zig_i8_truncate_i8(full_res, bits); |
| 1155 | return overflow || full_res < zig_minInt_i(8, bits) || full_res > zig_maxInt_i(8, bits); | 1325 | return overflow || full_res < zig_minInt_i(8, bits) || full_res > zig_maxInt_i(8, bits); |
| 1156 | #else | 1326 | #else |
| 1157 | int32_t full_res; | 1327 | int32_t full_res; |
| 1158 | bool overflow = zig_subo_i32(&full_res, lhs, rhs, bits); | 1328 | bool overflow = zig_subo_i32(&full_res, lhs, rhs, bits); |
| 1159 | *res = (int8_t)full_res; | 1329 | *res = zig_i8_intCast_i32(full_res); |
| 1160 | return overflow; | 1330 | return overflow; |
| 1161 | #endif | 1331 | #endif |
| 1162 | } | 1332 | } |
| ... | @@ -1165,12 +1335,12 @@ static inline bool zig_subo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8 | ... | @@ -1165,12 +1335,12 @@ static inline bool zig_subo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8 |
| 1165 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) | 1335 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) |
| 1166 | uint16_t full_res; | 1336 | uint16_t full_res; |
| 1167 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); | 1337 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); |
| 1168 | *res = zig_wrap_u16(full_res, bits); | 1338 | *res = zig_u16_truncate_u16(full_res, bits); |
| 1169 | return overflow || full_res < zig_minInt_u(16, bits) || full_res > zig_maxInt_u(16, bits); | 1339 | return overflow || full_res < zig_minInt_u(16, bits) || full_res > zig_maxInt_u(16, bits); |
| 1170 | #else | 1340 | #else |
| 1171 | uint32_t full_res; | 1341 | uint32_t full_res; |
| 1172 | bool overflow = zig_subo_u32(&full_res, lhs, rhs, bits); | 1342 | bool overflow = zig_subo_u32(&full_res, lhs, rhs, bits); |
| 1173 | *res = (uint16_t)full_res; | 1343 | *res = zig_u16_intCast_u32(full_res); |
| 1174 | return overflow; | 1344 | return overflow; |
| 1175 | #endif | 1345 | #endif |
| 1176 | } | 1346 | } |
| ... | @@ -1179,27 +1349,28 @@ static inline bool zig_subo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t | ... | @@ -1179,27 +1349,28 @@ static inline bool zig_subo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t |
| 1179 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) | 1349 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) |
| 1180 | int16_t full_res; | 1350 | int16_t full_res; |
| 1181 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); | 1351 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); |
| 1182 | *res = zig_wrap_i16(full_res, bits); | 1352 | *res = zig_i16_truncate_i16(full_res, bits); |
| 1183 | return overflow || full_res < zig_minInt_i(16, bits) || full_res > zig_maxInt_i(16, bits); | 1353 | return overflow || full_res < zig_minInt_i(16, bits) || full_res > zig_maxInt_i(16, bits); |
| 1184 | #else | 1354 | #else |
| 1185 | int32_t full_res; | 1355 | int32_t full_res; |
| 1186 | bool overflow = zig_subo_i32(&full_res, lhs, rhs, bits); | 1356 | bool overflow = zig_subo_i32(&full_res, lhs, rhs, bits); |
| 1187 | *res = (int16_t)full_res; | 1357 | *res = zig_i16_intCast_i32(full_res); |
| 1188 | return overflow; | 1358 | return overflow; |
| 1189 | #endif | 1359 | #endif |
| 1190 | } | 1360 | } |
| 1191 | 1361 | ||
| 1192 | #if defined(zig_ez80) | 1362 | #if defined(zig_ez80) |
| 1363 | |||
| 1193 | static inline bool zig_subo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) { | 1364 | static inline bool zig_subo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) { |
| 1194 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) | 1365 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) |
| 1195 | uint24_t full_res; | 1366 | uint24_t full_res; |
| 1196 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); | 1367 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); |
| 1197 | *res = zig_wrap_u24(full_res, bits); | 1368 | *res = zig_u24_truncate_u24(full_res, bits); |
| 1198 | return overflow || full_res < zig_minInt_u(24, bits) || full_res > zig_maxInt_u(24, bits); | 1369 | return overflow || full_res < zig_minInt_u(24, bits) || full_res > zig_maxInt_u(24, bits); |
| 1199 | #else | 1370 | #else |
| 1200 | uint32_t full_res; | 1371 | uint32_t full_res; |
| 1201 | bool overflow = zig_subo_u32(&full_res, lhs, rhs, bits); | 1372 | bool overflow = zig_subo_u32(&full_res, lhs, rhs, bits); |
| 1202 | *res = (uint24_t)full_res; | 1373 | *res = zig_u24_intCast_u32(full_res); |
| 1203 | return overflow; | 1374 | return overflow; |
| 1204 | #endif | 1375 | #endif |
| 1205 | } | 1376 | } |
| ... | @@ -1208,28 +1379,26 @@ static inline bool zig_subo_i24(int24_t *res, int24_t lhs, int24_t rhs, uint8_t | ... | @@ -1208,28 +1379,26 @@ static inline bool zig_subo_i24(int24_t *res, int24_t lhs, int24_t rhs, uint8_t |
| 1208 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) | 1379 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) |
| 1209 | int24_t full_res; | 1380 | int24_t full_res; |
| 1210 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); | 1381 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); |
| 1211 | *res = zig_wrap_i24(full_res, bits); | 1382 | *res = zig_i24_truncate_i24(full_res, bits); |
| 1212 | return overflow || full_res < zig_minInt_i(24, bits) || full_res > zig_maxInt_i(24, bits); | 1383 | return overflow || full_res < zig_minInt_i(24, bits) || full_res > zig_maxInt_i(24, bits); |
| 1213 | #else | 1384 | #else |
| 1214 | int32_t full_res; | 1385 | int32_t full_res; |
| 1215 | bool overflow = zig_subo_i32(&full_res, lhs, rhs, bits); | 1386 | bool overflow = zig_subo_i32(&full_res, lhs, rhs, bits); |
| 1216 | *res = (int24_t)full_res; | 1387 | *res = zig_i24_intCast_i32(full_res); |
| 1217 | return overflow; | 1388 | return overflow; |
| 1218 | #endif | 1389 | #endif |
| 1219 | } | 1390 | } |
| 1220 | #endif | ||
| 1221 | 1391 | ||
| 1222 | #if defined(zig_ez80) | ||
| 1223 | static inline bool zig_subo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) { | 1392 | static inline bool zig_subo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) { |
| 1224 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) | 1393 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) |
| 1225 | uint48_t full_res; | 1394 | uint48_t full_res; |
| 1226 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); | 1395 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); |
| 1227 | *res = zig_wrap_u48(full_res, bits); | 1396 | *res = zig_u48_truncate_u48(full_res, bits); |
| 1228 | return overflow || full_res < zig_minInt_u(48, bits) || full_res > zig_maxInt_u(48, bits); | 1397 | return overflow || full_res < zig_minInt_u(48, bits) || full_res > zig_maxInt_u(48, bits); |
| 1229 | #else | 1398 | #else |
| 1230 | uint64_t full_res; | 1399 | uint64_t full_res; |
| 1231 | bool overflow = zig_subo_u64(&full_res, lhs, rhs, bits); | 1400 | bool overflow = zig_subo_u64(&full_res, lhs, rhs, bits); |
| 1232 | *res = (uint48_t)full_res; | 1401 | *res = zig_u48_intCast_u64(full_res); |
| 1233 | return overflow; | 1402 | return overflow; |
| 1234 | #endif | 1403 | #endif |
| 1235 | } | 1404 | } |
| ... | @@ -1238,22 +1407,23 @@ static inline bool zig_subo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t | ... | @@ -1238,22 +1407,23 @@ static inline bool zig_subo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t |
| 1238 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) | 1407 | #if zig_has_builtin(sub_overflow) || defined(zig_gcc) |
| 1239 | int48_t full_res; | 1408 | int48_t full_res; |
| 1240 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); | 1409 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); |
| 1241 | *res = zig_wrap_i48(full_res, bits); | 1410 | *res = zig_i48_truncate_i48(full_res, bits); |
| 1242 | return overflow || full_res < zig_minInt_i(48, bits) || full_res > zig_maxInt_i(48, bits); | 1411 | return overflow || full_res < zig_minInt_i(48, bits) || full_res > zig_maxInt_i(48, bits); |
| 1243 | #else | 1412 | #else |
| 1244 | int64_t full_res; | 1413 | int64_t full_res; |
| 1245 | bool overflow = zig_subo_i64(&full_res, lhs, rhs, bits); | 1414 | bool overflow = zig_subo_i64(&full_res, lhs, rhs, bits); |
| 1246 | *res = (int48_t)full_res; | 1415 | *res = zig_i48_intCast_i64(full_res); |
| 1247 | return overflow; | 1416 | return overflow; |
| 1248 | #endif | 1417 | #endif |
| 1249 | } | 1418 | } |
| 1419 | |||
| 1250 | #endif | 1420 | #endif |
| 1251 | 1421 | ||
| 1252 | static inline bool zig_mulo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) { | 1422 | static inline bool zig_mulo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) { |
| 1253 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) | 1423 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) |
| 1254 | uint32_t full_res; | 1424 | uint32_t full_res; |
| 1255 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); | 1425 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); |
| 1256 | *res = zig_wrap_u32(full_res, bits); | 1426 | *res = zig_u32_truncate_u32(full_res, bits); |
| 1257 | return overflow || full_res < zig_minInt_u(32, bits) || full_res > zig_maxInt_u(32, bits); | 1427 | return overflow || full_res < zig_minInt_u(32, bits) || full_res > zig_maxInt_u(32, bits); |
| 1258 | #else | 1428 | #else |
| 1259 | *res = zig_mulw_u32(lhs, rhs, bits); | 1429 | *res = zig_mulw_u32(lhs, rhs, bits); |
| ... | @@ -1261,8 +1431,8 @@ static inline bool zig_mulo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8 | ... | @@ -1261,8 +1431,8 @@ static inline bool zig_mulo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8 |
| 1261 | #endif | 1431 | #endif |
| 1262 | } | 1432 | } |
| 1263 | 1433 | ||
| 1264 | zig_extern int32_t __mulosi4(int32_t lhs, int32_t rhs, int *overflow); | ||
| 1265 | static inline bool zig_mulo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t bits) { | 1434 | static inline bool zig_mulo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t bits) { |
| 1435 | zig_extern int32_t __mulosi4(int32_t lhs, int32_t rhs, int *overflow); | ||
| 1266 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) | 1436 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) |
| 1267 | int32_t full_res; | 1437 | int32_t full_res; |
| 1268 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); | 1438 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); |
| ... | @@ -1271,7 +1441,7 @@ static inline bool zig_mulo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t | ... | @@ -1271,7 +1441,7 @@ static inline bool zig_mulo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t |
| 1271 | int32_t full_res = __mulosi4(lhs, rhs, &overflow_int); | 1441 | int32_t full_res = __mulosi4(lhs, rhs, &overflow_int); |
| 1272 | bool overflow = overflow_int != 0; | 1442 | bool overflow = overflow_int != 0; |
| 1273 | #endif | 1443 | #endif |
| 1274 | *res = zig_wrap_i32(full_res, bits); | 1444 | *res = zig_i32_truncate_i32(full_res, bits); |
| 1275 | return overflow || full_res < zig_minInt_i(32, bits) || full_res > zig_maxInt_i(32, bits); | 1445 | return overflow || full_res < zig_minInt_i(32, bits) || full_res > zig_maxInt_i(32, bits); |
| 1276 | } | 1446 | } |
| 1277 | 1447 | ||
| ... | @@ -1279,7 +1449,7 @@ static inline bool zig_mulo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8 | ... | @@ -1279,7 +1449,7 @@ static inline bool zig_mulo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8 |
| 1279 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) | 1449 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) |
| 1280 | uint64_t full_res; | 1450 | uint64_t full_res; |
| 1281 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); | 1451 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); |
| 1282 | *res = zig_wrap_u64(full_res, bits); | 1452 | *res = zig_u64_truncate_u64(full_res, bits); |
| 1283 | return overflow || full_res < zig_minInt_u(64, bits) || full_res > zig_maxInt_u(64, bits); | 1453 | return overflow || full_res < zig_minInt_u(64, bits) || full_res > zig_maxInt_u(64, bits); |
| 1284 | #else | 1454 | #else |
| 1285 | *res = zig_mulw_u64(lhs, rhs, bits); | 1455 | *res = zig_mulw_u64(lhs, rhs, bits); |
| ... | @@ -1287,8 +1457,8 @@ static inline bool zig_mulo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8 | ... | @@ -1287,8 +1457,8 @@ static inline bool zig_mulo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8 |
| 1287 | #endif | 1457 | #endif |
| 1288 | } | 1458 | } |
| 1289 | 1459 | ||
| 1290 | zig_extern int64_t __mulodi4(int64_t lhs, int64_t rhs, int *overflow); | ||
| 1291 | static inline bool zig_mulo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t bits) { | 1460 | static inline bool zig_mulo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t bits) { |
| 1461 | zig_extern int64_t __mulodi4(int64_t lhs, int64_t rhs, int *overflow); | ||
| 1292 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) | 1462 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) |
| 1293 | int64_t full_res; | 1463 | int64_t full_res; |
| 1294 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); | 1464 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); |
| ... | @@ -1297,7 +1467,7 @@ static inline bool zig_mulo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t | ... | @@ -1297,7 +1467,7 @@ static inline bool zig_mulo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t |
| 1297 | int64_t full_res = __mulodi4(lhs, rhs, &overflow_int); | 1467 | int64_t full_res = __mulodi4(lhs, rhs, &overflow_int); |
| 1298 | bool overflow = overflow_int != 0; | 1468 | bool overflow = overflow_int != 0; |
| 1299 | #endif | 1469 | #endif |
| 1300 | *res = zig_wrap_i64(full_res, bits); | 1470 | *res = zig_i64_truncate_i64(full_res, bits); |
| 1301 | return overflow || full_res < zig_minInt_i(64, bits) || full_res > zig_maxInt_i(64, bits); | 1471 | return overflow || full_res < zig_minInt_i(64, bits) || full_res > zig_maxInt_i(64, bits); |
| 1302 | } | 1472 | } |
| 1303 | 1473 | ||
| ... | @@ -1305,12 +1475,12 @@ static inline bool zig_mulo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t b | ... | @@ -1305,12 +1475,12 @@ static inline bool zig_mulo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t b |
| 1305 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) | 1475 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) |
| 1306 | uint8_t full_res; | 1476 | uint8_t full_res; |
| 1307 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); | 1477 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); |
| 1308 | *res = zig_wrap_u8(full_res, bits); | 1478 | *res = zig_u8_truncate_u8(full_res, bits); |
| 1309 | return overflow || full_res < zig_minInt_u(8, bits) || full_res > zig_maxInt_u(8, bits); | 1479 | return overflow || full_res < zig_minInt_u(8, bits) || full_res > zig_maxInt_u(8, bits); |
| 1310 | #else | 1480 | #else |
| 1311 | uint32_t full_res; | 1481 | uint32_t full_res; |
| 1312 | bool overflow = zig_mulo_u32(&full_res, lhs, rhs, bits); | 1482 | bool overflow = zig_mulo_u32(&full_res, lhs, rhs, bits); |
| 1313 | *res = (uint8_t)full_res; | 1483 | *res = zig_u8_intCast_u32(full_res); |
| 1314 | return overflow; | 1484 | return overflow; |
| 1315 | #endif | 1485 | #endif |
| 1316 | } | 1486 | } |
| ... | @@ -1319,12 +1489,12 @@ static inline bool zig_mulo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits | ... | @@ -1319,12 +1489,12 @@ static inline bool zig_mulo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits |
| 1319 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) | 1489 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) |
| 1320 | int8_t full_res; | 1490 | int8_t full_res; |
| 1321 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); | 1491 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); |
| 1322 | *res = zig_wrap_i8(full_res, bits); | 1492 | *res = zig_i8_truncate_i8(full_res, bits); |
| 1323 | return overflow || full_res < zig_minInt_i(8, bits) || full_res > zig_maxInt_i(8, bits); | 1493 | return overflow || full_res < zig_minInt_i(8, bits) || full_res > zig_maxInt_i(8, bits); |
| 1324 | #else | 1494 | #else |
| 1325 | int32_t full_res; | 1495 | int32_t full_res; |
| 1326 | bool overflow = zig_mulo_i32(&full_res, lhs, rhs, bits); | 1496 | bool overflow = zig_mulo_i32(&full_res, lhs, rhs, bits); |
| 1327 | *res = (int8_t)full_res; | 1497 | *res = zig_i8_intCast_i32(full_res); |
| 1328 | return overflow; | 1498 | return overflow; |
| 1329 | #endif | 1499 | #endif |
| 1330 | } | 1500 | } |
| ... | @@ -1333,12 +1503,12 @@ static inline bool zig_mulo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8 | ... | @@ -1333,12 +1503,12 @@ static inline bool zig_mulo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8 |
| 1333 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) | 1503 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) |
| 1334 | uint16_t full_res; | 1504 | uint16_t full_res; |
| 1335 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); | 1505 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); |
| 1336 | *res = zig_wrap_u16(full_res, bits); | 1506 | *res = zig_u16_truncate_u16(full_res, bits); |
| 1337 | return overflow || full_res < zig_minInt_u(16, bits) || full_res > zig_maxInt_u(16, bits); | 1507 | return overflow || full_res < zig_minInt_u(16, bits) || full_res > zig_maxInt_u(16, bits); |
| 1338 | #else | 1508 | #else |
| 1339 | uint32_t full_res; | 1509 | uint32_t full_res; |
| 1340 | bool overflow = zig_mulo_u32(&full_res, lhs, rhs, bits); | 1510 | bool overflow = zig_mulo_u32(&full_res, lhs, rhs, bits); |
| 1341 | *res = (uint16_t)full_res; | 1511 | *res = zig_u16_intCast_u32(full_res); |
| 1342 | return overflow; | 1512 | return overflow; |
| 1343 | #endif | 1513 | #endif |
| 1344 | } | 1514 | } |
| ... | @@ -1347,27 +1517,28 @@ static inline bool zig_mulo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t | ... | @@ -1347,27 +1517,28 @@ static inline bool zig_mulo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t |
| 1347 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) | 1517 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) |
| 1348 | int16_t full_res; | 1518 | int16_t full_res; |
| 1349 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); | 1519 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); |
| 1350 | *res = zig_wrap_i16(full_res, bits); | 1520 | *res = zig_i16_truncate_i16(full_res, bits); |
| 1351 | return overflow || full_res < zig_minInt_i(16, bits) || full_res > zig_maxInt_i(16, bits); | 1521 | return overflow || full_res < zig_minInt_i(16, bits) || full_res > zig_maxInt_i(16, bits); |
| 1352 | #else | 1522 | #else |
| 1353 | int32_t full_res; | 1523 | int32_t full_res; |
| 1354 | bool overflow = zig_mulo_i32(&full_res, lhs, rhs, bits); | 1524 | bool overflow = zig_mulo_i32(&full_res, lhs, rhs, bits); |
| 1355 | *res = (int16_t)full_res; | 1525 | *res = zig_i16_intCast_i32(full_res); |
| 1356 | return overflow; | 1526 | return overflow; |
| 1357 | #endif | 1527 | #endif |
| 1358 | } | 1528 | } |
| 1359 | 1529 | ||
| 1360 | #if defined(zig_ez80) | 1530 | #if defined(zig_ez80) |
| 1531 | |||
| 1361 | static inline bool zig_mulo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) { | 1532 | static inline bool zig_mulo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) { |
| 1362 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) | 1533 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) |
| 1363 | uint24_t full_res; | 1534 | uint24_t full_res; |
| 1364 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); | 1535 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); |
| 1365 | *res = zig_wrap_u24(full_res, bits); | 1536 | *res = zig_u24_truncate_u24(full_res, bits); |
| 1366 | return overflow || full_res < zig_minInt_u(24, bits) || full_res > zig_maxInt_u(24, bits); | 1537 | return overflow || full_res < zig_minInt_u(24, bits) || full_res > zig_maxInt_u(24, bits); |
| 1367 | #else | 1538 | #else |
| 1368 | uint32_t full_res; | 1539 | uint32_t full_res; |
| 1369 | bool overflow = zig_mulo_u32(&full_res, lhs, rhs, bits); | 1540 | bool overflow = zig_mulo_u32(&full_res, lhs, rhs, bits); |
| 1370 | *res = (uint24_t)full_res; | 1541 | *res = zig_u24_intCast_u32(full_res); |
| 1371 | return overflow; | 1542 | return overflow; |
| 1372 | #endif | 1543 | #endif |
| 1373 | } | 1544 | } |
| ... | @@ -1376,28 +1547,26 @@ static inline bool zig_mulo_i24(int24_t *res, int24_t lhs, int24_t rhs, uint8_t | ... | @@ -1376,28 +1547,26 @@ static inline bool zig_mulo_i24(int24_t *res, int24_t lhs, int24_t rhs, uint8_t |
| 1376 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) | 1547 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) |
| 1377 | int24_t full_res; | 1548 | int24_t full_res; |
| 1378 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); | 1549 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); |
| 1379 | *res = zig_wrap_i24(full_res, bits); | 1550 | *res = zig_i24_truncate_i24(full_res, bits); |
| 1380 | return overflow || full_res < zig_minInt_i(24, bits) || full_res > zig_maxInt_i(24, bits); | 1551 | return overflow || full_res < zig_minInt_i(24, bits) || full_res > zig_maxInt_i(24, bits); |
| 1381 | #else | 1552 | #else |
| 1382 | int32_t full_res; | 1553 | int32_t full_res; |
| 1383 | bool overflow = zig_mulo_i32(&full_res, lhs, rhs, bits); | 1554 | bool overflow = zig_mulo_i32(&full_res, lhs, rhs, bits); |
| 1384 | *res = (int24_t)full_res; | 1555 | *res = zig_i24_intCast_i32(full_res); |
| 1385 | return overflow; | 1556 | return overflow; |
| 1386 | #endif | 1557 | #endif |
| 1387 | } | 1558 | } |
| 1388 | #endif | ||
| 1389 | 1559 | ||
| 1390 | #if defined(zig_ez80) | ||
| 1391 | static inline bool zig_mulo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) { | 1560 | static inline bool zig_mulo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) { |
| 1392 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) | 1561 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) |
| 1393 | uint48_t full_res; | 1562 | uint48_t full_res; |
| 1394 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); | 1563 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); |
| 1395 | *res = zig_wrap_u48(full_res, bits); | 1564 | *res = zig_u48_truncate_u48(full_res, bits); |
| 1396 | return overflow || full_res < zig_minInt_u(48, bits) || full_res > zig_maxInt_u(48, bits); | 1565 | return overflow || full_res < zig_minInt_u(48, bits) || full_res > zig_maxInt_u(48, bits); |
| 1397 | #else | 1566 | #else |
| 1398 | uint64_t full_res; | 1567 | uint64_t full_res; |
| 1399 | bool overflow = zig_mulo_u64(&full_res, lhs, rhs, bits); | 1568 | bool overflow = zig_mulo_u64(&full_res, lhs, rhs, bits); |
| 1400 | *res = (uint48_t)full_res; | 1569 | *res = zig_u48_intCast_u64(full_res); |
| 1401 | return overflow; | 1570 | return overflow; |
| 1402 | #endif | 1571 | #endif |
| 1403 | } | 1572 | } |
| ... | @@ -1406,18 +1575,32 @@ static inline bool zig_mulo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t | ... | @@ -1406,18 +1575,32 @@ static inline bool zig_mulo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t |
| 1406 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) | 1575 | #if zig_has_builtin(mul_overflow) || defined(zig_gcc) |
| 1407 | int48_t full_res; | 1576 | int48_t full_res; |
| 1408 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); | 1577 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); |
| 1409 | *res = zig_wrap_i48(full_res, bits); | 1578 | *res = zig_i48_truncate_i48(full_res, bits); |
| 1410 | return overflow || full_res < zig_minInt_i(48, bits) || full_res > zig_maxInt_i(48, bits); | 1579 | return overflow || full_res < zig_minInt_i(48, bits) || full_res > zig_maxInt_i(48, bits); |
| 1411 | #else | 1580 | #else |
| 1412 | int64_t full_res; | 1581 | int64_t full_res; |
| 1413 | bool overflow = zig_mulo_i64(&full_res, lhs, rhs, bits); | 1582 | bool overflow = zig_mulo_i64(&full_res, lhs, rhs, bits); |
| 1414 | *res = (int48_t)full_res; | 1583 | *res = zig_i48_intCast_i64(full_res); |
| 1415 | return overflow; | 1584 | return overflow; |
| 1416 | #endif | 1585 | #endif |
| 1417 | } | 1586 | } |
| 1587 | |||
| 1418 | #endif | 1588 | #endif |
| 1419 | 1589 | ||
| 1420 | #define zig_int_builtins(w) \ | 1590 | #define zig_shls_builtins(lw, rw) \ |
| 1591 | static inline uint##lw##_t zig_shls_u##lw##_u##rw(uint##lw##_t lhs, uint##rw##_t rhs, uint8_t bits) { \ | ||
| 1592 | uint##lw##_t res; \ | ||
| 1593 | if (rhs < bits && !zig_shlo_u##lw(&res, lhs, zig_u8_intCast_u##rw(rhs), bits)) return res; \ | ||
| 1594 | return lhs == INT##lw##_C(0) ? zig_minInt_u(lw, bits) : zig_maxInt_u(lw, bits); \ | ||
| 1595 | } \ | ||
| 1596 | \ | ||
| 1597 | static inline int##lw##_t zig_shls_i##lw##_u##rw(int##lw##_t lhs, uint##rw##_t rhs, uint8_t bits) { \ | ||
| 1598 | int##lw##_t res; \ | ||
| 1599 | if (rhs < bits && !zig_shlo_i##lw(&res, lhs, zig_u8_intCast_u##rw(rhs), bits)) return res; \ | ||
| 1600 | return lhs == INT##lw##_C(0) ? INT##lw##_C(0) : \ | ||
| 1601 | lhs < INT##lw##_C(0) ? zig_minInt_i(lw, bits) : zig_maxInt_i(lw, bits); \ | ||
| 1602 | } | ||
| 1603 | #define zig_int_sat_builtins(w) \ | ||
| 1421 | static inline bool zig_shlo_u##w(uint##w##_t *res, uint##w##_t lhs, uint8_t rhs, uint8_t bits) { \ | 1604 | static inline bool zig_shlo_u##w(uint##w##_t *res, uint##w##_t lhs, uint8_t rhs, uint8_t bits) { \ |
| 1422 | *res = zig_shlw_u##w(lhs, rhs, bits); \ | 1605 | *res = zig_shlw_u##w(lhs, rhs, bits); \ |
| 1423 | return lhs > zig_maxInt_u(w, bits) >> rhs; \ | 1606 | return lhs > zig_maxInt_u(w, bits) >> rhs; \ |
| ... | @@ -1429,18 +1612,10 @@ static inline bool zig_mulo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t | ... | @@ -1429,18 +1612,10 @@ static inline bool zig_mulo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t |
| 1429 | return (lhs & mask) != INT##w##_C(0) && (lhs & mask) != mask; \ | 1612 | return (lhs & mask) != INT##w##_C(0) && (lhs & mask) != mask; \ |
| 1430 | } \ | 1613 | } \ |
| 1431 | \ | 1614 | \ |
| 1432 | static inline uint##w##_t zig_shls_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \ | 1615 | zig_shls_builtins(w, 8) \ |
| 1433 | uint##w##_t res; \ | 1616 | zig_shls_builtins(w, 16) \ |
| 1434 | if (rhs < bits && !zig_shlo_u##w(&res, lhs, rhs, bits)) return res; \ | 1617 | zig_shls_builtins(w, 32) \ |
| 1435 | return lhs == INT##w##_C(0) ? INT##w##_C(0) : zig_maxInt_u(w, bits); \ | 1618 | zig_shls_builtins(w, 64) \ |
| 1436 | } \ | ||
| 1437 | \ | ||
| 1438 | static inline int##w##_t zig_shls_i##w(int##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \ | ||
| 1439 | int##w##_t res; \ | ||
| 1440 | if (rhs < bits && !zig_shlo_i##w(&res, lhs, rhs, bits)) return res; \ | ||
| 1441 | return lhs == INT##w##_C(0) ? INT##w##_C(0) : \ | ||
| 1442 | lhs < INT##w##_C(0) ? zig_minInt_i(w, bits) : zig_maxInt_i(w, bits); \ | ||
| 1443 | } \ | ||
| 1444 | \ | 1619 | \ |
| 1445 | static inline uint##w##_t zig_adds_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \ | 1620 | static inline uint##w##_t zig_adds_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \ |
| 1446 | uint##w##_t res; \ | 1621 | uint##w##_t res; \ |
| ... | @@ -1474,332 +1649,321 @@ static inline bool zig_mulo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t | ... | @@ -1474,332 +1649,321 @@ static inline bool zig_mulo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t |
| 1474 | if (!zig_mulo_i##w(&res, lhs, rhs, bits)) return res; \ | 1649 | if (!zig_mulo_i##w(&res, lhs, rhs, bits)) return res; \ |
| 1475 | return (lhs ^ rhs) < INT##w##_C(0) ? zig_minInt_i(w, bits) : zig_maxInt_i(w, bits); \ | 1650 | return (lhs ^ rhs) < INT##w##_C(0) ? zig_minInt_i(w, bits) : zig_maxInt_i(w, bits); \ |
| 1476 | } | 1651 | } |
| 1477 | zig_int_builtins(8) | 1652 | zig_int_sat_builtins(8) |
| 1478 | zig_int_builtins(16) | 1653 | zig_int_sat_builtins(16) |
| 1479 | #if defined(zig_ez80) | 1654 | zig_int_sat_builtins(32) |
| 1480 | zig_int_builtins(24) | 1655 | zig_int_sat_builtins(64) |
| 1481 | #endif | ||
| 1482 | zig_int_builtins(32) | ||
| 1483 | #if defined(zig_ez80) | 1656 | #if defined(zig_ez80) |
| 1484 | zig_int_builtins(48) | 1657 | zig_int_sat_builtins(24) |
| 1658 | zig_int_sat_builtins(48) | ||
| 1485 | #endif | 1659 | #endif |
| 1486 | zig_int_builtins(64) | ||
| 1487 | 1660 | ||
| 1488 | #define zig_builtin8(name, val) __builtin_##name(val) | 1661 | #define zig_builtin8(name, arg) __builtin_##name(arg) |
| 1489 | typedef unsigned int zig_Builtin8; | 1662 | typedef unsigned int zig_Builtin8; |
| 1490 | 1663 | ||
| 1491 | #define zig_builtin16(name, val) __builtin_##name(val) | 1664 | #define zig_builtin16(name, arg) __builtin_##name(arg) |
| 1492 | typedef unsigned int zig_Builtin16; | 1665 | typedef unsigned int zig_Builtin16; |
| 1493 | 1666 | ||
| 1494 | #if defined(zig_ez80) | ||
| 1495 | #define zig_builtin24(name, val) __builtin_##name(val) | ||
| 1496 | typedef unsigned int zig_Builtin24; | ||
| 1497 | #endif | ||
| 1498 | |||
| 1499 | #if INT_MIN <= INT32_MIN | 1667 | #if INT_MIN <= INT32_MIN |
| 1500 | #define zig_builtin32(name, val) __builtin_##name(val) | 1668 | #define zig_builtin32(name, arg) __builtin_##name(arg) |
| 1501 | typedef unsigned int zig_Builtin32; | 1669 | typedef unsigned int zig_Builtin32; |
| 1502 | #elif LONG_MIN <= INT32_MIN | 1670 | #elif LONG_MIN <= INT32_MIN |
| 1503 | #define zig_builtin32(name, val) __builtin_##name##l(val) | 1671 | #define zig_builtin32(name, arg) __builtin_##name##l(arg) |
| 1504 | typedef unsigned long zig_Builtin32; | 1672 | typedef unsigned long zig_Builtin32; |
| 1505 | #endif | 1673 | #endif |
| 1506 | 1674 | ||
| 1507 | #if defined(zig_ez80) | ||
| 1508 | #define zig_builtin48(name, val) __builtin_##name(val) | ||
| 1509 | typedef unsigned long long zig_Builtin48; | ||
| 1510 | #endif | ||
| 1511 | |||
| 1512 | #if INT_MIN <= INT64_MIN | 1675 | #if INT_MIN <= INT64_MIN |
| 1513 | #define zig_builtin64(name, val) __builtin_##name(val) | 1676 | #define zig_builtin64(name, arg) __builtin_##name(arg) |
| 1514 | typedef unsigned int zig_Builtin64; | 1677 | typedef unsigned int zig_Builtin64; |
| 1515 | #elif LONG_MIN <= INT64_MIN | 1678 | #elif LONG_MIN <= INT64_MIN |
| 1516 | #define zig_builtin64(name, val) __builtin_##name##l(val) | 1679 | #define zig_builtin64(name, arg) __builtin_##name##l(arg) |
| 1517 | typedef unsigned long zig_Builtin64; | 1680 | typedef unsigned long zig_Builtin64; |
| 1518 | #elif LLONG_MIN <= INT64_MIN | 1681 | #elif LLONG_MIN <= INT64_MIN |
| 1519 | #define zig_builtin64(name, val) __builtin_##name##ll(val) | 1682 | #define zig_builtin64(name, arg) __builtin_##name##ll(arg) |
| 1520 | typedef unsigned long long zig_Builtin64; | 1683 | typedef unsigned long long zig_Builtin64; |
| 1521 | #endif | 1684 | #endif |
| 1522 | 1685 | ||
| 1523 | static inline uint8_t zig_byte_swap_u8(uint8_t val, uint8_t bits) { | 1686 | #if defined(zig_ez80) |
| 1524 | return zig_wrap_u8(val >> (8 - bits), bits); | 1687 | #define zig_builtin24(name, arg) __builtin_##name(arg) |
| 1688 | typedef unsigned int zig_Builtin24; | ||
| 1689 | #define zig_builtin48(name, arg) __builtin_##name(arg) | ||
| 1690 | typedef unsigned long long zig_Builtin48; | ||
| 1691 | #endif | ||
| 1692 | |||
| 1693 | static inline uint8_t zig_byteSwap_u8(uint8_t arg, uint8_t bits) { | ||
| 1694 | return zig_u8_truncate_u8(arg >> (8 - bits), bits); | ||
| 1525 | } | 1695 | } |
| 1526 | 1696 | ||
| 1527 | static inline int8_t zig_byte_swap_i8(int8_t val, uint8_t bits) { | 1697 | static inline int8_t zig_byteSwap_i8(int8_t arg, uint8_t bits) { |
| 1528 | return zig_wrap_i8((int8_t)zig_byte_swap_u8((uint8_t)val, bits), bits); | 1698 | return zig_i8_truncate_i8((int8_t)zig_byteSwap_u8((uint8_t)arg, bits), bits); |
| 1529 | } | 1699 | } |
| 1530 | 1700 | ||
| 1531 | static inline uint16_t zig_byte_swap_u16(uint16_t val, uint8_t bits) { | 1701 | static inline uint16_t zig_byteSwap_u16(uint16_t arg, uint8_t bits) { |
| 1532 | uint16_t full_res; | 1702 | uint16_t full_res; |
| 1533 | #if zig_has_builtin(bswap16) || defined(zig_gcc) | 1703 | #if zig_has_builtin(bswap16) || defined(zig_gcc) |
| 1534 | full_res = __builtin_bswap16(val); | 1704 | full_res = __builtin_bswap16(arg); |
| 1535 | #else | 1705 | #else |
| 1536 | full_res = (uint16_t)zig_byte_swap_u8((uint8_t)(val >> 0), 8) << 8 | | 1706 | full_res = (uint16_t)zig_byteSwap_u8((uint8_t)(arg >> 0), 8) << 8 | |
| 1537 | (uint16_t)zig_byte_swap_u8((uint8_t)(val >> 8), 8) >> 0; | 1707 | (uint16_t)zig_byteSwap_u8((uint8_t)(arg >> 8), 8) >> 0; |
| 1538 | #endif | 1708 | #endif |
| 1539 | return zig_wrap_u16(full_res >> (16 - bits), bits); | 1709 | return zig_u16_truncate_u16(full_res >> (16 - bits), bits); |
| 1540 | } | 1710 | } |
| 1541 | 1711 | ||
| 1542 | static inline int16_t zig_byte_swap_i16(int16_t val, uint8_t bits) { | 1712 | static inline int16_t zig_byteSwap_i16(int16_t arg, uint8_t bits) { |
| 1543 | return zig_wrap_i16((int16_t)zig_byte_swap_u16((uint16_t)val, bits), bits); | 1713 | return zig_i16_truncate_i16((int16_t)zig_byteSwap_u16((uint16_t)arg, bits), bits); |
| 1544 | } | 1714 | } |
| 1545 | 1715 | ||
| 1546 | #if defined(zig_ez80) | 1716 | #if defined(zig_ez80) |
| 1547 | static inline uint16_t zig_byte_swap_u24(uint24_t val, uint8_t bits) { | 1717 | static inline uint16_t zig_byteSwap_u24(uint24_t arg, uint8_t bits) { |
| 1548 | uint24_t full_res; | 1718 | uint24_t full_res; |
| 1549 | #if zig_has_builtin(bswap24) || defined(zig_gcc) | 1719 | #if zig_has_builtin(bswap24) || defined(zig_gcc) |
| 1550 | full_res = __builtin_bswap24(val); | 1720 | full_res = __builtin_bswap24(arg); |
| 1551 | #else | 1721 | #else |
| 1552 | full_res = (uint24_t)zig_byte_swap_u8((uint8_t)(val >> 0), 8) << 16 | | 1722 | full_res = (uint24_t)zig_byteSwap_u8((uint8_t)(arg >> 0), 8) << 16 | |
| 1553 | (uint24_t)zig_byte_swap_u16((uint16_t)(val >> 8), 16) >> 0; | 1723 | (uint24_t)zig_byteSwap_u16((uint16_t)(arg >> 8), 16) >> 0; |
| 1554 | #endif | 1724 | #endif |
| 1555 | return zig_wrap_u24(full_res >> (24 - bits), bits); | 1725 | return zig_u24_truncate_u24(full_res >> (24 - bits), bits); |
| 1556 | } | 1726 | } |
| 1557 | 1727 | ||
| 1558 | static inline int16_t zig_byte_swap_i24(int24_t val, uint8_t bits) { | 1728 | static inline int16_t zig_byteSwap_i24(int24_t arg, uint8_t bits) { |
| 1559 | return zig_wrap_i24((int24_t)zig_byte_swap_u24((uint24_t)val, bits), bits); | 1729 | return zig_i24_truncate_i24((int24_t)zig_byteSwap_u24((uint24_t)arg, bits), bits); |
| 1560 | } | 1730 | } |
| 1561 | #endif | 1731 | #endif |
| 1562 | 1732 | ||
| 1563 | static inline uint32_t zig_byte_swap_u32(uint32_t val, uint8_t bits) { | 1733 | static inline uint32_t zig_byteSwap_u32(uint32_t arg, uint8_t bits) { |
| 1564 | uint32_t full_res; | 1734 | uint32_t full_res; |
| 1565 | #if zig_has_builtin(bswap32) || defined(zig_gcc) | 1735 | #if zig_has_builtin(bswap32) || defined(zig_gcc) |
| 1566 | full_res = __builtin_bswap32(val); | 1736 | full_res = __builtin_bswap32(arg); |
| 1567 | #else | 1737 | #else |
| 1568 | full_res = (uint32_t)zig_byte_swap_u16((uint16_t)(val >> 0), 16) << 16 | | 1738 | full_res = (uint32_t)zig_byteSwap_u16((uint16_t)(arg >> 0), 16) << 16 | |
| 1569 | (uint32_t)zig_byte_swap_u16((uint16_t)(val >> 16), 16) >> 0; | 1739 | (uint32_t)zig_byteSwap_u16((uint16_t)(arg >> 16), 16) >> 0; |
| 1570 | #endif | 1740 | #endif |
| 1571 | return zig_wrap_u32(full_res >> (32 - bits), bits); | 1741 | return zig_u32_truncate_u32(full_res >> (32 - bits), bits); |
| 1572 | } | 1742 | } |
| 1573 | 1743 | ||
| 1574 | static inline int32_t zig_byte_swap_i32(int32_t val, uint8_t bits) { | 1744 | static inline int32_t zig_byteSwap_i32(int32_t arg, uint8_t bits) { |
| 1575 | return zig_wrap_i32((int32_t)zig_byte_swap_u32((uint32_t)val, bits), bits); | 1745 | return zig_i32_truncate_i32((int32_t)zig_byteSwap_u32((uint32_t)arg, bits), bits); |
| 1576 | } | 1746 | } |
| 1577 | 1747 | ||
| 1578 | #if defined(zig_ez80) | 1748 | #if defined(zig_ez80) |
| 1579 | static inline uint32_t zig_byte_swap_u48(uint48_t val, uint8_t bits) { | 1749 | static inline uint32_t zig_byteSwap_u48(uint48_t arg, uint8_t bits) { |
| 1580 | uint48_t full_res; | 1750 | uint48_t full_res; |
| 1581 | #if zig_has_builtin(bswap48) || defined(zig_gcc) | 1751 | #if zig_has_builtin(bswap48) || defined(zig_gcc) |
| 1582 | full_res = __builtin_bswap48(val); | 1752 | full_res = __builtin_bswap48(arg); |
| 1583 | #else | 1753 | #else |
| 1584 | full_res = (uint48_t)zig_byte_swap_u24((uint24_t)(val >> 0), 24) << 24 | | 1754 | full_res = (uint48_t)zig_byteSwap_u24((uint24_t)(arg >> 0), 24) << 24 | |
| 1585 | (uint48_t)zig_byte_swap_u24((uint24_t)(val >> 24), 24) >> 0; | 1755 | (uint48_t)zig_byteSwap_u24((uint24_t)(arg >> 24), 24) >> 0; |
| 1586 | #endif | 1756 | #endif |
| 1587 | return zig_wrap_u48(full_res >> (48 - bits), bits); | 1757 | return zig_u48_truncate_u48(full_res >> (48 - bits), bits); |
| 1588 | } | 1758 | } |
| 1589 | 1759 | ||
| 1590 | static inline int32_t zig_byte_swap_i48(int48_t val, uint8_t bits) { | 1760 | static inline int32_t zig_byteSwap_i48(int48_t arg, uint8_t bits) { |
| 1591 | return zig_wrap_i48((int48_t)zig_byte_swap_u48((uint48_t)val, bits), bits); | 1761 | return zig_i48_truncate_i48((int48_t)zig_byteSwap_u48((uint48_t)arg, bits), bits); |
| 1592 | } | 1762 | } |
| 1593 | #endif | 1763 | #endif |
| 1594 | 1764 | ||
| 1595 | static inline uint64_t zig_byte_swap_u64(uint64_t val, uint8_t bits) { | 1765 | static inline uint64_t zig_byteSwap_u64(uint64_t arg, uint8_t bits) { |
| 1596 | uint64_t full_res; | 1766 | uint64_t full_res; |
| 1597 | #if zig_has_builtin(bswap64) || defined(zig_gcc) | 1767 | #if zig_has_builtin(bswap64) || defined(zig_gcc) |
| 1598 | full_res = __builtin_bswap64(val); | 1768 | full_res = __builtin_bswap64(arg); |
| 1599 | #else | 1769 | #else |
| 1600 | full_res = (uint64_t)zig_byte_swap_u32((uint32_t)(val >> 0), 32) << 32 | | 1770 | full_res = (uint64_t)zig_byteSwap_u32((uint32_t)(arg >> 0), 32) << 32 | |
| 1601 | (uint64_t)zig_byte_swap_u32((uint32_t)(val >> 32), 32) >> 0; | 1771 | (uint64_t)zig_byteSwap_u32((uint32_t)(arg >> 32), 32) >> 0; |
| 1602 | #endif | 1772 | #endif |
| 1603 | return zig_wrap_u64(full_res >> (64 - bits), bits); | 1773 | return zig_u64_truncate_u64(full_res >> (64 - bits), bits); |
| 1604 | } | 1774 | } |
| 1605 | 1775 | ||
| 1606 | static inline int64_t zig_byte_swap_i64(int64_t val, uint8_t bits) { | 1776 | static inline int64_t zig_byteSwap_i64(int64_t arg, uint8_t bits) { |
| 1607 | return zig_wrap_i64((int64_t)zig_byte_swap_u64((uint64_t)val, bits), bits); | 1777 | return zig_i64_truncate_i64((int64_t)zig_byteSwap_u64((uint64_t)arg, bits), bits); |
| 1608 | } | 1778 | } |
| 1609 | 1779 | ||
| 1610 | static inline uint8_t zig_bit_reverse_u8(uint8_t val, uint8_t bits) { | 1780 | static inline uint8_t zig_bitReverse_u8(uint8_t arg, uint8_t bits) { |
| 1611 | uint8_t full_res; | 1781 | uint8_t full_res; |
| 1612 | #if zig_has_builtin(bitreverse8) | 1782 | #if zig_has_builtin(bitreverse8) |
| 1613 | full_res = __builtin_bitreverse8(val); | 1783 | full_res = __builtin_bitreverse8(arg); |
| 1614 | #else | 1784 | #else |
| 1615 | static uint8_t const lut[0x10] = { | 1785 | static uint8_t const lut[0x10] = { |
| 1616 | 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe, | 1786 | 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe, |
| 1617 | 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf | 1787 | 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf |
| 1618 | }; | 1788 | }; |
| 1619 | full_res = lut[val >> 0 & 0xF] << 4 | lut[val >> 4 & 0xF] << 0; | 1789 | full_res = lut[arg >> 0 & 0xF] << 4 | lut[arg >> 4 & 0xF] << 0; |
| 1620 | #endif | 1790 | #endif |
| 1621 | return zig_wrap_u8(full_res >> (8 - bits), bits); | 1791 | return zig_u8_truncate_u8(full_res >> (8 - bits), bits); |
| 1622 | } | 1792 | } |
| 1623 | 1793 | ||
| 1624 | static inline int8_t zig_bit_reverse_i8(int8_t val, uint8_t bits) { | 1794 | static inline int8_t zig_bitReverse_i8(int8_t arg, uint8_t bits) { |
| 1625 | return zig_wrap_i8((int8_t)zig_bit_reverse_u8((uint8_t)val, bits), bits); | 1795 | return zig_i8_truncate_i8((int8_t)zig_bitReverse_u8((uint8_t)arg, bits), bits); |
| 1626 | } | 1796 | } |
| 1627 | 1797 | ||
| 1628 | static inline uint16_t zig_bit_reverse_u16(uint16_t val, uint8_t bits) { | 1798 | static inline uint16_t zig_bitReverse_u16(uint16_t arg, uint8_t bits) { |
| 1629 | uint16_t full_res; | 1799 | uint16_t full_res; |
| 1630 | #if zig_has_builtin(bitreverse16) | 1800 | #if zig_has_builtin(bitreverse16) |
| 1631 | full_res = __builtin_bitreverse16(val); | 1801 | full_res = __builtin_bitreverse16(arg); |
| 1632 | #else | 1802 | #else |
| 1633 | full_res = (uint16_t)zig_bit_reverse_u8((uint8_t)(val >> 0), 8) << 8 | | 1803 | full_res = (uint16_t)zig_bitReverse_u8((uint8_t)(arg >> 0), 8) << 8 | |
| 1634 | (uint16_t)zig_bit_reverse_u8((uint8_t)(val >> 8), 8) >> 0; | 1804 | (uint16_t)zig_bitReverse_u8((uint8_t)(arg >> 8), 8) >> 0; |
| 1635 | #endif | 1805 | #endif |
| 1636 | return zig_wrap_u16(full_res >> (16 - bits), bits); | 1806 | return zig_u16_truncate_u16(full_res >> (16 - bits), bits); |
| 1637 | } | 1807 | } |
| 1638 | 1808 | ||
| 1639 | static inline int16_t zig_bit_reverse_i16(int16_t val, uint8_t bits) { | 1809 | static inline int16_t zig_bitReverse_i16(int16_t arg, uint8_t bits) { |
| 1640 | return zig_wrap_i16((int16_t)zig_bit_reverse_u16((uint16_t)val, bits), bits); | 1810 | return zig_i16_truncate_i16((int16_t)zig_bitReverse_u16((uint16_t)arg, bits), bits); |
| 1641 | } | 1811 | } |
| 1642 | 1812 | ||
| 1643 | #if defined(zig_ez80) | 1813 | #if defined(zig_ez80) |
| 1644 | static inline uint24_t zig_bit_reverse_u24(uint24_t val, uint8_t bits) { | 1814 | static inline uint24_t zig_bitReverse_u24(uint24_t arg, uint8_t bits) { |
| 1645 | uint24_t full_res; | 1815 | uint24_t full_res; |
| 1646 | #if zig_has_builtin(bitreverse24) | 1816 | #if zig_has_builtin(bitreverse24) |
| 1647 | full_res = __builtin_bitreverse24(val); | 1817 | full_res = __builtin_bitreverse24(arg); |
| 1648 | #else | 1818 | #else |
| 1649 | full_res = (uint24_t)zig_bit_reverse_u8((uint8_t)(val >> 0), 8) << 16 | | 1819 | full_res = (uint24_t)zig_bitReverse_u8((uint8_t)(arg >> 0), 8) << 16 | |
| 1650 | (uint24_t)zig_bit_reverse_u16((uint16_t)(val >> 8), 16) >> 0; | 1820 | (uint24_t)zig_bitReverse_u16((uint16_t)(arg >> 8), 16) >> 0; |
| 1651 | #endif | 1821 | #endif |
| 1652 | return zig_wrap_u24(full_res >> (24 - bits), bits); | 1822 | return zig_u24_truncate_u24(full_res >> (24 - bits), bits); |
| 1653 | } | 1823 | } |
| 1654 | 1824 | ||
| 1655 | static inline int24_t zig_bit_reverse_i24(int24_t val, uint8_t bits) { | 1825 | static inline int24_t zig_bitReverse_i24(int24_t arg, uint8_t bits) { |
| 1656 | return zig_wrap_i24((int24_t)zig_bit_reverse_u24((uint24_t)val, bits), bits); | 1826 | return zig_i24_truncate_i24((int24_t)zig_bitReverse_u24((uint24_t)arg, bits), bits); |
| 1657 | } | 1827 | } |
| 1658 | #endif | 1828 | #endif |
| 1659 | 1829 | ||
| 1660 | static inline uint32_t zig_bit_reverse_u32(uint32_t val, uint8_t bits) { | 1830 | static inline uint32_t zig_bitReverse_u32(uint32_t arg, uint8_t bits) { |
| 1661 | uint32_t full_res; | 1831 | uint32_t full_res; |
| 1662 | #if zig_has_builtin(bitreverse32) | 1832 | #if zig_has_builtin(bitreverse32) |
| 1663 | full_res = __builtin_bitreverse32(val); | 1833 | full_res = __builtin_bitreverse32(arg); |
| 1664 | #else | 1834 | #else |
| 1665 | full_res = (uint32_t)zig_bit_reverse_u16((uint16_t)(val >> 0), 16) << 16 | | 1835 | full_res = (uint32_t)zig_bitReverse_u16((uint16_t)(arg >> 0), 16) << 16 | |
| 1666 | (uint32_t)zig_bit_reverse_u16((uint16_t)(val >> 16), 16) >> 0; | 1836 | (uint32_t)zig_bitReverse_u16((uint16_t)(arg >> 16), 16) >> 0; |
| 1667 | #endif | 1837 | #endif |
| 1668 | return zig_wrap_u32(full_res >> (32 - bits), bits); | 1838 | return zig_u32_truncate_u32(full_res >> (32 - bits), bits); |
| 1669 | } | 1839 | } |
| 1670 | 1840 | ||
| 1671 | static inline int32_t zig_bit_reverse_i32(int32_t val, uint8_t bits) { | 1841 | static inline int32_t zig_bitReverse_i32(int32_t arg, uint8_t bits) { |
| 1672 | return zig_wrap_i32((int32_t)zig_bit_reverse_u32((uint32_t)val, bits), bits); | 1842 | return zig_i32_truncate_i32((int32_t)zig_bitReverse_u32((uint32_t)arg, bits), bits); |
| 1673 | } | 1843 | } |
| 1674 | 1844 | ||
| 1675 | #if defined(zig_ez80) | 1845 | #if defined(zig_ez80) |
| 1676 | static inline uint32_t zig_bit_reverse_u48(uint48_t val, uint8_t bits) { | 1846 | static inline uint32_t zig_bitReverse_u48(uint48_t arg, uint8_t bits) { |
| 1677 | uint48_t full_res; | 1847 | uint48_t full_res; |
| 1678 | #if zig_has_builtin(bitreverse48) | 1848 | #if zig_has_builtin(bitreverse48) |
| 1679 | full_res = __builtin_bitreverse48(val); | 1849 | full_res = __builtin_bitreverse48(arg); |
| 1680 | #else | 1850 | #else |
| 1681 | full_res = (uint48_t)zig_bit_reverse_u24((uint24_t)(val >> 0), 24) << 24 | | 1851 | full_res = (uint48_t)zig_bitReverse_u24((uint24_t)(arg >> 0), 24) << 24 | |
| 1682 | (uint48_t)zig_bit_reverse_u24((uint24_t)(val >> 24), 24) >> 0; | 1852 | (uint48_t)zig_bitReverse_u24((uint24_t)(arg >> 24), 24) >> 0; |
| 1683 | #endif | 1853 | #endif |
| 1684 | return zig_wrap_u32(full_res >> (48 - bits), bits); | 1854 | return zig_u48_truncate_u48(full_res >> (48 - bits), bits); |
| 1685 | } | 1855 | } |
| 1686 | 1856 | ||
| 1687 | static inline int32_t zig_bit_reverse_i48(int48_t val, uint8_t bits) { | 1857 | static inline int32_t zig_bitReverse_i48(int48_t arg, uint8_t bits) { |
| 1688 | return zig_wrap_i48((int48_t)zig_bit_reverse_u48((uint48_t)val, bits), bits); | 1858 | return zig_i48_truncate_i48((int48_t)zig_bitReverse_u48((uint48_t)arg, bits), bits); |
| 1689 | } | 1859 | } |
| 1690 | #endif | 1860 | #endif |
| 1691 | 1861 | ||
| 1692 | static inline uint64_t zig_bit_reverse_u64(uint64_t val, uint8_t bits) { | 1862 | static inline uint64_t zig_bitReverse_u64(uint64_t arg, uint8_t bits) { |
| 1693 | uint64_t full_res; | 1863 | uint64_t full_res; |
| 1694 | #if zig_has_builtin(bitreverse64) | 1864 | #if zig_has_builtin(bitreverse64) |
| 1695 | full_res = __builtin_bitreverse64(val); | 1865 | full_res = __builtin_bitreverse64(arg); |
| 1696 | #else | 1866 | #else |
| 1697 | full_res = (uint64_t)zig_bit_reverse_u32((uint32_t)(val >> 0), 32) << 32 | | 1867 | full_res = (uint64_t)zig_bitReverse_u32((uint32_t)(arg >> 0), 32) << 32 | |
| 1698 | (uint64_t)zig_bit_reverse_u32((uint32_t)(val >> 32), 32) >> 0; | 1868 | (uint64_t)zig_bitReverse_u32((uint32_t)(arg >> 32), 32) >> 0; |
| 1699 | #endif | 1869 | #endif |
| 1700 | return zig_wrap_u64(full_res >> (64 - bits), bits); | 1870 | return zig_u64_truncate_u64(full_res >> (64 - bits), bits); |
| 1701 | } | 1871 | } |
| 1702 | 1872 | ||
| 1703 | static inline int64_t zig_bit_reverse_i64(int64_t val, uint8_t bits) { | 1873 | static inline int64_t zig_bitReverse_i64(int64_t arg, uint8_t bits) { |
| 1704 | return zig_wrap_i64((int64_t)zig_bit_reverse_u64((uint64_t)val, bits), bits); | 1874 | return zig_i64_truncate_i64((int64_t)zig_bitReverse_u64((uint64_t)arg, bits), bits); |
| 1705 | } | 1875 | } |
| 1706 | 1876 | ||
| 1707 | #define zig_builtin_popcount_common(w) \ | 1877 | #define zig_builtin_popCount_common(w) \ |
| 1708 | static inline uint8_t zig_popcount_i##w(int##w##_t val, uint8_t bits) { \ | 1878 | static inline uint8_t zig_popCount_i##w(int##w##_t arg, uint8_t bits) { \ |
| 1709 | return zig_popcount_u##w((uint##w##_t)val, bits); \ | 1879 | return zig_popCount_u##w((uint##w##_t)arg, bits); \ |
| 1710 | } | 1880 | } |
| 1711 | #if zig_has_builtin(popcount) || defined(zig_gcc) || defined(zig_tinyc) | 1881 | #if zig_has_builtin(popCount) || defined(zig_gcc) || defined(zig_tinyc) |
| 1712 | #define zig_builtin_popcount(w) \ | 1882 | #define zig_builtin_popCount(w) \ |
| 1713 | static inline uint8_t zig_popcount_u##w(uint##w##_t val, uint8_t bits) { \ | 1883 | static inline uint8_t zig_popCount_u##w(uint##w##_t arg, uint8_t bits) { \ |
| 1714 | (void)bits; \ | 1884 | (void)bits; \ |
| 1715 | return zig_builtin##w(popcount, val); \ | 1885 | return zig_builtin##w(popcount, arg); \ |
| 1716 | } \ | 1886 | } \ |
| 1717 | \ | 1887 | \ |
| 1718 | zig_builtin_popcount_common(w) | 1888 | zig_builtin_popCount_common(w) |
| 1719 | #else | 1889 | #else |
| 1720 | #define zig_builtin_popcount(w) \ | 1890 | #define zig_builtin_popCount(w) \ |
| 1721 | static inline uint8_t zig_popcount_u##w(uint##w##_t val, uint8_t bits) { \ | 1891 | static inline uint8_t zig_popCount_u##w(uint##w##_t arg, uint8_t bits) { \ |
| 1722 | (void)bits; \ | 1892 | (void)bits; \ |
| 1723 | uint##w##_t temp = val - ((val >> 1) & (UINT##w##_MAX / 3)); \ | 1893 | uint##w##_t temp = arg - ((arg >> 1) & (UINT##w##_MAX / 3)); \ |
| 1724 | temp = (temp & (UINT##w##_MAX / 5)) + ((temp >> 2) & (UINT##w##_MAX / 5)); \ | 1894 | temp = (temp & (UINT##w##_MAX / 5)) + ((temp >> 2) & (UINT##w##_MAX / 5)); \ |
| 1725 | temp = (temp + (temp >> 4)) & (UINT##w##_MAX / 17); \ | 1895 | temp = (temp + (temp >> 4)) & (UINT##w##_MAX / 17); \ |
| 1726 | return temp * (UINT##w##_MAX / 255) >> (UINT8_C(w) - UINT8_C(8)); \ | 1896 | return temp * (UINT##w##_MAX / 255) >> (UINT8_C(w) - UINT8_C(8)); \ |
| 1727 | } \ | 1897 | } \ |
| 1728 | \ | 1898 | \ |
| 1729 | zig_builtin_popcount_common(w) | 1899 | zig_builtin_popCount_common(w) |
| 1730 | #endif | ||
| 1731 | zig_builtin_popcount(8) | ||
| 1732 | zig_builtin_popcount(16) | ||
| 1733 | #if defined(zig_ez80) | ||
| 1734 | zig_builtin_popcount(24) | ||
| 1735 | #endif | 1900 | #endif |
| 1736 | zig_builtin_popcount(32) | 1901 | zig_builtin_popCount(8) |
| 1902 | zig_builtin_popCount(16) | ||
| 1903 | zig_builtin_popCount(32) | ||
| 1904 | zig_builtin_popCount(64) | ||
| 1737 | #if defined(zig_ez80) | 1905 | #if defined(zig_ez80) |
| 1738 | zig_builtin_popcount(48) | 1906 | zig_builtin_popCount(24) |
| 1907 | zig_builtin_popCount(48) | ||
| 1739 | #endif | 1908 | #endif |
| 1740 | zig_builtin_popcount(64) | ||
| 1741 | 1909 | ||
| 1742 | #define zig_builtin_ctz_common(w) \ | 1910 | #define zig_builtin_ctz_common(w) \ |
| 1743 | static inline uint8_t zig_ctz_i##w(int##w##_t val, uint8_t bits) { \ | 1911 | static inline uint8_t zig_ctz_i##w(int##w##_t arg, uint8_t bits) { \ |
| 1744 | return zig_ctz_u##w((uint##w##_t)val, bits); \ | 1912 | return zig_ctz_u##w((uint##w##_t)arg, bits); \ |
| 1745 | } | 1913 | } |
| 1746 | #if zig_has_builtin(ctz) || defined(zig_gcc) || defined(zig_tinyc) | 1914 | #if zig_has_builtin(ctz) || defined(zig_gcc) || defined(zig_tinyc) |
| 1747 | #define zig_builtin_ctz(w) \ | 1915 | #define zig_builtin_ctz(w) \ |
| 1748 | static inline uint8_t zig_ctz_u##w(uint##w##_t val, uint8_t bits) { \ | 1916 | static inline uint8_t zig_ctz_u##w(uint##w##_t arg, uint8_t bits) { \ |
| 1749 | if (val == 0) return bits; \ | 1917 | if (arg == 0) return bits; \ |
| 1750 | return zig_builtin##w(ctz, val); \ | 1918 | return zig_builtin##w(ctz, arg); \ |
| 1751 | } \ | 1919 | } \ |
| 1752 | \ | 1920 | \ |
| 1753 | zig_builtin_ctz_common(w) | 1921 | zig_builtin_ctz_common(w) |
| 1754 | #else | 1922 | #else |
| 1755 | #define zig_builtin_ctz(w) \ | 1923 | #define zig_builtin_ctz(w) \ |
| 1756 | static inline uint8_t zig_ctz_u##w(uint##w##_t val, uint8_t bits) { \ | 1924 | static inline uint8_t zig_ctz_u##w(uint##w##_t arg, uint8_t bits) { \ |
| 1757 | return zig_popcount_u##w(zig_not_u##w(val, bits) & zig_subw_u##w(val, 1, bits), bits); \ | 1925 | return zig_popCount_u##w(zig_not_u##w(arg, bits) & zig_subw_u##w(arg, 1, bits), bits); \ |
| 1758 | } \ | 1926 | } \ |
| 1759 | \ | 1927 | \ |
| 1760 | zig_builtin_ctz_common(w) | 1928 | zig_builtin_ctz_common(w) |
| 1761 | #endif | 1929 | #endif |
| 1762 | zig_builtin_ctz(8) | 1930 | zig_builtin_ctz(8) |
| 1763 | zig_builtin_ctz(16) | 1931 | zig_builtin_ctz(16) |
| 1764 | #if defined(zig_ez80) | ||
| 1765 | zig_builtin_ctz(24) | ||
| 1766 | #endif | ||
| 1767 | zig_builtin_ctz(32) | 1932 | zig_builtin_ctz(32) |
| 1933 | zig_builtin_ctz(64) | ||
| 1768 | #if defined(zig_ez80) | 1934 | #if defined(zig_ez80) |
| 1935 | zig_builtin_ctz(24) | ||
| 1769 | zig_builtin_ctz(48) | 1936 | zig_builtin_ctz(48) |
| 1770 | #endif | 1937 | #endif |
| 1771 | zig_builtin_ctz(64) | ||
| 1772 | 1938 | ||
| 1773 | #define zig_builtin_clz_common(w) \ | 1939 | #define zig_builtin_clz_common(w) \ |
| 1774 | static inline uint8_t zig_clz_i##w(int##w##_t val, uint8_t bits) { \ | 1940 | static inline uint8_t zig_clz_i##w(int##w##_t arg, uint8_t bits) { \ |
| 1775 | return zig_clz_u##w((uint##w##_t)val, bits); \ | 1941 | return zig_clz_u##w((uint##w##_t)arg, bits); \ |
| 1776 | } | 1942 | } |
| 1777 | #if zig_has_builtin(clz) || defined(zig_gcc) || defined(zig_tinyc) | 1943 | #if zig_has_builtin(clz) || defined(zig_gcc) || defined(zig_tinyc) |
| 1778 | #define zig_builtin_clz(w) \ | 1944 | #define zig_builtin_clz(w) \ |
| 1779 | static inline uint8_t zig_clz_u##w(uint##w##_t val, uint8_t bits) { \ | 1945 | static inline uint8_t zig_clz_u##w(uint##w##_t arg, uint8_t bits) { \ |
| 1780 | if (val == 0) return bits; \ | 1946 | if (arg == 0) return bits; \ |
| 1781 | return zig_builtin##w(clz, val) - (zig_bitSizeOf(zig_Builtin##w) - bits); \ | 1947 | return zig_builtin##w(clz, arg) - (zig_bitSizeOf(zig_Builtin##w) - bits); \ |
| 1782 | } \ | 1948 | } \ |
| 1783 | \ | 1949 | \ |
| 1784 | zig_builtin_clz_common(w) | 1950 | zig_builtin_clz_common(w) |
| 1785 | #else | 1951 | #else |
| 1786 | #define zig_builtin_clz(w) \ | 1952 | #define zig_builtin_clz(w) \ |
| 1787 | static inline uint8_t zig_clz_u##w(uint##w##_t val, uint8_t bits) { \ | 1953 | static inline uint8_t zig_clz_u##w(uint##w##_t arg, uint8_t bits) { \ |
| 1788 | return zig_ctz_u##w(zig_bit_reverse_u##w(val, bits), bits); \ | 1954 | return zig_ctz_u##w(zig_bitReverse_u##w(arg, bits), bits); \ |
| 1789 | } \ | 1955 | } \ |
| 1790 | \ | 1956 | \ |
| 1791 | zig_builtin_clz_common(w) | 1957 | zig_builtin_clz_common(w) |
| 1792 | #endif | 1958 | #endif |
| 1793 | zig_builtin_clz(8) | 1959 | zig_builtin_clz(8) |
| 1794 | zig_builtin_clz(16) | 1960 | zig_builtin_clz(16) |
| 1795 | #if defined(zig_ez80) | ||
| 1796 | zig_builtin_clz(24) | ||
| 1797 | #endif | ||
| 1798 | zig_builtin_clz(32) | 1961 | zig_builtin_clz(32) |
| 1962 | zig_builtin_clz(64) | ||
| 1799 | #if defined(zig_ez80) | 1963 | #if defined(zig_ez80) |
| 1964 | zig_builtin_clz(24) | ||
| 1800 | zig_builtin_clz(48) | 1965 | zig_builtin_clz(48) |
| 1801 | #endif | 1966 | #endif |
| 1802 | zig_builtin_clz(64) | ||
| 1803 | 1967 | ||
| 1804 | /* ======================== 128-bit Integer Support ========================= */ | 1968 | /* ======================== 128-bit Integer Support ========================= */ |
| 1805 | 1969 | ||
| ... | @@ -1816,16 +1980,14 @@ zig_builtin_clz(64) | ... | @@ -1816,16 +1980,14 @@ zig_builtin_clz(64) |
| 1816 | typedef unsigned __int128 zig_u128; | 1980 | typedef unsigned __int128 zig_u128; |
| 1817 | typedef signed __int128 zig_i128; | 1981 | typedef signed __int128 zig_i128; |
| 1818 | 1982 | ||
| 1819 | #define zig_make_u128(hi, lo) ((zig_u128)(hi)<<64|(lo)) | 1983 | #define zig_init_u128(hi, lo) ((zig_u128)(hi)<<64|(lo)) |
| 1820 | #define zig_make_i128(hi, lo) ((zig_i128)zig_make_u128(hi, lo)) | 1984 | #define zig_init_i128(hi, lo) ((zig_i128)zig_make_u128(hi, lo)) |
| 1821 | #define zig_init_u128(hi, lo) zig_make_u128(hi, lo) | 1985 | #define zig_make_u128(hi, lo) zig_init_u128(hi, lo) |
| 1822 | #define zig_init_i128(hi, lo) zig_make_i128(hi, lo) | 1986 | #define zig_make_i128(hi, lo) zig_init_i128(hi, lo) |
| 1823 | #define zig_hi_u128(val) ((uint64_t)((val) >> 64)) | 1987 | #define zig_hi_u128(arg) ((uint64_t)((arg) >> 64)) |
| 1824 | #define zig_lo_u128(val) ((uint64_t)((val) >> 0)) | 1988 | #define zig_lo_u128(arg) ((uint64_t)((arg) >> 0)) |
| 1825 | #define zig_hi_i128(val) (( int64_t)((val) >> 64)) | 1989 | #define zig_hi_i128(arg) (( int64_t)((arg) >> 64)) |
| 1826 | #define zig_lo_i128(val) ((uint64_t)((val) >> 0)) | 1990 | #define zig_lo_i128(arg) ((uint64_t)((arg) >> 0)) |
| 1827 | #define zig_bitCast_u128(val) ((zig_u128)(val)) | ||
| 1828 | #define zig_bitCast_i128(val) ((zig_i128)(val)) | ||
| 1829 | #define zig_cmp_int128(Type) \ | 1991 | #define zig_cmp_int128(Type) \ |
| 1830 | static inline int32_t zig_cmp_##Type(zig_##Type lhs, zig_##Type rhs) { \ | 1992 | static inline int32_t zig_cmp_##Type(zig_##Type lhs, zig_##Type rhs) { \ |
| 1831 | return (lhs > rhs) - (lhs < rhs); \ | 1993 | return (lhs > rhs) - (lhs < rhs); \ |
| ... | @@ -1835,32 +1997,49 @@ typedef signed __int128 zig_i128; | ... | @@ -1835,32 +1997,49 @@ typedef signed __int128 zig_i128; |
| 1835 | return lhs operator rhs; \ | 1997 | return lhs operator rhs; \ |
| 1836 | } | 1998 | } |
| 1837 | 1999 | ||
| 1838 | #else /* zig_has_int128 */ | 2000 | static inline zig_u128 zig_shl_u128(zig_u128 lhs, uint8_t rhs) { |
| 2001 | return lhs << rhs; | ||
| 2002 | } | ||
| 1839 | 2003 | ||
| 1840 | #if zig_little_endian | 2004 | static inline zig_u128 zig_shr_u128(zig_u128 lhs, uint8_t rhs) { |
| 1841 | typedef struct { zig_align(16) uint64_t lo; uint64_t hi; } zig_u128; | 2005 | return lhs >> rhs; |
| 1842 | typedef struct { zig_align(16) uint64_t lo; int64_t hi; } zig_i128; | 2006 | } |
| 2007 | |||
| 2008 | static inline zig_i128 zig_shl_i128(zig_i128 lhs, uint8_t rhs) { | ||
| 2009 | return lhs << rhs; | ||
| 2010 | } | ||
| 2011 | |||
| 2012 | static inline zig_i128 zig_shr_i128(zig_i128 lhs, uint8_t rhs) { | ||
| 2013 | // This works around a GCC miscompilation, but it has the side benefit of | ||
| 2014 | // emitting better code. It is behind the `#if` because it depends on | ||
| 2015 | // arithmetic right shift, which is implementation-defined in C, but should | ||
| 2016 | // be guaranteed on any GCC-compatible compiler. | ||
| 2017 | #if defined(zig_gnuc) | ||
| 2018 | return lhs >> rhs; | ||
| 1843 | #else | 2019 | #else |
| 1844 | typedef struct { zig_align(16) uint64_t hi; uint64_t lo; } zig_u128; | 2020 | zig_i128 sign_mask = lhs < zig_make_i128(0, 0) ? -zig_make_i128(0, 1) : zig_make_i128(0, 0); |
| 1845 | typedef struct { zig_align(16) int64_t hi; uint64_t lo; } zig_i128; | 2021 | return ((lhs ^ sign_mask) >> rhs) ^ sign_mask; |
| 1846 | #endif | 2022 | #endif |
| 2023 | } | ||
| 1847 | 2024 | ||
| 1848 | #define zig_make_u128(hi, lo) ((zig_u128){ .h##i = (hi), .l##o = (lo) }) | 2025 | #else /* zig_has_int128 */ |
| 1849 | #define zig_make_i128(hi, lo) ((zig_i128){ .h##i = (hi), .l##o = (lo) }) | ||
| 1850 | 2026 | ||
| 1851 | #if defined(zig_msvc) /* MSVC doesn't allow struct literals in constant expressions */ | 2027 | #if zig_little_endian |
| 1852 | #define zig_init_u128(hi, lo) { .h##i = (hi), .l##o = (lo) } | 2028 | typedef struct { zig_align(ZIG_TARGET_MAX_INT_ALIGNMENT) uint64_t lo; uint64_t hi; } zig_u128; |
| 1853 | #define zig_init_i128(hi, lo) { .h##i = (hi), .l##o = (lo) } | 2029 | typedef struct { zig_align(ZIG_TARGET_MAX_INT_ALIGNMENT) uint64_t lo; int64_t hi; } zig_i128; |
| 1854 | #else /* But non-MSVC doesn't like the unprotected commas */ | 2030 | #else |
| 1855 | #define zig_init_u128(hi, lo) zig_make_u128(hi, lo) | 2031 | typedef struct { zig_align(ZIG_TARGET_MAX_INT_ALIGNMENT) uint64_t hi; uint64_t lo; } zig_u128; |
| 1856 | #define zig_init_i128(hi, lo) zig_make_i128(hi, lo) | 2032 | typedef struct { zig_align(ZIG_TARGET_MAX_INT_ALIGNMENT) int64_t hi; uint64_t lo; } zig_i128; |
| 1857 | #endif | 2033 | #endif |
| 1858 | #define zig_hi_u128(val) ((val).hi) | 2034 | |
| 1859 | #define zig_lo_u128(val) ((val).lo) | 2035 | #define zig_init_u128(hi, lo) { .h##i = hi, .l##o = lo } |
| 1860 | #define zig_hi_i128(val) ((val).hi) | 2036 | #define zig_init_i128(hi, lo) { .h##i = hi, .l##o = lo } |
| 1861 | #define zig_lo_i128(val) ((val).lo) | 2037 | #define zig_make_u128(hi, lo) (zig_u128)zig_init_u128(hi, lo) |
| 1862 | #define zig_bitCast_u128(val) zig_make_u128((uint64_t)(val).hi, (val).lo) | 2038 | #define zig_make_i128(hi, lo) (zig_i128)zig_init_i128(hi, lo) |
| 1863 | #define zig_bitCast_i128(val) zig_make_i128(( int64_t)(val).hi, (val).lo) | 2039 | #define zig_hi_u128(arg) (arg).hi |
| 2040 | #define zig_lo_u128(arg) (arg).lo | ||
| 2041 | #define zig_hi_i128(arg) (arg).hi | ||
| 2042 | #define zig_lo_i128(arg) (arg).lo | ||
| 1864 | #define zig_cmp_int128(Type) \ | 2043 | #define zig_cmp_int128(Type) \ |
| 1865 | static inline int32_t zig_cmp_##Type(zig_##Type lhs, zig_##Type rhs) { \ | 2044 | static inline int32_t zig_cmp_##Type(zig_##Type lhs, zig_##Type rhs) { \ |
| 1866 | return (lhs.hi == rhs.hi) \ | 2045 | return (lhs.hi == rhs.hi) \ |
| ... | @@ -1872,6 +2051,30 @@ typedef struct { zig_align(16) int64_t hi; uint64_t lo; } zig_i128; | ... | @@ -1872,6 +2051,30 @@ typedef struct { zig_align(16) int64_t hi; uint64_t lo; } zig_i128; |
| 1872 | return (zig_##Type){ .hi = lhs.hi operator rhs.hi, .lo = lhs.lo operator rhs.lo }; \ | 2051 | return (zig_##Type){ .hi = lhs.hi operator rhs.hi, .lo = lhs.lo operator rhs.lo }; \ |
| 1873 | } | 2052 | } |
| 1874 | 2053 | ||
| 2054 | static inline zig_u128 zig_shl_u128(zig_u128 lhs, uint8_t rhs) { | ||
| 2055 | if (rhs == UINT8_C(0)) return lhs; | ||
| 2056 | if (rhs >= UINT8_C(64)) return (zig_u128){ .hi = lhs.lo << (rhs - UINT8_C(64)), .lo = zig_minInt_u64 }; | ||
| 2057 | return (zig_u128){ .hi = lhs.hi << rhs | lhs.lo >> (UINT8_C(64) - rhs), .lo = lhs.lo << rhs }; | ||
| 2058 | } | ||
| 2059 | |||
| 2060 | static inline zig_u128 zig_shr_u128(zig_u128 lhs, uint8_t rhs) { | ||
| 2061 | if (rhs == UINT8_C(0)) return lhs; | ||
| 2062 | if (rhs >= UINT8_C(64)) return (zig_u128){ .hi = zig_minInt_u64, .lo = lhs.hi >> (rhs - UINT8_C(64)) }; | ||
| 2063 | return (zig_u128){ .hi = lhs.hi >> rhs, .lo = lhs.hi << (UINT8_C(64) - rhs) | lhs.lo >> rhs }; | ||
| 2064 | } | ||
| 2065 | |||
| 2066 | static inline zig_i128 zig_shl_i128(zig_i128 lhs, uint8_t rhs) { | ||
| 2067 | if (rhs == UINT8_C(0)) return lhs; | ||
| 2068 | if (rhs >= UINT8_C(64)) return (zig_i128){ .hi = lhs.lo << (rhs - UINT8_C(64)), .lo = zig_minInt_u64 }; | ||
| 2069 | return (zig_i128){ .hi = lhs.hi << rhs | lhs.lo >> (UINT8_C(64) - rhs), .lo = lhs.lo << rhs }; | ||
| 2070 | } | ||
| 2071 | |||
| 2072 | static inline zig_i128 zig_shr_i128(zig_i128 lhs, uint8_t rhs) { | ||
| 2073 | if (rhs == UINT8_C(0)) return lhs; | ||
| 2074 | if (rhs >= UINT8_C(64)) return (zig_i128){ .hi = zig_shr_i64(lhs.hi, 63), .lo = zig_shr_i64(lhs.hi, (rhs - UINT8_C(64))) }; | ||
| 2075 | return (zig_i128){ .hi = zig_shr_i64(lhs.hi, rhs), .lo = lhs.lo >> rhs | (uint64_t)lhs.hi << (UINT8_C(64) - rhs) }; | ||
| 2076 | } | ||
| 2077 | |||
| 1875 | #endif /* zig_has_int128 */ | 2078 | #endif /* zig_has_int128 */ |
| 1876 | 2079 | ||
| 1877 | #define zig_minInt_u128 zig_make_u128(zig_minInt_u64, zig_minInt_u64) | 2080 | #define zig_minInt_u128 zig_make_u128(zig_minInt_u64, zig_minInt_u64) |
| ... | @@ -1891,42 +2094,177 @@ zig_bit_int128(i128, or, |) | ... | @@ -1891,42 +2094,177 @@ zig_bit_int128(i128, or, |) |
| 1891 | zig_bit_int128(u128, xor, ^) | 2094 | zig_bit_int128(u128, xor, ^) |
| 1892 | zig_bit_int128(i128, xor, ^) | 2095 | zig_bit_int128(i128, xor, ^) |
| 1893 | 2096 | ||
| 1894 | static inline zig_u128 zig_shr_u128(zig_u128 lhs, uint8_t rhs); | 2097 | static inline uint8_t zig_u8_intCast_u128(zig_u128 arg) { |
| 2098 | return (uint8_t)zig_lo_u128(arg); | ||
| 2099 | } | ||
| 2100 | static inline uint8_t zig_u8_intCast_i128(zig_i128 arg) { | ||
| 2101 | return (uint8_t)zig_lo_i128(arg); | ||
| 2102 | } | ||
| 2103 | static inline int8_t zig_i8_intCast_i128(zig_i128 arg) { | ||
| 2104 | return (int8_t)zig_lo_i128(arg); | ||
| 2105 | } | ||
| 2106 | static inline int8_t zig_i8_intCast_u128(zig_u128 arg) { | ||
| 2107 | return (int8_t)zig_lo_u128(arg); | ||
| 2108 | } | ||
| 1895 | 2109 | ||
| 1896 | #if zig_has_int128 | 2110 | static inline uint16_t zig_u16_intCast_u128(zig_u128 arg) { |
| 2111 | return (uint16_t)zig_lo_u128(arg); | ||
| 2112 | } | ||
| 2113 | static inline uint16_t zig_u16_intCast_i128(zig_i128 arg) { | ||
| 2114 | return (uint16_t)zig_lo_i128(arg); | ||
| 2115 | } | ||
| 2116 | static inline int16_t zig_i16_intCast_i128(zig_i128 arg) { | ||
| 2117 | return (int16_t)zig_lo_i128(arg); | ||
| 2118 | } | ||
| 2119 | static inline int16_t zig_i16_intCast_u128(zig_u128 arg) { | ||
| 2120 | return (int16_t)zig_lo_u128(arg); | ||
| 2121 | } | ||
| 1897 | 2122 | ||
| 1898 | static inline zig_u128 zig_not_u128(zig_u128 val, uint8_t bits) { | 2123 | static inline uint32_t zig_u32_intCast_u128(zig_u128 arg) { |
| 1899 | return val ^ zig_maxInt_u(128, bits); | 2124 | return (uint32_t)zig_lo_u128(arg); |
| 2125 | } | ||
| 2126 | static inline uint32_t zig_u32_intCast_i128(zig_i128 arg) { | ||
| 2127 | return (uint32_t)zig_lo_i128(arg); | ||
| 2128 | } | ||
| 2129 | static inline int32_t zig_i32_intCast_i128(zig_i128 arg) { | ||
| 2130 | return (int32_t)zig_lo_i128(arg); | ||
| 2131 | } | ||
| 2132 | static inline int32_t zig_i32_intCast_u128(zig_u128 arg) { | ||
| 2133 | return (int32_t)zig_lo_u128(arg); | ||
| 1900 | } | 2134 | } |
| 1901 | 2135 | ||
| 1902 | static inline zig_i128 zig_not_i128(zig_i128 val, uint8_t bits) { | 2136 | static inline uint64_t zig_u64_intCast_u128(zig_u128 arg) { |
| 1903 | (void)bits; | 2137 | return zig_lo_u128(arg); |
| 1904 | return ~val; | 2138 | } |
| 2139 | static inline uint64_t zig_u64_intCast_i128(zig_i128 arg) { | ||
| 2140 | return zig_lo_i128(arg); | ||
| 2141 | } | ||
| 2142 | static inline int64_t zig_i64_intCast_i128(zig_i128 arg) { | ||
| 2143 | return (int64_t)zig_lo_i128(arg); | ||
| 2144 | } | ||
| 2145 | static inline int64_t zig_i64_intCast_u128(zig_u128 arg) { | ||
| 2146 | return (int64_t)zig_lo_u128(arg); | ||
| 1905 | } | 2147 | } |
| 1906 | 2148 | ||
| 1907 | static inline zig_u128 zig_shr_u128(zig_u128 lhs, uint8_t rhs) { | 2149 | static inline zig_u128 zig_u128_intCast_u8(uint8_t arg) { |
| 1908 | return lhs >> rhs; | 2150 | return zig_make_u128(UINT8_C(0), arg); |
| 2151 | } | ||
| 2152 | static inline zig_u128 zig_u128_intCast_i8(int8_t arg) { | ||
| 2153 | return zig_make_u128(UINT8_C(0), (uint8_t)arg); | ||
| 2154 | } | ||
| 2155 | static inline zig_i128 zig_i128_intCast_i8(int8_t arg) { | ||
| 2156 | return zig_make_i128(zig_shr_i64(arg, 63), (uint8_t)arg); | ||
| 2157 | } | ||
| 2158 | static inline zig_i128 zig_i128_intCast_u8(uint8_t arg) { | ||
| 2159 | return zig_make_i128(INT8_C(0), arg); | ||
| 1909 | } | 2160 | } |
| 1910 | 2161 | ||
| 1911 | static inline zig_u128 zig_shl_u128(zig_u128 lhs, uint8_t rhs) { | 2162 | static inline zig_u128 zig_u128_intCast_u16(uint16_t arg) { |
| 1912 | return lhs << rhs; | 2163 | return zig_make_u128(UINT16_C(0), arg); |
| 2164 | } | ||
| 2165 | static inline zig_u128 zig_u128_intCast_i16(int16_t arg) { | ||
| 2166 | return zig_make_u128(UINT16_C(0), (uint16_t)arg); | ||
| 2167 | } | ||
| 2168 | static inline zig_i128 zig_i128_intCast_i16(int16_t arg) { | ||
| 2169 | return zig_make_i128(zig_shr_i64(arg, 63), (uint16_t)arg); | ||
| 2170 | } | ||
| 2171 | static inline zig_i128 zig_i128_intCast_u16(uint16_t arg) { | ||
| 2172 | return zig_make_i128(INT16_C(0), arg); | ||
| 1913 | } | 2173 | } |
| 1914 | 2174 | ||
| 1915 | static inline zig_i128 zig_shr_i128(zig_i128 lhs, uint8_t rhs) { | 2175 | static inline zig_u128 zig_u128_intCast_u32(uint32_t arg) { |
| 1916 | // This works around a GCC miscompilation, but it has the side benefit of | 2176 | return zig_make_u128(UINT32_C(0), arg); |
| 1917 | // emitting better code. It is behind the `#if` because it depends on | 2177 | } |
| 1918 | // arithmetic right shift, which is implementation-defined in C, but should | 2178 | static inline zig_u128 zig_u128_intCast_i32(int32_t arg) { |
| 1919 | // be guaranteed on any GCC-compatible compiler. | 2179 | return zig_make_u128(UINT32_C(0), (uint32_t)arg); |
| 1920 | #if defined(zig_gnuc) | 2180 | } |
| 1921 | return lhs >> rhs; | 2181 | static inline zig_i128 zig_i128_intCast_i32(int32_t arg) { |
| 2182 | return zig_make_i128(zig_shr_i64(arg, 63), (uint32_t)arg); | ||
| 2183 | } | ||
| 2184 | static inline zig_i128 zig_i128_intCast_u32(uint32_t arg) { | ||
| 2185 | return zig_make_i128(INT32_C(0), arg); | ||
| 2186 | } | ||
| 2187 | |||
| 2188 | static inline zig_u128 zig_u128_intCast_u64(uint64_t arg) { | ||
| 2189 | return zig_make_u128(UINT64_C(0), arg); | ||
| 2190 | } | ||
| 2191 | static inline zig_u128 zig_u128_intCast_i64(int64_t arg) { | ||
| 2192 | return zig_make_u128(UINT64_C(0), (uint64_t)arg); | ||
| 2193 | } | ||
| 2194 | static inline zig_i128 zig_i128_intCast_i64(int64_t arg) { | ||
| 2195 | return zig_make_i128(zig_shr_i64(arg, 63), (uint64_t)arg); | ||
| 2196 | } | ||
| 2197 | static inline zig_i128 zig_i128_intCast_u64(uint64_t arg) { | ||
| 2198 | return zig_make_i128(INT64_C(0), arg); | ||
| 2199 | } | ||
| 2200 | |||
| 2201 | static inline zig_u128 zig_u128_intCast_u128(zig_u128 arg) { | ||
| 2202 | return arg; | ||
| 2203 | } | ||
| 2204 | static inline zig_u128 zig_u128_intCast_i128(zig_i128 arg) { | ||
| 2205 | #if zig_has_int128 | ||
| 2206 | return (zig_u128)arg; | ||
| 1922 | #else | 2207 | #else |
| 1923 | zig_i128 sign_mask = lhs < zig_make_i128(0, 0) ? -zig_make_i128(0, 1) : zig_make_i128(0, 0); | 2208 | return zig_make_u128(zig_u64_bitCast_i64(zig_hi_i128(arg), UINT8_C(64)), zig_lo_u128(arg)); |
| 1924 | return ((lhs ^ sign_mask) >> rhs) ^ sign_mask; | 2209 | #endif |
| 2210 | } | ||
| 2211 | static inline zig_i128 zig_i128_intCast_i128(zig_i128 arg) { | ||
| 2212 | return arg; | ||
| 2213 | } | ||
| 2214 | static inline zig_i128 zig_i128_intCast_u128(zig_u128 arg) { | ||
| 2215 | #if zig_has_int128 | ||
| 2216 | return (zig_i128)arg; | ||
| 2217 | #else | ||
| 2218 | return zig_make_i128(zig_i64_bitCast_u64(zig_hi_i128(arg), UINT8_C(64)), zig_lo_u128(arg)); | ||
| 1925 | #endif | 2219 | #endif |
| 1926 | } | 2220 | } |
| 1927 | 2221 | ||
| 1928 | static inline zig_i128 zig_shl_i128(zig_i128 lhs, uint8_t rhs) { | 2222 | #define zig_int128_cast_builtins(w) \ |
| 1929 | return lhs << rhs; | 2223 | static inline uint##w##_t zig_u##w##_truncate_u128(zig_u128 arg, uint8_t bits) { \ |
| 2224 | return zig_u##w##_truncate_u##w((uint##w##_t)zig_lo_u128(arg), bits); \ | ||
| 2225 | } \ | ||
| 2226 | \ | ||
| 2227 | static inline int##w##_t zig_i##w##_truncate_i128(zig_i128 arg, uint8_t bits) { \ | ||
| 2228 | return zig_i##w##_truncate_i##w((int##w##_t)zig_lo_i128(arg), bits); \ | ||
| 2229 | } | ||
| 2230 | zig_int128_cast_builtins(8) | ||
| 2231 | zig_int128_cast_builtins(16) | ||
| 2232 | zig_int128_cast_builtins(32) | ||
| 2233 | zig_int128_cast_builtins(64) | ||
| 2234 | |||
| 2235 | static inline zig_u128 zig_u128_truncate_u128(zig_u128 arg, uint8_t bits) { | ||
| 2236 | return zig_and_u128(arg, zig_maxInt_u(128, bits)); | ||
| 2237 | } | ||
| 2238 | static inline zig_i128 zig_i128_truncate_i128(zig_i128 arg, uint8_t bits) { | ||
| 2239 | if (bits > UINT8_C(64)) return zig_make_i128(zig_i64_truncate_i64(zig_hi_i128(arg), bits - UINT8_C(64)), zig_lo_i128(arg)); | ||
| 2240 | int64_t lo = zig_i64_truncate_i128(arg, bits); | ||
| 2241 | return zig_make_i128(zig_shr_i64(lo, 63), (uint64_t)lo); | ||
| 2242 | } | ||
| 2243 | |||
| 2244 | static inline zig_u128 zig_u128_bitCast_u128(zig_u128 arg, uint8_t bits) { | ||
| 2245 | (void)bits; | ||
| 2246 | return arg; | ||
| 2247 | } | ||
| 2248 | static inline zig_u128 zig_u128_bitCast_i128(zig_i128 arg, uint8_t bits) { | ||
| 2249 | return zig_u128_truncate_u128(zig_u128_intCast_i128(arg), bits); | ||
| 2250 | } | ||
| 2251 | static inline zig_i128 zig_i128_bitCast_i128(zig_i128 arg, uint8_t bits) { | ||
| 2252 | (void)bits; | ||
| 2253 | return arg; | ||
| 2254 | } | ||
| 2255 | static inline zig_i128 zig_i128_bitCast_u128(zig_u128 arg, uint8_t bits) { | ||
| 2256 | return zig_i128_truncate_i128(zig_i128_intCast_u128(arg), bits); | ||
| 2257 | } | ||
| 2258 | |||
| 2259 | #if zig_has_int128 | ||
| 2260 | |||
| 2261 | static inline zig_u128 zig_not_u128(zig_u128 arg, uint8_t bits) { | ||
| 2262 | return arg ^ zig_maxInt_u(128, bits); | ||
| 2263 | } | ||
| 2264 | |||
| 2265 | static inline zig_i128 zig_not_i128(zig_i128 arg, uint8_t bits) { | ||
| 2266 | (void)bits; | ||
| 2267 | return ~arg; | ||
| 1930 | } | 2268 | } |
| 1931 | 2269 | ||
| 1932 | static inline zig_u128 zig_add_u128(zig_u128 lhs, zig_u128 rhs) { | 2270 | static inline zig_u128 zig_add_u128(zig_u128 lhs, zig_u128 rhs) { |
| ... | @@ -1953,11 +2291,11 @@ static inline zig_i128 zig_mul_i128(zig_i128 lhs, zig_i128 rhs) { | ... | @@ -1953,11 +2291,11 @@ static inline zig_i128 zig_mul_i128(zig_i128 lhs, zig_i128 rhs) { |
| 1953 | return lhs * rhs; | 2291 | return lhs * rhs; |
| 1954 | } | 2292 | } |
| 1955 | 2293 | ||
| 1956 | static inline zig_u128 zig_div_trunc_u128(zig_u128 lhs, zig_u128 rhs) { | 2294 | static inline zig_u128 zig_divTrunc_u128(zig_u128 lhs, zig_u128 rhs) { |
| 1957 | return lhs / rhs; | 2295 | return lhs / rhs; |
| 1958 | } | 2296 | } |
| 1959 | 2297 | ||
| 1960 | static inline zig_i128 zig_div_trunc_i128(zig_i128 lhs, zig_i128 rhs) { | 2298 | static inline zig_i128 zig_divTrunc_i128(zig_i128 lhs, zig_i128 rhs) { |
| 1961 | return lhs / rhs; | 2299 | return lhs / rhs; |
| 1962 | } | 2300 | } |
| 1963 | 2301 | ||
| ... | @@ -1971,36 +2309,14 @@ static inline zig_i128 zig_rem_i128(zig_i128 lhs, zig_i128 rhs) { | ... | @@ -1971,36 +2309,14 @@ static inline zig_i128 zig_rem_i128(zig_i128 lhs, zig_i128 rhs) { |
| 1971 | 2309 | ||
| 1972 | #else /* zig_has_int128 */ | 2310 | #else /* zig_has_int128 */ |
| 1973 | 2311 | ||
| 1974 | static inline zig_u128 zig_not_u128(zig_u128 val, uint8_t bits) { | 2312 | static inline zig_u128 zig_not_u128(zig_u128 arg, uint8_t bits) { |
| 1975 | return (zig_u128){ .hi = zig_not_u64(val.hi, bits - UINT8_C(64)), .lo = zig_not_u64(val.lo, UINT8_C(64)) }; | 2313 | if (bits <= UINT8_C(64)) return (zig_u128){ .hi = UINT64_C(0), .lo = zig_not_u64(arg.lo, bits) }; |
| 1976 | } | 2314 | return (zig_u128){ .hi = zig_not_u64(arg.hi, bits - UINT8_C(64)), .lo = zig_not_u64(arg.lo, UINT8_C(64)) }; |
| 1977 | |||
| 1978 | static inline zig_i128 zig_not_i128(zig_i128 val, uint8_t bits) { | ||
| 1979 | return (zig_i128){ .hi = zig_not_i64(val.hi, bits - UINT8_C(64)), .lo = zig_not_u64(val.lo, UINT8_C(64)) }; | ||
| 1980 | } | ||
| 1981 | |||
| 1982 | static inline zig_u128 zig_shr_u128(zig_u128 lhs, uint8_t rhs) { | ||
| 1983 | if (rhs == UINT8_C(0)) return lhs; | ||
| 1984 | if (rhs >= UINT8_C(64)) return (zig_u128){ .hi = zig_minInt_u64, .lo = lhs.hi >> (rhs - UINT8_C(64)) }; | ||
| 1985 | return (zig_u128){ .hi = lhs.hi >> rhs, .lo = lhs.hi << (UINT8_C(64) - rhs) | lhs.lo >> rhs }; | ||
| 1986 | } | ||
| 1987 | |||
| 1988 | static inline zig_u128 zig_shl_u128(zig_u128 lhs, uint8_t rhs) { | ||
| 1989 | if (rhs == UINT8_C(0)) return lhs; | ||
| 1990 | if (rhs >= UINT8_C(64)) return (zig_u128){ .hi = lhs.lo << (rhs - UINT8_C(64)), .lo = zig_minInt_u64 }; | ||
| 1991 | return (zig_u128){ .hi = lhs.hi << rhs | lhs.lo >> (UINT8_C(64) - rhs), .lo = lhs.lo << rhs }; | ||
| 1992 | } | ||
| 1993 | |||
| 1994 | static inline zig_i128 zig_shr_i128(zig_i128 lhs, uint8_t rhs) { | ||
| 1995 | if (rhs == UINT8_C(0)) return lhs; | ||
| 1996 | if (rhs >= UINT8_C(64)) return (zig_i128){ .hi = zig_shr_i64(lhs.hi, 63), .lo = zig_shr_i64(lhs.hi, (rhs - UINT8_C(64))) }; | ||
| 1997 | return (zig_i128){ .hi = zig_shr_i64(lhs.hi, rhs), .lo = lhs.lo >> rhs | (uint64_t)lhs.hi << (UINT8_C(64) - rhs) }; | ||
| 1998 | } | 2315 | } |
| 1999 | 2316 | ||
| 2000 | static inline zig_i128 zig_shl_i128(zig_i128 lhs, uint8_t rhs) { | 2317 | static inline zig_i128 zig_not_i128(zig_i128 arg, uint8_t bits) { |
| 2001 | if (rhs == UINT8_C(0)) return lhs; | 2318 | (void)bits; |
| 2002 | if (rhs >= UINT8_C(64)) return (zig_i128){ .hi = lhs.lo << (rhs - UINT8_C(64)), .lo = zig_minInt_u64 }; | 2319 | return (zig_i128){ .hi = ~arg.hi, .lo = ~arg.lo }; |
| 2003 | return (zig_i128){ .hi = lhs.hi << rhs | lhs.lo >> (UINT8_C(64) - rhs), .lo = lhs.lo << rhs }; | ||
| 2004 | } | 2320 | } |
| 2005 | 2321 | ||
| 2006 | static inline zig_u128 zig_add_u128(zig_u128 lhs, zig_u128 rhs) { | 2322 | static inline zig_u128 zig_add_u128(zig_u128 lhs, zig_u128 rhs) { |
| ... | @@ -2027,59 +2343,59 @@ static inline zig_i128 zig_sub_i128(zig_i128 lhs, zig_i128 rhs) { | ... | @@ -2027,59 +2343,59 @@ static inline zig_i128 zig_sub_i128(zig_i128 lhs, zig_i128 rhs) { |
| 2027 | return res; | 2343 | return res; |
| 2028 | } | 2344 | } |
| 2029 | 2345 | ||
| 2030 | zig_extern zig_i128 __multi3(zig_i128 lhs, zig_i128 rhs); | ||
| 2031 | static zig_i128 zig_mul_i128(zig_i128 lhs, zig_i128 rhs) { | 2346 | static zig_i128 zig_mul_i128(zig_i128 lhs, zig_i128 rhs) { |
| 2347 | zig_extern zig_i128 __multi3(zig_i128 lhs, zig_i128 rhs); | ||
| 2032 | return __multi3(lhs, rhs); | 2348 | return __multi3(lhs, rhs); |
| 2033 | } | 2349 | } |
| 2034 | 2350 | ||
| 2035 | static zig_u128 zig_mul_u128(zig_u128 lhs, zig_u128 rhs) { | 2351 | static zig_u128 zig_mul_u128(zig_u128 lhs, zig_u128 rhs) { |
| 2036 | return zig_bitCast_u128(zig_mul_i128(zig_bitCast_i128(lhs), zig_bitCast_i128(rhs))); | 2352 | return zig_u128_bitCast_i128(zig_mul_i128(zig_i128_bitCast_u128(lhs, UINT8_C(128)), zig_i128_bitCast_u128(rhs, UINT8_C(128))), UINT8_C(128)); |
| 2037 | } | 2353 | } |
| 2038 | 2354 | ||
| 2039 | zig_extern zig_u128 __udivti3(zig_u128 lhs, zig_u128 rhs); | 2355 | static zig_u128 zig_divTrunc_u128(zig_u128 lhs, zig_u128 rhs) { |
| 2040 | static zig_u128 zig_div_trunc_u128(zig_u128 lhs, zig_u128 rhs) { | 2356 | zig_extern zig_u128 __udivti3(zig_u128 lhs, zig_u128 rhs); |
| 2041 | return __udivti3(lhs, rhs); | 2357 | return __udivti3(lhs, rhs); |
| 2042 | } | 2358 | } |
| 2043 | 2359 | ||
| 2044 | zig_extern zig_i128 __divti3(zig_i128 lhs, zig_i128 rhs); | 2360 | static zig_i128 zig_divTrunc_i128(zig_i128 lhs, zig_i128 rhs) { |
| 2045 | static zig_i128 zig_div_trunc_i128(zig_i128 lhs, zig_i128 rhs) { | 2361 | zig_extern zig_i128 __divti3(zig_i128 lhs, zig_i128 rhs); |
| 2046 | return __divti3(lhs, rhs); | 2362 | return __divti3(lhs, rhs); |
| 2047 | } | 2363 | } |
| 2048 | 2364 | ||
| 2049 | zig_extern zig_u128 __umodti3(zig_u128 lhs, zig_u128 rhs); | ||
| 2050 | static zig_u128 zig_rem_u128(zig_u128 lhs, zig_u128 rhs) { | 2365 | static zig_u128 zig_rem_u128(zig_u128 lhs, zig_u128 rhs) { |
| 2366 | zig_extern zig_u128 __umodti3(zig_u128 lhs, zig_u128 rhs); | ||
| 2051 | return __umodti3(lhs, rhs); | 2367 | return __umodti3(lhs, rhs); |
| 2052 | } | 2368 | } |
| 2053 | 2369 | ||
| 2054 | zig_extern zig_i128 __modti3(zig_i128 lhs, zig_i128 rhs); | ||
| 2055 | static zig_i128 zig_rem_i128(zig_i128 lhs, zig_i128 rhs) { | 2370 | static zig_i128 zig_rem_i128(zig_i128 lhs, zig_i128 rhs) { |
| 2371 | zig_extern zig_i128 __modti3(zig_i128 lhs, zig_i128 rhs); | ||
| 2056 | return __modti3(lhs, rhs); | 2372 | return __modti3(lhs, rhs); |
| 2057 | } | 2373 | } |
| 2058 | 2374 | ||
| 2059 | #endif /* zig_has_int128 */ | 2375 | #endif /* zig_has_int128 */ |
| 2060 | 2376 | ||
| 2061 | #define zig_div_floor_u128 zig_div_trunc_u128 | 2377 | #define zig_divFloor_u128 zig_divTrunc_u128 |
| 2062 | 2378 | ||
| 2063 | static inline zig_i128 zig_div_floor_i128(zig_i128 lhs, zig_i128 rhs) { | 2379 | static inline zig_i128 zig_divFloor_i128(zig_i128 lhs, zig_i128 rhs) { |
| 2064 | zig_i128 rem = zig_rem_i128(lhs, rhs); | 2380 | zig_i128 rem = zig_rem_i128(lhs, rhs); |
| 2065 | int64_t mask = zig_or_u64((uint64_t)zig_hi_i128(rem), zig_lo_i128(rem)) != UINT64_C(0) | 2381 | int64_t mask = zig_or_u64((uint64_t)zig_hi_i128(rem), zig_lo_i128(rem)) != UINT64_C(0) |
| 2066 | ? zig_shr_i64(zig_xor_i64(zig_hi_i128(lhs), zig_hi_i128(rhs)), UINT8_C(63)) : INT64_C(0); | 2382 | ? zig_shr_i64(zig_xor_i64(zig_hi_i128(lhs), zig_hi_i128(rhs)), UINT8_C(63)) : INT64_C(0); |
| 2067 | return zig_add_i128(zig_div_trunc_i128(lhs, rhs), zig_make_i128(mask, (uint64_t)mask)); | 2383 | return zig_add_i128(zig_divTrunc_i128(lhs, rhs), zig_make_i128(mask, (uint64_t)mask)); |
| 2068 | } | 2384 | } |
| 2069 | 2385 | ||
| 2070 | static inline zig_u128 zig_div_ceil_u128(zig_u128 lhs, zig_u128 rhs) { | 2386 | static inline zig_u128 zig_divCeil_u128(zig_u128 lhs, zig_u128 rhs) { |
| 2071 | zig_u128 rem = zig_rem_u128(lhs, rhs); | 2387 | zig_u128 rem = zig_rem_u128(lhs, rhs); |
| 2072 | uint64_t mask = zig_or_u64(zig_hi_u128(rem), zig_lo_u128(rem)) != UINT64_C(0) | 2388 | uint64_t mask = zig_or_u64(zig_hi_u128(rem), zig_lo_u128(rem)) != UINT64_C(0) |
| 2073 | ? UINT64_C(1) : UINT64_C(0); | 2389 | ? UINT64_C(1) : UINT64_C(0); |
| 2074 | return zig_add_u128(zig_div_trunc_u128(lhs, rhs), zig_make_u128(UINT64_C(0), mask)); | 2390 | return zig_add_u128(zig_divTrunc_u128(lhs, rhs), zig_make_u128(UINT64_C(0), mask)); |
| 2075 | } | 2391 | } |
| 2076 | 2392 | ||
| 2077 | static inline zig_i128 zig_div_ceil_i128(zig_i128 lhs, zig_i128 rhs) { | 2393 | static inline zig_i128 zig_divCeil_i128(zig_i128 lhs, zig_i128 rhs) { |
| 2078 | zig_i128 rem = zig_rem_i128(lhs, rhs); | 2394 | zig_i128 rem = zig_rem_i128(lhs, rhs); |
| 2079 | int64_t mask = zig_or_u64((uint64_t)zig_hi_i128(rem), zig_lo_i128(rem)) != UINT64_C(0) | 2395 | int64_t mask = zig_or_u64((uint64_t)zig_hi_i128(rem), zig_lo_i128(rem)) != UINT64_C(0) |
| 2080 | ? zig_shr_i64(zig_xor_i64(zig_hi_i128(lhs), zig_hi_i128(rhs)), UINT8_C(63)) + INT64_C(1) | 2396 | ? zig_shr_i64(zig_xor_i64(zig_hi_i128(lhs), zig_hi_i128(rhs)), UINT8_C(63)) + INT64_C(1) |
| 2081 | : INT64_C(0); | 2397 | : INT64_C(0); |
| 2082 | return zig_add_i128(zig_div_trunc_i128(lhs, rhs), zig_make_i128(INT64_C(0), (uint64_t)mask)); | 2398 | return zig_add_i128(zig_divTrunc_i128(lhs, rhs), zig_make_i128(INT64_C(0), (uint64_t)mask)); |
| 2083 | } | 2399 | } |
| 2084 | 2400 | ||
| 2085 | #define zig_mod_u128 zig_rem_u128 | 2401 | #define zig_mod_u128 zig_rem_u128 |
| ... | @@ -2107,51 +2423,41 @@ static inline zig_i128 zig_max_i128(zig_i128 lhs, zig_i128 rhs) { | ... | @@ -2107,51 +2423,41 @@ static inline zig_i128 zig_max_i128(zig_i128 lhs, zig_i128 rhs) { |
| 2107 | return zig_cmp_i128(lhs, rhs) > INT32_C(0) ? lhs : rhs; | 2423 | return zig_cmp_i128(lhs, rhs) > INT32_C(0) ? lhs : rhs; |
| 2108 | } | 2424 | } |
| 2109 | 2425 | ||
| 2110 | static inline zig_u128 zig_wrap_u128(zig_u128 val, uint8_t bits) { | ||
| 2111 | return zig_and_u128(val, zig_maxInt_u(128, bits)); | ||
| 2112 | } | ||
| 2113 | |||
| 2114 | static inline zig_i128 zig_wrap_i128(zig_i128 val, uint8_t bits) { | ||
| 2115 | if (bits > UINT8_C(64)) return zig_make_i128(zig_wrap_i64(zig_hi_i128(val), bits - UINT8_C(64)), zig_lo_i128(val)); | ||
| 2116 | int64_t lo = zig_wrap_i64((int64_t)zig_lo_i128(val), bits); | ||
| 2117 | return zig_make_i128(zig_shr_i64(lo, 63), (uint64_t)lo); | ||
| 2118 | } | ||
| 2119 | |||
| 2120 | static inline zig_u128 zig_shlw_u128(zig_u128 lhs, uint8_t rhs, uint8_t bits) { | 2426 | static inline zig_u128 zig_shlw_u128(zig_u128 lhs, uint8_t rhs, uint8_t bits) { |
| 2121 | return zig_wrap_u128(zig_shl_u128(lhs, rhs), bits); | 2427 | return zig_u128_truncate_u128(zig_shl_u128(lhs, rhs), bits); |
| 2122 | } | 2428 | } |
| 2123 | 2429 | ||
| 2124 | static inline zig_i128 zig_shlw_i128(zig_i128 lhs, uint8_t rhs, uint8_t bits) { | 2430 | static inline zig_i128 zig_shlw_i128(zig_i128 lhs, uint8_t rhs, uint8_t bits) { |
| 2125 | return zig_wrap_i128(zig_bitCast_i128(zig_shl_u128(zig_bitCast_u128(lhs), rhs)), bits); | 2431 | return zig_i128_truncate_i128(zig_i128_bitCast_u128(zig_shl_u128(zig_u128_bitCast_i128(lhs, bits), rhs), bits), bits); |
| 2126 | } | 2432 | } |
| 2127 | 2433 | ||
| 2128 | static inline zig_u128 zig_addw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) { | 2434 | static inline zig_u128 zig_addw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) { |
| 2129 | return zig_wrap_u128(zig_add_u128(lhs, rhs), bits); | 2435 | return zig_u128_truncate_u128(zig_add_u128(lhs, rhs), bits); |
| 2130 | } | 2436 | } |
| 2131 | 2437 | ||
| 2132 | static inline zig_i128 zig_addw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) { | 2438 | static inline zig_i128 zig_addw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) { |
| 2133 | return zig_wrap_i128(zig_bitCast_i128(zig_add_u128(zig_bitCast_u128(lhs), zig_bitCast_u128(rhs))), bits); | 2439 | return zig_i128_truncate_i128(zig_i128_bitCast_u128(zig_add_u128(zig_u128_bitCast_i128(lhs, bits), zig_u128_bitCast_i128(rhs, bits)), bits), bits); |
| 2134 | } | 2440 | } |
| 2135 | 2441 | ||
| 2136 | static inline zig_u128 zig_subw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) { | 2442 | static inline zig_u128 zig_subw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) { |
| 2137 | return zig_wrap_u128(zig_sub_u128(lhs, rhs), bits); | 2443 | return zig_u128_truncate_u128(zig_sub_u128(lhs, rhs), bits); |
| 2138 | } | 2444 | } |
| 2139 | 2445 | ||
| 2140 | static inline zig_i128 zig_subw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) { | 2446 | static inline zig_i128 zig_subw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) { |
| 2141 | return zig_wrap_i128(zig_bitCast_i128(zig_sub_u128(zig_bitCast_u128(lhs), zig_bitCast_u128(rhs))), bits); | 2447 | return zig_i128_truncate_i128(zig_i128_bitCast_u128(zig_sub_u128(zig_u128_bitCast_i128(lhs, bits), zig_u128_bitCast_i128(rhs, bits)), bits), bits); |
| 2142 | } | 2448 | } |
| 2143 | 2449 | ||
| 2144 | static inline zig_u128 zig_mulw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) { | 2450 | static inline zig_u128 zig_mulw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) { |
| 2145 | return zig_wrap_u128(zig_mul_u128(lhs, rhs), bits); | 2451 | return zig_u128_truncate_u128(zig_mul_u128(lhs, rhs), bits); |
| 2146 | } | 2452 | } |
| 2147 | 2453 | ||
| 2148 | static inline zig_i128 zig_mulw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) { | 2454 | static inline zig_i128 zig_mulw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) { |
| 2149 | return zig_wrap_i128(zig_bitCast_i128(zig_mul_u128(zig_bitCast_u128(lhs), zig_bitCast_u128(rhs))), bits); | 2455 | return zig_i128_truncate_i128(zig_i128_bitCast_u128(zig_mul_u128(zig_u128_bitCast_i128(lhs, bits), zig_u128_bitCast_i128(rhs, bits)), bits), bits); |
| 2150 | } | 2456 | } |
| 2151 | 2457 | ||
| 2152 | static inline zig_u128 zig_abs_i128(zig_i128 val) { | 2458 | static inline zig_u128 zig_abs_i128(zig_i128 arg) { |
| 2153 | zig_i128 tmp = zig_shr_i128(val, 127); | 2459 | zig_u128 tmp = zig_u128_bitCast_i128(zig_shr_i128(arg, 127), UINT8_C(128)); |
| 2154 | return zig_bitCast_u128(zig_sub_i128(zig_xor_i128(val, tmp), tmp)); | 2460 | return zig_sub_u128(zig_xor_u128(zig_u128_bitCast_i128(arg, UINT8_C(128)), tmp), tmp); |
| 2155 | } | 2461 | } |
| 2156 | 2462 | ||
| 2157 | #if zig_has_int128 | 2463 | #if zig_has_int128 |
| ... | @@ -2160,7 +2466,7 @@ static inline bool zig_addo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint | ... | @@ -2160,7 +2466,7 @@ static inline bool zig_addo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint |
| 2160 | #if zig_has_builtin(add_overflow) | 2466 | #if zig_has_builtin(add_overflow) |
| 2161 | zig_u128 full_res; | 2467 | zig_u128 full_res; |
| 2162 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); | 2468 | bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); |
| 2163 | *res = zig_wrap_u128(full_res, bits); | 2469 | *res = zig_u128_truncate_u128(full_res, bits); |
| 2164 | return overflow || full_res < zig_minInt_u(128, bits) || full_res > zig_maxInt_u(128, bits); | 2470 | return overflow || full_res < zig_minInt_u(128, bits) || full_res > zig_maxInt_u(128, bits); |
| 2165 | #else | 2471 | #else |
| 2166 | *res = zig_addw_u128(lhs, rhs, bits); | 2472 | *res = zig_addw_u128(lhs, rhs, bits); |
| ... | @@ -2176,7 +2482,7 @@ static inline bool zig_addo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint | ... | @@ -2176,7 +2482,7 @@ static inline bool zig_addo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint |
| 2176 | zig_i128 full_res = (zig_i128)((zig_u128)lhs + (zig_u128)rhs); | 2482 | zig_i128 full_res = (zig_i128)((zig_u128)lhs + (zig_u128)rhs); |
| 2177 | bool overflow = ((full_res ^ lhs) & (full_res ^ rhs)) < 0; | 2483 | bool overflow = ((full_res ^ lhs) & (full_res ^ rhs)) < 0; |
| 2178 | #endif | 2484 | #endif |
| 2179 | *res = zig_wrap_i128(full_res, bits); | 2485 | *res = zig_i128_truncate_i128(full_res, bits); |
| 2180 | return overflow || full_res < zig_minInt_i(128, bits) || full_res > zig_maxInt_i(128, bits); | 2486 | return overflow || full_res < zig_minInt_i(128, bits) || full_res > zig_maxInt_i(128, bits); |
| 2181 | } | 2487 | } |
| 2182 | 2488 | ||
| ... | @@ -2184,7 +2490,7 @@ static inline bool zig_subo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint | ... | @@ -2184,7 +2490,7 @@ static inline bool zig_subo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint |
| 2184 | #if zig_has_builtin(sub_overflow) | 2490 | #if zig_has_builtin(sub_overflow) |
| 2185 | zig_u128 full_res; | 2491 | zig_u128 full_res; |
| 2186 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); | 2492 | bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); |
| 2187 | *res = zig_wrap_u128(full_res, bits); | 2493 | *res = zig_u128_truncate_u128(full_res, bits); |
| 2188 | return overflow || full_res < zig_minInt_u(128, bits) || full_res > zig_maxInt_u(128, bits); | 2494 | return overflow || full_res < zig_minInt_u(128, bits) || full_res > zig_maxInt_u(128, bits); |
| 2189 | #else | 2495 | #else |
| 2190 | *res = zig_subw_u128(lhs, rhs, bits); | 2496 | *res = zig_subw_u128(lhs, rhs, bits); |
| ... | @@ -2200,7 +2506,7 @@ static inline bool zig_subo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint | ... | @@ -2200,7 +2506,7 @@ static inline bool zig_subo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint |
| 2200 | zig_i128 full_res = (zig_i128)((zig_u128)lhs - (zig_u128)rhs); | 2506 | zig_i128 full_res = (zig_i128)((zig_u128)lhs - (zig_u128)rhs); |
| 2201 | bool overflow = ((lhs ^ rhs) & (full_res ^ lhs)) < 0; | 2507 | bool overflow = ((lhs ^ rhs) & (full_res ^ lhs)) < 0; |
| 2202 | #endif | 2508 | #endif |
| 2203 | *res = zig_wrap_i128(full_res, bits); | 2509 | *res = zig_i128_truncate_i128(full_res, bits); |
| 2204 | return overflow || full_res < zig_minInt_i(128, bits) || full_res > zig_maxInt_i(128, bits); | 2510 | return overflow || full_res < zig_minInt_i(128, bits) || full_res > zig_maxInt_i(128, bits); |
| 2205 | } | 2511 | } |
| 2206 | 2512 | ||
| ... | @@ -2208,7 +2514,7 @@ static inline bool zig_mulo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint | ... | @@ -2208,7 +2514,7 @@ static inline bool zig_mulo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint |
| 2208 | #if zig_has_builtin(mul_overflow) | 2514 | #if zig_has_builtin(mul_overflow) |
| 2209 | zig_u128 full_res; | 2515 | zig_u128 full_res; |
| 2210 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); | 2516 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); |
| 2211 | *res = zig_wrap_u128(full_res, bits); | 2517 | *res = zig_u128_truncate_u128(full_res, bits); |
| 2212 | return overflow || full_res < zig_minInt_u(128, bits) || full_res > zig_maxInt_u(128, bits); | 2518 | return overflow || full_res < zig_minInt_u(128, bits) || full_res > zig_maxInt_u(128, bits); |
| 2213 | #else | 2519 | #else |
| 2214 | *res = zig_mulw_u128(lhs, rhs, bits); | 2520 | *res = zig_mulw_u128(lhs, rhs, bits); |
| ... | @@ -2216,8 +2522,8 @@ static inline bool zig_mulo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint | ... | @@ -2216,8 +2522,8 @@ static inline bool zig_mulo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint |
| 2216 | #endif | 2522 | #endif |
| 2217 | } | 2523 | } |
| 2218 | 2524 | ||
| 2219 | zig_extern zig_i128 __muloti4(zig_i128 lhs, zig_i128 rhs, int *overflow); | ||
| 2220 | static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) { | 2525 | static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) { |
| 2526 | zig_extern zig_i128 __muloti4(zig_i128 lhs, zig_i128 rhs, int *overflow); | ||
| 2221 | #if zig_has_builtin(mul_overflow) | 2527 | #if zig_has_builtin(mul_overflow) |
| 2222 | zig_i128 full_res; | 2528 | zig_i128 full_res; |
| 2223 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); | 2529 | bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); |
| ... | @@ -2226,50 +2532,78 @@ static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint | ... | @@ -2226,50 +2532,78 @@ static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint |
| 2226 | zig_i128 full_res = __muloti4(lhs, rhs, &overflow_int); | 2532 | zig_i128 full_res = __muloti4(lhs, rhs, &overflow_int); |
| 2227 | bool overflow = overflow_int != 0; | 2533 | bool overflow = overflow_int != 0; |
| 2228 | #endif | 2534 | #endif |
| 2229 | *res = zig_wrap_i128(full_res, bits); | 2535 | *res = zig_i128_truncate_i128(full_res, bits); |
| 2230 | return overflow || full_res < zig_minInt_i(128, bits) || full_res > zig_maxInt_i(128, bits); | 2536 | return overflow || full_res < zig_minInt_i(128, bits) || full_res > zig_maxInt_i(128, bits); |
| 2231 | } | 2537 | } |
| 2232 | 2538 | ||
| 2233 | #else /* zig_has_int128 */ | 2539 | #else /* zig_has_int128 */ |
| 2234 | 2540 | ||
| 2235 | static inline bool zig_addo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) { | 2541 | static inline bool zig_addo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) { |
| 2236 | uint64_t hi; | 2542 | if (bits <= UINT8_C(64)) { |
| 2237 | bool overflow = zig_addo_u64(&hi, lhs.hi, rhs.hi, bits - 64); | 2543 | uint64_t lo; |
| 2238 | return overflow ^ zig_addo_u64(&res->hi, hi, zig_addo_u64(&res->lo, lhs.lo, rhs.lo, 64), bits - 64); | 2544 | bool overflow = zig_addo_u64(&lo, zig_u64_intCast_u128(lhs), zig_u64_intCast_u128(rhs), bits); |
| 2545 | *res = zig_u128_intCast_u64(lo); | ||
| 2546 | return overflow; | ||
| 2547 | } else { | ||
| 2548 | uint64_t hi; | ||
| 2549 | bool overflow = zig_addo_u64(&hi, lhs.hi, rhs.hi, bits - UINT8_C(64)); | ||
| 2550 | return overflow ^ zig_addo_u64(&res->hi, hi, zig_addo_u64(&res->lo, lhs.lo, rhs.lo, UINT8_C(64)), bits - UINT8_C(64)); | ||
| 2551 | } | ||
| 2239 | } | 2552 | } |
| 2240 | 2553 | ||
| 2241 | static inline bool zig_addo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) { | 2554 | static inline bool zig_addo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) { |
| 2242 | int64_t hi; | 2555 | if (bits <= UINT8_C(64)) { |
| 2243 | bool overflow = zig_addo_i64(&hi, lhs.hi, rhs.hi, bits - 64); | 2556 | int64_t lo; |
| 2244 | return overflow ^ zig_addo_i64(&res->hi, hi, zig_addo_u64(&res->lo, lhs.lo, rhs.lo, 64), bits - 64); | 2557 | bool overflow = zig_addo_i64(&lo, zig_i64_intCast_i128(lhs), zig_i64_intCast_i128(rhs), bits); |
| 2558 | *res = zig_i128_intCast_i64(lo); | ||
| 2559 | return overflow; | ||
| 2560 | } else { | ||
| 2561 | int64_t hi; | ||
| 2562 | bool overflow = zig_addo_i64(&hi, lhs.hi, rhs.hi, bits - UINT8_C(64)); | ||
| 2563 | return overflow ^ zig_addo_i64(&res->hi, hi, zig_addo_u64(&res->lo, lhs.lo, rhs.lo, UINT8_C(64)), bits - UINT8_C(64)); | ||
| 2564 | } | ||
| 2245 | } | 2565 | } |
| 2246 | 2566 | ||
| 2247 | static inline bool zig_subo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) { | 2567 | static inline bool zig_subo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) { |
| 2248 | uint64_t hi; | 2568 | if (bits <= UINT8_C(64)) { |
| 2249 | bool overflow = zig_subo_u64(&hi, lhs.hi, rhs.hi, bits - 64); | 2569 | uint64_t lo; |
| 2250 | return overflow ^ zig_subo_u64(&res->hi, hi, zig_subo_u64(&res->lo, lhs.lo, rhs.lo, 64), bits - 64); | 2570 | bool overflow = zig_subo_u64(&lo, zig_u64_intCast_u128(lhs), zig_u64_intCast_u128(rhs), bits); |
| 2571 | *res = zig_u128_intCast_u64(lo); | ||
| 2572 | return overflow; | ||
| 2573 | } else { | ||
| 2574 | uint64_t hi; | ||
| 2575 | bool overflow = zig_subo_u64(&hi, lhs.hi, rhs.hi, bits - UINT8_C(64)); | ||
| 2576 | return overflow ^ zig_subo_u64(&res->hi, hi, zig_subo_u64(&res->lo, lhs.lo, rhs.lo, UINT8_C(64)), bits - UINT8_C(64)); | ||
| 2577 | } | ||
| 2251 | } | 2578 | } |
| 2252 | 2579 | ||
| 2253 | static inline bool zig_subo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) { | 2580 | static inline bool zig_subo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) { |
| 2254 | int64_t hi; | 2581 | if (bits <= UINT8_C(64)) { |
| 2255 | bool overflow = zig_subo_i64(&hi, lhs.hi, rhs.hi, bits - 64); | 2582 | int64_t lo; |
| 2256 | return overflow ^ zig_subo_i64(&res->hi, hi, zig_subo_u64(&res->lo, lhs.lo, rhs.lo, 64), bits - 64); | 2583 | bool overflow = zig_subo_i64(&lo, zig_i64_intCast_i128(lhs), zig_i64_intCast_i128(rhs), bits); |
| 2584 | *res = zig_i128_intCast_i64(lo); | ||
| 2585 | return overflow; | ||
| 2586 | } else { | ||
| 2587 | int64_t hi; | ||
| 2588 | bool overflow = zig_subo_i64(&hi, lhs.hi, rhs.hi, bits - UINT8_C(64)); | ||
| 2589 | return overflow ^ zig_subo_i64(&res->hi, hi, zig_subo_u64(&res->lo, lhs.lo, rhs.lo, UINT8_C(64)), bits - UINT8_C(64)); | ||
| 2590 | } | ||
| 2257 | } | 2591 | } |
| 2258 | 2592 | ||
| 2259 | static inline bool zig_mulo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) { | 2593 | static inline bool zig_mulo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) { |
| 2260 | *res = zig_mulw_u128(lhs, rhs, bits); | 2594 | *res = zig_mulw_u128(lhs, rhs, bits); |
| 2261 | return zig_cmp_u128(*res, zig_make_u128(0, 0)) != INT32_C(0) && | 2595 | return zig_cmp_u128(rhs, zig_make_u128(0, 0)) != INT32_C(0) && |
| 2262 | zig_cmp_u128(lhs, zig_div_trunc_u128(zig_maxInt_u(128, bits), rhs)) > INT32_C(0); | 2596 | zig_cmp_u128(lhs, zig_divTrunc_u128(zig_maxInt_u(128, bits), rhs)) > INT32_C(0); |
| 2263 | } | 2597 | } |
| 2264 | 2598 | ||
| 2265 | zig_extern zig_i128 __muloti4(zig_i128 lhs, zig_i128 rhs, int *overflow); | ||
| 2266 | static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) { | 2599 | static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) { |
| 2600 | zig_extern zig_i128 __muloti4(zig_i128 lhs, zig_i128 rhs, int *overflow); | ||
| 2267 | int overflow_int; | 2601 | int overflow_int; |
| 2268 | zig_i128 full_res = __muloti4(lhs, rhs, &overflow_int); | 2602 | zig_i128 full_res = __muloti4(lhs, rhs, &overflow_int); |
| 2269 | bool overflow = overflow_int != 0 || | 2603 | bool overflow = overflow_int != 0 || |
| 2270 | zig_cmp_i128(full_res, zig_minInt_i(128, bits)) < INT32_C(0) || | 2604 | zig_cmp_i128(full_res, zig_minInt_i(128, bits)) < INT32_C(0) || |
| 2271 | zig_cmp_i128(full_res, zig_maxInt_i(128, bits)) > INT32_C(0); | 2605 | zig_cmp_i128(full_res, zig_maxInt_i(128, bits)) > INT32_C(0); |
| 2272 | *res = zig_wrap_i128(full_res, bits); | 2606 | *res = zig_i128_truncate_i128(full_res, bits); |
| 2273 | return overflow; | 2607 | return overflow; |
| 2274 | } | 2608 | } |
| 2275 | 2609 | ||
| ... | @@ -2282,28 +2616,54 @@ static inline bool zig_shlo_u128(zig_u128 *res, zig_u128 lhs, uint8_t rhs, uint8 | ... | @@ -2282,28 +2616,54 @@ static inline bool zig_shlo_u128(zig_u128 *res, zig_u128 lhs, uint8_t rhs, uint8 |
| 2282 | 2616 | ||
| 2283 | static inline bool zig_shlo_i128(zig_i128 *res, zig_i128 lhs, uint8_t rhs, uint8_t bits) { | 2617 | static inline bool zig_shlo_i128(zig_i128 *res, zig_i128 lhs, uint8_t rhs, uint8_t bits) { |
| 2284 | *res = zig_shlw_i128(lhs, rhs, bits); | 2618 | *res = zig_shlw_i128(lhs, rhs, bits); |
| 2285 | zig_i128 mask = zig_bitCast_i128(zig_shl_u128(zig_maxInt_u128, bits - rhs - UINT8_C(1))); | 2619 | zig_i128 mask = zig_i128_bitCast_u128(zig_shl_u128(zig_maxInt_u128, bits - rhs - UINT8_C(1)), bits); |
| 2286 | return zig_cmp_i128(zig_and_i128(lhs, mask), zig_make_i128(0, 0)) != INT32_C(0) && | 2620 | return zig_cmp_i128(zig_and_i128(lhs, mask), zig_make_i128(0, 0)) != INT32_C(0) && |
| 2287 | zig_cmp_i128(zig_and_i128(lhs, mask), mask) != INT32_C(0); | 2621 | zig_cmp_i128(zig_and_i128(lhs, mask), mask) != INT32_C(0); |
| 2288 | } | 2622 | } |
| 2289 | 2623 | ||
| 2290 | static inline zig_u128 zig_shls_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) { | 2624 | #define zig_int128_shls_builtins(rw) \ |
| 2625 | static inline zig_u128 zig_shls_u128_u##rw(zig_u128 lhs, uint##rw##_t rhs, uint8_t bits) { \ | ||
| 2626 | zig_u128 res; \ | ||
| 2627 | if (rhs < bits && !zig_shlo_u128(&res, lhs, zig_u8_intCast_u##rw(rhs), bits)) return res; \ | ||
| 2628 | switch (zig_cmp_u128(lhs, zig_make_u128(UINT64_C(0), UINT64_C(0)))) { \ | ||
| 2629 | case 0: return zig_minInt_u(128, bits); \ | ||
| 2630 | case 1: return zig_maxInt_u(128, bits); \ | ||
| 2631 | default: zig_unreachable(); \ | ||
| 2632 | } \ | ||
| 2633 | } \ | ||
| 2634 | \ | ||
| 2635 | static inline zig_i128 zig_shls_i128_u##rw(zig_i128 lhs, uint##rw##_t rhs, uint8_t bits) { \ | ||
| 2636 | zig_i128 res; \ | ||
| 2637 | if (rhs < bits && !zig_shlo_i128(&res, lhs, zig_u8_intCast_u##rw(rhs), bits)) return res; \ | ||
| 2638 | switch (zig_cmp_i128(lhs, zig_make_i128(INT64_C(0), UINT64_C(0)))) { \ | ||
| 2639 | case -1: return zig_minInt_i(128, bits); \ | ||
| 2640 | case 0: return zig_make_i128(INT64_C(0), UINT64_C(0)); \ | ||
| 2641 | case 1: return zig_maxInt_i(128, bits); \ | ||
| 2642 | default: zig_unreachable(); \ | ||
| 2643 | } \ | ||
| 2644 | } | ||
| 2645 | zig_int128_shls_builtins(8) | ||
| 2646 | zig_int128_shls_builtins(16) | ||
| 2647 | zig_int128_shls_builtins(32) | ||
| 2648 | zig_int128_shls_builtins(64) | ||
| 2649 | |||
| 2650 | static inline zig_u128 zig_shls_u128_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) { | ||
| 2291 | zig_u128 res; | 2651 | zig_u128 res; |
| 2292 | if (zig_cmp_u128(rhs, zig_make_u128(0, bits)) < INT32_C(0) && !zig_shlo_u128(&res, lhs, (uint8_t)zig_lo_u128(rhs), bits)) return res; | 2652 | if (zig_cmp_u128(rhs, zig_make_u128(0, bits)) < INT32_C(0) && !zig_shlo_u128(&res, lhs, (uint8_t)zig_lo_u128(rhs), bits)) return res; |
| 2293 | switch (zig_cmp_u128(lhs, zig_make_u128(0, 0))) { | 2653 | switch (zig_cmp_u128(lhs, zig_make_u128(0, 0))) { |
| 2294 | case 0: return zig_make_u128(0, 0); | 2654 | case INT32_C(0): return zig_make_u128(0, 0); |
| 2295 | case 1: return zig_maxInt_u(128, bits); | 2655 | case INT32_C(1): return zig_maxInt_u(128, bits); |
| 2296 | default: zig_unreachable(); | 2656 | default: zig_unreachable(); |
| 2297 | } | 2657 | } |
| 2298 | } | 2658 | } |
| 2299 | 2659 | ||
| 2300 | static inline zig_i128 zig_shls_i128(zig_i128 lhs, zig_u128 rhs, uint8_t bits) { | 2660 | static inline zig_i128 zig_shls_i128_u128(zig_i128 lhs, zig_u128 rhs, uint8_t bits) { |
| 2301 | zig_i128 res; | 2661 | zig_i128 res; |
| 2302 | if (zig_cmp_u128(rhs, zig_make_u128(0, bits)) < INT32_C(0) && !zig_shlo_i128(&res, lhs, (uint8_t)zig_lo_u128(rhs), bits)) return res; | 2662 | if (zig_cmp_u128(rhs, zig_make_u128(0, bits)) < INT32_C(0) && !zig_shlo_i128(&res, lhs, (uint8_t)zig_lo_u128(rhs), bits)) return res; |
| 2303 | switch (zig_cmp_i128(lhs, zig_make_i128(0, 0))) { | 2663 | switch (zig_cmp_i128(lhs, zig_make_i128(0, 0))) { |
| 2304 | case -1: return zig_minInt_i(128, bits); | 2664 | case -INT32_C(1): return zig_minInt_i(128, bits); |
| 2305 | case 0: return zig_make_i128(0, 0); | 2665 | case INT32_C(0): return zig_make_i128(0, 0); |
| 2306 | case 1: return zig_maxInt_i(128, bits); | 2666 | case INT32_C(1): return zig_maxInt_i(128, bits); |
| 2307 | default: zig_unreachable(); | 2667 | default: zig_unreachable(); |
| 2308 | } | 2668 | } |
| 2309 | } | 2669 | } |
| ... | @@ -2341,57 +2701,60 @@ static inline zig_i128 zig_muls_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) { | ... | @@ -2341,57 +2701,60 @@ static inline zig_i128 zig_muls_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) { |
| 2341 | return zig_cmp_i128(zig_xor_i128(lhs, rhs), zig_make_i128(0, 0)) < INT32_C(0) ? zig_minInt_i(128, bits) : zig_maxInt_i(128, bits); | 2701 | return zig_cmp_i128(zig_xor_i128(lhs, rhs), zig_make_i128(0, 0)) < INT32_C(0) ? zig_minInt_i(128, bits) : zig_maxInt_i(128, bits); |
| 2342 | } | 2702 | } |
| 2343 | 2703 | ||
| 2344 | static inline uint8_t zig_clz_u128(zig_u128 val, uint8_t bits) { | 2704 | static inline uint8_t zig_clz_u128(zig_u128 arg, uint8_t bits) { |
| 2345 | if (bits <= UINT8_C(64)) return zig_clz_u64(zig_lo_u128(val), bits); | 2705 | if (bits <= UINT8_C(64)) return zig_clz_u64(zig_lo_u128(arg), bits); |
| 2346 | if (zig_hi_u128(val) != 0) return zig_clz_u64(zig_hi_u128(val), bits - UINT8_C(64)); | 2706 | if (zig_hi_u128(arg) != 0) return zig_clz_u64(zig_hi_u128(arg), bits - UINT8_C(64)); |
| 2347 | return zig_clz_u64(zig_lo_u128(val), UINT8_C(64)) + (bits - UINT8_C(64)); | 2707 | return zig_clz_u64(zig_lo_u128(arg), UINT8_C(64)) + (bits - UINT8_C(64)); |
| 2348 | } | 2708 | } |
| 2349 | 2709 | ||
| 2350 | static inline uint8_t zig_clz_i128(zig_i128 val, uint8_t bits) { | 2710 | static inline uint8_t zig_clz_i128(zig_i128 arg, uint8_t bits) { |
| 2351 | return zig_clz_u128(zig_bitCast_u128(val), bits); | 2711 | return zig_clz_u128(zig_u128_bitCast_i128(arg, bits), bits); |
| 2352 | } | 2712 | } |
| 2353 | 2713 | ||
| 2354 | static inline uint8_t zig_ctz_u128(zig_u128 val, uint8_t bits) { | 2714 | static inline uint8_t zig_ctz_u128(zig_u128 arg, uint8_t bits) { |
| 2355 | if (zig_lo_u128(val) != 0) return zig_ctz_u64(zig_lo_u128(val), UINT8_C(64)); | 2715 | if (zig_lo_u128(arg) != 0) return zig_ctz_u64(zig_lo_u128(arg), UINT8_C(64)); |
| 2356 | return zig_ctz_u64(zig_hi_u128(val), bits - UINT8_C(64)) + UINT8_C(64); | 2716 | return zig_ctz_u64(zig_hi_u128(arg), bits - UINT8_C(64)) + UINT8_C(64); |
| 2357 | } | 2717 | } |
| 2358 | 2718 | ||
| 2359 | static inline uint8_t zig_ctz_i128(zig_i128 val, uint8_t bits) { | 2719 | static inline uint8_t zig_ctz_i128(zig_i128 arg, uint8_t bits) { |
| 2360 | return zig_ctz_u128(zig_bitCast_u128(val), bits); | 2720 | return zig_ctz_u128(zig_u128_bitCast_i128(arg, bits), bits); |
| 2361 | } | 2721 | } |
| 2362 | 2722 | ||
| 2363 | static inline uint8_t zig_popcount_u128(zig_u128 val, uint8_t bits) { | 2723 | static inline uint8_t zig_popCount_u128(zig_u128 arg, uint8_t bits) { |
| 2364 | return zig_popcount_u64(zig_hi_u128(val), bits - UINT8_C(64)) + | 2724 | return (bits > UINT8_C(64) ? zig_popCount_u64(zig_hi_u128(arg), bits - UINT8_C(64)) : UINT8_C(0)) + |
| 2365 | zig_popcount_u64(zig_lo_u128(val), UINT8_C(64)); | 2725 | zig_popCount_u64(zig_lo_u128(arg), UINT8_C(64)); |
| 2366 | } | 2726 | } |
| 2367 | 2727 | ||
| 2368 | static inline uint8_t zig_popcount_i128(zig_i128 val, uint8_t bits) { | 2728 | static inline uint8_t zig_popCount_i128(zig_i128 arg, uint8_t bits) { |
| 2369 | return zig_popcount_u128(zig_bitCast_u128(val), bits); | 2729 | return zig_popCount_u128(zig_u128_bitCast_i128(arg, bits), bits); |
| 2370 | } | 2730 | } |
| 2371 | 2731 | ||
| 2372 | static inline zig_u128 zig_byte_swap_u128(zig_u128 val, uint8_t bits) { | 2732 | static inline zig_u128 zig_byteSwap_u128(zig_u128 arg, uint8_t bits) { |
| 2373 | zig_u128 full_res; | 2733 | zig_u128 full_res; |
| 2374 | #if zig_has_builtin(bswap128) | 2734 | #if zig_has_builtin(bswap128) |
| 2375 | full_res = __builtin_bswap128(val); | 2735 | full_res = __builtin_bswap128(arg); |
| 2376 | #else | 2736 | #else |
| 2377 | full_res = zig_make_u128(zig_byte_swap_u64(zig_lo_u128(val), UINT8_C(64)), | 2737 | full_res = zig_make_u128( |
| 2378 | zig_byte_swap_u64(zig_hi_u128(val), UINT8_C(64))); | 2738 | zig_byteSwap_u64(zig_lo_u128(arg), UINT8_C(64)), |
| 2739 | zig_byteSwap_u64(zig_hi_u128(arg), UINT8_C(64)) | ||
| 2740 | ); | ||
| 2379 | #endif | 2741 | #endif |
| 2380 | return zig_shr_u128(full_res, UINT8_C(128) - bits); | 2742 | return zig_shr_u128(full_res, UINT8_C(128) - bits); |
| 2381 | } | 2743 | } |
| 2382 | 2744 | ||
| 2383 | static inline zig_i128 zig_byte_swap_i128(zig_i128 val, uint8_t bits) { | 2745 | static inline zig_i128 zig_byteSwap_i128(zig_i128 arg, uint8_t bits) { |
| 2384 | return zig_bitCast_i128(zig_byte_swap_u128(zig_bitCast_u128(val), bits)); | 2746 | return zig_i128_bitCast_u128(zig_byteSwap_u128(zig_u128_bitCast_i128(arg, bits), bits), bits); |
| 2385 | } | 2747 | } |
| 2386 | 2748 | ||
| 2387 | static inline zig_u128 zig_bit_reverse_u128(zig_u128 val, uint8_t bits) { | 2749 | static inline zig_u128 zig_bitReverse_u128(zig_u128 arg, uint8_t bits) { |
| 2388 | return zig_shr_u128(zig_make_u128(zig_bit_reverse_u64(zig_lo_u128(val), UINT8_C(64)), | 2750 | return zig_shr_u128(zig_make_u128( |
| 2389 | zig_bit_reverse_u64(zig_hi_u128(val), UINT8_C(64))), | 2751 | zig_bitReverse_u64(zig_lo_u128(arg), UINT8_C(64)), |
| 2390 | UINT8_C(128) - bits); | 2752 | zig_bitReverse_u64(zig_hi_u128(arg), UINT8_C(64)) |
| 2753 | ), UINT8_C(128) - bits); | ||
| 2391 | } | 2754 | } |
| 2392 | 2755 | ||
| 2393 | static inline zig_i128 zig_bit_reverse_i128(zig_i128 val, uint8_t bits) { | 2756 | static inline zig_i128 zig_bitReverse_i128(zig_i128 arg, uint8_t bits) { |
| 2394 | return zig_bitCast_i128(zig_bit_reverse_u128(zig_bitCast_u128(val), bits)); | 2757 | return zig_i128_bitCast_u128(zig_bitReverse_u128(zig_u128_bitCast_i128(arg, bits), bits), bits); |
| 2395 | } | 2758 | } |
| 2396 | 2759 | ||
| 2397 | #if zig_has_int128 | 2760 | #if zig_has_int128 |
| ... | @@ -2411,15 +2774,218 @@ static inline zig_i128 zig_bit_reverse_i128(zig_i128 val, uint8_t bits) { | ... | @@ -2411,15 +2774,218 @@ static inline zig_i128 zig_bit_reverse_i128(zig_i128 val, uint8_t bits) { |
| 2411 | /* ========================== Big Integer Support =========================== */ | 2774 | /* ========================== Big Integer Support =========================== */ |
| 2412 | 2775 | ||
| 2413 | static inline uint16_t zig_int_bytes(uint16_t bits) { | 2776 | static inline uint16_t zig_int_bytes(uint16_t bits) { |
| 2414 | uint16_t bytes = (bits + CHAR_BIT - 1) / CHAR_BIT; | 2777 | uint16_t bytes = (bits - UINT16_C(1)) / CHAR_BIT + UINT16_C(1); |
| 2415 | uint16_t alignment = ZIG_TARGET_MAX_INT_ALIGNMENT; | 2778 | uint16_t alignment = ZIG_TARGET_MAX_INT_ALIGNMENT; |
| 2779 | |||
| 2416 | while (alignment / 2 >= bytes) alignment /= 2; | 2780 | while (alignment / 2 >= bytes) alignment /= 2; |
| 2417 | return (bytes + alignment - 1) / alignment * alignment; | 2781 | return (bytes + alignment - 1) / alignment * alignment; |
| 2418 | } | 2782 | } |
| 2419 | 2783 | ||
| 2420 | static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | 2784 | static inline void zig_minInt_big(void *res, bool is_signed, uint16_t bits) { |
| 2785 | uint8_t *res_bytes = res; | ||
| 2786 | uint16_t size = zig_int_bytes(bits); | ||
| 2787 | uint16_t byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)); | ||
| 2788 | uint16_t remainder_bits = zig_u8_truncate_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT8_C(1); | ||
| 2789 | uint8_t sign_byte; | ||
| 2790 | uint8_t fill_byte; | ||
| 2791 | |||
| 2792 | if (is_signed) { | ||
| 2793 | int8_t signed_sign_byte = zig_minInt_i(8, remainder_bits); | ||
| 2794 | |||
| 2795 | sign_byte = zig_u8_bitCast_i8(signed_sign_byte, UINT8_C(8)); | ||
| 2796 | fill_byte = zig_u8_bitCast_i8(zig_shr_i8(signed_sign_byte, UINT8_C(7)), UINT8_C(8)); | ||
| 2797 | } else { | ||
| 2798 | sign_byte = zig_minInt_u(8, remainder_bits); | ||
| 2799 | fill_byte = UINT8_C(0); | ||
| 2800 | } | ||
| 2801 | |||
| 2802 | #if zig_little_endian | ||
| 2803 | memset(&res_bytes[0], zig_minInt_u8, byte_offset); | ||
| 2804 | res_bytes[byte_offset] = sign_byte; | ||
| 2805 | byte_offset += UINT16_C(1); | ||
| 2806 | memset(&res_bytes[byte_offset], fill_byte, size - byte_offset); | ||
| 2807 | #else | ||
| 2808 | byte_offset = size - UINT16_C(1) - byte_offset; | ||
| 2809 | memset(&res_bytes[0], fill_byte, byte_offset); | ||
| 2810 | res_bytes[byte_offset] = sign_byte; | ||
| 2811 | byte_offset += UINT16_C(1); | ||
| 2812 | memset(&res_bytes[byte_offset], zig_minInt_u8, size - byte_offset); | ||
| 2813 | #endif | ||
| 2814 | } | ||
| 2815 | |||
| 2816 | static inline void zig_maxInt_big(void *res, bool is_signed, uint16_t bits) { | ||
| 2817 | uint8_t *res_bytes = res; | ||
| 2818 | uint16_t size = zig_int_bytes(bits); | ||
| 2819 | uint16_t byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)); | ||
| 2820 | uint16_t remainder_bits = zig_u8_truncate_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT8_C(1); | ||
| 2821 | uint8_t sign_byte; | ||
| 2822 | uint8_t fill_byte; | ||
| 2823 | |||
| 2824 | if (is_signed) { | ||
| 2825 | int8_t signed_sign_byte = zig_maxInt_i(8, remainder_bits); | ||
| 2826 | |||
| 2827 | sign_byte = zig_u8_bitCast_i8(signed_sign_byte, UINT8_C(8)); | ||
| 2828 | fill_byte = zig_u8_bitCast_i8(zig_shr_i8(signed_sign_byte, UINT8_C(7)), UINT8_C(8)); | ||
| 2829 | } else { | ||
| 2830 | sign_byte = zig_maxInt_u(8, remainder_bits); | ||
| 2831 | fill_byte = UINT8_C(0); | ||
| 2832 | } | ||
| 2833 | |||
| 2834 | #if zig_little_endian | ||
| 2835 | memset(&res_bytes[0], zig_maxInt_u8, byte_offset); | ||
| 2836 | res_bytes[byte_offset] = sign_byte; | ||
| 2837 | byte_offset += UINT16_C(1); | ||
| 2838 | memset(&res_bytes[byte_offset], fill_byte, size - byte_offset); | ||
| 2839 | #else | ||
| 2840 | byte_offset = size - UINT16_C(1) - byte_offset; | ||
| 2841 | memset(&res_bytes[0], fill_byte, byte_offset); | ||
| 2842 | res_bytes[byte_offset] = sign_byte; | ||
| 2843 | byte_offset += UINT16_C(1); | ||
| 2844 | memset(&res_bytes[byte_offset], zig_maxInt_u8, size - byte_offset); | ||
| 2845 | #endif | ||
| 2846 | } | ||
| 2847 | |||
| 2848 | static inline int8_t zig_signFill_big(const void *arg, bool is_signed, uint16_t bits) { | ||
| 2849 | const uint8_t *arg_bytes = arg; | ||
| 2850 | uint16_t byte_offset = 0; | ||
| 2851 | |||
| 2852 | if (!is_signed) return INT8_C(0); | ||
| 2853 | #if zig_little_endian | ||
| 2854 | byte_offset = zig_int_bytes(bits) - 1; | ||
| 2855 | #endif | ||
| 2856 | return zig_shr_i8(zig_i8_bitCast_u8(arg_bytes[byte_offset], UINT8_C(8)), UINT8_C(7)); | ||
| 2857 | } | ||
| 2858 | |||
| 2859 | static inline void zig_big_intCast_big(void *res, const void *arg, bool res_is_signed, uint16_t res_bits, bool arg_is_signed, uint16_t arg_bits) { | ||
| 2860 | uint8_t *res_bytes = res; | ||
| 2861 | const uint8_t *arg_bytes = arg; | ||
| 2862 | uint16_t res_size = zig_int_bytes(res_bits); | ||
| 2863 | uint16_t arg_size = zig_int_bytes(arg_bits); | ||
| 2864 | uint16_t copy_size = zig_min_u16(res_size, arg_size); | ||
| 2865 | uint8_t sign_fill = zig_u8_bitCast_i8(zig_signFill_big(arg, arg_is_signed, arg_bits), UINT8_C(8)); | ||
| 2866 | |||
| 2867 | #if zig_little_endian | ||
| 2868 | memcpy(&res_bytes[0], &arg_bytes[0], copy_size); | ||
| 2869 | memset(&res_bytes[copy_size], sign_fill, res_size - copy_size); | ||
| 2870 | #else | ||
| 2871 | memset(&res_bytes[0], sign_fill, res_size - copy_size); | ||
| 2872 | memcpy(&res_bytes[res_size - copy_size], &arg_bytes[arg_size - copy_size], copy_size); | ||
| 2873 | #endif | ||
| 2874 | } | ||
| 2875 | |||
| 2876 | static inline void zig_big_truncate_big(void *res, const void *arg, bool res_is_signed, uint16_t res_bits, bool arg_is_signed, uint16_t arg_bits) { | ||
| 2877 | uint8_t *res_bytes = res; | ||
| 2878 | const uint8_t *arg_bytes = arg; | ||
| 2879 | uint16_t res_size = zig_int_bytes(res_bits); | ||
| 2880 | |||
| 2881 | if (res_is_signed != arg_is_signed) zig_unreachable(); | ||
| 2882 | if (res_bits > arg_bits) zig_unreachable(); | ||
| 2883 | |||
| 2884 | if (res_is_signed) { | ||
| 2885 | uint16_t arg_byte_offset = UINT16_C(0); | ||
| 2886 | |||
| 2887 | #if zig_big_endian | ||
| 2888 | arg_byte_offset = zig_int_bytes(arg_bits) - res_size; | ||
| 2889 | #endif | ||
| 2890 | |||
| 2891 | memcpy(&res_bytes[0], &arg_bytes[arg_byte_offset], res_size); | ||
| 2892 | } else { | ||
| 2893 | uint16_t res_byte_offset = zig_shr_u16(res_bits - UINT16_C(1), UINT8_C(3)); | ||
| 2894 | uint16_t arg_byte_offset = res_byte_offset; | ||
| 2895 | |||
| 2896 | #if zig_little_endian | ||
| 2897 | memcpy(&res_bytes[0], &arg_bytes[0], res_byte_offset); | ||
| 2898 | #else | ||
| 2899 | res_byte_offset = res_size - UINT16_C(1) - res_byte_offset; | ||
| 2900 | arg_byte_offset = zig_int_bytes(arg_bits) - UINT16_C(1) - arg_byte_offset; | ||
| 2901 | |||
| 2902 | memset(&res_bytes[0], zig_minInt_u8, res_byte_offset); | ||
| 2903 | #endif | ||
| 2904 | |||
| 2905 | res_bytes[res_byte_offset] = zig_u8_truncate_u8( | ||
| 2906 | arg_bytes[arg_byte_offset], | ||
| 2907 | zig_u8_truncate_u8(res_bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1) | ||
| 2908 | ); | ||
| 2909 | res_byte_offset += UINT16_C(1); | ||
| 2910 | arg_byte_offset += UINT16_C(1); | ||
| 2911 | |||
| 2912 | #if zig_little_endian | ||
| 2913 | memset(&res_bytes[res_byte_offset], zig_minInt_u8, res_size - res_byte_offset); | ||
| 2914 | #else | ||
| 2915 | memcpy(&res_bytes[res_byte_offset], &arg_bytes[arg_byte_offset], res_size - res_byte_offset); | ||
| 2916 | #endif | ||
| 2917 | } | ||
| 2918 | } | ||
| 2919 | |||
| 2920 | #define zig_big_casts(is, s, w, IntType) \ | ||
| 2921 | static inline IntType zig_##s##w##_intCast_big(const void *arg, bool arg_is_signed, uint16_t arg_bits) { \ | ||
| 2922 | IntType res; \ | ||
| 2923 | zig_big_intCast_big(&res, arg, is, w, arg_is_signed, arg_bits); \ | ||
| 2924 | return res; \ | ||
| 2925 | } \ | ||
| 2926 | \ | ||
| 2927 | static inline void zig_big_intCast_##s##w(void *res, IntType arg, bool res_is_signed, uint16_t res_bits) { \ | ||
| 2928 | zig_big_intCast_big(res, &arg, res_is_signed, res_bits, is, w); \ | ||
| 2929 | } \ | ||
| 2930 | \ | ||
| 2931 | static inline IntType zig_##s##w##_truncate_big(const void *arg, uint8_t res_bits, bool arg_is_signed, uint16_t arg_bits) { \ | ||
| 2932 | IntType res; \ | ||
| 2933 | zig_big_truncate_big(&res, arg, is, res_bits, arg_is_signed, arg_bits); \ | ||
| 2934 | return res; \ | ||
| 2935 | } \ | ||
| 2936 | \ | ||
| 2937 | static inline void zig_big_truncate_##s##w(void *res, IntType arg, bool res_is_signed, uint16_t res_bits) { \ | ||
| 2938 | zig_big_truncate_big(res, &arg, res_is_signed, res_bits, is, w); \ | ||
| 2939 | } | ||
| 2940 | zig_big_casts(false, u, 8, uint8_t) | ||
| 2941 | zig_big_casts(true , i, 8, int8_t) | ||
| 2942 | zig_big_casts(false, u, 16, uint16_t) | ||
| 2943 | zig_big_casts(true , i, 16, int16_t) | ||
| 2944 | zig_big_casts(false, u, 32, uint32_t) | ||
| 2945 | zig_big_casts(true , i, 32, int32_t) | ||
| 2946 | zig_big_casts(false, u, 64, uint64_t) | ||
| 2947 | zig_big_casts(true , i, 64, int64_t) | ||
| 2948 | zig_big_casts(false, u, 128, zig_u128) | ||
| 2949 | zig_big_casts(true , i, 128, zig_i128) | ||
| 2950 | |||
| 2951 | static inline void zig_big_bitCast_big(void *res, const void *arg, bool res_is_signed, uint16_t bits) { | ||
| 2952 | uint8_t *res_bytes = res; | ||
| 2953 | const uint8_t *arg_bytes = arg; | ||
| 2954 | uint16_t size = zig_int_bytes(bits); | ||
| 2955 | uint16_t byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)); | ||
| 2956 | uint16_t remainder_bits = zig_u8_truncate_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT8_C(1); | ||
| 2957 | uint8_t sign_byte; | ||
| 2958 | uint8_t fill_byte; | ||
| 2959 | |||
| 2960 | #if zig_big_endian | ||
| 2961 | byte_offset = size - UINT16_C(1) - byte_offset; | ||
| 2962 | #endif | ||
| 2963 | |||
| 2964 | if (res_is_signed) { | ||
| 2965 | int8_t signed_sign_byte = zig_i8_bitCast_u8(arg_bytes[byte_offset], remainder_bits); | ||
| 2966 | |||
| 2967 | sign_byte = zig_u8_bitCast_i8(signed_sign_byte, UINT8_C(8)); | ||
| 2968 | fill_byte = zig_u8_bitCast_i8(zig_shr_i8(signed_sign_byte, UINT8_C(7)), UINT8_C(8)); | ||
| 2969 | } else { | ||
| 2970 | sign_byte = zig_u8_bitCast_u8(arg_bytes[byte_offset], remainder_bits); | ||
| 2971 | fill_byte = UINT8_C(0); | ||
| 2972 | } | ||
| 2973 | |||
| 2974 | #if zig_little_endian | ||
| 2975 | memcpy(&res_bytes[0], &arg_bytes[0], byte_offset); | ||
| 2976 | res_bytes[byte_offset] = sign_byte; | ||
| 2977 | byte_offset += UINT16_C(1); | ||
| 2978 | memset(&res_bytes[byte_offset], fill_byte, size - byte_offset); | ||
| 2979 | #else | ||
| 2980 | memset(&res_bytes[0], fill_byte, byte_offset); | ||
| 2981 | res_bytes[byte_offset] = sign_byte; | ||
| 2982 | byte_offset += UINT16_C(1); | ||
| 2983 | memcpy(&res_bytes[byte_offset], &arg_bytes[byte_offset], size - byte_offset); | ||
| 2984 | #endif | ||
| 2985 | } | ||
| 2986 | |||
| 2987 | static inline int32_t zig_cmp_big_u8(const void *lhs, uint8_t rhs, bool is_signed, uint16_t bits) { | ||
| 2421 | const uint8_t *lhs_bytes = lhs; | 2988 | const uint8_t *lhs_bytes = lhs; |
| 2422 | const uint8_t *rhs_bytes = rhs; | ||
| 2423 | uint16_t byte_offset = 0; | 2989 | uint16_t byte_offset = 0; |
| 2424 | bool do_signed = is_signed; | 2990 | bool do_signed = is_signed; |
| 2425 | uint16_t remaining_bytes = zig_int_bytes(bits); | 2991 | uint16_t remaining_bytes = zig_int_bytes(bits); |
| ... | @@ -2429,6 +2995,7 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign | ... | @@ -2429,6 +2995,7 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign |
| 2429 | #endif | 2995 | #endif |
| 2430 | 2996 | ||
| 2431 | while (remaining_bytes >= 128 / CHAR_BIT) { | 2997 | while (remaining_bytes >= 128 / CHAR_BIT) { |
| 2998 | uint8_t rhs_byte = remaining_bytes == 128 / CHAR_BIT ? rhs : UINT8_C(0); | ||
| 2432 | int32_t limb_cmp; | 2999 | int32_t limb_cmp; |
| 2433 | 3000 | ||
| 2434 | #if zig_little_endian | 3001 | #if zig_little_endian |
| ... | @@ -2437,18 +3004,16 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign | ... | @@ -2437,18 +3004,16 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign |
| 2437 | 3004 | ||
| 2438 | if (do_signed) { | 3005 | if (do_signed) { |
| 2439 | zig_i128 lhs_limb; | 3006 | zig_i128 lhs_limb; |
| 2440 | zig_i128 rhs_limb; | 3007 | zig_i128 rhs_limb = zig_i128_intCast_u8(rhs_byte); |
| 2441 | 3008 | ||
| 2442 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | 3009 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); |
| 2443 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 2444 | limb_cmp = zig_cmp_i128(lhs_limb, rhs_limb); | 3010 | limb_cmp = zig_cmp_i128(lhs_limb, rhs_limb); |
| 2445 | do_signed = false; | 3011 | do_signed = false; |
| 2446 | } else { | 3012 | } else { |
| 2447 | zig_u128 lhs_limb; | 3013 | zig_u128 lhs_limb; |
| 2448 | zig_u128 rhs_limb; | 3014 | zig_u128 rhs_limb = zig_u128_intCast_u8(rhs_byte); |
| 2449 | 3015 | ||
| 2450 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | 3016 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); |
| 2451 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 2452 | limb_cmp = zig_cmp_u128(lhs_limb, rhs_limb); | 3017 | limb_cmp = zig_cmp_u128(lhs_limb, rhs_limb); |
| 2453 | } | 3018 | } |
| 2454 | 3019 | ||
| ... | @@ -2461,24 +3026,24 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign | ... | @@ -2461,24 +3026,24 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign |
| 2461 | } | 3026 | } |
| 2462 | 3027 | ||
| 2463 | while (remaining_bytes >= 64 / CHAR_BIT) { | 3028 | while (remaining_bytes >= 64 / CHAR_BIT) { |
| 3029 | uint8_t rhs_byte = remaining_bytes == 64 / CHAR_BIT ? rhs : UINT8_C(0); | ||
| 3030 | |||
| 2464 | #if zig_little_endian | 3031 | #if zig_little_endian |
| 2465 | byte_offset -= 64 / CHAR_BIT; | 3032 | byte_offset -= 64 / CHAR_BIT; |
| 2466 | #endif | 3033 | #endif |
| 2467 | 3034 | ||
| 2468 | if (do_signed) { | 3035 | if (do_signed) { |
| 2469 | int64_t lhs_limb; | 3036 | int64_t lhs_limb; |
| 2470 | int64_t rhs_limb; | 3037 | int64_t rhs_limb = zig_i64_intCast_u8(rhs_byte); |
| 2471 | 3038 | ||
| 2472 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | 3039 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); |
| 2473 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 2474 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); | 3040 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); |
| 2475 | do_signed = false; | 3041 | do_signed = false; |
| 2476 | } else { | 3042 | } else { |
| 2477 | uint64_t lhs_limb; | 3043 | uint64_t lhs_limb; |
| 2478 | uint64_t rhs_limb; | 3044 | uint64_t rhs_limb = zig_u64_intCast_u8(rhs_byte); |
| 2479 | 3045 | ||
| 2480 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | 3046 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); |
| 2481 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 2482 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); | 3047 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); |
| 2483 | } | 3048 | } |
| 2484 | 3049 | ||
| ... | @@ -2490,24 +3055,24 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign | ... | @@ -2490,24 +3055,24 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign |
| 2490 | } | 3055 | } |
| 2491 | 3056 | ||
| 2492 | while (remaining_bytes >= 32 / CHAR_BIT) { | 3057 | while (remaining_bytes >= 32 / CHAR_BIT) { |
| 3058 | uint8_t rhs_byte = remaining_bytes == 32 / CHAR_BIT ? rhs : UINT8_C(0); | ||
| 3059 | |||
| 2493 | #if zig_little_endian | 3060 | #if zig_little_endian |
| 2494 | byte_offset -= 32 / CHAR_BIT; | 3061 | byte_offset -= 32 / CHAR_BIT; |
| 2495 | #endif | 3062 | #endif |
| 2496 | 3063 | ||
| 2497 | if (do_signed) { | 3064 | if (do_signed) { |
| 2498 | int32_t lhs_limb; | 3065 | int32_t lhs_limb; |
| 2499 | int32_t rhs_limb; | 3066 | int32_t rhs_limb = zig_i32_intCast_u8(rhs_byte); |
| 2500 | 3067 | ||
| 2501 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | 3068 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); |
| 2502 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 2503 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); | 3069 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); |
| 2504 | do_signed = false; | 3070 | do_signed = false; |
| 2505 | } else { | 3071 | } else { |
| 2506 | uint32_t lhs_limb; | 3072 | uint32_t lhs_limb; |
| 2507 | uint32_t rhs_limb; | 3073 | uint32_t rhs_limb = zig_u32_intCast_u8(rhs_byte); |
| 2508 | 3074 | ||
| 2509 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | 3075 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); |
| 2510 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 2511 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); | 3076 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); |
| 2512 | } | 3077 | } |
| 2513 | 3078 | ||
| ... | @@ -2519,24 +3084,24 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign | ... | @@ -2519,24 +3084,24 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign |
| 2519 | } | 3084 | } |
| 2520 | 3085 | ||
| 2521 | while (remaining_bytes >= 16 / CHAR_BIT) { | 3086 | while (remaining_bytes >= 16 / CHAR_BIT) { |
| 3087 | uint8_t rhs_byte = remaining_bytes == 16 / CHAR_BIT ? rhs : UINT8_C(0); | ||
| 3088 | |||
| 2522 | #if zig_little_endian | 3089 | #if zig_little_endian |
| 2523 | byte_offset -= 16 / CHAR_BIT; | 3090 | byte_offset -= 16 / CHAR_BIT; |
| 2524 | #endif | 3091 | #endif |
| 2525 | 3092 | ||
| 2526 | if (do_signed) { | 3093 | if (do_signed) { |
| 2527 | int16_t lhs_limb; | 3094 | int16_t lhs_limb; |
| 2528 | int16_t rhs_limb; | 3095 | int16_t rhs_limb = zig_i16_intCast_u8(rhs_byte); |
| 2529 | 3096 | ||
| 2530 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | 3097 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); |
| 2531 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 2532 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); | 3098 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); |
| 2533 | do_signed = false; | 3099 | do_signed = false; |
| 2534 | } else { | 3100 | } else { |
| 2535 | uint16_t lhs_limb; | 3101 | uint16_t lhs_limb; |
| 2536 | uint16_t rhs_limb; | 3102 | uint16_t rhs_limb = zig_u16_intCast_u8(rhs_byte); |
| 2537 | 3103 | ||
| 2538 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | 3104 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); |
| 2539 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 2540 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); | 3105 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); |
| 2541 | } | 3106 | } |
| 2542 | 3107 | ||
| ... | @@ -2548,24 +3113,26 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign | ... | @@ -2548,24 +3113,26 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign |
| 2548 | } | 3113 | } |
| 2549 | 3114 | ||
| 2550 | while (remaining_bytes >= 8 / CHAR_BIT) { | 3115 | while (remaining_bytes >= 8 / CHAR_BIT) { |
| 3116 | uint8_t rhs_byte = remaining_bytes == 16 / CHAR_BIT ? rhs : UINT8_C(0); | ||
| 3117 | |||
| 2551 | #if zig_little_endian | 3118 | #if zig_little_endian |
| 2552 | byte_offset -= 8 / CHAR_BIT; | 3119 | byte_offset -= 8 / CHAR_BIT; |
| 2553 | #endif | 3120 | #endif |
| 2554 | 3121 | ||
| 2555 | if (do_signed) { | 3122 | if (do_signed) { |
| 2556 | int8_t lhs_limb; | 3123 | int8_t lhs_limb; |
| 2557 | int8_t rhs_limb; | 3124 | int16_t lhs_cmp_limb; |
| 3125 | int16_t rhs_cmp_limb = zig_i16_intCast_u8(rhs_byte); | ||
| 2558 | 3126 | ||
| 2559 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | 3127 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); |
| 2560 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | 3128 | lhs_cmp_limb = zig_i16_intCast_i8(lhs_limb); |
| 2561 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); | 3129 | if (lhs_cmp_limb != rhs_cmp_limb) return (lhs_cmp_limb > rhs_cmp_limb) - (lhs_cmp_limb < rhs_cmp_limb); |
| 2562 | do_signed = false; | 3130 | do_signed = false; |
| 2563 | } else { | 3131 | } else { |
| 2564 | uint8_t lhs_limb; | 3132 | uint8_t lhs_limb; |
| 2565 | uint8_t rhs_limb; | 3133 | uint8_t rhs_limb = rhs_byte; |
| 2566 | 3134 | ||
| 2567 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | 3135 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); |
| 2568 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 2569 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); | 3136 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); |
| 2570 | } | 3137 | } |
| 2571 | 3138 | ||
| ... | @@ -2579,148 +3146,472 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign | ... | @@ -2579,148 +3146,472 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign |
| 2579 | return 0; | 3146 | return 0; |
| 2580 | } | 3147 | } |
| 2581 | 3148 | ||
| 2582 | static inline void zig_and_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | 3149 | static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { |
| 2583 | uint8_t *res_bytes = res; | ||
| 2584 | const uint8_t *lhs_bytes = lhs; | 3150 | const uint8_t *lhs_bytes = lhs; |
| 2585 | const uint8_t *rhs_bytes = rhs; | 3151 | const uint8_t *rhs_bytes = rhs; |
| 2586 | uint16_t byte_offset = 0; | 3152 | uint16_t byte_offset = 0; |
| 3153 | bool do_signed = is_signed; | ||
| 2587 | uint16_t remaining_bytes = zig_int_bytes(bits); | 3154 | uint16_t remaining_bytes = zig_int_bytes(bits); |
| 2588 | (void)is_signed; | 3155 | |
| 3156 | #if zig_little_endian | ||
| 3157 | byte_offset = remaining_bytes; | ||
| 3158 | #endif | ||
| 2589 | 3159 | ||
| 2590 | while (remaining_bytes >= 128 / CHAR_BIT) { | 3160 | while (remaining_bytes >= 128 / CHAR_BIT) { |
| 2591 | zig_u128 res_limb; | 3161 | int32_t limb_cmp; |
| 2592 | zig_u128 lhs_limb; | ||
| 2593 | zig_u128 rhs_limb; | ||
| 2594 | 3162 | ||
| 2595 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | 3163 | #if zig_little_endian |
| 2596 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | 3164 | byte_offset -= 128 / CHAR_BIT; |
| 2597 | res_limb = zig_and_u128(lhs_limb, rhs_limb); | 3165 | #endif |
| 2598 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | 3166 | |
| 3167 | if (do_signed) { | ||
| 3168 | zig_i128 lhs_limb; | ||
| 3169 | zig_i128 rhs_limb; | ||
| 3170 | |||
| 3171 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | ||
| 3172 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 3173 | limb_cmp = zig_cmp_i128(lhs_limb, rhs_limb); | ||
| 3174 | do_signed = false; | ||
| 3175 | } else { | ||
| 3176 | zig_u128 lhs_limb; | ||
| 3177 | zig_u128 rhs_limb; | ||
| 3178 | |||
| 3179 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | ||
| 3180 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 3181 | limb_cmp = zig_cmp_u128(lhs_limb, rhs_limb); | ||
| 3182 | } | ||
| 2599 | 3183 | ||
| 3184 | if (limb_cmp != 0) return limb_cmp; | ||
| 2600 | remaining_bytes -= 128 / CHAR_BIT; | 3185 | remaining_bytes -= 128 / CHAR_BIT; |
| 3186 | |||
| 3187 | #if zig_big_endian | ||
| 2601 | byte_offset += 128 / CHAR_BIT; | 3188 | byte_offset += 128 / CHAR_BIT; |
| 3189 | #endif | ||
| 2602 | } | 3190 | } |
| 2603 | 3191 | ||
| 2604 | while (remaining_bytes >= 64 / CHAR_BIT) { | 3192 | while (remaining_bytes >= 64 / CHAR_BIT) { |
| 2605 | uint64_t res_limb; | 3193 | #if zig_little_endian |
| 2606 | uint64_t lhs_limb; | 3194 | byte_offset -= 64 / CHAR_BIT; |
| 2607 | uint64_t rhs_limb; | 3195 | #endif |
| 2608 | 3196 | ||
| 2609 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | 3197 | if (do_signed) { |
| 2610 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | 3198 | int64_t lhs_limb; |
| 2611 | res_limb = zig_and_u64(lhs_limb, rhs_limb); | 3199 | int64_t rhs_limb; |
| 2612 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | 3200 | |
| 3201 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | ||
| 3202 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 3203 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); | ||
| 3204 | do_signed = false; | ||
| 3205 | } else { | ||
| 3206 | uint64_t lhs_limb; | ||
| 3207 | uint64_t rhs_limb; | ||
| 3208 | |||
| 3209 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | ||
| 3210 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 3211 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); | ||
| 3212 | } | ||
| 2613 | 3213 | ||
| 2614 | remaining_bytes -= 64 / CHAR_BIT; | 3214 | remaining_bytes -= 64 / CHAR_BIT; |
| 3215 | |||
| 3216 | #if zig_big_endian | ||
| 2615 | byte_offset += 64 / CHAR_BIT; | 3217 | byte_offset += 64 / CHAR_BIT; |
| 3218 | #endif | ||
| 2616 | } | 3219 | } |
| 2617 | 3220 | ||
| 2618 | while (remaining_bytes >= 32 / CHAR_BIT) { | 3221 | while (remaining_bytes >= 32 / CHAR_BIT) { |
| 2619 | uint32_t res_limb; | 3222 | #if zig_little_endian |
| 2620 | uint32_t lhs_limb; | 3223 | byte_offset -= 32 / CHAR_BIT; |
| 2621 | uint32_t rhs_limb; | 3224 | #endif |
| 2622 | 3225 | ||
| 2623 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | 3226 | if (do_signed) { |
| 2624 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | 3227 | int32_t lhs_limb; |
| 2625 | res_limb = zig_and_u32(lhs_limb, rhs_limb); | 3228 | int32_t rhs_limb; |
| 2626 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | 3229 | |
| 3230 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | ||
| 3231 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 3232 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); | ||
| 3233 | do_signed = false; | ||
| 3234 | } else { | ||
| 3235 | uint32_t lhs_limb; | ||
| 3236 | uint32_t rhs_limb; | ||
| 3237 | |||
| 3238 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | ||
| 3239 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 3240 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); | ||
| 3241 | } | ||
| 2627 | 3242 | ||
| 2628 | remaining_bytes -= 32 / CHAR_BIT; | 3243 | remaining_bytes -= 32 / CHAR_BIT; |
| 3244 | |||
| 3245 | #if zig_big_endian | ||
| 2629 | byte_offset += 32 / CHAR_BIT; | 3246 | byte_offset += 32 / CHAR_BIT; |
| 3247 | #endif | ||
| 2630 | } | 3248 | } |
| 2631 | 3249 | ||
| 2632 | while (remaining_bytes >= 16 / CHAR_BIT) { | 3250 | while (remaining_bytes >= 16 / CHAR_BIT) { |
| 2633 | uint16_t res_limb; | 3251 | #if zig_little_endian |
| 2634 | uint16_t lhs_limb; | 3252 | byte_offset -= 16 / CHAR_BIT; |
| 2635 | uint16_t rhs_limb; | 3253 | #endif |
| 2636 | 3254 | ||
| 2637 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | 3255 | if (do_signed) { |
| 2638 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | 3256 | int16_t lhs_limb; |
| 2639 | res_limb = zig_and_u16(lhs_limb, rhs_limb); | 3257 | int16_t rhs_limb; |
| 2640 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | 3258 | |
| 3259 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | ||
| 3260 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 3261 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); | ||
| 3262 | do_signed = false; | ||
| 3263 | } else { | ||
| 3264 | uint16_t lhs_limb; | ||
| 3265 | uint16_t rhs_limb; | ||
| 3266 | |||
| 3267 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | ||
| 3268 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 3269 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); | ||
| 3270 | } | ||
| 2641 | 3271 | ||
| 2642 | remaining_bytes -= 16 / CHAR_BIT; | 3272 | remaining_bytes -= 16 / CHAR_BIT; |
| 3273 | |||
| 3274 | #if zig_big_endian | ||
| 2643 | byte_offset += 16 / CHAR_BIT; | 3275 | byte_offset += 16 / CHAR_BIT; |
| 3276 | #endif | ||
| 2644 | } | 3277 | } |
| 2645 | 3278 | ||
| 2646 | while (remaining_bytes >= 8 / CHAR_BIT) { | 3279 | while (remaining_bytes >= 8 / CHAR_BIT) { |
| 2647 | uint8_t res_limb; | 3280 | #if zig_little_endian |
| 2648 | uint8_t lhs_limb; | 3281 | byte_offset -= 8 / CHAR_BIT; |
| 2649 | uint8_t rhs_limb; | 3282 | #endif |
| 2650 | 3283 | ||
| 2651 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | 3284 | if (do_signed) { |
| 2652 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | 3285 | int8_t lhs_limb; |
| 2653 | res_limb = zig_and_u8(lhs_limb, rhs_limb); | 3286 | int8_t rhs_limb; |
| 2654 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | 3287 | |
| 3288 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | ||
| 3289 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 3290 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); | ||
| 3291 | do_signed = false; | ||
| 3292 | } else { | ||
| 3293 | uint8_t lhs_limb; | ||
| 3294 | uint8_t rhs_limb; | ||
| 3295 | |||
| 3296 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | ||
| 3297 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 3298 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); | ||
| 3299 | } | ||
| 2655 | 3300 | ||
| 2656 | remaining_bytes -= 8 / CHAR_BIT; | 3301 | remaining_bytes -= 8 / CHAR_BIT; |
| 3302 | |||
| 3303 | #if zig_big_endian | ||
| 2657 | byte_offset += 8 / CHAR_BIT; | 3304 | byte_offset += 8 / CHAR_BIT; |
| 3305 | #endif | ||
| 2658 | } | 3306 | } |
| 3307 | |||
| 3308 | return 0; | ||
| 2659 | } | 3309 | } |
| 2660 | 3310 | ||
| 2661 | static inline void zig_or_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | 3311 | static inline void zig_not_big(void *res, const void *arg, bool is_signed, uint16_t bits) { |
| 2662 | uint8_t *res_bytes = res; | 3312 | uint8_t *res_bytes = res; |
| 2663 | const uint8_t *lhs_bytes = lhs; | 3313 | const uint8_t *arg_bytes = arg; |
| 2664 | const uint8_t *rhs_bytes = rhs; | ||
| 2665 | uint16_t byte_offset = 0; | 3314 | uint16_t byte_offset = 0; |
| 2666 | uint16_t remaining_bytes = zig_int_bytes(bits); | 3315 | uint16_t remaining_bytes = zig_int_bytes(bits); |
| 2667 | (void)is_signed; | 3316 | uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits); |
| 3317 | |||
| 3318 | #if zig_big_endian | ||
| 3319 | byte_offset = remaining_bytes; | ||
| 3320 | #endif | ||
| 2668 | 3321 | ||
| 2669 | while (remaining_bytes >= 128 / CHAR_BIT) { | 3322 | while (remaining_bytes >= 128 / CHAR_BIT) { |
| 2670 | zig_u128 res_limb; | 3323 | uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0); |
| 2671 | zig_u128 lhs_limb; | ||
| 2672 | zig_u128 rhs_limb; | ||
| 2673 | 3324 | ||
| 2674 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | 3325 | #if zig_big_endian |
| 2675 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | 3326 | byte_offset -= 128 / CHAR_BIT; |
| 2676 | res_limb = zig_or_u128(lhs_limb, rhs_limb); | 3327 | #endif |
| 2677 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | 3328 | |
| 3329 | if (remaining_bytes != 128 / CHAR_BIT || is_signed) { | ||
| 3330 | zig_i128 res_limb; | ||
| 3331 | zig_i128 arg_limb; | ||
| 3332 | |||
| 3333 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); | ||
| 3334 | res_limb = zig_not_i128(arg_limb, limb_bits); | ||
| 3335 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3336 | } else { | ||
| 3337 | zig_u128 res_limb; | ||
| 3338 | zig_u128 arg_limb; | ||
| 3339 | |||
| 3340 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); | ||
| 3341 | res_limb = zig_not_u128(arg_limb, limb_bits); | ||
| 3342 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3343 | } | ||
| 2678 | 3344 | ||
| 2679 | remaining_bytes -= 128 / CHAR_BIT; | 3345 | remaining_bytes -= 128 / CHAR_BIT; |
| 3346 | |||
| 3347 | #if zig_little_endian | ||
| 2680 | byte_offset += 128 / CHAR_BIT; | 3348 | byte_offset += 128 / CHAR_BIT; |
| 3349 | #endif | ||
| 2681 | } | 3350 | } |
| 2682 | 3351 | ||
| 2683 | while (remaining_bytes >= 64 / CHAR_BIT) { | 3352 | while (remaining_bytes >= 64 / CHAR_BIT) { |
| 2684 | uint64_t res_limb; | 3353 | uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0); |
| 2685 | uint64_t lhs_limb; | ||
| 2686 | uint64_t rhs_limb; | ||
| 2687 | 3354 | ||
| 2688 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | 3355 | #if zig_big_endian |
| 2689 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | 3356 | byte_offset -= 64 / CHAR_BIT; |
| 2690 | res_limb = zig_or_u64(lhs_limb, rhs_limb); | 3357 | #endif |
| 2691 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | 3358 | |
| 3359 | if (remaining_bytes != 64 / CHAR_BIT || is_signed) { | ||
| 3360 | int64_t res_limb; | ||
| 3361 | int64_t arg_limb; | ||
| 3362 | |||
| 3363 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); | ||
| 3364 | res_limb = zig_not_i64(arg_limb, limb_bits); | ||
| 3365 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3366 | } else { | ||
| 3367 | uint64_t res_limb; | ||
| 3368 | uint64_t arg_limb; | ||
| 3369 | |||
| 3370 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); | ||
| 3371 | res_limb = zig_not_u64(arg_limb, limb_bits); | ||
| 3372 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3373 | } | ||
| 2692 | 3374 | ||
| 2693 | remaining_bytes -= 64 / CHAR_BIT; | 3375 | remaining_bytes -= 64 / CHAR_BIT; |
| 3376 | |||
| 3377 | #if zig_little_endian | ||
| 2694 | byte_offset += 64 / CHAR_BIT; | 3378 | byte_offset += 64 / CHAR_BIT; |
| 3379 | #endif | ||
| 2695 | } | 3380 | } |
| 2696 | 3381 | ||
| 2697 | while (remaining_bytes >= 32 / CHAR_BIT) { | 3382 | while (remaining_bytes >= 32 / CHAR_BIT) { |
| 2698 | uint32_t res_limb; | 3383 | uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0); |
| 2699 | uint32_t lhs_limb; | ||
| 2700 | uint32_t rhs_limb; | ||
| 2701 | 3384 | ||
| 2702 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | 3385 | #if zig_big_endian |
| 2703 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | 3386 | byte_offset -= 32 / CHAR_BIT; |
| 2704 | res_limb = zig_or_u32(lhs_limb, rhs_limb); | 3387 | #endif |
| 2705 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | 3388 | |
| 3389 | if (remaining_bytes != 32 / CHAR_BIT || is_signed) { | ||
| 3390 | int32_t res_limb; | ||
| 3391 | int32_t arg_limb; | ||
| 3392 | |||
| 3393 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); | ||
| 3394 | res_limb = zig_not_i32(arg_limb, limb_bits); | ||
| 3395 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3396 | } else { | ||
| 3397 | uint32_t res_limb; | ||
| 3398 | uint32_t arg_limb; | ||
| 3399 | |||
| 3400 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); | ||
| 3401 | res_limb = zig_not_u32(arg_limb, limb_bits); | ||
| 3402 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3403 | } | ||
| 2706 | 3404 | ||
| 2707 | remaining_bytes -= 32 / CHAR_BIT; | 3405 | remaining_bytes -= 32 / CHAR_BIT; |
| 3406 | |||
| 3407 | #if zig_little_endian | ||
| 2708 | byte_offset += 32 / CHAR_BIT; | 3408 | byte_offset += 32 / CHAR_BIT; |
| 3409 | #endif | ||
| 2709 | } | 3410 | } |
| 2710 | 3411 | ||
| 2711 | while (remaining_bytes >= 16 / CHAR_BIT) { | 3412 | while (remaining_bytes >= 16 / CHAR_BIT) { |
| 2712 | uint16_t res_limb; | 3413 | uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0); |
| 2713 | uint16_t lhs_limb; | ||
| 2714 | uint16_t rhs_limb; | ||
| 2715 | 3414 | ||
| 2716 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | 3415 | #if zig_big_endian |
| 2717 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | 3416 | byte_offset -= 16 / CHAR_BIT; |
| 2718 | res_limb = zig_or_u16(lhs_limb, rhs_limb); | 3417 | #endif |
| 2719 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 2720 | 3418 | ||
| 2721 | remaining_bytes -= 16 / CHAR_BIT; | 3419 | if (remaining_bytes != 16 / CHAR_BIT || is_signed) { |
| 2722 | byte_offset += 16 / CHAR_BIT; | 3420 | int16_t res_limb; |
| 2723 | } | 3421 | int16_t arg_limb; |
| 3422 | |||
| 3423 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); | ||
| 3424 | res_limb = zig_not_i16(arg_limb, limb_bits); | ||
| 3425 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3426 | } else { | ||
| 3427 | uint16_t res_limb; | ||
| 3428 | uint16_t arg_limb; | ||
| 3429 | |||
| 3430 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); | ||
| 3431 | res_limb = zig_not_u16(arg_limb, limb_bits); | ||
| 3432 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3433 | } | ||
| 3434 | |||
| 3435 | remaining_bytes -= 16 / CHAR_BIT; | ||
| 3436 | |||
| 3437 | #if zig_little_endian | ||
| 3438 | byte_offset += 16 / CHAR_BIT; | ||
| 3439 | #endif | ||
| 3440 | } | ||
| 3441 | |||
| 3442 | while (remaining_bytes >= 8 / CHAR_BIT) { | ||
| 3443 | uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0); | ||
| 3444 | |||
| 3445 | #if zig_big_endian | ||
| 3446 | byte_offset -= 8 / CHAR_BIT; | ||
| 3447 | #endif | ||
| 3448 | |||
| 3449 | if (remaining_bytes != 8 / CHAR_BIT || is_signed) { | ||
| 3450 | int8_t res_limb; | ||
| 3451 | int8_t arg_limb; | ||
| 3452 | |||
| 3453 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); | ||
| 3454 | res_limb = zig_not_i8(arg_limb, limb_bits); | ||
| 3455 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3456 | } else { | ||
| 3457 | uint8_t res_limb; | ||
| 3458 | uint8_t arg_limb; | ||
| 3459 | |||
| 3460 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); | ||
| 3461 | res_limb = zig_not_u8(arg_limb, limb_bits); | ||
| 3462 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3463 | } | ||
| 3464 | |||
| 3465 | remaining_bytes -= 8 / CHAR_BIT; | ||
| 3466 | |||
| 3467 | #if zig_little_endian | ||
| 3468 | byte_offset += 8 / CHAR_BIT; | ||
| 3469 | #endif | ||
| 3470 | } | ||
| 3471 | } | ||
| 3472 | |||
| 3473 | static inline void zig_and_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | ||
| 3474 | uint8_t *res_bytes = res; | ||
| 3475 | const uint8_t *lhs_bytes = lhs; | ||
| 3476 | const uint8_t *rhs_bytes = rhs; | ||
| 3477 | uint16_t byte_offset = 0; | ||
| 3478 | uint16_t remaining_bytes = zig_int_bytes(bits); | ||
| 3479 | (void)is_signed; | ||
| 3480 | |||
| 3481 | while (remaining_bytes >= 128 / CHAR_BIT) { | ||
| 3482 | zig_u128 res_limb; | ||
| 3483 | zig_u128 lhs_limb; | ||
| 3484 | zig_u128 rhs_limb; | ||
| 3485 | |||
| 3486 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | ||
| 3487 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 3488 | res_limb = zig_and_u128(lhs_limb, rhs_limb); | ||
| 3489 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3490 | |||
| 3491 | remaining_bytes -= 128 / CHAR_BIT; | ||
| 3492 | byte_offset += 128 / CHAR_BIT; | ||
| 3493 | } | ||
| 3494 | |||
| 3495 | while (remaining_bytes >= 64 / CHAR_BIT) { | ||
| 3496 | uint64_t res_limb; | ||
| 3497 | uint64_t lhs_limb; | ||
| 3498 | uint64_t rhs_limb; | ||
| 3499 | |||
| 3500 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | ||
| 3501 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 3502 | res_limb = zig_and_u64(lhs_limb, rhs_limb); | ||
| 3503 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3504 | |||
| 3505 | remaining_bytes -= 64 / CHAR_BIT; | ||
| 3506 | byte_offset += 64 / CHAR_BIT; | ||
| 3507 | } | ||
| 3508 | |||
| 3509 | while (remaining_bytes >= 32 / CHAR_BIT) { | ||
| 3510 | uint32_t res_limb; | ||
| 3511 | uint32_t lhs_limb; | ||
| 3512 | uint32_t rhs_limb; | ||
| 3513 | |||
| 3514 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | ||
| 3515 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 3516 | res_limb = zig_and_u32(lhs_limb, rhs_limb); | ||
| 3517 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3518 | |||
| 3519 | remaining_bytes -= 32 / CHAR_BIT; | ||
| 3520 | byte_offset += 32 / CHAR_BIT; | ||
| 3521 | } | ||
| 3522 | |||
| 3523 | while (remaining_bytes >= 16 / CHAR_BIT) { | ||
| 3524 | uint16_t res_limb; | ||
| 3525 | uint16_t lhs_limb; | ||
| 3526 | uint16_t rhs_limb; | ||
| 3527 | |||
| 3528 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | ||
| 3529 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 3530 | res_limb = zig_and_u16(lhs_limb, rhs_limb); | ||
| 3531 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3532 | |||
| 3533 | remaining_bytes -= 16 / CHAR_BIT; | ||
| 3534 | byte_offset += 16 / CHAR_BIT; | ||
| 3535 | } | ||
| 3536 | |||
| 3537 | while (remaining_bytes >= 8 / CHAR_BIT) { | ||
| 3538 | uint8_t res_limb; | ||
| 3539 | uint8_t lhs_limb; | ||
| 3540 | uint8_t rhs_limb; | ||
| 3541 | |||
| 3542 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | ||
| 3543 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 3544 | res_limb = zig_and_u8(lhs_limb, rhs_limb); | ||
| 3545 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3546 | |||
| 3547 | remaining_bytes -= 8 / CHAR_BIT; | ||
| 3548 | byte_offset += 8 / CHAR_BIT; | ||
| 3549 | } | ||
| 3550 | } | ||
| 3551 | |||
| 3552 | static inline void zig_or_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | ||
| 3553 | uint8_t *res_bytes = res; | ||
| 3554 | const uint8_t *lhs_bytes = lhs; | ||
| 3555 | const uint8_t *rhs_bytes = rhs; | ||
| 3556 | uint16_t byte_offset = 0; | ||
| 3557 | uint16_t remaining_bytes = zig_int_bytes(bits); | ||
| 3558 | (void)is_signed; | ||
| 3559 | |||
| 3560 | while (remaining_bytes >= 128 / CHAR_BIT) { | ||
| 3561 | zig_u128 res_limb; | ||
| 3562 | zig_u128 lhs_limb; | ||
| 3563 | zig_u128 rhs_limb; | ||
| 3564 | |||
| 3565 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | ||
| 3566 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 3567 | res_limb = zig_or_u128(lhs_limb, rhs_limb); | ||
| 3568 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3569 | |||
| 3570 | remaining_bytes -= 128 / CHAR_BIT; | ||
| 3571 | byte_offset += 128 / CHAR_BIT; | ||
| 3572 | } | ||
| 3573 | |||
| 3574 | while (remaining_bytes >= 64 / CHAR_BIT) { | ||
| 3575 | uint64_t res_limb; | ||
| 3576 | uint64_t lhs_limb; | ||
| 3577 | uint64_t rhs_limb; | ||
| 3578 | |||
| 3579 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | ||
| 3580 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 3581 | res_limb = zig_or_u64(lhs_limb, rhs_limb); | ||
| 3582 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3583 | |||
| 3584 | remaining_bytes -= 64 / CHAR_BIT; | ||
| 3585 | byte_offset += 64 / CHAR_BIT; | ||
| 3586 | } | ||
| 3587 | |||
| 3588 | while (remaining_bytes >= 32 / CHAR_BIT) { | ||
| 3589 | uint32_t res_limb; | ||
| 3590 | uint32_t lhs_limb; | ||
| 3591 | uint32_t rhs_limb; | ||
| 3592 | |||
| 3593 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | ||
| 3594 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 3595 | res_limb = zig_or_u32(lhs_limb, rhs_limb); | ||
| 3596 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3597 | |||
| 3598 | remaining_bytes -= 32 / CHAR_BIT; | ||
| 3599 | byte_offset += 32 / CHAR_BIT; | ||
| 3600 | } | ||
| 3601 | |||
| 3602 | while (remaining_bytes >= 16 / CHAR_BIT) { | ||
| 3603 | uint16_t res_limb; | ||
| 3604 | uint16_t lhs_limb; | ||
| 3605 | uint16_t rhs_limb; | ||
| 3606 | |||
| 3607 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | ||
| 3608 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | ||
| 3609 | res_limb = zig_or_u16(lhs_limb, rhs_limb); | ||
| 3610 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3611 | |||
| 3612 | remaining_bytes -= 16 / CHAR_BIT; | ||
| 3613 | byte_offset += 16 / CHAR_BIT; | ||
| 3614 | } | ||
| 2724 | 3615 | ||
| 2725 | while (remaining_bytes >= 8 / CHAR_BIT) { | 3616 | while (remaining_bytes >= 8 / CHAR_BIT) { |
| 2726 | uint8_t res_limb; | 3617 | uint8_t res_limb; |
| ... | @@ -2816,13 +3707,415 @@ static inline void zig_xor_big(void *res, const void *lhs, const void *rhs, bool | ... | @@ -2816,13 +3707,415 @@ static inline void zig_xor_big(void *res, const void *lhs, const void *rhs, bool |
| 2816 | } | 3707 | } |
| 2817 | } | 3708 | } |
| 2818 | 3709 | ||
| 3710 | static inline void zig_increment_big(void *res, bool is_signed, uint16_t bits) { | ||
| 3711 | uint8_t *res_bytes = res; | ||
| 3712 | uint16_t byte_offset = 0; | ||
| 3713 | uint16_t remaining_bytes = zig_int_bytes(bits); | ||
| 3714 | uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits); | ||
| 3715 | |||
| 3716 | #if zig_big_endian | ||
| 3717 | byte_offset = remaining_bytes; | ||
| 3718 | #endif | ||
| 3719 | |||
| 3720 | while (remaining_bytes >= 128 / CHAR_BIT) { | ||
| 3721 | uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0); | ||
| 3722 | |||
| 3723 | #if zig_big_endian | ||
| 3724 | byte_offset -= 128 / CHAR_BIT; | ||
| 3725 | #endif | ||
| 3726 | |||
| 3727 | { | ||
| 3728 | zig_u128 res_limb; | ||
| 3729 | bool limb_overflow; | ||
| 3730 | |||
| 3731 | memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb)); | ||
| 3732 | limb_overflow = zig_addo_u128(&res_limb, res_limb, zig_make_u128(UINT64_C(0), UINT64_C(1)), limb_bits); | ||
| 3733 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3734 | if (!limb_overflow) return; | ||
| 3735 | } | ||
| 3736 | |||
| 3737 | remaining_bytes -= 128 / CHAR_BIT; | ||
| 3738 | |||
| 3739 | #if zig_little_endian | ||
| 3740 | byte_offset += 128 / CHAR_BIT; | ||
| 3741 | #endif | ||
| 3742 | } | ||
| 3743 | |||
| 3744 | while (remaining_bytes >= 64 / CHAR_BIT) { | ||
| 3745 | uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0); | ||
| 3746 | |||
| 3747 | #if zig_big_endian | ||
| 3748 | byte_offset -= 64 / CHAR_BIT; | ||
| 3749 | #endif | ||
| 3750 | |||
| 3751 | { | ||
| 3752 | uint64_t res_limb; | ||
| 3753 | bool limb_overflow; | ||
| 3754 | |||
| 3755 | memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb)); | ||
| 3756 | limb_overflow = zig_addo_u64(&res_limb, res_limb, UINT64_C(1), limb_bits); | ||
| 3757 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3758 | if (!limb_overflow) return; | ||
| 3759 | } | ||
| 3760 | |||
| 3761 | remaining_bytes -= 64 / CHAR_BIT; | ||
| 3762 | |||
| 3763 | #if zig_little_endian | ||
| 3764 | byte_offset += 64 / CHAR_BIT; | ||
| 3765 | #endif | ||
| 3766 | } | ||
| 3767 | |||
| 3768 | while (remaining_bytes >= 32 / CHAR_BIT) { | ||
| 3769 | uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0); | ||
| 3770 | |||
| 3771 | #if zig_big_endian | ||
| 3772 | byte_offset -= 32 / CHAR_BIT; | ||
| 3773 | #endif | ||
| 3774 | |||
| 3775 | { | ||
| 3776 | uint32_t res_limb; | ||
| 3777 | bool limb_overflow; | ||
| 3778 | |||
| 3779 | memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb)); | ||
| 3780 | limb_overflow = zig_addo_u32(&res_limb, res_limb, UINT32_C(1), limb_bits); | ||
| 3781 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3782 | if (!limb_overflow) return; | ||
| 3783 | } | ||
| 3784 | |||
| 3785 | remaining_bytes -= 32 / CHAR_BIT; | ||
| 3786 | |||
| 3787 | #if zig_little_endian | ||
| 3788 | byte_offset += 32 / CHAR_BIT; | ||
| 3789 | #endif | ||
| 3790 | } | ||
| 3791 | |||
| 3792 | while (remaining_bytes >= 16 / CHAR_BIT) { | ||
| 3793 | uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0); | ||
| 3794 | |||
| 3795 | #if zig_big_endian | ||
| 3796 | byte_offset -= 16 / CHAR_BIT; | ||
| 3797 | #endif | ||
| 3798 | |||
| 3799 | { | ||
| 3800 | uint16_t res_limb; | ||
| 3801 | bool limb_overflow; | ||
| 3802 | |||
| 3803 | memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb)); | ||
| 3804 | limb_overflow = zig_addo_u16(&res_limb, res_limb, UINT16_C(1), limb_bits); | ||
| 3805 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3806 | if (!limb_overflow) return; | ||
| 3807 | } | ||
| 3808 | |||
| 3809 | remaining_bytes -= 16 / CHAR_BIT; | ||
| 3810 | |||
| 3811 | #if zig_little_endian | ||
| 3812 | byte_offset += 16 / CHAR_BIT; | ||
| 3813 | #endif | ||
| 3814 | } | ||
| 3815 | |||
| 3816 | while (remaining_bytes >= 8 / CHAR_BIT) { | ||
| 3817 | uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0); | ||
| 3818 | |||
| 3819 | #if zig_big_endian | ||
| 3820 | byte_offset -= 8 / CHAR_BIT; | ||
| 3821 | #endif | ||
| 3822 | |||
| 3823 | { | ||
| 3824 | uint8_t res_limb; | ||
| 3825 | bool limb_overflow; | ||
| 3826 | |||
| 3827 | memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb)); | ||
| 3828 | limb_overflow = zig_addo_u8(&res_limb, res_limb, UINT8_C(1), limb_bits); | ||
| 3829 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3830 | if (!limb_overflow) return; | ||
| 3831 | } | ||
| 3832 | |||
| 3833 | remaining_bytes -= 8 / CHAR_BIT; | ||
| 3834 | |||
| 3835 | #if zig_little_endian | ||
| 3836 | byte_offset += 8 / CHAR_BIT; | ||
| 3837 | #endif | ||
| 3838 | } | ||
| 3839 | } | ||
| 3840 | |||
| 3841 | static inline void zig_decrement_big(void *res, bool is_signed, uint16_t bits) { | ||
| 3842 | uint8_t *res_bytes = res; | ||
| 3843 | uint16_t byte_offset = 0; | ||
| 3844 | uint16_t remaining_bytes = zig_int_bytes(bits); | ||
| 3845 | uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits); | ||
| 3846 | |||
| 3847 | #if zig_big_endian | ||
| 3848 | byte_offset = remaining_bytes; | ||
| 3849 | #endif | ||
| 3850 | |||
| 3851 | while (remaining_bytes >= 128 / CHAR_BIT) { | ||
| 3852 | uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0); | ||
| 3853 | |||
| 3854 | #if zig_big_endian | ||
| 3855 | byte_offset -= 128 / CHAR_BIT; | ||
| 3856 | #endif | ||
| 3857 | |||
| 3858 | { | ||
| 3859 | zig_u128 res_limb; | ||
| 3860 | bool limb_overflow; | ||
| 3861 | |||
| 3862 | memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb)); | ||
| 3863 | limb_overflow = zig_subo_u128(&res_limb, res_limb, zig_make_u128(UINT64_C(0), UINT64_C(1)), limb_bits); | ||
| 3864 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3865 | if (!limb_overflow) return; | ||
| 3866 | } | ||
| 3867 | |||
| 3868 | remaining_bytes -= 128 / CHAR_BIT; | ||
| 3869 | |||
| 3870 | #if zig_little_endian | ||
| 3871 | byte_offset += 128 / CHAR_BIT; | ||
| 3872 | #endif | ||
| 3873 | } | ||
| 3874 | |||
| 3875 | while (remaining_bytes >= 64 / CHAR_BIT) { | ||
| 3876 | uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0); | ||
| 3877 | |||
| 3878 | #if zig_big_endian | ||
| 3879 | byte_offset -= 64 / CHAR_BIT; | ||
| 3880 | #endif | ||
| 3881 | |||
| 3882 | { | ||
| 3883 | uint64_t res_limb; | ||
| 3884 | bool limb_overflow; | ||
| 3885 | |||
| 3886 | memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb)); | ||
| 3887 | limb_overflow = zig_subo_u64(&res_limb, res_limb, UINT64_C(1), limb_bits); | ||
| 3888 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3889 | if (!limb_overflow) return; | ||
| 3890 | } | ||
| 3891 | |||
| 3892 | remaining_bytes -= 64 / CHAR_BIT; | ||
| 3893 | |||
| 3894 | #if zig_little_endian | ||
| 3895 | byte_offset += 64 / CHAR_BIT; | ||
| 3896 | #endif | ||
| 3897 | } | ||
| 3898 | |||
| 3899 | while (remaining_bytes >= 32 / CHAR_BIT) { | ||
| 3900 | uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0); | ||
| 3901 | |||
| 3902 | #if zig_big_endian | ||
| 3903 | byte_offset -= 32 / CHAR_BIT; | ||
| 3904 | #endif | ||
| 3905 | |||
| 3906 | { | ||
| 3907 | uint32_t res_limb; | ||
| 3908 | bool limb_overflow; | ||
| 3909 | |||
| 3910 | memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb)); | ||
| 3911 | limb_overflow = zig_subo_u32(&res_limb, res_limb, UINT32_C(1), limb_bits); | ||
| 3912 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3913 | if (!limb_overflow) return; | ||
| 3914 | } | ||
| 3915 | |||
| 3916 | remaining_bytes -= 32 / CHAR_BIT; | ||
| 3917 | |||
| 3918 | #if zig_little_endian | ||
| 3919 | byte_offset += 32 / CHAR_BIT; | ||
| 3920 | #endif | ||
| 3921 | } | ||
| 3922 | |||
| 3923 | while (remaining_bytes >= 16 / CHAR_BIT) { | ||
| 3924 | uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0); | ||
| 3925 | |||
| 3926 | #if zig_big_endian | ||
| 3927 | byte_offset -= 16 / CHAR_BIT; | ||
| 3928 | #endif | ||
| 3929 | |||
| 3930 | { | ||
| 3931 | uint16_t res_limb; | ||
| 3932 | bool limb_overflow; | ||
| 3933 | |||
| 3934 | memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb)); | ||
| 3935 | limb_overflow = zig_subo_u16(&res_limb, res_limb, UINT16_C(1), limb_bits); | ||
| 3936 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3937 | if (!limb_overflow) return; | ||
| 3938 | } | ||
| 3939 | |||
| 3940 | remaining_bytes -= 16 / CHAR_BIT; | ||
| 3941 | |||
| 3942 | #if zig_little_endian | ||
| 3943 | byte_offset += 16 / CHAR_BIT; | ||
| 3944 | #endif | ||
| 3945 | } | ||
| 3946 | |||
| 3947 | while (remaining_bytes >= 8 / CHAR_BIT) { | ||
| 3948 | uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0); | ||
| 3949 | |||
| 3950 | #if zig_big_endian | ||
| 3951 | byte_offset -= 8 / CHAR_BIT; | ||
| 3952 | #endif | ||
| 3953 | |||
| 3954 | { | ||
| 3955 | uint8_t res_limb; | ||
| 3956 | bool limb_overflow; | ||
| 3957 | |||
| 3958 | memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb)); | ||
| 3959 | limb_overflow = zig_subo_u8(&res_limb, res_limb, UINT8_C(1), limb_bits); | ||
| 3960 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 3961 | if (!limb_overflow) return; | ||
| 3962 | } | ||
| 3963 | |||
| 3964 | remaining_bytes -= 8 / CHAR_BIT; | ||
| 3965 | |||
| 3966 | #if zig_little_endian | ||
| 3967 | byte_offset += 8 / CHAR_BIT; | ||
| 3968 | #endif | ||
| 3969 | } | ||
| 3970 | } | ||
| 3971 | |||
| 3972 | static inline void zig_abs_big(void *res, const void *arg, bool is_signed, uint16_t bits) { | ||
| 3973 | uint8_t *res_bytes = res; | ||
| 3974 | const uint8_t *arg_bytes = arg; | ||
| 3975 | uint16_t byte_offset = 0; | ||
| 3976 | uint16_t remaining_bytes = zig_int_bytes(bits); | ||
| 3977 | if (zig_signFill_big(arg, is_signed, bits) >= INT8_C(0)) { | ||
| 3978 | memcpy(res, arg, remaining_bytes); | ||
| 3979 | return; | ||
| 3980 | } | ||
| 3981 | uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits); | ||
| 3982 | bool overflow = true; | ||
| 3983 | |||
| 3984 | #if zig_big_endian | ||
| 3985 | byte_offset = remaining_bytes; | ||
| 3986 | #endif | ||
| 3987 | |||
| 3988 | while (remaining_bytes >= 128 / CHAR_BIT) { | ||
| 3989 | uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0); | ||
| 3990 | |||
| 3991 | #if zig_big_endian | ||
| 3992 | byte_offset -= 128 / CHAR_BIT; | ||
| 3993 | #endif | ||
| 3994 | |||
| 3995 | { | ||
| 3996 | zig_u128 res_limb; | ||
| 3997 | zig_u128 arg_limb; | ||
| 3998 | |||
| 3999 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); | ||
| 4000 | overflow = zig_addo_u128(&res_limb, zig_not_u128(arg_limb, UINT8_C(128)), zig_make_u128(UINT64_C(0), overflow ? UINT64_C(1) : UINT64_C(0)), limb_bits); | ||
| 4001 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 4002 | } | ||
| 4003 | |||
| 4004 | remaining_bytes -= 128 / CHAR_BIT; | ||
| 4005 | |||
| 4006 | #if zig_little_endian | ||
| 4007 | byte_offset += 128 / CHAR_BIT; | ||
| 4008 | #endif | ||
| 4009 | } | ||
| 4010 | |||
| 4011 | while (remaining_bytes >= 64 / CHAR_BIT) { | ||
| 4012 | uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0); | ||
| 4013 | |||
| 4014 | #if zig_big_endian | ||
| 4015 | byte_offset -= 64 / CHAR_BIT; | ||
| 4016 | #endif | ||
| 4017 | |||
| 4018 | { | ||
| 4019 | uint64_t res_limb; | ||
| 4020 | uint64_t arg_limb; | ||
| 4021 | |||
| 4022 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); | ||
| 4023 | overflow = zig_addo_u64(&res_limb, zig_not_u64(arg_limb, UINT8_C(64)), overflow ? UINT64_C(1) : UINT64_C(0), limb_bits); | ||
| 4024 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 4025 | } | ||
| 4026 | |||
| 4027 | remaining_bytes -= 64 / CHAR_BIT; | ||
| 4028 | |||
| 4029 | #if zig_little_endian | ||
| 4030 | byte_offset += 64 / CHAR_BIT; | ||
| 4031 | #endif | ||
| 4032 | } | ||
| 4033 | |||
| 4034 | while (remaining_bytes >= 32 / CHAR_BIT) { | ||
| 4035 | uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0); | ||
| 4036 | |||
| 4037 | #if zig_big_endian | ||
| 4038 | byte_offset -= 32 / CHAR_BIT; | ||
| 4039 | #endif | ||
| 4040 | |||
| 4041 | { | ||
| 4042 | uint32_t res_limb; | ||
| 4043 | uint32_t arg_limb; | ||
| 4044 | |||
| 4045 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); | ||
| 4046 | overflow = zig_addo_u32(&res_limb, zig_not_u32(arg_limb, UINT8_C(32)), overflow ? UINT32_C(1) : UINT32_C(0), limb_bits); | ||
| 4047 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 4048 | } | ||
| 4049 | |||
| 4050 | remaining_bytes -= 32 / CHAR_BIT; | ||
| 4051 | |||
| 4052 | #if zig_little_endian | ||
| 4053 | byte_offset += 32 / CHAR_BIT; | ||
| 4054 | #endif | ||
| 4055 | } | ||
| 4056 | |||
| 4057 | while (remaining_bytes >= 16 / CHAR_BIT) { | ||
| 4058 | uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0); | ||
| 4059 | |||
| 4060 | #if zig_big_endian | ||
| 4061 | byte_offset -= 16 / CHAR_BIT; | ||
| 4062 | #endif | ||
| 4063 | |||
| 4064 | { | ||
| 4065 | uint16_t res_limb; | ||
| 4066 | uint16_t arg_limb; | ||
| 4067 | |||
| 4068 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); | ||
| 4069 | overflow = zig_addo_u16(&res_limb, zig_not_u16(arg_limb, UINT8_C(16)), overflow ? UINT16_C(1) : UINT16_C(0), limb_bits); | ||
| 4070 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 4071 | } | ||
| 4072 | |||
| 4073 | remaining_bytes -= 16 / CHAR_BIT; | ||
| 4074 | |||
| 4075 | #if zig_little_endian | ||
| 4076 | byte_offset += 16 / CHAR_BIT; | ||
| 4077 | #endif | ||
| 4078 | } | ||
| 4079 | |||
| 4080 | while (remaining_bytes >= 8 / CHAR_BIT) { | ||
| 4081 | uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0); | ||
| 4082 | |||
| 4083 | #if zig_big_endian | ||
| 4084 | byte_offset -= 8 / CHAR_BIT; | ||
| 4085 | #endif | ||
| 4086 | |||
| 4087 | { | ||
| 4088 | uint8_t res_limb; | ||
| 4089 | uint8_t arg_limb; | ||
| 4090 | |||
| 4091 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); | ||
| 4092 | overflow = zig_addo_u8(&res_limb, zig_not_u8(arg_limb, UINT8_C(8)), overflow ? UINT8_C(1) : UINT8_C(0), limb_bits); | ||
| 4093 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | ||
| 4094 | } | ||
| 4095 | |||
| 4096 | remaining_bytes -= 8 / CHAR_BIT; | ||
| 4097 | |||
| 4098 | #if zig_little_endian | ||
| 4099 | byte_offset += 8 / CHAR_BIT; | ||
| 4100 | #endif | ||
| 4101 | } | ||
| 4102 | } | ||
| 4103 | |||
| 4104 | static inline void zig_min_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | ||
| 4105 | memcpy(res, zig_cmp_big(lhs, rhs, is_signed, bits) < INT32_C(0) ? lhs : rhs, zig_int_bytes(bits)); | ||
| 4106 | } | ||
| 4107 | |||
| 4108 | static inline void zig_max_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | ||
| 4109 | memcpy(res, zig_cmp_big(lhs, rhs, is_signed, bits) >= INT32_C(0) ? lhs : rhs, zig_int_bytes(bits)); | ||
| 4110 | } | ||
| 4111 | |||
| 2819 | static inline bool zig_addo_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | 4112 | static inline bool zig_addo_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { |
| 2820 | uint8_t *res_bytes = res; | 4113 | uint8_t *res_bytes = res; |
| 2821 | const uint8_t *lhs_bytes = lhs; | 4114 | const uint8_t *lhs_bytes = lhs; |
| 2822 | const uint8_t *rhs_bytes = rhs; | 4115 | const uint8_t *rhs_bytes = rhs; |
| 2823 | uint16_t byte_offset = 0; | 4116 | uint16_t byte_offset = 0; |
| 2824 | uint16_t remaining_bytes = zig_int_bytes(bits); | 4117 | uint16_t remaining_bytes = zig_int_bytes(bits); |
| 2825 | uint8_t top_bits = (uint8_t)(remaining_bytes * 8 - bits); | 4118 | uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits); |
| 2826 | bool overflow = false; | 4119 | bool overflow = false; |
| 2827 | 4120 | ||
| 2828 | #if zig_big_endian | 4121 | #if zig_big_endian |
| ... | @@ -3038,7 +4331,7 @@ static inline bool zig_subo_big(void *res, const void *lhs, const void *rhs, boo | ... | @@ -3038,7 +4331,7 @@ static inline bool zig_subo_big(void *res, const void *lhs, const void *rhs, boo |
| 3038 | const uint8_t *rhs_bytes = rhs; | 4331 | const uint8_t *rhs_bytes = rhs; |
| 3039 | uint16_t byte_offset = 0; | 4332 | uint16_t byte_offset = 0; |
| 3040 | uint16_t remaining_bytes = zig_int_bytes(bits); | 4333 | uint16_t remaining_bytes = zig_int_bytes(bits); |
| 3041 | uint8_t top_bits = (uint8_t)(remaining_bytes * 8 - bits); | 4334 | uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits); |
| 3042 | bool overflow = false; | 4335 | bool overflow = false; |
| 3043 | 4336 | ||
| 3044 | #if zig_big_endian | 4337 | #if zig_big_endian |
| ... | @@ -3238,218 +4531,890 @@ static inline bool zig_subo_big(void *res, const void *lhs, const void *rhs, boo | ... | @@ -3238,218 +4531,890 @@ static inline bool zig_subo_big(void *res, const void *lhs, const void *rhs, boo |
| 3238 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | 4531 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); |
| 3239 | } | 4532 | } |
| 3240 | 4533 | ||
| 3241 | remaining_bytes -= 8 / CHAR_BIT; | 4534 | remaining_bytes -= 8 / CHAR_BIT; |
| 4535 | |||
| 4536 | #if zig_little_endian | ||
| 4537 | byte_offset += 8 / CHAR_BIT; | ||
| 4538 | #endif | ||
| 4539 | } | ||
| 4540 | |||
| 4541 | return overflow; | ||
| 4542 | } | ||
| 4543 | |||
| 4544 | static inline void zig_add_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | ||
| 4545 | if (zig_addo_big(res, lhs, rhs, is_signed, bits)) zig_trap(); // panic: integer overflow | ||
| 4546 | } | ||
| 4547 | |||
| 4548 | static inline void zig_addw_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | ||
| 4549 | (void)zig_addo_big(res, lhs, rhs, is_signed, bits); | ||
| 4550 | } | ||
| 4551 | |||
| 4552 | static inline void zig_adds_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | ||
| 4553 | int8_t sat_sign = zig_signFill_big(lhs, is_signed, bits); | ||
| 4554 | |||
| 4555 | if (!zig_addo_big(res, lhs, rhs, is_signed, bits)) return; | ||
| 4556 | switch (sat_sign) { | ||
| 4557 | case -INT8_C(1): return zig_minInt_big(res, is_signed, bits); | ||
| 4558 | case INT8_C(0): return zig_maxInt_big(res, is_signed, bits); | ||
| 4559 | } | ||
| 4560 | } | ||
| 4561 | |||
| 4562 | static inline void zig_sub_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | ||
| 4563 | if (zig_subo_big(res, lhs, rhs, is_signed, bits)) zig_trap(); // panic: integer overflow | ||
| 4564 | } | ||
| 4565 | |||
| 4566 | static inline void zig_subw_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | ||
| 4567 | (void)zig_subo_big(res, lhs, rhs, is_signed, bits); | ||
| 4568 | } | ||
| 4569 | |||
| 4570 | static inline void zig_subs_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | ||
| 4571 | int8_t sat_sign = is_signed ? zig_signFill_big(lhs, is_signed, bits) : -INT8_C(1); | ||
| 4572 | |||
| 4573 | if (!zig_subo_big(res, lhs, rhs, is_signed, bits)) return; | ||
| 4574 | switch (sat_sign) { | ||
| 4575 | case -INT8_C(1): return zig_minInt_big(res, is_signed, bits); | ||
| 4576 | case INT8_C(0): return zig_maxInt_big(res, is_signed, bits); | ||
| 4577 | } | ||
| 4578 | } | ||
| 4579 | |||
| 4580 | static inline bool zig_mulo_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | ||
| 4581 | uint8_t *res_bytes = res; | ||
| 4582 | const uint8_t *lhs_bytes = lhs; | ||
| 4583 | const uint8_t *rhs_bytes = rhs; | ||
| 4584 | uint16_t size = zig_int_bytes(bits); | ||
| 4585 | uint16_t sign_byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1); | ||
| 4586 | uint8_t lhs_sign_fill = zig_u8_bitCast_i8(zig_signFill_big(lhs, is_signed, bits), UINT8_C(8)); | ||
| 4587 | uint8_t rhs_sign_fill = zig_u8_bitCast_i8(zig_signFill_big(rhs, is_signed, bits), UINT8_C(8)); | ||
| 4588 | uint16_t lhs_byte_offset = sign_byte_offset; | ||
| 4589 | uint16_t lhs_end_byte_offset = UINT16_C(0); | ||
| 4590 | bool overflow = false; | ||
| 4591 | |||
| 4592 | #if zig_big_endian | ||
| 4593 | lhs_byte_offset = size - lhs_byte_offset; | ||
| 4594 | lhs_end_byte_offset = size - lhs_end_byte_offset; | ||
| 4595 | #endif | ||
| 4596 | |||
| 4597 | while (lhs_byte_offset != lhs_end_byte_offset) { | ||
| 4598 | uint16_t rhs_byte_offset = UINT16_C(0); | ||
| 4599 | uint16_t end_byte_offset = sign_byte_offset; | ||
| 4600 | uint16_t res_byte_offset; | ||
| 4601 | uint16_t lhs_byte; | ||
| 4602 | uint8_t res_byte = UINT8_C(0); | ||
| 4603 | uint16_t mul_res = UINT16_C(0); | ||
| 4604 | uint8_t carry = UINT8_C(0); | ||
| 4605 | |||
| 4606 | #if zig_little_endian | ||
| 4607 | lhs_byte_offset -= UINT16_C(1); | ||
| 4608 | #else | ||
| 4609 | rhs_byte_offset = size - rhs_byte_offset; | ||
| 4610 | end_byte_offset = size - end_byte_offset; | ||
| 4611 | #endif | ||
| 4612 | |||
| 4613 | lhs_byte = zig_u16_intCast_u8(lhs_bytes[lhs_byte_offset]) ^ lhs_sign_fill; | ||
| 4614 | |||
| 4615 | #if zig_big_endian | ||
| 4616 | lhs_byte_offset += UINT16_C(1); | ||
| 4617 | #endif | ||
| 4618 | |||
| 4619 | res_byte_offset = lhs_byte_offset; | ||
| 4620 | |||
| 4621 | while (res_byte_offset != end_byte_offset) { | ||
| 4622 | bool res_byte_initialized = res_byte_offset != lhs_byte_offset; | ||
| 4623 | |||
| 4624 | #if zig_big_endian | ||
| 4625 | rhs_byte_offset -= UINT16_C(1); | ||
| 4626 | res_byte_offset -= UINT16_C(1); | ||
| 4627 | #endif | ||
| 4628 | |||
| 4629 | if (res_byte_initialized) res_byte = res_bytes[res_byte_offset]; | ||
| 4630 | carry = zig_addo_u8(&res_byte, res_byte, carry, UINT8_C(8)); | ||
| 4631 | carry += zig_addo_u8(&res_byte, res_byte, zig_u8_intCast_u16( | ||
| 4632 | zig_shr_u16(mul_res, UINT8_C(8)) | ||
| 4633 | ), UINT8_C(8)); | ||
| 4634 | mul_res = lhs_byte * zig_u16_intCast_u8(rhs_bytes[rhs_byte_offset] ^ rhs_sign_fill); | ||
| 4635 | carry += zig_addo_u8(&res_bytes[res_byte_offset], res_byte, zig_u8_truncate_u16( | ||
| 4636 | mul_res, | ||
| 4637 | UINT8_C(8) | ||
| 4638 | ), UINT8_C(8)); | ||
| 4639 | |||
| 4640 | #if zig_little_endian | ||
| 4641 | rhs_byte_offset += UINT16_C(1); | ||
| 4642 | res_byte_offset += UINT16_C(1); | ||
| 4643 | #endif | ||
| 4644 | } | ||
| 4645 | |||
| 4646 | while (rhs_byte_offset != end_byte_offset) { | ||
| 4647 | #if zig_big_endian | ||
| 4648 | rhs_byte_offset -= UINT16_C(1); | ||
| 4649 | #endif | ||
| 4650 | |||
| 4651 | carry = zig_addo_u8( | ||
| 4652 | &res_byte, | ||
| 4653 | zig_u8_intCast_u16(zig_shr_u16(mul_res, UINT8_C(8))), | ||
| 4654 | carry, | ||
| 4655 | UINT8_C(8) | ||
| 4656 | ); | ||
| 4657 | mul_res = lhs_byte * zig_u16_intCast_u8(rhs_bytes[rhs_byte_offset] ^ rhs_sign_fill); | ||
| 4658 | carry += zig_addo_u8(&res_byte, res_byte, zig_u8_truncate_u16( | ||
| 4659 | mul_res, | ||
| 4660 | UINT8_C(8) | ||
| 4661 | ), UINT8_C(8)); | ||
| 4662 | overflow |= res_byte != UINT8_C(0); | ||
| 4663 | |||
| 4664 | #if zig_little_endian | ||
| 4665 | rhs_byte_offset += UINT16_C(1); | ||
| 4666 | #endif | ||
| 4667 | } | ||
| 4668 | |||
| 4669 | overflow |= zig_shr_u16(mul_res, UINT8_C(8)) != UINT16_C(0); | ||
| 4670 | overflow |= carry != UINT8_C(0); | ||
| 4671 | } | ||
| 4672 | |||
| 4673 | #if zig_little_endian | ||
| 4674 | sign_byte_offset -= UINT64_C(1); | ||
| 4675 | #else | ||
| 4676 | sign_byte_offset = size - sign_byte_offset; | ||
| 4677 | #endif | ||
| 4678 | |||
| 4679 | if (lhs_sign_fill != rhs_sign_fill) { | ||
| 4680 | uint16_t byte_offset = UINT16_C(0); | ||
| 4681 | uint16_t end_byte_offset = sign_byte_offset; | ||
| 4682 | uint8_t res_byte; | ||
| 4683 | int8_t signed_res_byte; | ||
| 4684 | uint8_t carry = UINT8_C(0); | ||
| 4685 | |||
| 4686 | #if zig_big_endian | ||
| 4687 | byte_offset = size - byte_offset; | ||
| 4688 | end_byte_offset += UINT16_C(1); | ||
| 4689 | #endif | ||
| 4690 | |||
| 4691 | while (byte_offset != end_byte_offset) { | ||
| 4692 | #if zig_big_endian | ||
| 4693 | byte_offset -= UINT16_C(1); | ||
| 4694 | #endif | ||
| 4695 | |||
| 4696 | carry = zig_subo_u8(&res_byte, UINT8_C(0), carry, UINT8_C(8)); | ||
| 4697 | carry += zig_subo_u8(&res_byte, res_byte, res_bytes[byte_offset], UINT8_C(8)); | ||
| 4698 | carry += zig_subo_u8( | ||
| 4699 | &res_bytes[byte_offset], | ||
| 4700 | res_byte, | ||
| 4701 | (lhs_sign_fill == UINT8_C(0) ? lhs_bytes : rhs_bytes)[byte_offset], | ||
| 4702 | UINT8_C(8) | ||
| 4703 | ); | ||
| 4704 | |||
| 4705 | #if zig_little_endian | ||
| 4706 | byte_offset += UINT16_C(1); | ||
| 4707 | #endif | ||
| 4708 | } | ||
| 4709 | |||
| 4710 | #if zig_big_endian | ||
| 4711 | byte_offset -= UINT16_C(1); | ||
| 4712 | #endif | ||
| 4713 | |||
| 4714 | signed_res_byte = zig_i8_bitCast_u8(res_bytes[byte_offset], UINT8_C(8)); | ||
| 4715 | overflow |= signed_res_byte < INT8_C(0); | ||
| 4716 | overflow |= zig_subo_i8(&signed_res_byte, INT8_C(0), signed_res_byte, UINT8_C(8)); | ||
| 4717 | overflow |= zig_subo_i8(&signed_res_byte, signed_res_byte, zig_i8_intCast_u8(carry), UINT8_C(8)); | ||
| 4718 | overflow |= zig_subo_i8(&signed_res_byte, signed_res_byte, zig_i8_bitCast_u8( | ||
| 4719 | (lhs_sign_fill == UINT8_C(0) ? lhs_bytes : rhs_bytes)[byte_offset], | ||
| 4720 | UINT8_C(8) | ||
| 4721 | ), UINT8_C(8)); | ||
| 4722 | res_bytes[byte_offset] = zig_i8_bitCast_u8(signed_res_byte, UINT8_C(8)); | ||
| 4723 | } else if (lhs_sign_fill != UINT8_C(0)) { | ||
| 4724 | uint16_t byte_offset = UINT16_C(0); | ||
| 4725 | uint16_t end_byte_offset = sign_byte_offset; | ||
| 4726 | uint8_t res_byte; | ||
| 4727 | int8_t signed_res_byte; | ||
| 4728 | uint8_t carry = UINT8_C(1); | ||
| 4729 | |||
| 4730 | #if zig_big_endian | ||
| 4731 | byte_offset = size - byte_offset; | ||
| 4732 | end_byte_offset += UINT16_C(1); | ||
| 4733 | #endif | ||
| 4734 | |||
| 4735 | while (byte_offset != end_byte_offset) { | ||
| 4736 | #if zig_big_endian | ||
| 4737 | byte_offset -= UINT16_C(1); | ||
| 4738 | #endif | ||
| 4739 | |||
| 4740 | carry = zig_subo_u8(&res_byte, res_bytes[byte_offset], carry, UINT8_C(8)); | ||
| 4741 | carry += zig_subo_u8(&res_byte, res_byte, lhs_bytes[byte_offset], UINT8_C(8)); | ||
| 4742 | carry += zig_subo_u8(&res_bytes[byte_offset], res_byte, rhs_bytes[byte_offset], UINT8_C(8)); | ||
| 4743 | |||
| 4744 | #if zig_little_endian | ||
| 4745 | byte_offset += UINT16_C(1); | ||
| 4746 | #endif | ||
| 4747 | } | ||
| 4748 | |||
| 4749 | #if zig_big_endian | ||
| 4750 | byte_offset -= UINT16_C(1); | ||
| 4751 | #endif | ||
| 4752 | |||
| 4753 | signed_res_byte = zig_i8_bitCast_u8(res_bytes[byte_offset], UINT8_C(8)); | ||
| 4754 | overflow |= signed_res_byte < INT8_C(0); | ||
| 4755 | overflow |= zig_subo_i8(&signed_res_byte, signed_res_byte, zig_i8_intCast_u8(carry), UINT8_C(8)); | ||
| 4756 | overflow |= zig_subo_i8(&signed_res_byte, signed_res_byte, zig_i8_bitCast_u8( | ||
| 4757 | lhs_bytes[byte_offset], | ||
| 4758 | UINT8_C(8) | ||
| 4759 | ), UINT8_C(8)); | ||
| 4760 | overflow |= zig_subo_i8(&signed_res_byte, signed_res_byte, zig_i8_bitCast_u8( | ||
| 4761 | rhs_bytes[byte_offset], | ||
| 4762 | UINT8_C(8) | ||
| 4763 | ), UINT8_C(8)); | ||
| 4764 | res_bytes[byte_offset] = zig_i8_bitCast_u8(signed_res_byte, UINT8_C(8)); | ||
| 4765 | } else if (is_signed) { | ||
| 4766 | int8_t signed_res_byte = zig_i8_bitCast_u8(res_bytes[sign_byte_offset], UINT8_C(8)); | ||
| 4767 | |||
| 4768 | overflow |= signed_res_byte < INT8_C(0); | ||
| 4769 | } | ||
| 4770 | |||
| 4771 | { | ||
| 4772 | uint8_t truncate_bits = zig_u8_truncate_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1); | ||
| 4773 | uint8_t fill_byte = UINT8_C(0); | ||
| 4774 | |||
| 4775 | if (is_signed) { | ||
| 4776 | int8_t sign_byte = zig_i8_bitCast_u8(res_bytes[sign_byte_offset], UINT8_C(8)); | ||
| 4777 | int8_t truncated = zig_i8_truncate_i8(sign_byte, truncate_bits); | ||
| 4778 | |||
| 4779 | overflow |= sign_byte != truncated; | ||
| 4780 | res_bytes[sign_byte_offset] = zig_u8_bitCast_i8(truncated, UINT8_C(8)); | ||
| 4781 | fill_byte = zig_u8_bitCast_i8(zig_shr_i8(truncated, UINT8_C(7)), UINT8_C(8)); | ||
| 4782 | } else { | ||
| 4783 | uint8_t sign_byte = res_bytes[sign_byte_offset]; | ||
| 4784 | uint8_t truncated = zig_u8_truncate_u8(sign_byte, truncate_bits); | ||
| 4785 | |||
| 4786 | overflow |= sign_byte != truncated; | ||
| 4787 | res_bytes[sign_byte_offset] = truncated; | ||
| 4788 | } | ||
| 4789 | |||
| 4790 | #if zig_little_endian | ||
| 4791 | sign_byte_offset += UINT16_C(1); | ||
| 4792 | memset(&res_bytes[sign_byte_offset], fill_byte, size - sign_byte_offset); | ||
| 4793 | #else | ||
| 4794 | memset(&res_bytes[0], fill_byte, sign_byte_offset); | ||
| 4795 | #endif | ||
| 4796 | } | ||
| 4797 | |||
| 4798 | return overflow; | ||
| 4799 | } | ||
| 4800 | |||
| 4801 | static inline void zig_mul_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | ||
| 4802 | if (zig_mulo_big(res, lhs, rhs, is_signed, bits)) zig_trap(); // panic: integer overflow | ||
| 4803 | } | ||
| 4804 | |||
| 4805 | static inline void zig_mulw_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | ||
| 4806 | (void)zig_mulo_big(res, lhs, rhs, is_signed, bits); | ||
| 4807 | } | ||
| 4808 | |||
| 4809 | static inline void zig_muls_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | ||
| 4810 | int8_t sat_sign = zig_signFill_big(lhs, is_signed, bits) ^ zig_signFill_big(rhs, is_signed, bits); | ||
| 4811 | |||
| 4812 | if (!zig_mulo_big(res, lhs, rhs, is_signed, bits)) return; | ||
| 4813 | switch (sat_sign) { | ||
| 4814 | case -INT8_C(1): return zig_minInt_big(res, is_signed, bits); | ||
| 4815 | case INT8_C(0): return zig_maxInt_big(res, is_signed, bits); | ||
| 4816 | } | ||
| 4817 | } | ||
| 4818 | |||
| 4819 | static inline void zig_divTrunc_big(void *res, const void *lhs, const void *rhs, void *temp, bool is_signed, uint16_t bits) { | ||
| 4820 | if (is_signed) { | ||
| 4821 | zig_extern void __divei5(uint32_t *res, const uint32_t *lhs, const uint32_t *rhs, uint32_t *temp, uintptr_t bits); | ||
| 4822 | __divei5(res, lhs, rhs, temp, bits); | ||
| 4823 | } else { | ||
| 4824 | zig_extern void __udivei5(uint32_t *res, const uint32_t *lhs, const uint32_t *rhs, uint32_t *temp, uintptr_t bits); | ||
| 4825 | __udivei5(res, lhs, rhs, temp, bits); | ||
| 4826 | } | ||
| 4827 | } | ||
| 4828 | |||
| 4829 | static inline void zig_rem_big(void *res, const void *lhs, const void *rhs, void *temp, bool is_signed, uint16_t bits) { | ||
| 4830 | if (is_signed) { | ||
| 4831 | zig_extern void __modei5(uint32_t *res, const uint32_t *lhs, const uint32_t *rhs, uint32_t *temp, uintptr_t bits); | ||
| 4832 | __modei5(res, lhs, rhs, temp, bits); | ||
| 4833 | } else { | ||
| 4834 | zig_extern void __umodei5(uint32_t *res, const uint32_t *lhs, const uint32_t *rhs, uint32_t *temp, uintptr_t bits); | ||
| 4835 | __umodei5(res, lhs, rhs, temp, bits); | ||
| 4836 | } | ||
| 4837 | } | ||
| 4838 | |||
| 4839 | static inline void zig_divFloor_big(void *res, const void *lhs, const void *rhs, void *temp, bool is_signed, uint16_t bits) { | ||
| 4840 | bool decrement = false; | ||
| 4841 | |||
| 4842 | if (is_signed) { | ||
| 4843 | zig_rem_big(res, lhs, rhs, temp, is_signed, bits); | ||
| 4844 | decrement = zig_u32_bitCast_i32(zig_xor_i32( | ||
| 4845 | zig_cmp_big_u8(res, UINT8_C(0), is_signed, bits), | ||
| 4846 | zig_and_i32(zig_i32_intCast_i8(zig_signFill_big(rhs, is_signed, bits)), zig_minInt_i32) | ||
| 4847 | ), UINT8_C(32)) > zig_u32_bitCast_i32(zig_minInt_i32, UINT8_C(32)); | ||
| 4848 | } | ||
| 4849 | zig_divTrunc_big(res, lhs, rhs, temp, is_signed, bits); | ||
| 4850 | if (decrement) zig_decrement_big(res, is_signed, bits); | ||
| 4851 | } | ||
| 4852 | |||
| 4853 | static inline void zig_divCeil_big(void *res, const void *lhs, const void *rhs, void *temp, bool is_signed, uint16_t bits) { | ||
| 4854 | bool increment = false; | ||
| 4855 | |||
| 4856 | zig_rem_big(res, lhs, rhs, temp, is_signed, bits); | ||
| 4857 | increment = zig_xor_i32( | ||
| 4858 | zig_cmp_big_u8(res, UINT8_C(0), is_signed, bits), | ||
| 4859 | zig_and_i32(zig_i32_intCast_i8(zig_signFill_big(rhs, is_signed, bits)), zig_minInt_i32) | ||
| 4860 | ) > INT32_C(0); | ||
| 4861 | zig_divTrunc_big(res, lhs, rhs, temp, is_signed, bits); | ||
| 4862 | if (increment) zig_increment_big(res, is_signed, bits); | ||
| 4863 | } | ||
| 4864 | |||
| 4865 | static inline void zig_mod_big(void *res, const void *lhs, const void *rhs, void *temp, bool is_signed, uint16_t bits) { | ||
| 4866 | bool fixup = false; | ||
| 4867 | |||
| 4868 | zig_rem_big(res, lhs, rhs, temp, is_signed, bits); | ||
| 4869 | if (is_signed && zig_u32_bitCast_i32(zig_xor_i32( | ||
| 4870 | zig_cmp_big_u8(res, UINT8_C(0), is_signed, bits), | ||
| 4871 | zig_and_i32(zig_i32_intCast_i8(zig_signFill_big(rhs, is_signed, bits)), zig_minInt_i32) | ||
| 4872 | ), UINT8_C(32)) > zig_u32_bitCast_i32(zig_minInt_i32, UINT8_C(32))) zig_add_big(res, res, rhs, is_signed, bits); | ||
| 4873 | } | ||
| 4874 | |||
| 4875 | static inline void zig_shr_big(void *res, const void *lhs, uint16_t rhs, bool is_signed, uint16_t bits) { | ||
| 4876 | uint8_t *res_bytes = res; | ||
| 4877 | const uint8_t *lhs_bytes = lhs; | ||
| 4878 | uint16_t size = zig_int_bytes(bits); | ||
| 4879 | uint16_t res_byte_offset = UINT16_C(0); | ||
| 4880 | uint16_t lhs_byte_offset = zig_shr_u16(rhs, UINT8_C(3)); | ||
| 4881 | uint16_t end_byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1); | ||
| 4882 | uint8_t lhs_prev_byte; | ||
| 4883 | uint8_t byte_shift = zig_u8_truncate_u16(rhs, UINT8_C(3)); | ||
| 4884 | |||
| 4885 | #if zig_big_endian | ||
| 4886 | res_byte_offset = size - res_byte_offset; | ||
| 4887 | lhs_byte_offset = size - lhs_byte_offset; | ||
| 4888 | end_byte_offset = size - end_byte_offset; | ||
| 4889 | #endif | ||
| 4890 | |||
| 4891 | { | ||
| 4892 | #if zig_big_endian | ||
| 4893 | lhs_byte_offset -= UINT16_C(1); | ||
| 4894 | #endif | ||
| 4895 | |||
| 4896 | lhs_prev_byte = lhs_bytes[lhs_byte_offset]; | ||
| 4897 | |||
| 4898 | #if zig_little_endian | ||
| 4899 | lhs_byte_offset += UINT16_C(1); | ||
| 4900 | #endif | ||
| 4901 | } | ||
| 4902 | |||
| 4903 | while (lhs_byte_offset != end_byte_offset) { | ||
| 4904 | #if zig_big_endian | ||
| 4905 | res_byte_offset -= UINT16_C(1); | ||
| 4906 | lhs_byte_offset -= UINT16_C(1); | ||
| 4907 | #endif | ||
| 4908 | |||
| 4909 | { | ||
| 4910 | uint8_t lhs_byte = lhs_bytes[lhs_byte_offset]; | ||
| 4911 | |||
| 4912 | res_bytes[res_byte_offset] = zig_u8_intCast_u16(zig_shr_u16(zig_or_u16( | ||
| 4913 | zig_shl_u16(zig_u16_intCast_u8(lhs_byte), UINT8_C(8)), | ||
| 4914 | zig_u16_intCast_u8(lhs_prev_byte) | ||
| 4915 | ), byte_shift)); | ||
| 4916 | lhs_prev_byte = lhs_byte; | ||
| 4917 | } | ||
| 4918 | |||
| 4919 | #if zig_little_endian | ||
| 4920 | res_byte_offset += UINT16_C(1); | ||
| 4921 | lhs_byte_offset += UINT16_C(1); | ||
| 4922 | #endif | ||
| 4923 | } | ||
| 4924 | |||
| 4925 | { | ||
| 4926 | uint8_t lhs_sign_fill = UINT8_C(0); | ||
| 4927 | |||
| 4928 | #if zig_big_endian | ||
| 4929 | res_byte_offset -= UINT16_C(1); | ||
| 4930 | #endif | ||
| 4931 | |||
| 4932 | if (is_signed) { | ||
| 4933 | int8_t signed_byte = zig_i8_bitCast_u8(lhs_prev_byte, UINT8_C(8)); | ||
| 4934 | |||
| 4935 | res_bytes[res_byte_offset] = zig_shr_i8(signed_byte, byte_shift); | ||
| 4936 | lhs_sign_fill = zig_u8_bitCast_i8(zig_shr_i8(signed_byte, UINT8_C(7)), UINT8_C(8)); | ||
| 4937 | } else { | ||
| 4938 | res_bytes[res_byte_offset] = zig_shr_u8(lhs_prev_byte, byte_shift); | ||
| 4939 | } | ||
| 4940 | |||
| 4941 | #if zig_little_endian | ||
| 4942 | res_byte_offset += UINT16_C(1); | ||
| 4943 | memset(&res_bytes[res_byte_offset], lhs_sign_fill, size - res_byte_offset); | ||
| 4944 | #else | ||
| 4945 | memset(&res_bytes[0], lhs_sign_fill, res_byte_offset); | ||
| 4946 | #endif | ||
| 4947 | } | ||
| 4948 | } | ||
| 4949 | |||
| 4950 | static inline bool zig_shlo_big(void *res, const void *lhs, uint16_t rhs, bool is_signed, uint16_t bits) { | ||
| 4951 | uint8_t *res_bytes = res; | ||
| 4952 | const uint8_t *lhs_bytes = lhs; | ||
| 4953 | uint8_t lhs_sign_fill = zig_u8_bitCast_i8(zig_signFill_big(lhs, is_signed, bits), UINT8_C(8)); | ||
| 4954 | uint16_t size = zig_int_bytes(bits); | ||
| 4955 | uint16_t res_byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1); | ||
| 4956 | uint16_t lhs_byte_offset = UINT16_C(0); | ||
| 4957 | uint16_t end_byte_offset = res_byte_offset - UINT16_C(1) - zig_shr_u16(rhs, UINT8_C(3)); | ||
| 4958 | uint8_t lhs_prev_byte = lhs_sign_fill; | ||
| 4959 | uint8_t byte_shift = UINT8_C(8) - zig_u8_truncate_u16(rhs, UINT8_C(3)); | ||
| 4960 | bool overflow = false; | ||
| 4961 | |||
| 4962 | #if zig_little_endian | ||
| 4963 | lhs_byte_offset = size - lhs_byte_offset; | ||
| 4964 | #else | ||
| 4965 | res_byte_offset = size - res_byte_offset; | ||
| 4966 | end_byte_offset = size - end_byte_offset; | ||
| 4967 | #endif | ||
| 4968 | |||
| 4969 | while (lhs_byte_offset != end_byte_offset) { | ||
| 4970 | #if zig_little_endian | ||
| 4971 | lhs_byte_offset -= UINT16_C(1); | ||
| 4972 | #endif | ||
| 4973 | |||
| 4974 | overflow |= lhs_prev_byte != lhs_sign_fill; | ||
| 4975 | lhs_prev_byte = lhs_bytes[lhs_byte_offset]; | ||
| 4976 | |||
| 4977 | #if zig_big_endian | ||
| 4978 | lhs_byte_offset += UINT16_C(1); | ||
| 4979 | #endif | ||
| 4980 | } | ||
| 4981 | |||
| 4982 | #if zig_little_endian | ||
| 4983 | end_byte_offset = UINT16_C(0); | ||
| 4984 | #else | ||
| 4985 | end_byte_offset = size; | ||
| 4986 | #endif | ||
| 4987 | |||
| 4988 | { | ||
| 4989 | bool lhs_more_bytes = lhs_byte_offset != end_byte_offset; | ||
| 4990 | |||
| 4991 | #if zig_little_endian | ||
| 4992 | if (lhs_more_bytes) lhs_byte_offset -= UINT16_C(1); | ||
| 4993 | #endif | ||
| 4994 | |||
| 4995 | { | ||
| 4996 | uint8_t lhs_byte = UINT8_C(0); | ||
| 4997 | |||
| 4998 | if (lhs_more_bytes) lhs_byte = lhs_bytes[lhs_byte_offset]; | ||
| 4999 | |||
| 5000 | if (is_signed) { | ||
| 5001 | int16_t shifted = zig_shr_i16(zig_or_i16( | ||
| 5002 | zig_shl_i16(zig_i16_intCast_u8(lhs_prev_byte), UINT8_C(8)), | ||
| 5003 | zig_i16_intCast_u8(lhs_byte) | ||
| 5004 | ), byte_shift); | ||
| 5005 | int8_t truncated = zig_i8_truncate_i16( | ||
| 5006 | shifted, | ||
| 5007 | zig_u8_truncate_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT8_C(1) | ||
| 5008 | ); | ||
| 5009 | uint8_t fill = zig_u8_bitCast_i8(zig_shr_i8(truncated, UINT8_C(7)), UINT8_C(8)); | ||
| 5010 | |||
| 5011 | overflow |= zig_i16_intCast_i8(truncated) != shifted; | ||
| 5012 | #if zig_little_endian | ||
| 5013 | memset(&res_bytes[res_byte_offset], fill, size - res_byte_offset); | ||
| 5014 | res_byte_offset -= UINT16_C(1); | ||
| 5015 | #else | ||
| 5016 | memset(&res_bytes[0], fill, res_byte_offset); | ||
| 5017 | #endif | ||
| 5018 | res_bytes[res_byte_offset] = zig_u8_bitCast_i8(truncated, UINT8_C(8)); | ||
| 5019 | } else { | ||
| 5020 | uint16_t shifted = zig_shr_u16(zig_or_u16( | ||
| 5021 | zig_shl_u16(zig_u16_intCast_u8(lhs_prev_byte), UINT8_C(8)), | ||
| 5022 | zig_u16_intCast_u8(lhs_byte) | ||
| 5023 | ), byte_shift); | ||
| 5024 | uint8_t truncated = zig_u8_truncate_u16( | ||
| 5025 | shifted, | ||
| 5026 | zig_u8_truncate_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT8_C(1) | ||
| 5027 | ); | ||
| 5028 | |||
| 5029 | overflow |= zig_u16_intCast_u8(truncated) != shifted; | ||
| 5030 | #if zig_little_endian | ||
| 5031 | memset(&res_bytes[res_byte_offset], zig_minInt_u8, size - res_byte_offset); | ||
| 5032 | res_byte_offset -= UINT16_C(1); | ||
| 5033 | #else | ||
| 5034 | memset(&res_bytes[0], zig_minInt_u8, res_byte_offset); | ||
| 5035 | #endif | ||
| 5036 | res_bytes[res_byte_offset] = truncated; | ||
| 5037 | } | ||
| 5038 | |||
| 5039 | lhs_prev_byte = lhs_byte; | ||
| 5040 | } | ||
| 5041 | |||
| 5042 | #if zig_big_endian | ||
| 5043 | res_byte_offset += UINT16_C(1); | ||
| 5044 | if (lhs_more_bytes) lhs_byte_offset += UINT16_C(1); | ||
| 5045 | #endif | ||
| 5046 | } | ||
| 5047 | |||
| 5048 | while (lhs_byte_offset != end_byte_offset) { | ||
| 5049 | #if zig_little_endian | ||
| 5050 | res_byte_offset -= UINT16_C(1); | ||
| 5051 | lhs_byte_offset -= UINT16_C(1); | ||
| 5052 | #endif | ||
| 5053 | |||
| 5054 | { | ||
| 5055 | uint8_t lhs_byte = lhs_bytes[lhs_byte_offset]; | ||
| 5056 | |||
| 5057 | res_bytes[res_byte_offset] = zig_u8_intCast_u16(zig_shr_u16(zig_or_u16( | ||
| 5058 | zig_shl_u16(zig_u16_intCast_u8(lhs_prev_byte), UINT8_C(8)), | ||
| 5059 | zig_u16_intCast_u8(lhs_byte) | ||
| 5060 | ), byte_shift)); | ||
| 5061 | lhs_prev_byte = lhs_byte; | ||
| 5062 | } | ||
| 5063 | |||
| 5064 | #if zig_big_endian | ||
| 5065 | res_byte_offset += UINT16_C(1); | ||
| 5066 | lhs_byte_offset += UINT16_C(1); | ||
| 5067 | #endif | ||
| 5068 | } | ||
| 5069 | |||
| 5070 | { | ||
| 5071 | #if zig_little_endian | ||
| 5072 | res_byte_offset -= UINT16_C(1); | ||
| 5073 | #endif | ||
| 5074 | |||
| 5075 | res_bytes[res_byte_offset] = zig_u8_intCast_u16(zig_shr_u16( | ||
| 5076 | zig_shl_u16(zig_u16_intCast_u8(lhs_prev_byte), UINT8_C(8)), | ||
| 5077 | byte_shift | ||
| 5078 | )); | ||
| 5079 | |||
| 5080 | #if zig_big_endian | ||
| 5081 | res_byte_offset += UINT16_C(1); | ||
| 5082 | #endif | ||
| 5083 | } | ||
| 5084 | |||
| 5085 | #if zig_little_endian | ||
| 5086 | memset(&res_bytes[0], zig_minInt_u8, res_byte_offset); | ||
| 5087 | #else | ||
| 5088 | memset(&res_bytes[res_byte_offset], zig_minInt_u8, size - res_byte_offset); | ||
| 5089 | #endif | ||
| 5090 | |||
| 5091 | return overflow; | ||
| 5092 | } | ||
| 5093 | |||
| 5094 | static inline void zig_shl_big(void *res, const void *lhs, uint16_t rhs, bool is_signed, uint16_t bits) { | ||
| 5095 | if (zig_shlo_big(res, lhs, rhs, is_signed, bits)) zig_trap(); // panic: left shift overflowed bits | ||
| 5096 | } | ||
| 5097 | |||
| 5098 | static inline void zig_shlw_big(void *res, const void *lhs, uint16_t rhs, bool is_signed, uint16_t bits) { | ||
| 5099 | (void)zig_shlo_big(res, lhs, rhs, is_signed, bits); | ||
| 5100 | } | ||
| 5101 | |||
| 5102 | #define zig_big_shls_builtin(w) \ | ||
| 5103 | static inline uint##w##_t zig_shls_u##w##_big(uint##w##_t lhs, const void *rhs, \ | ||
| 5104 | uint8_t lhs_bits, bool rhs_is_signed, uint16_t rhs_bits) { \ | ||
| 5105 | uint##w##_t res; \ | ||
| 5106 | const uint8_t *rhs_bytes = rhs; \ | ||
| 5107 | if (zig_cmp_big_u8(rhs, lhs_bits, rhs_is_signed, rhs_bits) < INT32_C(0) && \ | ||
| 5108 | !zig_shlo_u##w(&res, lhs, rhs_bytes[0], lhs_bits)) return res; \ | ||
| 5109 | return lhs == INT##w##_C(0) ? zig_minInt_u(w, lhs_bits) : zig_maxInt_u(w, lhs_bits); \ | ||
| 5110 | } \ | ||
| 5111 | \ | ||
| 5112 | static inline int##w##_t zig_shls_i##w##_big(int##w##_t lhs, const void *rhs, \ | ||
| 5113 | uint8_t lhs_bits, bool rhs_is_signed, uint16_t rhs_bits) { \ | ||
| 5114 | int##w##_t res; \ | ||
| 5115 | const uint8_t *rhs_bytes = rhs; \ | ||
| 5116 | if (zig_cmp_big_u8(rhs, lhs_bits, rhs_is_signed, rhs_bits) < INT32_C(0) && \ | ||
| 5117 | !zig_shlo_i##w(&res, lhs, rhs_bytes[0], lhs_bits)) return res; \ | ||
| 5118 | return lhs == INT##w##_C(0) ? INT##w##_C(0) : \ | ||
| 5119 | lhs < INT##w##_C(0) ? zig_minInt_i(w, lhs_bits) : zig_maxInt_i(w, lhs_bits); \ | ||
| 5120 | } \ | ||
| 5121 | \ | ||
| 5122 | static inline void zig_shls_big_u##w(void *res, const void *lhs, uint##w##_t rhs, bool is_signed, uint16_t bits) { \ | ||
| 5123 | const uint8_t *lhs_bytes = lhs; \ | ||
| 5124 | if (rhs < bits && !zig_shlo_big(res, lhs, zig_u16_intCast_u##w(rhs), is_signed, bits)) return; \ | ||
| 5125 | switch (zig_cmp_big_u8(lhs, UINT8_C(0), is_signed, bits)) { \ | ||
| 5126 | case -INT32_C(1): return zig_minInt_big(res, is_signed, bits); \ | ||
| 5127 | case INT32_C(0): return zig_minInt_big(res, false, bits); \ | ||
| 5128 | case INT32_C(1): return zig_maxInt_big(res, is_signed, bits); \ | ||
| 5129 | default: zig_unreachable(); \ | ||
| 5130 | } \ | ||
| 5131 | } | ||
| 5132 | zig_big_shls_builtin(8) | ||
| 5133 | zig_big_shls_builtin(16) | ||
| 5134 | zig_big_shls_builtin(32) | ||
| 5135 | zig_big_shls_builtin(64) | ||
| 5136 | |||
| 5137 | static inline void zig_byteSwap_big(void *res, const void *arg, bool is_signed, uint16_t bits) { | ||
| 5138 | uint8_t *res_bytes = res; | ||
| 5139 | const uint8_t *arg_bytes = arg; | ||
| 5140 | uint16_t res_byte_offset = UINT16_C(0); | ||
| 5141 | uint16_t arg_byte_offset = bits / CHAR_BIT; | ||
| 5142 | uint16_t end_byte_offset = UINT16_C(1); | ||
| 5143 | uint16_t size = zig_int_bytes(bits); | ||
| 5144 | |||
| 5145 | #if zig_big_endian | ||
| 5146 | res_byte_offset = size - res_byte_offset; | ||
| 5147 | arg_byte_offset = size - arg_byte_offset; | ||
| 5148 | end_byte_offset = size - end_byte_offset; | ||
| 5149 | #endif | ||
| 5150 | |||
| 5151 | while (arg_byte_offset != end_byte_offset) { | ||
| 5152 | #if zig_little_endian | ||
| 5153 | arg_byte_offset -= UINT16_C(1); | ||
| 5154 | #else | ||
| 5155 | res_byte_offset -= UINT16_C(1); | ||
| 5156 | #endif | ||
| 5157 | |||
| 5158 | res_bytes[res_byte_offset] = arg_bytes[arg_byte_offset]; | ||
| 3242 | 5159 | ||
| 3243 | #if zig_little_endian | 5160 | #if zig_little_endian |
| 3244 | byte_offset += 8 / CHAR_BIT; | 5161 | res_byte_offset += UINT16_C(1); |
| 5162 | #else | ||
| 5163 | arg_byte_offset += UINT16_C(1); | ||
| 3245 | #endif | 5164 | #endif |
| 3246 | } | 5165 | } |
| 3247 | 5166 | ||
| 3248 | return overflow; | 5167 | { |
| 3249 | } | 5168 | #if zig_little_endian |
| 5169 | arg_byte_offset -= UINT16_C(1); | ||
| 5170 | #else | ||
| 5171 | res_byte_offset -= UINT16_C(1); | ||
| 5172 | #endif | ||
| 3250 | 5173 | ||
| 3251 | static inline void zig_addw_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | 5174 | { |
| 3252 | (void)zig_addo_big(res, lhs, rhs, is_signed, bits); | 5175 | uint8_t byte = arg_bytes[arg_byte_offset]; |
| 3253 | } | 5176 | uint8_t fill = is_signed |
| 5177 | ? zig_u8_bitCast_i8(zig_shr_i8(zig_i8_bitCast_u8(byte, UINT8_C(8)), UINT8_C(7)), UINT8_C(8)) | ||
| 5178 | : UINT8_C(0); | ||
| 3254 | 5179 | ||
| 3255 | static inline void zig_subw_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | 5180 | res_bytes[res_byte_offset] = byte; |
| 3256 | (void)zig_subo_big(res, lhs, rhs, is_signed, bits); | ||
| 3257 | } | ||
| 3258 | 5181 | ||
| 3259 | zig_extern void __udivei4(uint32_t *res, const uint32_t *lhs, const uint32_t *rhs, uintptr_t bits); | 5182 | #if zig_little_endian |
| 3260 | static inline void zig_div_trunc_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | 5183 | res_byte_offset += UINT16_C(1); |
| 3261 | if (!is_signed) { | 5184 | memset(&res_bytes[res_byte_offset], fill, size - res_byte_offset); |
| 3262 | __udivei4(res, lhs, rhs, bits); | 5185 | #else |
| 3263 | return; | 5186 | memset(&res_bytes[0], fill, res_byte_offset); |
| 5187 | #endif | ||
| 5188 | } | ||
| 3264 | } | 5189 | } |
| 3265 | |||
| 3266 | zig_trap(); | ||
| 3267 | } | 5190 | } |
| 3268 | 5191 | ||
| 3269 | static inline void zig_div_floor_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | 5192 | static inline void zig_bitReverse_big(void *res, const void *arg, bool is_signed, uint16_t bits) { |
| 3270 | if (!is_signed) { | 5193 | uint8_t *res_bytes = res; |
| 3271 | zig_div_trunc_big(res, lhs, rhs, is_signed, bits); | 5194 | const uint8_t *arg_bytes = arg; |
| 3272 | return; | 5195 | uint16_t size = zig_int_bytes(bits); |
| 3273 | } | 5196 | uint16_t res_byte_offset = UINT16_C(0); |
| 5197 | uint16_t arg_byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1); | ||
| 5198 | uint16_t end_byte_offset = UINT16_C(0); | ||
| 5199 | uint8_t arg_prev_byte; | ||
| 5200 | uint8_t byte_shift = zig_u8_intCast_u16(zig_subw_u16(UINT16_C(0), bits, UINT8_C(3))); | ||
| 3274 | 5201 | ||
| 3275 | zig_trap(); | 5202 | #if zig_big_endian |
| 3276 | } | 5203 | res_byte_offset = size - res_byte_offset; |
| 5204 | arg_byte_offset = size - arg_byte_offset; | ||
| 5205 | end_byte_offset = size - end_byte_offset; | ||
| 5206 | #endif | ||
| 3277 | 5207 | ||
| 3278 | static inline void zig_div_ceil_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | 5208 | { |
| 3279 | zig_trap(); | 5209 | #if zig_little_endian |
| 3280 | } | 5210 | arg_byte_offset -= UINT16_C(1); |
| 5211 | #endif | ||
| 3281 | 5212 | ||
| 3282 | zig_extern void __umodei4(uint32_t *res, const uint32_t *lhs, const uint32_t *rhs, uintptr_t bits); | 5213 | arg_prev_byte = zig_bitReverse_u8(arg_bytes[arg_byte_offset], UINT8_C(8)); |
| 3283 | static inline void zig_rem_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | 5214 | |
| 3284 | if (!is_signed) { | 5215 | #if zig_big_endian |
| 3285 | __umodei4(res, lhs, rhs, bits); | 5216 | arg_byte_offset += UINT16_C(1); |
| 3286 | return; | 5217 | #endif |
| 3287 | } | 5218 | } |
| 3288 | 5219 | ||
| 3289 | zig_trap(); | 5220 | while (arg_byte_offset != end_byte_offset) { |
| 3290 | } | 5221 | #if zig_big_endian |
| 5222 | res_byte_offset -= UINT16_C(1); | ||
| 5223 | #else | ||
| 5224 | arg_byte_offset -= UINT16_C(1); | ||
| 5225 | #endif | ||
| 3291 | 5226 | ||
| 3292 | static inline void zig_mod_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | 5227 | { |
| 3293 | if (!is_signed) { | 5228 | uint8_t arg_byte = zig_bitReverse_u8(arg_bytes[arg_byte_offset], UINT8_C(8)); |
| 3294 | zig_rem_big(res, lhs, rhs, is_signed, bits); | 5229 | |
| 3295 | return; | 5230 | res_bytes[res_byte_offset] = zig_u8_intCast_u16(zig_shr_u16(zig_or_u16( |
| 5231 | zig_shl_u16(zig_u16_intCast_u8(arg_byte), UINT8_C(8)), | ||
| 5232 | zig_u16_intCast_u8(arg_prev_byte) | ||
| 5233 | ), byte_shift)); | ||
| 5234 | arg_prev_byte = arg_byte; | ||
| 5235 | } | ||
| 5236 | |||
| 5237 | #if zig_little_endian | ||
| 5238 | res_byte_offset += UINT16_C(1); | ||
| 5239 | #else | ||
| 5240 | arg_byte_offset += UINT16_C(1); | ||
| 5241 | #endif | ||
| 3296 | } | 5242 | } |
| 3297 | 5243 | ||
| 3298 | zig_trap(); | 5244 | { |
| 5245 | uint8_t arg_sign_fill = UINT8_C(0); | ||
| 5246 | |||
| 5247 | #if zig_big_endian | ||
| 5248 | res_byte_offset -= UINT16_C(1); | ||
| 5249 | #endif | ||
| 5250 | |||
| 5251 | if (is_signed) { | ||
| 5252 | int8_t signed_byte = zig_i8_bitCast_u8(arg_prev_byte, UINT8_C(8)); | ||
| 5253 | |||
| 5254 | res_bytes[res_byte_offset] = zig_shr_i8(signed_byte, byte_shift); | ||
| 5255 | arg_sign_fill = zig_u8_bitCast_i8(zig_shr_i8(signed_byte, UINT8_C(7)), UINT8_C(8)); | ||
| 5256 | } else { | ||
| 5257 | res_bytes[res_byte_offset] = zig_shr_u8(arg_prev_byte, byte_shift); | ||
| 5258 | } | ||
| 5259 | |||
| 5260 | #if zig_little_endian | ||
| 5261 | res_byte_offset += UINT16_C(1); | ||
| 5262 | memset(&res_bytes[res_byte_offset], arg_sign_fill, size - res_byte_offset); | ||
| 5263 | #else | ||
| 5264 | memset(&res_bytes[0], arg_sign_fill, res_byte_offset); | ||
| 5265 | #endif | ||
| 5266 | } | ||
| 3299 | } | 5267 | } |
| 3300 | 5268 | ||
| 3301 | static inline uint16_t zig_clz_big(const void *val, bool is_signed, uint16_t bits) { | 5269 | static inline uint16_t zig_popCount_big(const void *arg, bool is_signed, uint16_t bits) { |
| 3302 | const uint8_t *val_bytes = val; | 5270 | const uint8_t *arg_bytes = arg; |
| 3303 | uint16_t byte_offset = 0; | 5271 | uint16_t byte_offset = 0; |
| 3304 | uint16_t remaining_bytes = zig_int_bytes(bits); | 5272 | uint16_t remaining_bytes = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1); |
| 3305 | uint16_t skip_bits = remaining_bytes * 8 - bits; | 5273 | uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits); |
| 3306 | uint16_t total_lz = 0; | 5274 | uint16_t total_pc = 0; |
| 3307 | uint16_t limb_lz; | ||
| 3308 | (void)is_signed; | 5275 | (void)is_signed; |
| 3309 | 5276 | ||
| 3310 | #if zig_little_endian | 5277 | #if zig_big_endian |
| 3311 | byte_offset = remaining_bytes; | 5278 | byte_offset = zig_int_bytes(bits); |
| 3312 | #endif | 5279 | #endif |
| 3313 | 5280 | ||
| 3314 | while (remaining_bytes >= 128 / CHAR_BIT) { | 5281 | while (remaining_bytes >= 128 / CHAR_BIT) { |
| 3315 | #if zig_little_endian | 5282 | uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0); |
| 5283 | |||
| 5284 | #if zig_big_endian | ||
| 3316 | byte_offset -= 128 / CHAR_BIT; | 5285 | byte_offset -= 128 / CHAR_BIT; |
| 3317 | #endif | 5286 | #endif |
| 3318 | 5287 | ||
| 3319 | { | 5288 | { |
| 3320 | zig_u128 val_limb; | 5289 | zig_u128 arg_limb; |
| 3321 | 5290 | ||
| 3322 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | 5291 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); |
| 3323 | limb_lz = zig_clz_u128(val_limb, 128 - skip_bits); | 5292 | total_pc += zig_popCount_u128(zig_u128_truncate_u128(arg_limb, limb_bits), limb_bits); |
| 3324 | } | 5293 | } |
| 3325 | 5294 | ||
| 3326 | total_lz += limb_lz; | ||
| 3327 | if (limb_lz < 128 - skip_bits) return total_lz; | ||
| 3328 | skip_bits = 0; | ||
| 3329 | remaining_bytes -= 128 / CHAR_BIT; | 5295 | remaining_bytes -= 128 / CHAR_BIT; |
| 3330 | 5296 | ||
| 3331 | #if zig_big_endian | 5297 | #if zig_little_endian |
| 3332 | byte_offset += 128 / CHAR_BIT; | 5298 | byte_offset += 128 / CHAR_BIT; |
| 3333 | #endif | 5299 | #endif |
| 3334 | } | 5300 | } |
| 3335 | 5301 | ||
| 3336 | while (remaining_bytes >= 64 / CHAR_BIT) { | 5302 | while (remaining_bytes >= 64 / CHAR_BIT) { |
| 3337 | #if zig_little_endian | 5303 | uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0); |
| 5304 | |||
| 5305 | #if zig_big_endian | ||
| 3338 | byte_offset -= 64 / CHAR_BIT; | 5306 | byte_offset -= 64 / CHAR_BIT; |
| 3339 | #endif | 5307 | #endif |
| 3340 | 5308 | ||
| 3341 | { | 5309 | { |
| 3342 | uint64_t val_limb; | 5310 | uint64_t arg_limb; |
| 3343 | 5311 | ||
| 3344 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | 5312 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); |
| 3345 | limb_lz = zig_clz_u64(val_limb, 64 - skip_bits); | 5313 | total_pc += zig_popCount_u64(zig_u64_truncate_u64(arg_limb, limb_bits), limb_bits); |
| 3346 | } | 5314 | } |
| 3347 | 5315 | ||
| 3348 | total_lz += limb_lz; | ||
| 3349 | if (limb_lz < 64 - skip_bits) return total_lz; | ||
| 3350 | skip_bits = 0; | ||
| 3351 | remaining_bytes -= 64 / CHAR_BIT; | 5316 | remaining_bytes -= 64 / CHAR_BIT; |
| 3352 | 5317 | ||
| 3353 | #if zig_big_endian | 5318 | #if zig_little_endian |
| 3354 | byte_offset += 64 / CHAR_BIT; | 5319 | byte_offset += 64 / CHAR_BIT; |
| 3355 | #endif | 5320 | #endif |
| 3356 | } | 5321 | } |
| 3357 | 5322 | ||
| 3358 | while (remaining_bytes >= 32 / CHAR_BIT) { | 5323 | while (remaining_bytes >= 32 / CHAR_BIT) { |
| 3359 | #if zig_little_endian | 5324 | uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0); |
| 5325 | |||
| 5326 | #if zig_big_endian | ||
| 3360 | byte_offset -= 32 / CHAR_BIT; | 5327 | byte_offset -= 32 / CHAR_BIT; |
| 3361 | #endif | 5328 | #endif |
| 3362 | 5329 | ||
| 3363 | { | 5330 | { |
| 3364 | uint32_t val_limb; | 5331 | uint32_t arg_limb; |
| 3365 | 5332 | ||
| 3366 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | 5333 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); |
| 3367 | limb_lz = zig_clz_u32(val_limb, 32 - skip_bits); | 5334 | total_pc += zig_popCount_u32(zig_u32_truncate_u32(arg_limb, limb_bits), limb_bits); |
| 3368 | } | 5335 | } |
| 3369 | 5336 | ||
| 3370 | total_lz += limb_lz; | ||
| 3371 | if (limb_lz < 32 - skip_bits) return total_lz; | ||
| 3372 | skip_bits = 0; | ||
| 3373 | remaining_bytes -= 32 / CHAR_BIT; | 5337 | remaining_bytes -= 32 / CHAR_BIT; |
| 3374 | 5338 | ||
| 3375 | #if zig_big_endian | 5339 | #if zig_little_endian |
| 3376 | byte_offset += 32 / CHAR_BIT; | 5340 | byte_offset += 32 / CHAR_BIT; |
| 3377 | #endif | 5341 | #endif |
| 3378 | } | 5342 | } |
| 3379 | 5343 | ||
| 3380 | while (remaining_bytes >= 16 / CHAR_BIT) { | 5344 | while (remaining_bytes >= 16 / CHAR_BIT) { |
| 3381 | #if zig_little_endian | 5345 | uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0); |
| 5346 | |||
| 5347 | #if zig_big_endian | ||
| 3382 | byte_offset -= 16 / CHAR_BIT; | 5348 | byte_offset -= 16 / CHAR_BIT; |
| 3383 | #endif | 5349 | #endif |
| 3384 | 5350 | ||
| 3385 | { | 5351 | { |
| 3386 | uint16_t val_limb; | 5352 | uint16_t arg_limb; |
| 3387 | 5353 | ||
| 3388 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | 5354 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); |
| 3389 | limb_lz = zig_clz_u16(val_limb, 16 - skip_bits); | 5355 | total_pc += zig_popCount_u16(zig_u16_truncate_u16(arg_limb, limb_bits), limb_bits); |
| 3390 | } | 5356 | } |
| 3391 | 5357 | ||
| 3392 | total_lz += limb_lz; | ||
| 3393 | if (limb_lz < 16 - skip_bits) return total_lz; | ||
| 3394 | skip_bits = 0; | ||
| 3395 | remaining_bytes -= 16 / CHAR_BIT; | 5358 | remaining_bytes -= 16 / CHAR_BIT; |
| 3396 | 5359 | ||
| 3397 | #if zig_big_endian | 5360 | #if zig_little_endian |
| 3398 | byte_offset += 16 / CHAR_BIT; | 5361 | byte_offset += 16 / CHAR_BIT; |
| 3399 | #endif | 5362 | #endif |
| 3400 | } | 5363 | } |
| 3401 | 5364 | ||
| 3402 | while (remaining_bytes >= 8 / CHAR_BIT) { | 5365 | while (remaining_bytes >= 8 / CHAR_BIT) { |
| 3403 | #if zig_little_endian | 5366 | uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0); |
| 5367 | |||
| 5368 | #if zig_big_endian | ||
| 3404 | byte_offset -= 8 / CHAR_BIT; | 5369 | byte_offset -= 8 / CHAR_BIT; |
| 3405 | #endif | 5370 | #endif |
| 3406 | 5371 | ||
| 3407 | { | 5372 | { |
| 3408 | uint8_t val_limb; | 5373 | uint8_t arg_limb; |
| 3409 | 5374 | ||
| 3410 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | 5375 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); |
| 3411 | limb_lz = zig_clz_u8(val_limb, 8 - skip_bits); | 5376 | total_pc += zig_popCount_u8(zig_u8_truncate_u8(arg_limb, limb_bits), limb_bits); |
| 3412 | } | 5377 | } |
| 3413 | 5378 | ||
| 3414 | total_lz += limb_lz; | ||
| 3415 | if (limb_lz < 8 - skip_bits) return total_lz; | ||
| 3416 | skip_bits = 0; | ||
| 3417 | remaining_bytes -= 8 / CHAR_BIT; | 5379 | remaining_bytes -= 8 / CHAR_BIT; |
| 3418 | 5380 | ||
| 3419 | #if zig_big_endian | 5381 | #if zig_little_endian |
| 3420 | byte_offset += 8 / CHAR_BIT; | 5382 | byte_offset += 8 / CHAR_BIT; |
| 3421 | #endif | 5383 | #endif |
| 3422 | } | 5384 | } |
| 3423 | 5385 | ||
| 3424 | return total_lz; | 5386 | return total_pc; |
| 3425 | } | 5387 | } |
| 3426 | 5388 | ||
| 3427 | static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bits) { | 5389 | static inline uint16_t zig_ctz_big(const void *arg, bool is_signed, uint16_t bits) { |
| 3428 | const uint8_t *val_bytes = val; | 5390 | const uint8_t *arg_bytes = arg; |
| 3429 | uint16_t byte_offset = 0; | 5391 | uint16_t byte_offset = UINT16_C(0); |
| 3430 | uint16_t remaining_bytes = zig_int_bytes(bits); | 5392 | uint16_t remaining_bytes = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1); |
| 3431 | uint16_t total_tz = 0; | 5393 | uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits); |
| 5394 | uint16_t total_tz = UINT16_C(0); | ||
| 3432 | uint16_t limb_tz; | 5395 | uint16_t limb_tz; |
| 3433 | (void)is_signed; | 5396 | (void)is_signed; |
| 3434 | 5397 | ||
| 3435 | #if zig_big_endian | 5398 | #if zig_big_endian |
| 3436 | byte_offset = remaining_bytes; | 5399 | byte_offset = zig_int_bytes(bits); |
| 3437 | #endif | 5400 | #endif |
| 3438 | 5401 | ||
| 3439 | while (remaining_bytes >= 128 / CHAR_BIT) { | 5402 | while (remaining_bytes >= 128 / CHAR_BIT) { |
| 5403 | uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0); | ||
| 5404 | |||
| 3440 | #if zig_big_endian | 5405 | #if zig_big_endian |
| 3441 | byte_offset -= 128 / CHAR_BIT; | 5406 | byte_offset -= 128 / CHAR_BIT; |
| 3442 | #endif | 5407 | #endif |
| 3443 | 5408 | ||
| 3444 | { | 5409 | { |
| 3445 | zig_u128 val_limb; | 5410 | zig_u128 arg_limb; |
| 3446 | 5411 | ||
| 3447 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | 5412 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); |
| 3448 | limb_tz = zig_ctz_u128(val_limb, 128); | 5413 | limb_tz = zig_ctz_u128(zig_u128_truncate_u128(arg_limb, limb_bits), limb_bits); |
| 3449 | } | 5414 | } |
| 3450 | 5415 | ||
| 3451 | total_tz += limb_tz; | 5416 | total_tz += limb_tz; |
| 3452 | if (limb_tz < 128) return total_tz; | 5417 | if (limb_tz < limb_bits) return total_tz; |
| 3453 | remaining_bytes -= 128 / CHAR_BIT; | 5418 | remaining_bytes -= 128 / CHAR_BIT; |
| 3454 | 5419 | ||
| 3455 | #if zig_little_endian | 5420 | #if zig_little_endian |
| ... | @@ -3458,19 +5423,21 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit | ... | @@ -3458,19 +5423,21 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit |
| 3458 | } | 5423 | } |
| 3459 | 5424 | ||
| 3460 | while (remaining_bytes >= 64 / CHAR_BIT) { | 5425 | while (remaining_bytes >= 64 / CHAR_BIT) { |
| 5426 | uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0); | ||
| 5427 | |||
| 3461 | #if zig_big_endian | 5428 | #if zig_big_endian |
| 3462 | byte_offset -= 64 / CHAR_BIT; | 5429 | byte_offset -= 64 / CHAR_BIT; |
| 3463 | #endif | 5430 | #endif |
| 3464 | 5431 | ||
| 3465 | { | 5432 | { |
| 3466 | uint64_t val_limb; | 5433 | uint64_t arg_limb; |
| 3467 | 5434 | ||
| 3468 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | 5435 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); |
| 3469 | limb_tz = zig_ctz_u64(val_limb, 64); | 5436 | limb_tz = zig_ctz_u64(zig_u64_truncate_u64(arg_limb, limb_bits), limb_bits); |
| 3470 | } | 5437 | } |
| 3471 | 5438 | ||
| 3472 | total_tz += limb_tz; | 5439 | total_tz += limb_tz; |
| 3473 | if (limb_tz < 64) return total_tz; | 5440 | if (limb_tz < limb_bits) return total_tz; |
| 3474 | remaining_bytes -= 64 / CHAR_BIT; | 5441 | remaining_bytes -= 64 / CHAR_BIT; |
| 3475 | 5442 | ||
| 3476 | #if zig_little_endian | 5443 | #if zig_little_endian |
| ... | @@ -3479,19 +5446,21 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit | ... | @@ -3479,19 +5446,21 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit |
| 3479 | } | 5446 | } |
| 3480 | 5447 | ||
| 3481 | while (remaining_bytes >= 32 / CHAR_BIT) { | 5448 | while (remaining_bytes >= 32 / CHAR_BIT) { |
| 5449 | uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0); | ||
| 5450 | |||
| 3482 | #if zig_big_endian | 5451 | #if zig_big_endian |
| 3483 | byte_offset -= 32 / CHAR_BIT; | 5452 | byte_offset -= 32 / CHAR_BIT; |
| 3484 | #endif | 5453 | #endif |
| 3485 | 5454 | ||
| 3486 | { | 5455 | { |
| 3487 | uint32_t val_limb; | 5456 | uint32_t arg_limb; |
| 3488 | 5457 | ||
| 3489 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | 5458 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); |
| 3490 | limb_tz = zig_ctz_u32(val_limb, 32); | 5459 | limb_tz = zig_ctz_u32(zig_u32_truncate_u32(arg_limb, limb_bits), limb_bits); |
| 3491 | } | 5460 | } |
| 3492 | 5461 | ||
| 3493 | total_tz += limb_tz; | 5462 | total_tz += limb_tz; |
| 3494 | if (limb_tz < 32) return total_tz; | 5463 | if (limb_tz < limb_bits) return total_tz; |
| 3495 | remaining_bytes -= 32 / CHAR_BIT; | 5464 | remaining_bytes -= 32 / CHAR_BIT; |
| 3496 | 5465 | ||
| 3497 | #if zig_little_endian | 5466 | #if zig_little_endian |
| ... | @@ -3500,19 +5469,21 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit | ... | @@ -3500,19 +5469,21 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit |
| 3500 | } | 5469 | } |
| 3501 | 5470 | ||
| 3502 | while (remaining_bytes >= 16 / CHAR_BIT) { | 5471 | while (remaining_bytes >= 16 / CHAR_BIT) { |
| 5472 | uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0); | ||
| 5473 | |||
| 3503 | #if zig_big_endian | 5474 | #if zig_big_endian |
| 3504 | byte_offset -= 16 / CHAR_BIT; | 5475 | byte_offset -= 16 / CHAR_BIT; |
| 3505 | #endif | 5476 | #endif |
| 3506 | 5477 | ||
| 3507 | { | 5478 | { |
| 3508 | uint16_t val_limb; | 5479 | uint16_t arg_limb; |
| 3509 | 5480 | ||
| 3510 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | 5481 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); |
| 3511 | limb_tz = zig_ctz_u16(val_limb, 16); | 5482 | limb_tz = zig_ctz_u16(zig_u16_truncate_u16(arg_limb, limb_bits), limb_bits); |
| 3512 | } | 5483 | } |
| 3513 | 5484 | ||
| 3514 | total_tz += limb_tz; | 5485 | total_tz += limb_tz; |
| 3515 | if (limb_tz < 16) return total_tz; | 5486 | if (limb_tz < limb_bits) return total_tz; |
| 3516 | remaining_bytes -= 16 / CHAR_BIT; | 5487 | remaining_bytes -= 16 / CHAR_BIT; |
| 3517 | 5488 | ||
| 3518 | #if zig_little_endian | 5489 | #if zig_little_endian |
| ... | @@ -3521,19 +5492,21 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit | ... | @@ -3521,19 +5492,21 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit |
| 3521 | } | 5492 | } |
| 3522 | 5493 | ||
| 3523 | while (remaining_bytes >= 8 / CHAR_BIT) { | 5494 | while (remaining_bytes >= 8 / CHAR_BIT) { |
| 5495 | uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0); | ||
| 5496 | |||
| 3524 | #if zig_big_endian | 5497 | #if zig_big_endian |
| 3525 | byte_offset -= 8 / CHAR_BIT; | 5498 | byte_offset -= 8 / CHAR_BIT; |
| 3526 | #endif | 5499 | #endif |
| 3527 | 5500 | ||
| 3528 | { | 5501 | { |
| 3529 | uint8_t val_limb; | 5502 | uint8_t arg_limb; |
| 3530 | 5503 | ||
| 3531 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | 5504 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); |
| 3532 | limb_tz = zig_ctz_u8(val_limb, 8); | 5505 | limb_tz = zig_ctz_u8(zig_u8_truncate_u8(arg_limb, limb_bits), limb_bits); |
| 3533 | } | 5506 | } |
| 3534 | 5507 | ||
| 3535 | total_tz += limb_tz; | 5508 | total_tz += limb_tz; |
| 3536 | if (limb_tz < 8) return total_tz; | 5509 | if (limb_tz < limb_bits) return total_tz; |
| 3537 | remaining_bytes -= 8 / CHAR_BIT; | 5510 | remaining_bytes -= 8 / CHAR_BIT; |
| 3538 | 5511 | ||
| 3539 | #if zig_little_endian | 5512 | #if zig_little_endian |
| ... | @@ -3544,113 +5517,141 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit | ... | @@ -3544,113 +5517,141 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit |
| 3544 | return total_tz; | 5517 | return total_tz; |
| 3545 | } | 5518 | } |
| 3546 | 5519 | ||
| 3547 | static inline uint16_t zig_popcount_big(const void *val, bool is_signed, uint16_t bits) { | 5520 | static inline uint16_t zig_clz_big(const void *arg, bool is_signed, uint16_t bits) { |
| 3548 | const uint8_t *val_bytes = val; | 5521 | const uint8_t *arg_bytes = arg; |
| 3549 | uint16_t byte_offset = 0; | 5522 | uint16_t byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1); |
| 3550 | uint16_t remaining_bytes = zig_int_bytes(bits); | 5523 | uint16_t remaining_bytes = byte_offset; |
| 3551 | uint16_t total_pc = 0; | 5524 | uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits); |
| 5525 | bool sign_limb = true; | ||
| 5526 | uint16_t total_lz = UINT16_C(0); | ||
| 5527 | uint16_t limb_lz; | ||
| 3552 | (void)is_signed; | 5528 | (void)is_signed; |
| 3553 | 5529 | ||
| 3554 | #if zig_big_endian | 5530 | #if zig_big_endian |
| 3555 | byte_offset = remaining_bytes; | 5531 | byte_offset = zig_int_bytes(bits) - remaining_bytes; |
| 3556 | #endif | 5532 | #endif |
| 3557 | 5533 | ||
| 3558 | while (remaining_bytes >= 128 / CHAR_BIT) { | 5534 | while (remaining_bytes >= 128 / CHAR_BIT) { |
| 3559 | #if zig_big_endian | 5535 | uint8_t limb_bits = UINT8_C(128) - (sign_limb ? top_bits : UINT8_C(0)); |
| 5536 | |||
| 5537 | #if zig_little_endian | ||
| 3560 | byte_offset -= 128 / CHAR_BIT; | 5538 | byte_offset -= 128 / CHAR_BIT; |
| 3561 | #endif | 5539 | #endif |
| 3562 | 5540 | ||
| 3563 | { | 5541 | { |
| 3564 | zig_u128 val_limb; | 5542 | zig_u128 arg_limb; |
| 3565 | 5543 | ||
| 3566 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | 5544 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); |
| 3567 | total_pc += zig_popcount_u128(val_limb, 128); | 5545 | limb_lz = zig_clz_u128(zig_u128_truncate_u128(arg_limb, limb_bits), limb_bits); |
| 3568 | } | 5546 | } |
| 3569 | 5547 | ||
| 5548 | total_lz += limb_lz; | ||
| 5549 | if (limb_lz < limb_bits) return total_lz; | ||
| 5550 | sign_limb = false; | ||
| 3570 | remaining_bytes -= 128 / CHAR_BIT; | 5551 | remaining_bytes -= 128 / CHAR_BIT; |
| 3571 | 5552 | ||
| 3572 | #if zig_little_endian | 5553 | #if zig_big_endian |
| 3573 | byte_offset += 128 / CHAR_BIT; | 5554 | byte_offset += 128 / CHAR_BIT; |
| 3574 | #endif | 5555 | #endif |
| 3575 | } | 5556 | } |
| 3576 | 5557 | ||
| 3577 | while (remaining_bytes >= 64 / CHAR_BIT) { | 5558 | while (remaining_bytes >= 64 / CHAR_BIT) { |
| 3578 | #if zig_big_endian | 5559 | uint8_t limb_bits = UINT8_C(64) - (sign_limb ? top_bits : UINT8_C(0)); |
| 5560 | |||
| 5561 | #if zig_little_endian | ||
| 3579 | byte_offset -= 64 / CHAR_BIT; | 5562 | byte_offset -= 64 / CHAR_BIT; |
| 3580 | #endif | 5563 | #endif |
| 3581 | 5564 | ||
| 3582 | { | 5565 | { |
| 3583 | uint64_t val_limb; | 5566 | uint64_t arg_limb; |
| 3584 | 5567 | ||
| 3585 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | 5568 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); |
| 3586 | total_pc += zig_popcount_u64(val_limb, 64); | 5569 | limb_lz = zig_clz_u64(zig_u64_truncate_u64(arg_limb, limb_bits), limb_bits); |
| 3587 | } | 5570 | } |
| 3588 | 5571 | ||
| 5572 | total_lz += limb_lz; | ||
| 5573 | if (limb_lz < limb_bits) return total_lz; | ||
| 5574 | sign_limb = false; | ||
| 3589 | remaining_bytes -= 64 / CHAR_BIT; | 5575 | remaining_bytes -= 64 / CHAR_BIT; |
| 3590 | 5576 | ||
| 3591 | #if zig_little_endian | 5577 | #if zig_big_endian |
| 3592 | byte_offset += 64 / CHAR_BIT; | 5578 | byte_offset += 64 / CHAR_BIT; |
| 3593 | #endif | 5579 | #endif |
| 3594 | } | 5580 | } |
| 3595 | 5581 | ||
| 3596 | while (remaining_bytes >= 32 / CHAR_BIT) { | 5582 | while (remaining_bytes >= 32 / CHAR_BIT) { |
| 3597 | #if zig_big_endian | 5583 | uint8_t limb_bits = UINT8_C(32) - (sign_limb ? top_bits : UINT8_C(0)); |
| 5584 | |||
| 5585 | #if zig_little_endian | ||
| 3598 | byte_offset -= 32 / CHAR_BIT; | 5586 | byte_offset -= 32 / CHAR_BIT; |
| 3599 | #endif | 5587 | #endif |
| 3600 | 5588 | ||
| 3601 | { | 5589 | { |
| 3602 | uint32_t val_limb; | 5590 | uint32_t arg_limb; |
| 3603 | 5591 | ||
| 3604 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | 5592 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); |
| 3605 | total_pc += zig_popcount_u32(val_limb, 32); | 5593 | limb_lz = zig_clz_u32(zig_u32_truncate_u32(arg_limb, limb_bits), limb_bits); |
| 3606 | } | 5594 | } |
| 3607 | 5595 | ||
| 5596 | total_lz += limb_lz; | ||
| 5597 | if (limb_lz < limb_bits) return total_lz; | ||
| 5598 | sign_limb = false; | ||
| 3608 | remaining_bytes -= 32 / CHAR_BIT; | 5599 | remaining_bytes -= 32 / CHAR_BIT; |
| 3609 | 5600 | ||
| 3610 | #if zig_little_endian | 5601 | #if zig_big_endian |
| 3611 | byte_offset += 32 / CHAR_BIT; | 5602 | byte_offset += 32 / CHAR_BIT; |
| 3612 | #endif | 5603 | #endif |
| 3613 | } | 5604 | } |
| 3614 | 5605 | ||
| 3615 | while (remaining_bytes >= 16 / CHAR_BIT) { | 5606 | while (remaining_bytes >= 16 / CHAR_BIT) { |
| 3616 | #if zig_big_endian | 5607 | uint8_t limb_bits = UINT8_C(16) - (sign_limb ? top_bits : UINT8_C(0)); |
| 5608 | |||
| 5609 | #if zig_little_endian | ||
| 3617 | byte_offset -= 16 / CHAR_BIT; | 5610 | byte_offset -= 16 / CHAR_BIT; |
| 3618 | #endif | 5611 | #endif |
| 3619 | 5612 | ||
| 3620 | { | 5613 | { |
| 3621 | uint16_t val_limb; | 5614 | uint16_t arg_limb; |
| 3622 | 5615 | ||
| 3623 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | 5616 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); |
| 3624 | total_pc = zig_popcount_u16(val_limb, 16); | 5617 | limb_lz = zig_clz_u16(zig_u16_truncate_u16(arg_limb, limb_bits), limb_bits); |
| 3625 | } | 5618 | } |
| 3626 | 5619 | ||
| 5620 | total_lz += limb_lz; | ||
| 5621 | if (limb_lz < limb_bits) return total_lz; | ||
| 5622 | sign_limb = false; | ||
| 3627 | remaining_bytes -= 16 / CHAR_BIT; | 5623 | remaining_bytes -= 16 / CHAR_BIT; |
| 3628 | 5624 | ||
| 3629 | #if zig_little_endian | 5625 | #if zig_big_endian |
| 3630 | byte_offset += 16 / CHAR_BIT; | 5626 | byte_offset += 16 / CHAR_BIT; |
| 3631 | #endif | 5627 | #endif |
| 3632 | } | 5628 | } |
| 3633 | 5629 | ||
| 3634 | while (remaining_bytes >= 8 / CHAR_BIT) { | 5630 | while (remaining_bytes >= 8 / CHAR_BIT) { |
| 3635 | #if zig_big_endian | 5631 | uint8_t limb_bits = UINT8_C(8) - (sign_limb ? top_bits : UINT8_C(0)); |
| 5632 | |||
| 5633 | #if zig_little_endian | ||
| 3636 | byte_offset -= 8 / CHAR_BIT; | 5634 | byte_offset -= 8 / CHAR_BIT; |
| 3637 | #endif | 5635 | #endif |
| 3638 | 5636 | ||
| 3639 | { | 5637 | { |
| 3640 | uint8_t val_limb; | 5638 | uint8_t arg_limb; |
| 3641 | 5639 | ||
| 3642 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | 5640 | memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); |
| 3643 | total_pc = zig_popcount_u8(val_limb, 8); | 5641 | limb_lz = zig_clz_u8(zig_u8_truncate_u8(arg_limb, limb_bits), limb_bits); |
| 3644 | } | 5642 | } |
| 3645 | 5643 | ||
| 5644 | total_lz += limb_lz; | ||
| 5645 | if (limb_lz < limb_bits) return total_lz; | ||
| 5646 | sign_limb = false; | ||
| 3646 | remaining_bytes -= 8 / CHAR_BIT; | 5647 | remaining_bytes -= 8 / CHAR_BIT; |
| 3647 | 5648 | ||
| 3648 | #if zig_little_endian | 5649 | #if zig_big_endian |
| 3649 | byte_offset += 8 / CHAR_BIT; | 5650 | byte_offset += 8 / CHAR_BIT; |
| 3650 | #endif | 5651 | #endif |
| 3651 | } | 5652 | } |
| 3652 | 5653 | ||
| 3653 | return total_pc; | 5654 | return total_lz; |
| 3654 | } | 5655 | } |
| 3655 | 5656 | ||
| 3656 | /* ========================= Floating Point Support ========================= */ | 5657 | /* ========================= Floating Point Support ========================= */ |
| ... | @@ -3687,29 +5688,29 @@ long double __cdecl nanl(char const* input); | ... | @@ -3687,29 +5688,29 @@ long double __cdecl nanl(char const* input); |
| 3687 | #define zig_make_special_f80(sign, name, arg, repr) sign zig_make_f80 (__builtin_##name, )(arg) | 5688 | #define zig_make_special_f80(sign, name, arg, repr) sign zig_make_f80 (__builtin_##name, )(arg) |
| 3688 | #define zig_make_special_f128(sign, name, arg, repr) sign zig_make_f128(__builtin_##name, )(arg) | 5689 | #define zig_make_special_f128(sign, name, arg, repr) sign zig_make_f128(__builtin_##name, )(arg) |
| 3689 | #else | 5690 | #else |
| 3690 | #define zig_make_special_f16(sign, name, arg, repr) zig_bitCast_f16 (repr) | 5691 | #define zig_make_special_f16(sign, name, arg, repr) zig_f16_bitCast_u16 (repr) |
| 3691 | #define zig_make_special_f32(sign, name, arg, repr) zig_bitCast_f32 (repr) | 5692 | #define zig_make_special_f32(sign, name, arg, repr) zig_f32_bitCast_u32 (repr) |
| 3692 | #define zig_make_special_f64(sign, name, arg, repr) zig_bitCast_f64 (repr) | 5693 | #define zig_make_special_f64(sign, name, arg, repr) zig_f64_bitCast_u64 (repr) |
| 3693 | #define zig_make_special_f80(sign, name, arg, repr) zig_bitCast_f80 (repr) | 5694 | #define zig_make_special_f80(sign, name, arg, repr) zig_f80_bitCast_u128(repr) |
| 3694 | #define zig_make_special_f128(sign, name, arg, repr) zig_bitCast_f128(repr) | 5695 | #define zig_make_special_f128(sign, name, arg, repr) zig_f128_bitCast_u128(repr) |
| 3695 | #endif | 5696 | #endif |
| 3696 | 5697 | ||
| 3697 | #define zig_has_f16 1 | 5698 | #define zig_has_f16 1 |
| 3698 | #define zig_libc_name_f16(name) __##name##h | 5699 | #define zig_libc_name_f16(name) __##name##h |
| 3699 | #define zig_init_special_f16(sign, name, arg, repr) zig_make_special_f16(sign, name, arg, repr) | 5700 | #define zig_init_special_f16(sign, name, arg, repr) zig_make_special_f16(sign, name, arg, repr) |
| 3700 | #if FLT_MANT_DIG == 11 | 5701 | #if !defined(ZIG_TARGET_SOFT_COMPILER_RT_F16_ABI) && FLT_MANT_DIG == 11 |
| 3701 | typedef float zig_f16; | 5702 | typedef float zig_f16; |
| 3702 | #define zig_make_f16(fp, repr) fp##f | 5703 | #define zig_make_f16(fp, repr) fp##f |
| 3703 | #elif DBL_MANT_DIG == 11 | 5704 | #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F16_ABI) && DBL_MANT_DIG == 11 |
| 3704 | typedef double zig_f16; | 5705 | typedef double zig_f16; |
| 3705 | #define zig_make_f16(fp, repr) fp | 5706 | #define zig_make_f16(fp, repr) fp |
| 3706 | #elif LDBL_MANT_DIG == 11 | 5707 | #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F16_ABI) && LDBL_MANT_DIG == 11 |
| 3707 | typedef long double zig_f16; | 5708 | typedef long double zig_f16; |
| 3708 | #define zig_make_f16(fp, repr) fp##l | 5709 | #define zig_make_f16(fp, repr) fp##l |
| 3709 | #elif FLT16_MANT_DIG == 11 && (zig_has_builtin(inff16) || defined(zig_gcc)) | 5710 | #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F16_ABI) && FLT16_MANT_DIG == 11 && (zig_has_builtin(inff16) || defined(zig_gcc)) |
| 3710 | typedef _Float16 zig_f16; | 5711 | typedef _Float16 zig_f16; |
| 3711 | #define zig_make_f16(fp, repr) fp##f16 | 5712 | #define zig_make_f16(fp, repr) fp##f16 |
| 3712 | #elif defined(__SIZEOF_FP16__) | 5713 | #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F16_ABI) && defined(__SIZEOF_FP16__) |
| 3713 | typedef __fp16 zig_f16; | 5714 | typedef __fp16 zig_f16; |
| 3714 | #define zig_make_f16(fp, repr) fp##f16 | 5715 | #define zig_make_f16(fp, repr) fp##f16 |
| 3715 | #else | 5716 | #else |
| ... | @@ -3723,11 +5724,6 @@ typedef uint16_t zig_f16; | ... | @@ -3723,11 +5724,6 @@ typedef uint16_t zig_f16; |
| 3723 | #undef zig_init_special_f16 | 5724 | #undef zig_init_special_f16 |
| 3724 | #define zig_init_special_f16(sign, name, arg, repr) repr | 5725 | #define zig_init_special_f16(sign, name, arg, repr) repr |
| 3725 | #endif | 5726 | #endif |
| 3726 | #if defined(zig_darwin) && defined(zig_x86) | ||
| 3727 | typedef uint16_t zig_compiler_rt_f16; | ||
| 3728 | #else | ||
| 3729 | typedef zig_f16 zig_compiler_rt_f16; | ||
| 3730 | #endif | ||
| 3731 | 5727 | ||
| 3732 | #define zig_has_f32 1 | 5728 | #define zig_has_f32 1 |
| 3733 | #define zig_libc_name_f32(name) name##f | 5729 | #define zig_libc_name_f32(name) name##f |
| ... | @@ -3736,16 +5732,16 @@ typedef zig_f16 zig_compiler_rt_f16; | ... | @@ -3736,16 +5732,16 @@ typedef zig_f16 zig_compiler_rt_f16; |
| 3736 | #else | 5732 | #else |
| 3737 | #define zig_init_special_f32(sign, name, arg, repr) zig_make_special_f32(sign, name, arg, repr) | 5733 | #define zig_init_special_f32(sign, name, arg, repr) zig_make_special_f32(sign, name, arg, repr) |
| 3738 | #endif | 5734 | #endif |
| 3739 | #if FLT_MANT_DIG == 24 | 5735 | #if !defined(ZIG_TARGET_SOFT_COMPILER_RT_F32_ABI) && FLT_MANT_DIG == 24 |
| 3740 | typedef float zig_f32; | 5736 | typedef float zig_f32; |
| 3741 | #define zig_make_f32(fp, repr) fp##f | 5737 | #define zig_make_f32(fp, repr) fp##f |
| 3742 | #elif DBL_MANT_DIG == 24 | 5738 | #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F32_ABI) && DBL_MANT_DIG == 24 |
| 3743 | typedef double zig_f32; | 5739 | typedef double zig_f32; |
| 3744 | #define zig_make_f32(fp, repr) fp | 5740 | #define zig_make_f32(fp, repr) fp |
| 3745 | #elif LDBL_MANT_DIG == 24 | 5741 | #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F32_ABI) && LDBL_MANT_DIG == 24 |
| 3746 | typedef long double zig_f32; | 5742 | typedef long double zig_f32; |
| 3747 | #define zig_make_f32(fp, repr) fp##l | 5743 | #define zig_make_f32(fp, repr) fp##l |
| 3748 | #elif FLT32_MANT_DIG == 24 | 5744 | #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F32_ABI) && FLT32_MANT_DIG == 24 |
| 3749 | typedef _Float32 zig_f32; | 5745 | typedef _Float32 zig_f32; |
| 3750 | #define zig_make_f32(fp, repr) fp##f32 | 5746 | #define zig_make_f32(fp, repr) fp##f32 |
| 3751 | #else | 5747 | #else |
| ... | @@ -3768,19 +5764,19 @@ typedef uint32_t zig_f32; | ... | @@ -3768,19 +5764,19 @@ typedef uint32_t zig_f32; |
| 3768 | #else | 5764 | #else |
| 3769 | #define zig_init_special_f64(sign, name, arg, repr) zig_make_special_f64(sign, name, arg, repr) | 5765 | #define zig_init_special_f64(sign, name, arg, repr) zig_make_special_f64(sign, name, arg, repr) |
| 3770 | #endif | 5766 | #endif |
| 3771 | #if FLT_MANT_DIG == 53 | 5767 | #if !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && FLT_MANT_DIG == 53 |
| 3772 | typedef float zig_f64; | 5768 | typedef float zig_f64; |
| 3773 | #define zig_make_f64(fp, repr) fp##f | 5769 | #define zig_make_f64(fp, repr) fp##f |
| 3774 | #elif DBL_MANT_DIG == 53 | 5770 | #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && DBL_MANT_DIG == 53 |
| 3775 | typedef double zig_f64; | 5771 | typedef double zig_f64; |
| 3776 | #define zig_make_f64(fp, repr) fp | 5772 | #define zig_make_f64(fp, repr) fp |
| 3777 | #elif LDBL_MANT_DIG == 53 | 5773 | #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && LDBL_MANT_DIG == 53 |
| 3778 | typedef long double zig_f64; | 5774 | typedef long double zig_f64; |
| 3779 | #define zig_make_f64(fp, repr) fp##l | 5775 | #define zig_make_f64(fp, repr) fp##l |
| 3780 | #elif FLT64_MANT_DIG == 53 | 5776 | #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && FLT64_MANT_DIG == 53 |
| 3781 | typedef _Float64 zig_f64; | 5777 | typedef _Float64 zig_f64; |
| 3782 | #define zig_make_f64(fp, repr) fp##f64 | 5778 | #define zig_make_f64(fp, repr) fp##f64 |
| 3783 | #elif FLT32X_MANT_DIG == 53 | 5779 | #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && FLT32X_MANT_DIG == 53 |
| 3784 | typedef _Float32x zig_f64; | 5780 | typedef _Float32x zig_f64; |
| 3785 | #define zig_make_f64(fp, repr) fp##f32x | 5781 | #define zig_make_f64(fp, repr) fp##f32x |
| 3786 | #else | 5782 | #else |
| ... | @@ -3798,7 +5794,14 @@ typedef uint64_t zig_f64; | ... | @@ -3798,7 +5794,14 @@ typedef uint64_t zig_f64; |
| 3798 | #define zig_has_f80 1 | 5794 | #define zig_has_f80 1 |
| 3799 | #define zig_libc_name_f80(name) __##name##x | 5795 | #define zig_libc_name_f80(name) __##name##x |
| 3800 | #define zig_init_special_f80(sign, name, arg, repr) zig_make_special_f80(sign, name, arg, repr) | 5796 | #define zig_init_special_f80(sign, name, arg, repr) zig_make_special_f80(sign, name, arg, repr) |
| 3801 | #if FLT_MANT_DIG == 64 | 5797 | #ifdef ZIG_TARGET_SOFT_COMPILER_RT_F80_ABI |
| 5798 | #undef zig_has_f80 | ||
| 5799 | typedef struct { uint64_t mantissa; uint16_t exponent; } zig_f80; | ||
| 5800 | #define zig_init_repr_f80(mantissa, exponent) { .mant##issa = mantissa, .expo##nent = exponent } | ||
| 5801 | #define zig_make_repr_f80(mantissa, exponent) (zig_f80)zig_init_repr_f80(mantissa, exponent) | ||
| 5802 | #define zig_mantissa_repr_f80(arg) (arg).mantissa | ||
| 5803 | #define zig_exponent_repr_f80(arg) (arg).exponent | ||
| 5804 | #elif FLT_MANT_DIG == 64 | ||
| 3802 | typedef float zig_f80; | 5805 | typedef float zig_f80; |
| 3803 | #define zig_make_f80(fp, repr) fp##f | 5806 | #define zig_make_f80(fp, repr) fp##f |
| 3804 | #elif DBL_MANT_DIG == 64 | 5807 | #elif DBL_MANT_DIG == 64 |
| ... | @@ -3818,68 +5821,91 @@ typedef __float80 zig_f80; | ... | @@ -3818,68 +5821,91 @@ typedef __float80 zig_f80; |
| 3818 | #define zig_make_f80(fp, repr) fp##l | 5821 | #define zig_make_f80(fp, repr) fp##l |
| 3819 | #else | 5822 | #else |
| 3820 | #undef zig_has_f80 | 5823 | #undef zig_has_f80 |
| 3821 | #define zig_has_f80 0 | ||
| 3822 | #define zig_repr_f80 u128 | ||
| 3823 | typedef zig_u128 zig_f80; | 5824 | typedef zig_u128 zig_f80; |
| 5825 | #define zig_init_repr_f80(mantissa, exponent) zig_init_u128(exponent, mantissa) | ||
| 5826 | #define zig_make_repr_f80(mantissa, exponent) zig_make_u128(exponent, mantissa) | ||
| 5827 | #define zig_mantissa_repr_f80(arg) zig_lo_u128(arg) | ||
| 5828 | #define zig_exponent_repr_f80(arg) (uint16_t)zig_hi_u128(arg) | ||
| 5829 | #endif | ||
| 5830 | #ifndef zig_has_f80 | ||
| 5831 | #define zig_has_f80 0 | ||
| 3824 | #define zig_make_f80(fp, repr) repr | 5832 | #define zig_make_f80(fp, repr) repr |
| 5833 | #ifndef zig_make_repr_f80 | ||
| 5834 | #define zig_make_repr_f80(mantissa, exponent) (zig_f80)zig_init_repr_f80(mantissa, exponent) | ||
| 5835 | #endif | ||
| 3825 | #undef zig_make_special_f80 | 5836 | #undef zig_make_special_f80 |
| 3826 | #define zig_make_special_f80(sign, name, arg, repr) repr | 5837 | #define zig_make_special_f80(sign, name, arg, repr) repr |
| 3827 | #undef zig_init_special_f80 | 5838 | #undef zig_init_special_f80 |
| 3828 | #define zig_init_special_f80(sign, name, arg, repr) repr | 5839 | #define zig_init_special_f80(sign, name, arg, repr) repr |
| 3829 | #endif | 5840 | #endif |
| 3830 | 5841 | ||
| 3831 | #if defined(zig_gcc) && defined(zig_x86) | ||
| 3832 | #define zig_f128_has_miscompilations 1 | ||
| 3833 | #else | ||
| 3834 | #define zig_f128_has_miscompilations 0 | ||
| 3835 | #endif | ||
| 3836 | |||
| 3837 | #define zig_has_f128 1 | 5842 | #define zig_has_f128 1 |
| 3838 | #define zig_libc_name_f128(name) name##q | 5843 | #define zig_libc_name_f128(name) name##f128 |
| 3839 | #define zig_init_special_f128(sign, name, arg, repr) zig_make_special_f128(sign, name, arg, repr) | 5844 | #define zig_init_special_f128(sign, name, arg, repr) zig_make_special_f128(sign, name, arg, repr) |
| 3840 | #if !zig_f128_has_miscompilations && FLT_MANT_DIG == 113 | 5845 | #ifdef ZIG_TARGET_SOFT_COMPILER_RT_F128_ABI |
| 5846 | #undef zig_has_f128 | ||
| 5847 | #if zig_little_endian | ||
| 5848 | typedef struct { uint64_t lo, hi; } zig_f128; | ||
| 5849 | #else | ||
| 5850 | typedef struct { uint64_t hi, lo; } zig_f128; | ||
| 5851 | #endif | ||
| 5852 | #define zig_init_repr_f128(hi, lo) { .h##i = hi, .l##o = lo } | ||
| 5853 | #define zig_lo_repr_f128(arg) (arg).lo | ||
| 5854 | #define zig_hi_repr_f128(arg) (arg).hi | ||
| 5855 | #elif FLT_MANT_DIG == 113 | ||
| 3841 | typedef float zig_f128; | 5856 | typedef float zig_f128; |
| 3842 | #define zig_make_f128(fp, repr) fp##f | 5857 | #define zig_make_f128(fp, repr) fp##f |
| 3843 | #elif !zig_f128_has_miscompilations && DBL_MANT_DIG == 113 | 5858 | #elif DBL_MANT_DIG == 113 |
| 3844 | typedef double zig_f128; | 5859 | typedef double zig_f128; |
| 3845 | #define zig_make_f128(fp, repr) fp | 5860 | #define zig_make_f128(fp, repr) fp |
| 3846 | #elif !zig_f128_has_miscompilations && LDBL_MANT_DIG == 113 | 5861 | #elif LDBL_MANT_DIG == 113 |
| 3847 | typedef long double zig_f128; | 5862 | typedef long double zig_f128; |
| 3848 | #define zig_make_f128(fp, repr) fp##l | 5863 | #define zig_make_f128(fp, repr) fp##l |
| 3849 | #elif !zig_f128_has_miscompilations && FLT128_MANT_DIG == 113 | 5864 | #elif FLT128_MANT_DIG == 113 |
| 3850 | typedef _Float128 zig_f128; | 5865 | typedef _Float128 zig_f128; |
| 3851 | #define zig_make_f128(fp, repr) fp##f128 | 5866 | #define zig_make_f128(fp, repr) fp##f128 |
| 3852 | #elif !zig_f128_has_miscompilations && FLT64X_MANT_DIG == 113 | 5867 | #elif FLT64X_MANT_DIG == 113 |
| 3853 | typedef _Float64x zig_f128; | 5868 | typedef _Float64x zig_f128; |
| 3854 | #define zig_make_f128(fp, repr) fp##f64x | 5869 | #define zig_make_f128(fp, repr) fp##f64x |
| 3855 | #elif !zig_f128_has_miscompilations && defined(__SIZEOF_FLOAT128__) | 5870 | #elif defined(__SIZEOF_FLOAT128__) |
| 3856 | typedef __float128 zig_f128; | 5871 | typedef __float128 zig_f128; |
| 3857 | #define zig_make_f128(fp, repr) fp##q | 5872 | #define zig_make_f128(fp, repr) fp##q |
| 3858 | #undef zig_make_special_f128 | 5873 | #undef zig_make_special_f128 |
| 3859 | #define zig_make_special_f128(sign, name, arg, repr) sign __builtin_##name##f128(arg) | 5874 | #define zig_make_special_f128(sign, name, arg, repr) sign __builtin_##name##f128(arg) |
| 3860 | #else | 5875 | #else |
| 3861 | #undef zig_has_f128 | 5876 | #undef zig_has_f128 |
| 3862 | #define zig_has_f128 0 | 5877 | #if defined(zig_x86_64) && defined(ZIG_TARGET_ABI_MSVC) |
| 3863 | #undef zig_make_special_f128 | 5878 | #if defined(zig_msvc) && !defined(__clang__) |
| 3864 | #undef zig_init_special_f128 | 5879 | #include <emmintrin.h> |
| 3865 | #if defined(zig_darwin) || defined(zig_aarch64) | 5880 | typedef __m128i zig_f128; |
| 3866 | typedef __attribute__((__vector_size__(2 * sizeof(uint64_t)))) uint64_t zig_v2u64; | 5881 | #define zig_init_repr_f128(hi, lo) { .m128i_u64 = { lo, hi } } |
| 3867 | zig_basic_operator(zig_v2u64, xor_v2u64, ^) | 5882 | #define zig_lo_repr_f128(arg) (arg).m128i_u64[0] |
| 3868 | #define zig_repr_f128 v2u64 | 5883 | #define zig_hi_repr_f128(arg) (arg).m128i_u64[1] |
| 3869 | typedef zig_v2u64 zig_f128; | 5884 | #else |
| 3870 | #define zig_make_f128_zig_make_u128(hi, lo) (zig_f128){ lo, hi } | 5885 | typedef __attribute__((__vector_size__(2 * sizeof(uint64_t)))) uint64_t zig_f128; |
| 3871 | #define zig_make_f128_zig_init_u128 zig_make_f128_zig_make_u128 | 5886 | #define zig_init_repr_f128(hi, lo) { lo, hi } |
| 3872 | #define zig_make_f128(fp, repr) zig_make_f128_##repr | 5887 | #define zig_lo_repr_f128(arg) (arg)[0] |
| 3873 | #define zig_make_special_f128(sign, name, arg, repr) zig_make_f128_##repr | 5888 | #define zig_hi_repr_f128(arg) (arg)[1] |
| 3874 | #define zig_init_special_f128(sign, name, arg, repr) zig_make_f128_##repr | 5889 | #endif |
| 3875 | #else | 5890 | #else |
| 3876 | #define zig_repr_f128 u128 | ||
| 3877 | typedef zig_u128 zig_f128; | 5891 | typedef zig_u128 zig_f128; |
| 5892 | #define zig_init_repr_f128(hi, lo) zig_init_u128(hi, lo) | ||
| 5893 | #define zig_make_repr_f128(hi, lo) zig_make_u128(hi, lo) | ||
| 5894 | #define zig_lo_repr_f128(arg) zig_lo_u128(arg) | ||
| 5895 | #define zig_hi_repr_f128(arg) zig_hi_u128(arg) | ||
| 5896 | #endif | ||
| 5897 | #endif | ||
| 5898 | #ifndef zig_has_f128 | ||
| 5899 | #define zig_has_f128 0 | ||
| 3878 | #define zig_make_f128(fp, repr) repr | 5900 | #define zig_make_f128(fp, repr) repr |
| 5901 | #ifndef zig_make_repr_f128 | ||
| 5902 | #define zig_make_repr_f128(hi, lo) (zig_f128)zig_init_repr_f128(hi, lo) | ||
| 5903 | #endif | ||
| 5904 | #undef zig_make_special_f128 | ||
| 3879 | #define zig_make_special_f128(sign, name, arg, repr) repr | 5905 | #define zig_make_special_f128(sign, name, arg, repr) repr |
| 5906 | #undef zig_init_special_f128 | ||
| 3880 | #define zig_init_special_f128(sign, name, arg, repr) repr | 5907 | #define zig_init_special_f128(sign, name, arg, repr) repr |
| 3881 | #endif | 5908 | #endif |
| 3882 | #endif | ||
| 3883 | 5909 | ||
| 3884 | #if !defined(zig_msvc) && defined(ZIG_TARGET_ABI_MSVC) | 5910 | #if !defined(zig_msvc) && defined(ZIG_TARGET_ABI_MSVC) |
| 3885 | /* Emulate msvc abi on a gnu compiler */ | 5911 | /* Emulate msvc abi on a gnu compiler */ |
| ... | @@ -3892,84 +5918,141 @@ typedef zig_f128 zig_c_longdouble; | ... | @@ -3892,84 +5918,141 @@ typedef zig_f128 zig_c_longdouble; |
| 3892 | typedef long double zig_c_longdouble; | 5918 | typedef long double zig_c_longdouble; |
| 3893 | #endif | 5919 | #endif |
| 3894 | 5920 | ||
| 3895 | #define zig_bitCast_float(Type, ReprType) \ | 5921 | #if __AVR__ |
| 3896 | static inline zig_##Type zig_bitCast_##Type(ReprType repr) { \ | 5922 | typedef signed char zig_FloatCompareResult; |
| 3897 | zig_##Type result; \ | 5923 | #elif defined(zig_aarch64) |
| 3898 | memcpy(&result, &repr, sizeof(result)); \ | 5924 | typedef signed int zig_FloatCompareResult; |
| 3899 | return result; \ | 5925 | #elif __SIZEOF_LONG__ >= __SIZEOF_POINTER__ |
| 5926 | typedef signed long zig_FloatCompareResult; | ||
| 5927 | #else | ||
| 5928 | typedef signed long long zig_FloatCompareResult; | ||
| 5929 | #endif | ||
| 5930 | |||
| 5931 | #define zig_bitCast_float(w, iw, UnsignedReprType, SignedReprType) \ | ||
| 5932 | static inline zig_f##w zig_f##w##_bitCast_u##iw(UnsignedReprType arg) { \ | ||
| 5933 | zig_f##w res; \ | ||
| 5934 | memcpy(&res, &arg, sizeof(zig_f##w)); \ | ||
| 5935 | return res; \ | ||
| 5936 | } \ | ||
| 5937 | static inline zig_f##w zig_f##w##_bitCast_i##iw(SignedReprType arg) { \ | ||
| 5938 | zig_f##w res; \ | ||
| 5939 | memcpy(&res, &arg, sizeof(zig_f##w)); \ | ||
| 5940 | return res; \ | ||
| 5941 | } \ | ||
| 5942 | static inline UnsignedReprType zig_u##iw##_bitCast_f##w(zig_f##w arg) { \ | ||
| 5943 | UnsignedReprType res; \ | ||
| 5944 | memcpy(&res, &arg, sizeof(zig_f##w)); \ | ||
| 5945 | return zig_u##iw##_truncate_u##iw(res, w); \ | ||
| 5946 | } \ | ||
| 5947 | static inline SignedReprType zig_i##iw##_bitCast_f##w(zig_f##w arg) { \ | ||
| 5948 | SignedReprType res; \ | ||
| 5949 | memcpy(&res, &arg, sizeof(zig_f##w)); \ | ||
| 5950 | return zig_i##iw##_truncate_i##iw(res, w); \ | ||
| 3900 | } | 5951 | } |
| 3901 | zig_bitCast_float(f16, uint16_t) | 5952 | zig_bitCast_float(16, 16, uint16_t, int16_t) |
| 3902 | zig_bitCast_float(f32, uint32_t) | 5953 | zig_bitCast_float(32, 32, uint32_t, int32_t) |
| 3903 | zig_bitCast_float(f64, uint64_t) | 5954 | zig_bitCast_float(64, 64, uint64_t, int64_t) |
| 3904 | zig_bitCast_float(f80, zig_u128) | 5955 | #if zig_has_f80 |
| 3905 | zig_bitCast_float(f128, zig_u128) | 5956 | zig_bitCast_float(80, 128, zig_u128, zig_i128) |
| 5957 | #else | ||
| 5958 | static inline zig_f80 zig_f80_bitCast_u128(zig_u128 arg) { | ||
| 5959 | return zig_make_repr_f80(zig_lo_u128(arg), (uint16_t)zig_hi_u128(arg)); | ||
| 5960 | } | ||
| 5961 | static inline zig_f80 zig_f80_bitCast_i128(zig_i128 arg) { | ||
| 5962 | return zig_make_repr_f80(zig_lo_i128(arg), (uint16_t)zig_hi_i128(arg)); | ||
| 5963 | } | ||
| 5964 | static inline zig_u128 zig_u128_bitCast_f80(zig_f80 arg) { | ||
| 5965 | return zig_make_u128(zig_exponent_repr_f80(arg), zig_mantissa_repr_f80(arg)); | ||
| 5966 | } | ||
| 5967 | static inline zig_i128 zig_i128_bitCast_f80(zig_f80 arg) { | ||
| 5968 | return zig_make_i128((int16_t)zig_exponent_repr_f80(arg), zig_mantissa_repr_f80(arg)); | ||
| 5969 | } | ||
| 5970 | #endif | ||
| 5971 | static inline zig_f80 zig_f80_bitCast_big(const void *arg) { | ||
| 5972 | return zig_f80_bitCast_u128(zig_u128_truncate_big(arg, UINT8_C(80), false, UINT16_C(80))); | ||
| 5973 | } | ||
| 5974 | static inline void zig_big_bitCast_f80(void *res, zig_f80 arg, bool res_is_signed, uint16_t res_bits) { | ||
| 5975 | if (res_is_signed) { | ||
| 5976 | zig_big_truncate_i128(res, zig_i128_bitCast_f80(arg), res_is_signed, res_bits); | ||
| 5977 | } else { | ||
| 5978 | zig_big_truncate_u128(res, zig_u128_bitCast_f80(arg), res_is_signed, res_bits); | ||
| 5979 | } | ||
| 5980 | } | ||
| 5981 | #if zig_has_f128 | ||
| 5982 | zig_bitCast_float(128, 128, zig_u128, zig_i128) | ||
| 5983 | #else | ||
| 5984 | static inline zig_f128 zig_f128_bitCast_u128(zig_u128 arg) { | ||
| 5985 | return zig_make_repr_f128(zig_hi_u128(arg), zig_lo_u128(arg)); | ||
| 5986 | } | ||
| 5987 | static inline zig_f128 zig_f128_bitCast_i128(zig_i128 arg) { | ||
| 5988 | return zig_make_repr_f128((uint64_t)zig_hi_i128(arg), zig_lo_i128(arg)); | ||
| 5989 | } | ||
| 5990 | static inline zig_u128 zig_u128_bitCast_f128(zig_f128 arg) { | ||
| 5991 | return zig_make_u128(zig_hi_repr_f128(arg), zig_lo_repr_f128(arg)); | ||
| 5992 | } | ||
| 5993 | static inline zig_i128 zig_i128_bitCast_f128(zig_f128 arg) { | ||
| 5994 | return zig_make_i128((int64_t)zig_hi_repr_f128(arg), zig_lo_repr_f128(arg)); | ||
| 5995 | } | ||
| 5996 | #endif | ||
| 3906 | 5997 | ||
| 3907 | #define zig_convert_builtin(ExternResType, ResType, operation, ExternArgType, ArgType, version) \ | 5998 | #define zig_convert_float_00(ResType, operation, ArgType, version) \ |
| 3908 | zig_extern ExternResType zig_expand_concat(zig_expand_concat(zig_expand_concat(__##operation, \ | 5999 | zig_extern ResType zig_expand_concat(zig_expand_concat(zig_expand_concat(__##operation, \ |
| 3909 | zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType), version)(ExternArgType); \ | 6000 | zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType), version)(ArgType arg); \ |
| 6001 | return zig_expand_concat(zig_expand_concat(zig_expand_concat(__##operation, \ | ||
| 6002 | zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType), version)(arg) | ||
| 6003 | #define zig_convert_float_01(ResType, operation, ArgType, version) \ | ||
| 6004 | zig_convert_float_00(ResType, operation, ArgType, version) | ||
| 6005 | #define zig_convert_float_10(ResType, operation, ArgType, version) \ | ||
| 6006 | zig_convert_float_00(ResType, operation, ArgType, version) | ||
| 6007 | #define zig_convert_float_11(ResType, operation, ArgType, version) \ | ||
| 6008 | return (ResType)arg | ||
| 6009 | #define zig_convert_float(res_when, ResType, operation, arg_when, ArgType, version) \ | ||
| 3910 | static inline ResType zig_expand_concat(zig_expand_concat(zig_##operation, \ | 6010 | static inline ResType zig_expand_concat(zig_expand_concat(zig_##operation, \ |
| 3911 | zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType)(ArgType arg) { \ | 6011 | zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType)(ArgType arg) { \ |
| 3912 | ResType res; \ | 6012 | zig_expand_concat(zig_expand_concat(zig_convert_float_, zig_has_##res_when), \ |
| 3913 | ExternResType extern_res; \ | 6013 | zig_has_##arg_when)(ResType, operation, ArgType, version); \ |
| 3914 | ExternArgType extern_arg; \ | 6014 | } |
| 3915 | memcpy(&extern_arg, &arg, sizeof(extern_arg)); \ | 6015 | |
| 3916 | extern_res = zig_expand_concat(zig_expand_concat(zig_expand_concat(__##operation, \ | 6016 | #define zig_convert_floats(SmallType, BigType) \ |
| 3917 | zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType), version)(extern_arg); \ | 6017 | zig_convert_float(SmallType, zig_##SmallType, trunc, BigType, zig_##BigType, 2) \ |
| 3918 | memcpy(&res, &extern_res, sizeof(res)); \ | 6018 | zig_convert_float(BigType, zig_##BigType, extend, SmallType, zig_##SmallType, 2) |
| 3919 | return extern_res; \ | 6019 | zig_convert_floats(f16, f32) |
| 3920 | } | 6020 | zig_convert_floats(f16, f64) |
| 3921 | zig_convert_builtin(zig_compiler_rt_f16, zig_f16, trunc, zig_f32, zig_f32, 2) | 6021 | zig_convert_floats(f16, f80) |
| 3922 | zig_convert_builtin(zig_compiler_rt_f16, zig_f16, trunc, zig_f64, zig_f64, 2) | 6022 | zig_convert_floats(f16, f128) |
| 3923 | zig_convert_builtin(zig_f16, zig_f16, trunc, zig_f80, zig_f80, 2) | 6023 | zig_convert_floats(f32, f64) |
| 3924 | zig_convert_builtin(zig_f16, zig_f16, trunc, zig_f128, zig_f128, 2) | 6024 | zig_convert_floats(f32, f80) |
| 3925 | zig_convert_builtin(zig_f32, zig_f32, extend, zig_compiler_rt_f16, zig_f16, 2) | 6025 | zig_convert_floats(f32, f128) |
| 3926 | zig_convert_builtin(zig_f32, zig_f32, trunc, zig_f80, zig_f80, 2) | 6026 | zig_convert_floats(f64, f80) |
| 3927 | zig_convert_builtin(zig_f32, zig_f32, trunc, zig_f128, zig_f128, 2) | 6027 | zig_convert_floats(f64, f128) |
| 3928 | zig_convert_builtin(zig_f64, zig_f64, extend, zig_compiler_rt_f16, zig_f16, 2) | 6028 | zig_convert_floats(f80, f128) |
| 3929 | zig_convert_builtin(zig_f64, zig_f64, trunc, zig_f80, zig_f80, 2) | 6029 | |
| 3930 | zig_convert_builtin(zig_f64, zig_f64, trunc, zig_f128, zig_f128, 2) | 6030 | #define zig_float_negate_builtin_0(w, sb) \ |
| 3931 | zig_convert_builtin(zig_f80, zig_f80, extend, zig_f16, zig_f16, 2) | 6031 | zig_expand_concat(zig_xor_, zig_repr_f##w)(arg, zig_make_f##w(-0x0.0p0, sb)) |
| 3932 | zig_convert_builtin(zig_f80, zig_f80, extend, zig_f32, zig_f32, 2) | 6032 | #define zig_float_negate_builtin_1(w, sb) -arg |
| 3933 | zig_convert_builtin(zig_f80, zig_f80, extend, zig_f64, zig_f64, 2) | 6033 | #define zig_float_negate_builtin(w, sb) \ |
| 3934 | zig_convert_builtin(zig_f80, zig_f80, trunc, zig_f128, zig_f128, 2) | ||
| 3935 | zig_convert_builtin(zig_f128, zig_f128, extend, zig_f16, zig_f16, 2) | ||
| 3936 | zig_convert_builtin(zig_f128, zig_f128, extend, zig_f32, zig_f32, 2) | ||
| 3937 | zig_convert_builtin(zig_f128, zig_f128, extend, zig_f64, zig_f64, 2) | ||
| 3938 | zig_convert_builtin(zig_f128, zig_f128, extend, zig_f80, zig_f80, 2) | ||
| 3939 | |||
| 3940 | #ifdef __ARM_EABI__ | ||
| 3941 | |||
| 3942 | zig_extern zig_callconv(pcs("aapcs")) zig_f32 __aeabi_d2f(zig_f64); | ||
| 3943 | static inline zig_f32 zig_truncdfsf(zig_f64 arg) { return __aeabi_d2f(arg); } | ||
| 3944 | |||
| 3945 | zig_extern zig_callconv(pcs("aapcs")) zig_f64 __aeabi_f2d(zig_f32); | ||
| 3946 | static inline zig_f64 zig_extendsfdf(zig_f32 arg) { return __aeabi_f2d(arg); } | ||
| 3947 | |||
| 3948 | #else /* __ARM_EABI__ */ | ||
| 3949 | |||
| 3950 | zig_convert_builtin(zig_f32, zig_f32, trunc, zig_f64, zig_f64, 2) | ||
| 3951 | zig_convert_builtin(zig_f64, zig_f64, extend, zig_f32, zig_f32, 2) | ||
| 3952 | |||
| 3953 | #endif /* __ARM_EABI__ */ | ||
| 3954 | |||
| 3955 | #define zig_float_negate_builtin_0(w, c, sb) \ | ||
| 3956 | zig_expand_concat(zig_xor_, zig_repr_f##w)(arg, zig_make_f##w(-0x0.0p0, c sb)) | ||
| 3957 | #define zig_float_negate_builtin_1(w, c, sb) -arg | ||
| 3958 | #define zig_float_negate_builtin(w, c, sb) \ | ||
| 3959 | static inline zig_f##w zig_neg_f##w(zig_f##w arg) { \ | 6034 | static inline zig_f##w zig_neg_f##w(zig_f##w arg) { \ |
| 3960 | return zig_expand_concat(zig_float_negate_builtin_, zig_has_f##w)(w, c, sb); \ | 6035 | return zig_expand_concat(zig_float_negate_builtin_, zig_has_f##w)(w, sb); \ |
| 3961 | } | 6036 | } |
| 3962 | zig_float_negate_builtin(16, , UINT16_C(1) << 15 ) | 6037 | zig_float_negate_builtin(16, UINT16_C(1) << 15) |
| 3963 | zig_float_negate_builtin(32, , UINT32_C(1) << 31 ) | 6038 | zig_float_negate_builtin(32, UINT32_C(1) << 31) |
| 3964 | zig_float_negate_builtin(64, , UINT64_C(1) << 63 ) | 6039 | zig_float_negate_builtin(64, UINT64_C(1) << 63) |
| 3965 | zig_float_negate_builtin(80, zig_make_u128, (UINT64_C(1) << 15, UINT64_C(0))) | 6040 | |
| 3966 | zig_float_negate_builtin(128, zig_make_u128, (UINT64_C(1) << 63, UINT64_C(0))) | 6041 | #undef zig_float_negate_builtin_0 |
| 6042 | #define zig_float_negate_builtin_0(w, sb) \ | ||
| 6043 | zig_make_repr_f##w(zig_mantissa_repr_f##w(arg), zig_xor_u16(zig_exponent_repr_f##w(arg), sb)) | ||
| 6044 | zig_float_negate_builtin(80, UINT16_C(1) << 15) | ||
| 6045 | |||
| 6046 | #undef zig_float_negate_builtin_0 | ||
| 6047 | #define zig_float_negate_builtin_0(w, sb) \ | ||
| 6048 | zig_make_repr_f##w(zig_xor_u64(zig_hi_repr_f##w(arg), sb), zig_lo_repr_f##w(arg)) | ||
| 6049 | zig_float_negate_builtin(128, UINT64_C(1) << 63) | ||
| 3967 | 6050 | ||
| 3968 | #define zig_float_less_builtin_0(Type, operation) \ | 6051 | #define zig_float_less_builtin_0(Type, operation) \ |
| 3969 | zig_extern int32_t zig_expand_concat(zig_expand_concat(__##operation, \ | 6052 | zig_extern zig_FloatCompareResult zig_expand_concat(zig_expand_concat(__##operation, \ |
| 3970 | zig_compiler_rt_abbrev_zig_##Type), 2)(zig_##Type, zig_##Type); \ | 6053 | zig_compiler_rt_abbrev_zig_##Type), 2)(zig_##Type, zig_##Type); \ |
| 3971 | static inline int32_t zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \ | 6054 | static inline int32_t zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \ |
| 3972 | return zig_expand_concat(zig_expand_concat(__##operation, zig_compiler_rt_abbrev_zig_##Type), 2)(lhs, rhs); \ | 6055 | return (int32_t)zig_expand_concat(zig_expand_concat(__##operation, zig_compiler_rt_abbrev_zig_##Type), 2)(lhs, rhs); \ |
| 3973 | } | 6056 | } |
| 3974 | #define zig_float_less_builtin_1(Type, operation) \ | 6057 | #define zig_float_less_builtin_1(Type, operation) \ |
| 3975 | static inline int32_t zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \ | 6058 | static inline int32_t zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \ |
| ... | @@ -3994,13 +6077,52 @@ zig_float_negate_builtin(128, zig_make_u128, (UINT64_C(1) << 63, UINT64_C(0))) | ... | @@ -3994,13 +6077,52 @@ zig_float_negate_builtin(128, zig_make_u128, (UINT64_C(1) << 63, UINT64_C(0))) |
| 3994 | return lhs operator rhs; \ | 6077 | return lhs operator rhs; \ |
| 3995 | } | 6078 | } |
| 3996 | 6079 | ||
| 6080 | #define zig_float_builtins(w) \ | ||
| 6081 | zig_common_float_builtins(w) \ | ||
| 6082 | zig_convert_float(f##w, zig_f##w, float, int128, zig_i128, ) \ | ||
| 6083 | zig_convert_float(f##w, zig_f##w, floatun, int128, zig_u128, ) | ||
| 3997 | #define zig_common_float_builtins(w) \ | 6084 | #define zig_common_float_builtins(w) \ |
| 3998 | zig_convert_builtin( int64_t, int64_t, fix, zig_f##w, zig_f##w, ) \ | 6085 | zig_convert_float(always, int32_t, fix, f##w, zig_f##w, ) \ |
| 3999 | zig_convert_builtin(zig_i128, zig_i128, fix, zig_f##w, zig_f##w, ) \ | 6086 | zig_convert_float(always, int64_t, fix, f##w, zig_f##w, ) \ |
| 4000 | zig_convert_builtin(zig_u128, zig_u128, fixuns, zig_f##w, zig_f##w, ) \ | 6087 | zig_convert_float(int128, zig_i128, fix, f##w, zig_f##w, ) \ |
| 4001 | zig_convert_builtin(zig_f##w, zig_f##w, float, int64_t, int64_t, ) \ | 6088 | zig_convert_float(always, uint32_t, fixuns, f##w, zig_f##w, ) \ |
| 4002 | zig_convert_builtin(zig_f##w, zig_f##w, float, zig_i128, zig_i128, ) \ | 6089 | zig_convert_float(always, uint64_t, fixuns, f##w, zig_f##w, ) \ |
| 4003 | zig_convert_builtin(zig_f##w, zig_f##w, floatun, zig_u128, zig_u128, ) \ | 6090 | zig_convert_float(int128, zig_u128, fixuns, f##w, zig_f##w, ) \ |
| 6091 | zig_convert_float(f##w, zig_f##w, float, always, int32_t, ) \ | ||
| 6092 | zig_convert_float(f##w, zig_f##w, float, always, int64_t, ) \ | ||
| 6093 | zig_convert_float(f##w, zig_f##w, floatun, always, uint32_t, ) \ | ||
| 6094 | zig_convert_float(f##w, zig_f##w, floatun, always, uint64_t, ) \ | ||
| 6095 | \ | ||
| 6096 | static inline void zig_expand_concat(zig_expand_concat(zig_fix, \ | ||
| 6097 | zig_compiler_rt_abbrev_zig_f##w), ei)(void *res, zig_f##w arg, uint16_t bits) { \ | ||
| 6098 | zig_extern void zig_expand_concat(zig_expand_concat(__fix, \ | ||
| 6099 | zig_compiler_rt_abbrev_zig_f##w), ei)(uint8_t *res, uintptr_t bits, zig_f##w arg); \ | ||
| 6100 | zig_expand_concat(zig_expand_concat(__fix, \ | ||
| 6101 | zig_compiler_rt_abbrev_zig_f##w), ei)(res, bits, arg); \ | ||
| 6102 | } \ | ||
| 6103 | \ | ||
| 6104 | static inline void zig_expand_concat(zig_expand_concat(zig_fixuns, \ | ||
| 6105 | zig_compiler_rt_abbrev_zig_f##w), ei)(void *res, zig_f##w arg, uint16_t bits) { \ | ||
| 6106 | zig_extern void zig_expand_concat(zig_expand_concat(__fixuns, \ | ||
| 6107 | zig_compiler_rt_abbrev_zig_f##w), ei)(uint8_t *res, uintptr_t bits, zig_f##w arg); \ | ||
| 6108 | zig_expand_concat(zig_expand_concat(__fixuns, \ | ||
| 6109 | zig_compiler_rt_abbrev_zig_f##w), ei)(res, bits, arg); \ | ||
| 6110 | } \ | ||
| 6111 | \ | ||
| 6112 | static inline zig_f##w zig_expand_concat(zig_floatei, \ | ||
| 6113 | zig_compiler_rt_abbrev_zig_f##w)(void *res, uint16_t bits) { \ | ||
| 6114 | zig_extern zig_f##w zig_expand_concat(__floatei, \ | ||
| 6115 | zig_compiler_rt_abbrev_zig_f##w)(const uint8_t *arg, uintptr_t bits); \ | ||
| 6116 | return zig_expand_concat(__floatei, zig_compiler_rt_abbrev_zig_f##w)(res, bits); \ | ||
| 6117 | } \ | ||
| 6118 | \ | ||
| 6119 | static inline zig_f##w zig_expand_concat(zig_floatunei, \ | ||
| 6120 | zig_compiler_rt_abbrev_zig_f##w)(void *res, uint16_t bits) { \ | ||
| 6121 | zig_extern zig_f##w zig_expand_concat(__floatunei, \ | ||
| 6122 | zig_compiler_rt_abbrev_zig_f##w)(const uint8_t *arg, uintptr_t bits); \ | ||
| 6123 | return zig_expand_concat(__floatunei, zig_compiler_rt_abbrev_zig_f##w)(res, bits); \ | ||
| 6124 | } \ | ||
| 6125 | \ | ||
| 4004 | zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, cmp) \ | 6126 | zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, cmp) \ |
| 4005 | zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, ne) \ | 6127 | zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, ne) \ |
| 4006 | zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, eq) \ | 6128 | zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, eq) \ |
| ... | @@ -4031,82 +6153,48 @@ zig_float_negate_builtin(128, zig_make_u128, (UINT64_C(1) << 63, UINT64_C(0))) | ... | @@ -4031,82 +6153,48 @@ zig_float_negate_builtin(128, zig_make_u128, (UINT64_C(1) << 63, UINT64_C(0))) |
| 4031 | zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(fmax)))(zig_f##w, zig_max_f##w, zig_libc_name_f##w(fmax), (zig_f##w x, zig_f##w y), (x, y)) \ | 6153 | zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(fmax)))(zig_f##w, zig_max_f##w, zig_libc_name_f##w(fmax), (zig_f##w x, zig_f##w y), (x, y)) \ |
| 4032 | zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(fma)))(zig_f##w, zig_fma_f##w, zig_libc_name_f##w(fma), (zig_f##w x, zig_f##w y, zig_f##w z), (x, y, z)) \ | 6154 | zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(fma)))(zig_f##w, zig_fma_f##w, zig_libc_name_f##w(fma), (zig_f##w x, zig_f##w y, zig_f##w z), (x, y, z)) \ |
| 4033 | \ | 6155 | \ |
| 4034 | static inline zig_f##w zig_div_trunc_f##w(zig_f##w lhs, zig_f##w rhs) { \ | 6156 | static inline zig_f##w zig_divTrunc_f##w(zig_f##w lhs, zig_f##w rhs) { \ |
| 4035 | return zig_trunc_f##w(zig_div_f##w(lhs, rhs)); \ | 6157 | return zig_trunc_f##w(zig_div_f##w(lhs, rhs)); \ |
| 4036 | } \ | 6158 | } \ |
| 4037 | \ | 6159 | \ |
| 4038 | static inline zig_f##w zig_div_floor_f##w(zig_f##w lhs, zig_f##w rhs) { \ | 6160 | static inline zig_f##w zig_divFloor_f##w(zig_f##w lhs, zig_f##w rhs) { \ |
| 4039 | return zig_floor_f##w(zig_div_f##w(lhs, rhs)); \ | 6161 | return zig_floor_f##w(zig_div_f##w(lhs, rhs)); \ |
| 4040 | } \ | 6162 | } \ |
| 4041 | \ | 6163 | \ |
| 4042 | static inline zig_f##w zig_div_ceil_f##w(zig_f##w lhs, zig_f##w rhs) { \ | 6164 | static inline zig_f##w zig_divCeil_f##w(zig_f##w lhs, zig_f##w rhs) { \ |
| 4043 | return zig_ceil_f##w(zig_div_f##w(lhs, rhs)); \ | 6165 | return zig_ceil_f##w(zig_div_f##w(lhs, rhs)); \ |
| 4044 | } \ | 6166 | } \ |
| 4045 | \ | 6167 | \ |
| 4046 | static inline zig_f##w zig_mod_f##w(zig_f##w lhs, zig_f##w rhs) { \ | 6168 | static inline zig_f##w zig_mod_f##w(zig_f##w lhs, zig_f##w rhs) { \ |
| 4047 | return zig_sub_f##w(lhs, zig_mul_f##w(zig_div_floor_f##w(lhs, rhs), rhs)); \ | 6169 | return zig_sub_f##w(lhs, zig_mul_f##w(zig_divFloor_f##w(lhs, rhs), rhs)); \ |
| 4048 | } | 6170 | } |
| 4049 | zig_common_float_builtins(16) | ||
| 4050 | zig_common_float_builtins(32) | ||
| 4051 | zig_common_float_builtins(64) | ||
| 4052 | zig_common_float_builtins(80) | ||
| 4053 | zig_common_float_builtins(128) | ||
| 4054 | |||
| 4055 | #define zig_float_builtins(w) \ | ||
| 4056 | zig_convert_builtin( int32_t, int32_t, fix, zig_f##w, zig_f##w, ) \ | ||
| 4057 | zig_convert_builtin(uint32_t, uint32_t, fixuns, zig_f##w, zig_f##w, ) \ | ||
| 4058 | zig_convert_builtin(uint64_t, uint64_t, fixuns, zig_f##w, zig_f##w, ) \ | ||
| 4059 | zig_convert_builtin(zig_f##w, zig_f##w, float, int32_t, int32_t, ) \ | ||
| 4060 | zig_convert_builtin(zig_f##w, zig_f##w, floatun, uint32_t, uint32_t, ) \ | ||
| 4061 | zig_convert_builtin(zig_f##w, zig_f##w, floatun, uint64_t, uint64_t, ) | ||
| 4062 | zig_float_builtins(16) | 6171 | zig_float_builtins(16) |
| 4063 | zig_float_builtins(80) | ||
| 4064 | zig_float_builtins(128) | ||
| 4065 | |||
| 4066 | #ifdef __ARM_EABI__ | ||
| 4067 | |||
| 4068 | zig_extern zig_callconv(pcs("aapcs")) int32_t __aeabi_f2iz(zig_f32); | ||
| 4069 | static inline int32_t zig_fixsfsi(zig_f32 arg) { return __aeabi_f2iz(arg); } | ||
| 4070 | |||
| 4071 | zig_extern zig_callconv(pcs("aapcs")) uint32_t __aeabi_f2uiz(zig_f32); | ||
| 4072 | static inline uint32_t zig_fixunssfsi(zig_f32 arg) { return __aeabi_f2uiz(arg); } | ||
| 4073 | |||
| 4074 | zig_extern zig_callconv(pcs("aapcs")) uint64_t __aeabi_f2ulz(zig_f32); | ||
| 4075 | static inline uint64_t zig_fixunssfdi(zig_f32 arg) { return __aeabi_f2ulz(arg); } | ||
| 4076 | |||
| 4077 | zig_extern zig_callconv(pcs("aapcs")) zig_f32 __aeabi_i2f(int32_t); | ||
| 4078 | static inline zig_f32 zig_floatsisf(int32_t arg) { return __aeabi_i2f(arg); } | ||
| 4079 | |||
| 4080 | zig_extern zig_callconv(pcs("aapcs")) zig_f32 __aeabi_ui2f(uint32_t); | ||
| 4081 | static inline zig_f32 zig_floatunsisf(uint32_t arg) { return __aeabi_ui2f(arg); } | ||
| 4082 | |||
| 4083 | zig_extern zig_callconv(pcs("aapcs")) zig_f32 __aeabi_ul2f(uint64_t); | ||
| 4084 | static inline zig_f32 zig_floatundisf(uint64_t arg) { return __aeabi_ul2f(arg); } | ||
| 4085 | |||
| 4086 | zig_extern zig_callconv(pcs("aapcs")) int32_t __aeabi_d2iz(zig_f64); | ||
| 4087 | static inline int32_t zig_fixdfsi(zig_f64 arg) { return __aeabi_d2iz(arg); } | ||
| 4088 | |||
| 4089 | zig_extern zig_callconv(pcs("aapcs")) uint32_t __aeabi_d2uiz(zig_f64); | ||
| 4090 | static inline uint32_t zig_fixunsdfsi(zig_f64 arg) { return __aeabi_d2uiz(arg); } | ||
| 4091 | |||
| 4092 | zig_extern zig_callconv(pcs("aapcs")) uint64_t __aeabi_d2ulz(zig_f64); | ||
| 4093 | static inline uint64_t zig_fixunsdfdi(zig_f64 arg) { return __aeabi_d2ulz(arg); } | ||
| 4094 | |||
| 4095 | zig_extern zig_callconv(pcs("aapcs")) zig_f64 __aeabi_i2d(int32_t); | ||
| 4096 | static inline zig_f64 zig_floatsidf(int32_t arg) { return __aeabi_i2d(arg); } | ||
| 4097 | |||
| 4098 | zig_extern zig_callconv(pcs("aapcs")) zig_f64 __aeabi_ui2d(uint32_t); | ||
| 4099 | static inline zig_f64 zig_floatunsidf(uint32_t arg) { return __aeabi_ui2d(arg); } | ||
| 4100 | |||
| 4101 | zig_extern zig_callconv(pcs("aapcs")) zig_f64 __aeabi_ul2d(uint64_t); | ||
| 4102 | static inline zig_f64 zig_floatundidf(uint64_t arg) { return __aeabi_ul2d(arg); } | ||
| 4103 | |||
| 4104 | #else /* __ARM_EABI__ */ | ||
| 4105 | |||
| 4106 | zig_float_builtins(32) | 6172 | zig_float_builtins(32) |
| 4107 | zig_float_builtins(64) | 6173 | zig_float_builtins(64) |
| 4108 | 6174 | zig_float_builtins(80) | |
| 4109 | #endif /* __ARM_EABI__ */ | 6175 | #if defined(zig_x86_32) |
| 6176 | zig_common_float_builtins(128) | ||
| 6177 | static inline zig_f128 zig_floattitf(zig_i128 arg) { | ||
| 6178 | extern zig_f128 __floattitf(zig_f128 arg); | ||
| 6179 | return __floattitf(zig_f128_bitCast_i128(arg)); | ||
| 6180 | } | ||
| 6181 | static inline zig_f128 zig_floatuntitf(zig_u128 arg) { | ||
| 6182 | extern zig_f128 __floatuntitf(zig_f128 arg); | ||
| 6183 | return __floatuntitf(zig_f128_bitCast_u128(arg)); | ||
| 6184 | } | ||
| 6185 | #elif defined(zig_x86_64) && defined(zig_windows) | ||
| 6186 | zig_common_float_builtins(128) | ||
| 6187 | static inline zig_f128 zig_floattitf(zig_i128 arg) { | ||
| 6188 | extern zig_f128 __floattitf(zig_i128 arg); | ||
| 6189 | return __floattitf(arg); | ||
| 6190 | } | ||
| 6191 | static inline zig_f128 zig_floatuntitf(zig_u128 arg) { | ||
| 6192 | extern zig_f128 __floatuntitf(uint64_t arg_lo, uint64_t arg_hi); | ||
| 6193 | return __floatuntitf(zig_lo_u128(arg), zig_hi_u128(arg)); | ||
| 6194 | } | ||
| 6195 | #else | ||
| 6196 | zig_float_builtins(128) | ||
| 6197 | #endif | ||
| 4110 | 6198 | ||
| 4111 | /* ============================ Atomics Support ============================= */ | 6199 | /* ============================ Atomics Support ============================= */ |
| 4112 | 6200 | ||
| ... | @@ -4410,19 +6498,19 @@ typedef int zig_memory_order; | ... | @@ -4410,19 +6498,19 @@ typedef int zig_memory_order; |
| 4410 | } \ | 6498 | } \ |
| 4411 | static inline void zig_msvc_atomic_store_##ZigType(Type volatile* obj, Type value) { \ | 6499 | static inline void zig_msvc_atomic_store_##ZigType(Type volatile* obj, Type value) { \ |
| 4412 | (void)_InterlockedExchange##suffix((SigType volatile*)obj, (SigType)value); \ | 6500 | (void)_InterlockedExchange##suffix((SigType volatile*)obj, (SigType)value); \ |
| 4413 | } \ | 6501 | } \ |
| 4414 | static inline Type zig_msvc_atomic_load_zig_memory_order_relaxed_##ZigType(Type volatile* obj) { \ | 6502 | static inline Type zig_msvc_atomic_load_zig_memory_order_relaxed_##ZigType(Type volatile* obj) { \ |
| 4415 | return __iso_volatile_load##iso_suffix((SigType volatile*)obj); \ | 6503 | return __iso_volatile_load##iso_suffix((SigType volatile*)obj); \ |
| 4416 | } \ | 6504 | } \ |
| 4417 | static inline Type zig_msvc_atomic_load_zig_memory_order_acquire_##ZigType(Type volatile* obj) { \ | 6505 | static inline Type zig_msvc_atomic_load_zig_memory_order_acquire_##ZigType(Type volatile* obj) { \ |
| 4418 | Type val = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \ | 6506 | Type value = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \ |
| 4419 | _ReadWriteBarrier(); \ | 6507 | _ReadWriteBarrier(); \ |
| 4420 | return val; \ | 6508 | return value; \ |
| 4421 | } \ | 6509 | } \ |
| 4422 | static inline Type zig_msvc_atomic_load_zig_memory_order_seq_cst_##ZigType(Type volatile* obj) { \ | 6510 | static inline Type zig_msvc_atomic_load_zig_memory_order_seq_cst_##ZigType(Type volatile* obj) { \ |
| 4423 | Type val = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \ | 6511 | Type value = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \ |
| 4424 | _ReadWriteBarrier(); \ | 6512 | _ReadWriteBarrier(); \ |
| 4425 | return val; \ | 6513 | return value; \ |
| 4426 | } | 6514 | } |
| 4427 | 6515 | ||
| 4428 | zig_msvc_atomics( u8, uint8_t, char, 8, 8) | 6516 | zig_msvc_atomics( u8, uint8_t, char, 8, 8) |
| ... | @@ -4465,14 +6553,14 @@ zig_msvc_atomics(i64, int64_t, __int64, 64, 64) | ... | @@ -4465,14 +6553,14 @@ zig_msvc_atomics(i64, int64_t, __int64, 64, 64) |
| 4465 | zig_##Type result; \ | 6553 | zig_##Type result; \ |
| 4466 | SigType initial = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \ | 6554 | SigType initial = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \ |
| 4467 | _ReadWriteBarrier(); \ | 6555 | _ReadWriteBarrier(); \ |
| 4468 | memcpy(&result, &initial, sizeof(result)); \ | 6556 | memcpy(&result, &initial, sizeof(result)); \ |
| 4469 | return result; \ | 6557 | return result; \ |
| 4470 | } \ | 6558 | } \ |
| 4471 | static inline zig_##Type zig_msvc_atomic_load_zig_memory_order_seq_cst_##Type(zig_##Type volatile* obj) { \ | 6559 | static inline zig_##Type zig_msvc_atomic_load_zig_memory_order_seq_cst_##Type(zig_##Type volatile* obj) { \ |
| 4472 | zig_##Type result; \ | 6560 | zig_##Type result; \ |
| 4473 | SigType initial = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \ | 6561 | SigType initial = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \ |
| 4474 | _ReadWriteBarrier(); \ | 6562 | _ReadWriteBarrier(); \ |
| 4475 | memcpy(&result, &initial, sizeof(result)); \ | 6563 | memcpy(&result, &initial, sizeof(result)); \ |
| 4476 | return result; \ | 6564 | return result; \ |
| 4477 | } | 6565 | } |
| 4478 | 6566 | ||
| ... | @@ -4502,9 +6590,9 @@ static inline void* zig_msvc_atomic_load_zig_memory_order_relaxed_p32(void volat | ... | @@ -4502,9 +6590,9 @@ static inline void* zig_msvc_atomic_load_zig_memory_order_relaxed_p32(void volat |
| 4502 | } | 6590 | } |
| 4503 | 6591 | ||
| 4504 | static inline void* zig_msvc_atomic_load_zig_memory_order_acquire_p32(void volatile* obj) { | 6592 | static inline void* zig_msvc_atomic_load_zig_memory_order_acquire_p32(void volatile* obj) { |
| 4505 | void* val = (void*)__iso_volatile_load32(obj); | 6593 | void* value = (void*)__iso_volatile_load32(obj); |
| 4506 | _ReadWriteBarrier(); | 6594 | _ReadWriteBarrier(); |
| 4507 | return val; | 6595 | return value; |
| 4508 | } | 6596 | } |
| 4509 | 6597 | ||
| 4510 | static inline void* zig_msvc_atomic_load_zig_memory_order_seq_cst_p32(void volatile* obj) { | 6598 | static inline void* zig_msvc_atomic_load_zig_memory_order_seq_cst_p32(void volatile* obj) { |
| ... | @@ -4532,9 +6620,9 @@ static inline void* zig_msvc_atomic_load_zig_memory_order_relaxed_p64(void volat | ... | @@ -4532,9 +6620,9 @@ static inline void* zig_msvc_atomic_load_zig_memory_order_relaxed_p64(void volat |
| 4532 | } | 6620 | } |
| 4533 | 6621 | ||
| 4534 | static inline void* zig_msvc_atomic_load_zig_memory_order_acquire_p64(void volatile* obj) { | 6622 | static inline void* zig_msvc_atomic_load_zig_memory_order_acquire_p64(void volatile* obj) { |
| 4535 | void* val = (void*)__iso_volatile_load64(obj); | 6623 | void* value = (void*)__iso_volatile_load64(obj); |
| 4536 | _ReadWriteBarrier(); | 6624 | _ReadWriteBarrier(); |
| 4537 | return val; | 6625 | return value; |
| 4538 | } | 6626 | } |
| 4539 | 6627 | ||
| 4540 | static inline void* zig_msvc_atomic_load_zig_memory_order_seq_cst_p64(void volatile* obj) { | 6628 | static inline void* zig_msvc_atomic_load_zig_memory_order_seq_cst_p64(void volatile* obj) { |
stage1/zig1.wasm| Binary files a/stage1/zig1.wasm and b/stage1/zig1.wasm differ | |||
test/behavior/abs.zig-2| ... | @@ -144,7 +144,6 @@ test "@abs big int <= 128 bits" { | ... | @@ -144,7 +144,6 @@ test "@abs big int <= 128 bits" { |
| 144 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 144 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 145 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 145 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 146 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO | 146 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO |
| 147 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 148 | 147 | ||
| 149 | try comptime testAbsSignedBigInt(); | 148 | try comptime testAbsSignedBigInt(); |
| 150 | try testAbsSignedBigInt(); | 149 | try testAbsSignedBigInt(); |
| ... | @@ -256,7 +255,6 @@ fn testAbsFloats(comptime T: type) !void { | ... | @@ -256,7 +255,6 @@ fn testAbsFloats(comptime T: type) !void { |
| 256 | 255 | ||
| 257 | test "@abs int vectors" { | 256 | test "@abs int vectors" { |
| 258 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 257 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 259 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 260 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 258 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 261 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 259 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 262 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 260 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
test/behavior/align.zig+32-13| ... | @@ -129,8 +129,7 @@ test "alignment and size of structs with 128-bit fields" { | ... | @@ -129,8 +129,7 @@ test "alignment and size of structs with 128-bit fields" { |
| 129 | y: u8, | 129 | y: u8, |
| 130 | }; | 130 | }; |
| 131 | const expected = switch (builtin.cpu.arch) { | 131 | const expected = switch (builtin.cpu.arch) { |
| 132 | .s390x, | 132 | .s390x => .{ |
| 133 | => .{ | ||
| 134 | .a_align = 8, | 133 | .a_align = 8, |
| 135 | .a_size = 16, | 134 | .a_size = 16, |
| 136 | 135 | ||
| ... | @@ -142,7 +141,32 @@ test "alignment and size of structs with 128-bit fields" { | ... | @@ -142,7 +141,32 @@ test "alignment and size of structs with 128-bit fields" { |
| 142 | .u129_align = 8, | 141 | .u129_align = 8, |
| 143 | .u129_size = 24, | 142 | .u129_size = 24, |
| 144 | }, | 143 | }, |
| 145 | 144 | .x86 => switch (builtin.os.tag) { | |
| 145 | else => .{ | ||
| 146 | .a_align = 4, | ||
| 147 | .a_size = 16, | ||
| 148 | |||
| 149 | .b_align = 4, | ||
| 150 | .b_size = 20, | ||
| 151 | |||
| 152 | .u128_align = 4, | ||
| 153 | .u128_size = 16, | ||
| 154 | .u129_align = 4, | ||
| 155 | .u129_size = 20, | ||
| 156 | }, | ||
| 157 | .uefi, .windows => .{ | ||
| 158 | .a_align = 8, | ||
| 159 | .a_size = 16, | ||
| 160 | |||
| 161 | .b_align = 8, | ||
| 162 | .b_size = 24, | ||
| 163 | |||
| 164 | .u128_align = 8, | ||
| 165 | .u128_size = 16, | ||
| 166 | .u129_align = 8, | ||
| 167 | .u129_size = 24, | ||
| 168 | }, | ||
| 169 | }, | ||
| 146 | .amdgcn, | 170 | .amdgcn, |
| 147 | .arm, | 171 | .arm, |
| 148 | .armeb, | 172 | .armeb, |
| ... | @@ -155,12 +179,13 @@ test "alignment and size of structs with 128-bit fields" { | ... | @@ -155,12 +179,13 @@ test "alignment and size of structs with 128-bit fields" { |
| 155 | .powerpc, | 179 | .powerpc, |
| 156 | .powerpcle, | 180 | .powerpcle, |
| 157 | .riscv32, | 181 | .riscv32, |
| 182 | .sparc, | ||
| 158 | => .{ | 183 | => .{ |
| 159 | .a_align = 8, | 184 | .a_align = 8, |
| 160 | .a_size = 16, | 185 | .a_size = 16, |
| 161 | 186 | ||
| 162 | .b_align = 16, | 187 | .b_align = 8, |
| 163 | .b_size = 32, | 188 | .b_size = 24, |
| 164 | 189 | ||
| 165 | .u128_align = 8, | 190 | .u128_align = 8, |
| 166 | .u128_size = 16, | 191 | .u128_size = 16, |
| ... | @@ -178,12 +203,10 @@ test "alignment and size of structs with 128-bit fields" { | ... | @@ -178,12 +203,10 @@ test "alignment and size of structs with 128-bit fields" { |
| 178 | .nvptx64, | 203 | .nvptx64, |
| 179 | .powerpc64, | 204 | .powerpc64, |
| 180 | .powerpc64le, | 205 | .powerpc64le, |
| 181 | .sparc, | ||
| 182 | .sparc64, | 206 | .sparc64, |
| 183 | .riscv64, | 207 | .riscv64, |
| 184 | .wasm32, | 208 | .wasm32, |
| 185 | .wasm64, | 209 | .wasm64, |
| 186 | .x86, | ||
| 187 | .x86_64, | 210 | .x86_64, |
| 188 | => .{ | 211 | => .{ |
| 189 | .a_align = 16, | 212 | .a_align = 16, |
| ... | @@ -200,12 +223,11 @@ test "alignment and size of structs with 128-bit fields" { | ... | @@ -200,12 +223,11 @@ test "alignment and size of structs with 128-bit fields" { |
| 200 | 223 | ||
| 201 | else => return error.SkipZigTest, | 224 | else => return error.SkipZigTest, |
| 202 | }; | 225 | }; |
| 203 | const min_struct_align = if (builtin.zig_backend == .stage2_c) if (builtin.cpu.arch == .s390x) 8 else 16 else 0; | ||
| 204 | comptime { | 226 | comptime { |
| 205 | assert(@alignOf(A) == @max(expected.a_align, min_struct_align)); | 227 | assert(@alignOf(A) == expected.a_align); |
| 206 | assert(@sizeOf(A) == expected.a_size); | 228 | assert(@sizeOf(A) == expected.a_size); |
| 207 | 229 | ||
| 208 | assert(@alignOf(B) == @max(expected.b_align, min_struct_align)); | 230 | assert(@alignOf(B) == expected.b_align); |
| 209 | assert(@sizeOf(B) == expected.b_size); | 231 | assert(@sizeOf(B) == expected.b_size); |
| 210 | 232 | ||
| 211 | assert(@alignOf(u128) == expected.u128_align); | 233 | assert(@alignOf(u128) == expected.u128_align); |
| ... | @@ -547,8 +569,6 @@ test "sub-aligned pointer field access" { | ... | @@ -547,8 +569,6 @@ test "sub-aligned pointer field access" { |
| 547 | } | 569 | } |
| 548 | 570 | ||
| 549 | test "alignment of zero-bit types is respected" { | 571 | test "alignment of zero-bit types is respected" { |
| 550 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 551 | if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; | ||
| 552 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 572 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 553 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO | 573 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO |
| 554 | 574 | ||
| ... | @@ -582,7 +602,6 @@ test "zero-bit fields in extern struct pad fields appropriately" { | ... | @@ -582,7 +602,6 @@ test "zero-bit fields in extern struct pad fields appropriately" { |
| 582 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 602 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 583 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; | 603 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; |
| 584 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 604 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 585 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 586 | 605 | ||
| 587 | const S = extern struct { | 606 | const S = extern struct { |
| 588 | x: u8, | 607 | x: u8, |
test/behavior/basic.zig-3| ... | @@ -797,10 +797,8 @@ test "auto created variables have correct alignment" { | ... | @@ -797,10 +797,8 @@ test "auto created variables have correct alignment" { |
| 797 | } | 797 | } |
| 798 | 798 | ||
| 799 | test "extern variable with non-pointer opaque type" { | 799 | test "extern variable with non-pointer opaque type" { |
| 800 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | ||
| 801 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 800 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 802 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 801 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 803 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 804 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO | 802 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO |
| 805 | 803 | ||
| 806 | @export(&var_to_export, .{ .name = "opaque_extern_var" }); | 804 | @export(&var_to_export, .{ .name = "opaque_extern_var" }); |
| ... | @@ -1398,7 +1396,6 @@ test "allocation and looping over 3-byte integer" { | ... | @@ -1398,7 +1396,6 @@ test "allocation and looping over 3-byte integer" { |
| 1398 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1396 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1399 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 1397 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 1400 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 1398 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 1401 | if (builtin.zig_backend == .stage2_llvm and builtin.os.tag.isDarwin()) return error.SkipZigTest; // TODO | ||
| 1402 | 1399 | ||
| 1403 | try expect(@sizeOf(u24) == 4); | 1400 | try expect(@sizeOf(u24) == 4); |
| 1404 | try expect(@sizeOf([1]u24) == 4); | 1401 | try expect(@sizeOf([1]u24) == 4); |
test/behavior/bit_shifting.zig-1| ... | @@ -147,7 +147,6 @@ test "Saturating Shift Left where lhs is of a computed type" { | ... | @@ -147,7 +147,6 @@ test "Saturating Shift Left where lhs is of a computed type" { |
| 147 | 147 | ||
| 148 | test "Saturating Shift Left" { | 148 | test "Saturating Shift Left" { |
| 149 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 149 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 150 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 151 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; | 150 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; |
| 152 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 151 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 153 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 152 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
test/behavior/bitcast.zig+17-6| ... | @@ -210,7 +210,6 @@ test "triple level result location with bitcast sandwich passed as tuple element | ... | @@ -210,7 +210,6 @@ test "triple level result location with bitcast sandwich passed as tuple element |
| 210 | 210 | ||
| 211 | test "@bitCast packed struct of floats" { | 211 | test "@bitCast packed struct of floats" { |
| 212 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 212 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 213 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 214 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 213 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 215 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 214 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 216 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 215 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| ... | @@ -247,7 +246,6 @@ test "@bitCast packed struct of floats" { | ... | @@ -247,7 +246,6 @@ test "@bitCast packed struct of floats" { |
| 247 | 246 | ||
| 248 | test "comptime @bitCast packed struct to int and back" { | 247 | test "comptime @bitCast packed struct to int and back" { |
| 249 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 248 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 250 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 251 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 249 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 252 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 250 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 253 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 251 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| ... | @@ -283,7 +281,6 @@ test "comptime @bitCast packed struct to int and back" { | ... | @@ -283,7 +281,6 @@ test "comptime @bitCast packed struct to int and back" { |
| 283 | test "bitcast vector to integer and back" { | 281 | test "bitcast vector to integer and back" { |
| 284 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 282 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 285 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 283 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 286 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 287 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 284 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 288 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 285 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 289 | 286 | ||
| ... | @@ -329,10 +326,10 @@ fn bitCastWrapper128(x: f128) u128 { | ... | @@ -329,10 +326,10 @@ fn bitCastWrapper128(x: f128) u128 { |
| 329 | } | 326 | } |
| 330 | test "bitcast nan float does not modify signaling bit" { | 327 | test "bitcast nan float does not modify signaling bit" { |
| 331 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 328 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 332 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 333 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 329 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 334 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 330 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 335 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | 331 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; |
| 332 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 336 | 333 | ||
| 337 | const snan_u16: u16 = 0x7D00; | 334 | const snan_u16: u16 = 0x7D00; |
| 338 | const snan_u32: u32 = 0x7FA00000; | 335 | const snan_u32: u32 = 0x7FA00000; |
| ... | @@ -383,7 +380,6 @@ test "bitcast nan float does not modify signaling bit" { | ... | @@ -383,7 +380,6 @@ test "bitcast nan float does not modify signaling bit" { |
| 383 | test "@bitCast of packed struct of bools all true" { | 380 | test "@bitCast of packed struct of bools all true" { |
| 384 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 381 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 385 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 382 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 386 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 387 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO | 383 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO |
| 388 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO | 384 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO |
| 389 | 385 | ||
| ... | @@ -404,7 +400,6 @@ test "@bitCast of packed struct of bools all true" { | ... | @@ -404,7 +400,6 @@ test "@bitCast of packed struct of bools all true" { |
| 404 | test "@bitCast of packed struct of bools all false" { | 400 | test "@bitCast of packed struct of bools all false" { |
| 405 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 401 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 406 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 402 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 407 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 408 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO | 403 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO |
| 409 | 404 | ||
| 410 | const P = packed struct { | 405 | const P = packed struct { |
| ... | @@ -437,6 +432,22 @@ test "@bitCast of packed struct with void field to integer" { | ... | @@ -437,6 +432,22 @@ test "@bitCast of packed struct with void field to integer" { |
| 437 | try comptime S.doTheTest(123); | 432 | try comptime S.doTheTest(123); |
| 438 | } | 433 | } |
| 439 | 434 | ||
| 435 | test "@bitCast of packed struct with void field and multiple integers" { | ||
| 436 | const S = packed struct { | ||
| 437 | x: u8, | ||
| 438 | v: void, | ||
| 439 | y: u8, | ||
| 440 | |||
| 441 | fn doTheTest(x: u8, y: u8) !void { | ||
| 442 | const foo = @as(@This(), .{ .x = x, .v = {}, .y = y }); | ||
| 443 | const as_int: u16 = @bitCast(foo); | ||
| 444 | try expect(as_int == @as(u16, y) << 8 | x); | ||
| 445 | } | ||
| 446 | }; | ||
| 447 | try S.doTheTest(123, 45); | ||
| 448 | try comptime S.doTheTest(123, 45); | ||
| 449 | } | ||
| 450 | |||
| 440 | test "@bitCast vector to array with different element size" { | 451 | test "@bitCast vector to array with different element size" { |
| 441 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 452 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 442 | 453 |
test/behavior/builtin_functions_returning_void_or_noreturn.zig-1| ... | @@ -6,7 +6,6 @@ var x: u8 = 1; | ... | @@ -6,7 +6,6 @@ var x: u8 = 1; |
| 6 | 6 | ||
| 7 | // This excludes builtin functions that return void or noreturn that cannot be tested. | 7 | // This excludes builtin functions that return void or noreturn that cannot be tested. |
| 8 | test { | 8 | test { |
| 9 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | ||
| 10 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 9 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 11 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 10 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 12 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 11 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
test/behavior/call.zig-1| ... | @@ -21,7 +21,6 @@ test "super basic invocations" { | ... | @@ -21,7 +21,6 @@ test "super basic invocations" { |
| 21 | 21 | ||
| 22 | test "basic invocations" { | 22 | test "basic invocations" { |
| 23 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 23 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 24 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | ||
| 25 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 24 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 26 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 25 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 27 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 26 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
test/behavior/cast.zig+7-19| ... | @@ -120,6 +120,7 @@ test "@floatFromInt" { | ... | @@ -120,6 +120,7 @@ test "@floatFromInt" { |
| 120 | try expect(@as(i32, @floor(f)) == k); | 120 | try expect(@as(i32, @floor(f)) == k); |
| 121 | try expect(@as(i32, @ceil(f)) == k); | 121 | try expect(@as(i32, @ceil(f)) == k); |
| 122 | try expect(@as(i32, @trunc(f)) == k); | 122 | try expect(@as(i32, @trunc(f)) == k); |
| 123 | try expect(@as(i32, @trunc(@floor(f))) == k); | ||
| 123 | } | 124 | } |
| 124 | }; | 125 | }; |
| 125 | try S.doTheTest(); | 126 | try S.doTheTest(); |
| ... | @@ -134,7 +135,6 @@ test "@intFromFloat > 128 bits" { | ... | @@ -134,7 +135,6 @@ test "@intFromFloat > 128 bits" { |
| 134 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 135 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 135 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 136 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 136 | if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; | 137 | if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; |
| 137 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 138 | 138 | ||
| 139 | try testIntFromFloat(f16, 1024, u140, 1024); | 139 | try testIntFromFloat(f16, 1024, u140, 1024); |
| 140 | try testIntFromFloat(f16, -1024, i140, -1024); | 140 | try testIntFromFloat(f16, -1024, i140, -1024); |
| ... | @@ -160,7 +160,6 @@ test "@floatFromInt > 128 bits" { | ... | @@ -160,7 +160,6 @@ test "@floatFromInt > 128 bits" { |
| 160 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 160 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 161 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 161 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 162 | if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; | 162 | if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; |
| 163 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 164 | 163 | ||
| 165 | try testFloatFromInt(u140, 1024, f16, 1024); | 164 | try testFloatFromInt(u140, 1024, f16, 1024); |
| 166 | try testFloatFromInt(i140, -1024, f16, -1024); | 165 | try testFloatFromInt(i140, -1024, f16, -1024); |
| ... | @@ -182,8 +181,8 @@ test "@floatFromInt(f80)" { | ... | @@ -182,8 +181,8 @@ test "@floatFromInt(f80)" { |
| 182 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 181 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 183 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 182 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 184 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 183 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 185 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 186 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 184 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 185 | if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; | ||
| 187 | 186 | ||
| 188 | const S = struct { | 187 | const S = struct { |
| 189 | fn doTheTest(comptime Int: type) !void { | 188 | fn doTheTest(comptime Int: type) !void { |
| ... | @@ -199,6 +198,7 @@ test "@floatFromInt(f80)" { | ... | @@ -199,6 +198,7 @@ test "@floatFromInt(f80)" { |
| 199 | try expect(@as(Int, @floor(f)) == k); | 198 | try expect(@as(Int, @floor(f)) == k); |
| 200 | try expect(@as(Int, @ceil(f)) == k); | 199 | try expect(@as(Int, @ceil(f)) == k); |
| 201 | try expect(@as(Int, @trunc(f)) == k); | 200 | try expect(@as(Int, @trunc(f)) == k); |
| 201 | try expect(@as(Int, @trunc(@floor(f))) == k); | ||
| 202 | } | 202 | } |
| 203 | }; | 203 | }; |
| 204 | try S.doTheTest(i31); | 204 | try S.doTheTest(i31); |
| ... | @@ -207,7 +207,7 @@ test "@floatFromInt(f80)" { | ... | @@ -207,7 +207,7 @@ test "@floatFromInt(f80)" { |
| 207 | try S.doTheTest(i64); | 207 | try S.doTheTest(i64); |
| 208 | try S.doTheTest(i80); | 208 | try S.doTheTest(i80); |
| 209 | try S.doTheTest(i128); | 209 | try S.doTheTest(i128); |
| 210 | // try S.doTheTest(i256); // TODO missing compiler_rt symbols | 210 | try S.doTheTest(i256); |
| 211 | try comptime S.doTheTest(i31); | 211 | try comptime S.doTheTest(i31); |
| 212 | try comptime S.doTheTest(i32); | 212 | try comptime S.doTheTest(i32); |
| 213 | try comptime S.doTheTest(i45); | 213 | try comptime S.doTheTest(i45); |
| ... | @@ -281,6 +281,7 @@ test "type coercion from int to float" { | ... | @@ -281,6 +281,7 @@ test "type coercion from int to float" { |
| 281 | test "@intFromFloat" { | 281 | test "@intFromFloat" { |
| 282 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 282 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 283 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 283 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 284 | |||
| 284 | try testIntFromFloats(); | 285 | try testIntFromFloats(); |
| 285 | try comptime testIntFromFloats(); | 286 | try comptime testIntFromFloats(); |
| 286 | } | 287 | } |
| ... | @@ -498,7 +499,7 @@ test "array coercion to undefined at runtime" { | ... | @@ -498,7 +499,7 @@ test "array coercion to undefined at runtime" { |
| 498 | 499 | ||
| 499 | @setRuntimeSafety(true); | 500 | @setRuntimeSafety(true); |
| 500 | 501 | ||
| 501 | if (builtin.mode != .Debug and builtin.mode != .ReleaseSafe) { | 502 | if (builtin.mode != .debug and builtin.mode != .safe) { |
| 502 | return error.SkipZigTest; | 503 | return error.SkipZigTest; |
| 503 | } | 504 | } |
| 504 | 505 | ||
| ... | @@ -1473,11 +1474,6 @@ fn foobar(func: PFN_void) !void { | ... | @@ -1473,11 +1474,6 @@ fn foobar(func: PFN_void) !void { |
| 1473 | test "cast function with an opaque parameter" { | 1474 | test "cast function with an opaque parameter" { |
| 1474 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 1475 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 1475 | 1476 | ||
| 1476 | if (builtin.zig_backend == .stage2_c) { | ||
| 1477 | // https://github.com/ziglang/zig/issues/16845 | ||
| 1478 | return error.SkipZigTest; | ||
| 1479 | } | ||
| 1480 | |||
| 1481 | const Container = struct { | 1477 | const Container = struct { |
| 1482 | const Ctx = opaque {}; | 1478 | const Ctx = opaque {}; |
| 1483 | ctx: *Ctx, | 1479 | ctx: *Ctx, |
| ... | @@ -1724,9 +1720,7 @@ test "cast f16 to wider types" { | ... | @@ -1724,9 +1720,7 @@ test "cast f16 to wider types" { |
| 1724 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1720 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1725 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1721 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1726 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 1722 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 1727 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 1728 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 1723 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 1729 | if (builtin.target.cpu.arch == .x86_64 and builtin.target.os.tag == .macos) return error.SkipZigTest; | ||
| 1730 | 1724 | ||
| 1731 | const S = struct { | 1725 | const S = struct { |
| 1732 | fn doTheTest() !void { | 1726 | fn doTheTest() !void { |
| ... | @@ -1831,21 +1825,15 @@ test "pointer to empty struct literal to mutable slice" { | ... | @@ -1831,21 +1825,15 @@ test "pointer to empty struct literal to mutable slice" { |
| 1831 | 1825 | ||
| 1832 | test "coerce between pointers of compatible differently-named floats" { | 1826 | test "coerce between pointers of compatible differently-named floats" { |
| 1833 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1827 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1834 | if (builtin.zig_backend == .stage2_c and builtin.os.tag == .windows and !builtin.link_libc) return error.SkipZigTest; | ||
| 1835 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1828 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1836 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 1829 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 1837 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 1830 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 1838 | 1831 | ||
| 1839 | if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) { | ||
| 1840 | // https://github.com/ziglang/zig/issues/12396 | ||
| 1841 | return error.SkipZigTest; | ||
| 1842 | } | ||
| 1843 | |||
| 1844 | const F = switch (@typeInfo(c_longdouble).float.bits) { | 1832 | const F = switch (@typeInfo(c_longdouble).float.bits) { |
| 1845 | 64 => f64, | 1833 | 64 => f64, |
| 1846 | 80 => f80, | 1834 | 80 => f80, |
| 1847 | 128 => f128, | 1835 | 128 => f128, |
| 1848 | else => @compileError("unreachable"), | 1836 | else => comptime unreachable, |
| 1849 | }; | 1837 | }; |
| 1850 | var f1: F = 12.34; | 1838 | var f1: F = 12.34; |
| 1851 | const f2: *c_longdouble = &f1; | 1839 | const f2: *c_longdouble = &f1; |
test/behavior/cast_int.zig-1| ... | @@ -168,7 +168,6 @@ test "@intCast <= 64 bits" { | ... | @@ -168,7 +168,6 @@ test "@intCast <= 64 bits" { |
| 168 | 168 | ||
| 169 | test "@intCast > 128 bits" { | 169 | test "@intCast > 128 bits" { |
| 170 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 170 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 171 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 172 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 171 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 173 | 172 | ||
| 174 | try testIntCast(u8, 123, u140, 123); | 173 | try testIntCast(u8, 123, u140, 123); |
test/behavior/eval.zig-1| ... | @@ -513,7 +513,6 @@ test "runtime 128 bit integer division" { | ... | @@ -513,7 +513,6 @@ test "runtime 128 bit integer division" { |
| 513 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 513 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 514 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 514 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 515 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 515 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 516 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 517 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 516 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 518 | 517 | ||
| 519 | var a: u128 = 152313999999999991610955792383; | 518 | var a: u128 = 152313999999999991610955792383; |
test/behavior/export_builtin.zig-15| ... | @@ -5,11 +5,6 @@ const expect = std.testing.expect; | ... | @@ -5,11 +5,6 @@ const expect = std.testing.expect; |
| 5 | test "exporting enum value" { | 5 | test "exporting enum value" { |
| 6 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 6 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 7 | 7 | ||
| 8 | if (builtin.cpu.arch.isWasm()) { | ||
| 9 | // https://github.com/ziglang/zig/issues/4866 | ||
| 10 | return error.SkipZigTest; | ||
| 11 | } | ||
| 12 | |||
| 13 | const S = struct { | 8 | const S = struct { |
| 14 | const E = enum(c_int) { one, two }; | 9 | const E = enum(c_int) { one, two }; |
| 15 | const e: E = .two; | 10 | const e: E = .two; |
| ... | @@ -35,11 +30,6 @@ test "exporting with internal linkage" { | ... | @@ -35,11 +30,6 @@ test "exporting with internal linkage" { |
| 35 | test "exporting using namespace access" { | 30 | test "exporting using namespace access" { |
| 36 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 31 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 37 | 32 | ||
| 38 | if (builtin.cpu.arch.isWasm()) { | ||
| 39 | // https://github.com/ziglang/zig/issues/4866 | ||
| 40 | return error.SkipZigTest; | ||
| 41 | } | ||
| 42 | |||
| 43 | const S = struct { | 33 | const S = struct { |
| 44 | const Inner = struct { | 34 | const Inner = struct { |
| 45 | const x: u32 = 5; | 35 | const x: u32 = 5; |
| ... | @@ -57,11 +47,6 @@ test "exporting comptime-known value" { | ... | @@ -57,11 +47,6 @@ test "exporting comptime-known value" { |
| 57 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | 47 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; |
| 58 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 48 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 59 | 49 | ||
| 60 | if (builtin.cpu.arch.isWasm()) { | ||
| 61 | // https://github.com/ziglang/zig/issues/4866 | ||
| 62 | return error.SkipZigTest; | ||
| 63 | } | ||
| 64 | |||
| 65 | const x: u32 = 10; | 50 | const x: u32 = 10; |
| 66 | @export(&x, .{ .name = "exporting_comptime_known_value_foo" }); | 51 | @export(&x, .{ .name = "exporting_comptime_known_value_foo" }); |
| 67 | const S = struct { | 52 | const S = struct { |
test/behavior/extern.zig-1| ... | @@ -3,7 +3,6 @@ const std = @import("std"); | ... | @@ -3,7 +3,6 @@ const std = @import("std"); |
| 3 | const expect = std.testing.expect; | 3 | const expect = std.testing.expect; |
| 4 | 4 | ||
| 5 | test "anyopaque extern symbol" { | 5 | test "anyopaque extern symbol" { |
| 6 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 7 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | 6 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 8 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 7 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 9 | 8 |
test/behavior/field_parent_ptr.zig-3| ... | @@ -586,7 +586,6 @@ test "@fieldParentPtr extern struct last zero-bit field" { | ... | @@ -586,7 +586,6 @@ test "@fieldParentPtr extern struct last zero-bit field" { |
| 586 | } | 586 | } |
| 587 | 587 | ||
| 588 | test "@fieldParentPtr unaligned packed struct" { | 588 | test "@fieldParentPtr unaligned packed struct" { |
| 589 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 590 | if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; | 589 | if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; |
| 591 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 590 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 592 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 591 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| ... | @@ -725,7 +724,6 @@ test "@fieldParentPtr unaligned packed struct" { | ... | @@ -725,7 +724,6 @@ test "@fieldParentPtr unaligned packed struct" { |
| 725 | } | 724 | } |
| 726 | 725 | ||
| 727 | test "@fieldParentPtr aligned packed struct" { | 726 | test "@fieldParentPtr aligned packed struct" { |
| 728 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 729 | if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; | 727 | if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; |
| 730 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 728 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 731 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 729 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| ... | @@ -1897,7 +1895,6 @@ test "@fieldParentPtr packed union" { | ... | @@ -1897,7 +1895,6 @@ test "@fieldParentPtr packed union" { |
| 1897 | } | 1895 | } |
| 1898 | 1896 | ||
| 1899 | test "@fieldParentPtr tagged union all zero-bit fields" { | 1897 | test "@fieldParentPtr tagged union all zero-bit fields" { |
| 1900 | if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; | ||
| 1901 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 1898 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 1902 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 1899 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 1903 | 1900 |
test/behavior/floatop.zig+10-50| ... | @@ -118,7 +118,6 @@ fn testMul(comptime T: type) !void { | ... | @@ -118,7 +118,6 @@ fn testMul(comptime T: type) !void { |
| 118 | test "cmp f16" { | 118 | test "cmp f16" { |
| 119 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 119 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 120 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 120 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 121 | if (builtin.cpu.arch.isArm() and builtin.target.abi.float() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234 | ||
| 122 | 121 | ||
| 123 | try testCmp(f16); | 122 | try testCmp(f16); |
| 124 | try comptime testCmp(f16); | 123 | try comptime testCmp(f16); |
| ... | @@ -127,7 +126,6 @@ test "cmp f16" { | ... | @@ -127,7 +126,6 @@ test "cmp f16" { |
| 127 | test "cmp f32" { | 126 | test "cmp f32" { |
| 128 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 127 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 129 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 128 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 130 | if (builtin.cpu.arch.isArm() and builtin.target.abi.float() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234 | ||
| 131 | 129 | ||
| 132 | try testCmp(f32); | 130 | try testCmp(f32); |
| 133 | try comptime testCmp(f32); | 131 | try comptime testCmp(f32); |
| ... | @@ -142,7 +140,6 @@ test "cmp f64" { | ... | @@ -142,7 +140,6 @@ test "cmp f64" { |
| 142 | 140 | ||
| 143 | test "cmp f128" { | 141 | test "cmp f128" { |
| 144 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 142 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 145 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 146 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 143 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 147 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 144 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 148 | 145 | ||
| ... | @@ -152,7 +149,6 @@ test "cmp f128" { | ... | @@ -152,7 +149,6 @@ test "cmp f128" { |
| 152 | 149 | ||
| 153 | test "cmp f80/c_longdouble" { | 150 | test "cmp f80/c_longdouble" { |
| 154 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 151 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 155 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 156 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 152 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 157 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 153 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 158 | 154 | ||
| ... | @@ -220,7 +216,6 @@ test "vector cmp f16" { | ... | @@ -220,7 +216,6 @@ test "vector cmp f16" { |
| 220 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 216 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 221 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 217 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 222 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 218 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 223 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 224 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 219 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 225 | 220 | ||
| 226 | try testCmpVector(f16); | 221 | try testCmpVector(f16); |
| ... | @@ -233,7 +228,7 @@ test "vector cmp f32" { | ... | @@ -233,7 +228,7 @@ test "vector cmp f32" { |
| 233 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 228 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 234 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 229 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 235 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isArm()) return error.SkipZigTest; | 230 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isArm()) return error.SkipZigTest; |
| 236 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 231 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; // https://github.com/llvm/llvm-project/issues/214198 |
| 237 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 232 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 238 | 233 | ||
| 239 | try testCmpVector(f32); | 234 | try testCmpVector(f32); |
| ... | @@ -253,10 +248,9 @@ test "vector cmp f64" { | ... | @@ -253,10 +248,9 @@ test "vector cmp f64" { |
| 253 | test "vector cmp f128" { | 248 | test "vector cmp f128" { |
| 254 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 249 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 255 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 250 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 256 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 257 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 251 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 258 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 252 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 259 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .powerpc64le) return error.SkipZigTest; | 253 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; // https://github.com/llvm/llvm-project/issues/214198 |
| 260 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 254 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 261 | 255 | ||
| 262 | try testCmpVector(f128); | 256 | try testCmpVector(f128); |
| ... | @@ -266,7 +260,7 @@ test "vector cmp f128" { | ... | @@ -266,7 +260,7 @@ test "vector cmp f128" { |
| 266 | test "vector cmp f80/c_longdouble" { | 260 | test "vector cmp f80/c_longdouble" { |
| 267 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 261 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 268 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 262 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 269 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .powerpc64le) return error.SkipZigTest; | 263 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; // https://github.com/llvm/llvm-project/issues/214198 |
| 270 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 264 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 271 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 265 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 272 | 266 | ||
| ... | @@ -381,11 +375,7 @@ test "@sqrt f80/f128/c_longdouble" { | ... | @@ -381,11 +375,7 @@ test "@sqrt f80/f128/c_longdouble" { |
| 381 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 375 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 382 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 376 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 383 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 377 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 384 | 378 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | |
| 385 | if (builtin.os.tag == .freebsd) { | ||
| 386 | // TODO https://github.com/ziglang/zig/issues/10875 | ||
| 387 | return error.SkipZigTest; | ||
| 388 | } | ||
| 389 | 379 | ||
| 390 | try testSqrt(f80); | 380 | try testSqrt(f80); |
| 391 | try comptime testSqrt(f80); | 381 | try comptime testSqrt(f80); |
| ... | @@ -431,9 +421,9 @@ fn testSqrt(comptime T: type) !void { | ... | @@ -431,9 +421,9 @@ fn testSqrt(comptime T: type) !void { |
| 431 | var inf: T = math.inf(T); | 421 | var inf: T = math.inf(T); |
| 432 | try expect(math.isPositiveInf(@sqrt(inf))); | 422 | try expect(math.isPositiveInf(@sqrt(inf))); |
| 433 | var zero: T = 0.0; | 423 | var zero: T = 0.0; |
| 434 | try expect(@sqrt(zero) == 0.0); | 424 | try expect(math.isPositiveZero(@sqrt(zero))); |
| 435 | var neg_zero: T = -0.0; | 425 | var neg_zero: T = -0.0; |
| 436 | try expect(@sqrt(neg_zero) == 0.0); | 426 | try expect(math.isNegativeZero(@sqrt(neg_zero))); |
| 437 | var neg_one: T = -1.0; | 427 | var neg_one: T = -1.0; |
| 438 | try expect(math.isNan(@sqrt(neg_one))); | 428 | try expect(math.isNan(@sqrt(neg_one))); |
| 439 | var nan: T = math.nan(T); | 429 | var nan: T = math.nan(T); |
| ... | @@ -947,7 +937,7 @@ test "@log2 with vectors" { | ... | @@ -947,7 +937,7 @@ test "@log2 with vectors" { |
| 947 | builtin.cpu.arch == .aarch64 and | 937 | builtin.cpu.arch == .aarch64 and |
| 948 | builtin.os.tag == .windows) return error.SkipZigTest; | 938 | builtin.os.tag == .windows) return error.SkipZigTest; |
| 949 | 939 | ||
| 950 | if (builtin.os.tag == .windows and builtin.cpu.arch == .x86) { | 940 | if (builtin.os.tag == .windows and builtin.cpu.arch == .x86 and builtin.abi == .msvc) { |
| 951 | // https://codeberg.org/ziglang/zig/issues/35518 | 941 | // https://codeberg.org/ziglang/zig/issues/35518 |
| 952 | return error.SkipZigTest; | 942 | return error.SkipZigTest; |
| 953 | } | 943 | } |
| ... | @@ -1054,7 +1044,6 @@ test "@abs f32/f64" { | ... | @@ -1054,7 +1044,6 @@ test "@abs f32/f64" { |
| 1054 | 1044 | ||
| 1055 | test "@abs f80/f128/c_longdouble" { | 1045 | test "@abs f80/f128/c_longdouble" { |
| 1056 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1046 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1057 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 1058 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1047 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1059 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 1048 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 1060 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 1049 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| ... | @@ -1172,16 +1161,10 @@ test "@floor f32/f64" { | ... | @@ -1172,16 +1161,10 @@ test "@floor f32/f64" { |
| 1172 | 1161 | ||
| 1173 | test "@floor f80/f128/c_longdouble" { | 1162 | test "@floor f80/f128/c_longdouble" { |
| 1174 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1163 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1175 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 1176 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1164 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1177 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 1165 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 1178 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 1166 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 1179 | 1167 | ||
| 1180 | if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) { | ||
| 1181 | // https://github.com/ziglang/zig/issues/12602 | ||
| 1182 | return error.SkipZigTest; | ||
| 1183 | } | ||
| 1184 | |||
| 1185 | try testFloor(f80); | 1168 | try testFloor(f80); |
| 1186 | try comptime testFloor(f80); | 1169 | try comptime testFloor(f80); |
| 1187 | try testFloor(f128); | 1170 | try testFloor(f128); |
| ... | @@ -1261,16 +1244,10 @@ test "@ceil f32/f64" { | ... | @@ -1261,16 +1244,10 @@ test "@ceil f32/f64" { |
| 1261 | 1244 | ||
| 1262 | test "@ceil f80/f128/c_longdouble" { | 1245 | test "@ceil f80/f128/c_longdouble" { |
| 1263 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1246 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1264 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 1265 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1247 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1266 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 1248 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 1267 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 1249 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 1268 | 1250 | ||
| 1269 | if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) { | ||
| 1270 | // https://github.com/ziglang/zig/issues/12602 | ||
| 1271 | return error.SkipZigTest; | ||
| 1272 | } | ||
| 1273 | |||
| 1274 | try testCeil(f80); | 1251 | try testCeil(f80); |
| 1275 | try comptime testCeil(f80); | 1252 | try comptime testCeil(f80); |
| 1276 | try testCeil(f128); | 1253 | try testCeil(f128); |
| ... | @@ -1281,16 +1258,10 @@ test "@ceil f80/f128/c_longdouble" { | ... | @@ -1281,16 +1258,10 @@ test "@ceil f80/f128/c_longdouble" { |
| 1281 | 1258 | ||
| 1282 | test "@ceil f80 maxInt(u64)" { | 1259 | test "@ceil f80 maxInt(u64)" { |
| 1283 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1260 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1284 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 1285 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1261 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1286 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 1262 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 1287 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 1263 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 1288 | 1264 | ||
| 1289 | if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) { | ||
| 1290 | // https://github.com/ziglang/zig/issues/12602 | ||
| 1291 | return error.SkipZigTest; | ||
| 1292 | } | ||
| 1293 | |||
| 1294 | var x: u64 = std.math.maxInt(u64); | 1265 | var x: u64 = std.math.maxInt(u64); |
| 1295 | x = x; | 1266 | x = x; |
| 1296 | const float: f80 = @floatFromInt(x); | 1267 | const float: f80 = @floatFromInt(x); |
| ... | @@ -1368,16 +1339,10 @@ test "@trunc f32/f64" { | ... | @@ -1368,16 +1339,10 @@ test "@trunc f32/f64" { |
| 1368 | 1339 | ||
| 1369 | test "@trunc f80/f128/c_longdouble" { | 1340 | test "@trunc f80/f128/c_longdouble" { |
| 1370 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1341 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1371 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 1372 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1342 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1373 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 1343 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 1374 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 1344 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 1375 | 1345 | ||
| 1376 | if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) { | ||
| 1377 | // https://github.com/ziglang/zig/issues/12602 | ||
| 1378 | return error.SkipZigTest; | ||
| 1379 | } | ||
| 1380 | |||
| 1381 | try testTrunc(f80); | 1346 | try testTrunc(f80); |
| 1382 | try comptime testTrunc(f80); | 1347 | try comptime testTrunc(f80); |
| 1383 | try testTrunc(f128); | 1348 | try testTrunc(f128); |
| ... | @@ -1440,11 +1405,6 @@ test "neg f16" { | ... | @@ -1440,11 +1405,6 @@ test "neg f16" { |
| 1440 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1405 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1441 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 1406 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 1442 | 1407 | ||
| 1443 | if (builtin.os.tag == .freebsd) { | ||
| 1444 | // TODO file issue to track this failure | ||
| 1445 | return error.SkipZigTest; | ||
| 1446 | } | ||
| 1447 | |||
| 1448 | try testNeg(f16); | 1408 | try testNeg(f16); |
| 1449 | try comptime testNeg(f16); | 1409 | try comptime testNeg(f16); |
| 1450 | } | 1410 | } |
| ... | @@ -1501,9 +1461,9 @@ fn testNeg(comptime T: type) !void { | ... | @@ -1501,9 +1461,9 @@ fn testNeg(comptime T: type) !void { |
| 1501 | 1461 | ||
| 1502 | // subnormals | 1462 | // subnormals |
| 1503 | var zero: T = 0.0; | 1463 | var zero: T = 0.0; |
| 1504 | try expect(-zero == -0.0); | 1464 | try expect(math.isNegativeZero(-zero)); |
| 1505 | var neg_zero: T = -0.0; | 1465 | var neg_zero: T = -0.0; |
| 1506 | try expect(-neg_zero == 0.0); | 1466 | try expect(math.isPositiveZero(-neg_zero)); |
| 1507 | var true_min: T = math.floatTrueMin(T); | 1467 | var true_min: T = math.floatTrueMin(T); |
| 1508 | try expect(-true_min == -math.floatTrueMin(T)); | 1468 | try expect(-true_min == -math.floatTrueMin(T)); |
| 1509 | var neg_true_min: T = -math.floatTrueMin(T); | 1469 | var neg_true_min: T = -math.floatTrueMin(T); |
| ... | @@ -1678,7 +1638,7 @@ test "runtime isNan(inf * 0)" { | ... | @@ -1678,7 +1638,7 @@ test "runtime isNan(inf * 0)" { |
| 1678 | 1638 | ||
| 1679 | test "optimized float mode" { | 1639 | test "optimized float mode" { |
| 1680 | if (builtin.zig_backend != .stage2_llvm) return error.SkipZigTest; | 1640 | if (builtin.zig_backend != .stage2_llvm) return error.SkipZigTest; |
| 1681 | if (builtin.mode == .Debug) return error.SkipZigTest; | 1641 | if (builtin.mode == .debug) return error.SkipZigTest; |
| 1682 | 1642 | ||
| 1683 | const big = 0x1p40; | 1643 | const big = 0x1p40; |
| 1684 | const small = 0.001; | 1644 | const small = 0.001; |
test/behavior/fn.zig-2| ... | @@ -147,7 +147,6 @@ fn fnWithUnreachable() noreturn { | ... | @@ -147,7 +147,6 @@ fn fnWithUnreachable() noreturn { |
| 147 | 147 | ||
| 148 | test "extern struct with stdcallcc fn pointer" { | 148 | test "extern struct with stdcallcc fn pointer" { |
| 149 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 149 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 150 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch == .x86) return error.SkipZigTest; | ||
| 151 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 150 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 152 | 151 | ||
| 153 | const S = extern struct { | 152 | const S = extern struct { |
| ... | @@ -419,7 +418,6 @@ test "import passed byref to function in return type" { | ... | @@ -419,7 +418,6 @@ test "import passed byref to function in return type" { |
| 419 | 418 | ||
| 420 | test "implicit cast function to function ptr" { | 419 | test "implicit cast function to function ptr" { |
| 421 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 420 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 422 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | ||
| 423 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 421 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 424 | 422 | ||
| 425 | const S1 = struct { | 423 | const S1 = struct { |
test/behavior/int128.zig+1-1| ... | @@ -31,7 +31,7 @@ test "undefined 128 bit int" { | ... | @@ -31,7 +31,7 @@ test "undefined 128 bit int" { |
| 31 | @setRuntimeSafety(true); | 31 | @setRuntimeSafety(true); |
| 32 | 32 | ||
| 33 | // TODO implement @setRuntimeSafety | 33 | // TODO implement @setRuntimeSafety |
| 34 | if (builtin.mode != .Debug and builtin.mode != .ReleaseSafe) { | 34 | if (builtin.mode != .debug and builtin.mode != .safe) { |
| 35 | return error.SkipZigTest; | 35 | return error.SkipZigTest; |
| 36 | } | 36 | } |
| 37 | 37 |
test/behavior/math.zig-35| ... | @@ -873,7 +873,6 @@ test "umax wrapped squaring" { | ... | @@ -873,7 +873,6 @@ test "umax wrapped squaring" { |
| 873 | test "128-bit multiplication" { | 873 | test "128-bit multiplication" { |
| 874 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 874 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 875 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 875 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 876 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 877 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 876 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 878 | 877 | ||
| 879 | { | 878 | { |
| ... | @@ -968,7 +967,6 @@ test "@addWithOverflow > 128 bits" { | ... | @@ -968,7 +967,6 @@ test "@addWithOverflow > 128 bits" { |
| 968 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 967 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 969 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 968 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 970 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO | 969 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO |
| 971 | if (builtin.zig_backend == .stage2_c and builtin.target.abi == .msvc) return error.SkipZigTest; | ||
| 972 | 970 | ||
| 973 | try testAddWithOverflow(u129, 4, 105, 109, 0); | 971 | try testAddWithOverflow(u129, 4, 105, 109, 0); |
| 974 | try testAddWithOverflow(u129, 1000, 100, 1100, 0); | 972 | try testAddWithOverflow(u129, 1000, 100, 1100, 0); |
| ... | @@ -1136,7 +1134,6 @@ test "Multiply unwrap error * immediate" { | ... | @@ -1136,7 +1134,6 @@ test "Multiply unwrap error * immediate" { |
| 1136 | 1134 | ||
| 1137 | test "@mulWithOverflow bitsize 128 bits" { | 1135 | test "@mulWithOverflow bitsize 128 bits" { |
| 1138 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1136 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1139 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 1140 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 1137 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 1141 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1138 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1142 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1139 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -1163,7 +1160,6 @@ test "@mulWithOverflow bitsize 128 bits" { | ... | @@ -1163,7 +1160,6 @@ test "@mulWithOverflow bitsize 128 bits" { |
| 1163 | 1160 | ||
| 1164 | test "@mulWithOverflow > 128 bits" { | 1161 | test "@mulWithOverflow > 128 bits" { |
| 1165 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1162 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1166 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 1167 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 1163 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 1168 | 1164 | ||
| 1169 | try testMulWithOverflow(u140, 0, maxInt(u140), 0, 0); | 1165 | try testMulWithOverflow(u140, 0, maxInt(u140), 0, 0); |
| ... | @@ -1193,7 +1189,6 @@ test "@mulWithOverflow > 128 bits" { | ... | @@ -1193,7 +1189,6 @@ test "@mulWithOverflow > 128 bits" { |
| 1193 | 1189 | ||
| 1194 | test "@mulWithOverflow bitsize 256 bits" { | 1190 | test "@mulWithOverflow bitsize 256 bits" { |
| 1195 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1191 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1196 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 1197 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 1192 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 1198 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 1193 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 1199 | 1194 | ||
| ... | @@ -1298,7 +1293,6 @@ test "@subWithOverflow > 128 bits" { | ... | @@ -1298,7 +1293,6 @@ test "@subWithOverflow > 128 bits" { |
| 1298 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1293 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1299 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 1294 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 1300 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO | 1295 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO |
| 1301 | if (builtin.zig_backend == .stage2_c and builtin.target.abi == .msvc) return error.SkipZigTest; | ||
| 1302 | 1296 | ||
| 1303 | try testSubWithOverflow(u129, 4, 105, maxInt(u129) - 100, 1); | 1297 | try testSubWithOverflow(u129, 4, 105, maxInt(u129) - 100, 1); |
| 1304 | try testSubWithOverflow(u129, 1000, 100, 900, 0); | 1298 | try testSubWithOverflow(u129, 1000, 100, 900, 0); |
| ... | @@ -1389,7 +1383,6 @@ test "@shlWithOverflow > 64 bits" { | ... | @@ -1389,7 +1383,6 @@ test "@shlWithOverflow > 64 bits" { |
| 1389 | 1383 | ||
| 1390 | test "@shlWithOverflow > 128 bits" { | 1384 | test "@shlWithOverflow > 128 bits" { |
| 1391 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1385 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1392 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 1393 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 1386 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 1394 | 1387 | ||
| 1395 | try testShlWithOverflow(u140, 1 << 100, 20, 1 << 120, 0); | 1388 | try testShlWithOverflow(u140, 1 << 100, 20, 1 << 120, 0); |
| ... | @@ -1419,7 +1412,6 @@ fn testAnd(comptime T: type, a: T, b: T, expected: T) !void { | ... | @@ -1419,7 +1412,6 @@ fn testAnd(comptime T: type, a: T, b: T, expected: T) !void { |
| 1419 | 1412 | ||
| 1420 | test "and > 128 bits" { | 1413 | test "and > 128 bits" { |
| 1421 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1414 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1422 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 1423 | 1415 | ||
| 1424 | try testAnd(u140, (1 << 139) | (1 << 70) | 0xaa, (1 << 139) | (1 << 69) | 0xcc, (1 << 139) | 0x88); | 1416 | try testAnd(u140, (1 << 139) | (1 << 70) | 0xaa, (1 << 139) | (1 << 69) | 0xcc, (1 << 139) | 0x88); |
| 1425 | try testAnd(u140, maxInt(u140), 1 << 100, 1 << 100); | 1417 | try testAnd(u140, maxInt(u140), 1 << 100, 1 << 100); |
| ... | @@ -1448,7 +1440,6 @@ fn testOr(comptime T: type, a: T, b: T, expected: T) !void { | ... | @@ -1448,7 +1440,6 @@ fn testOr(comptime T: type, a: T, b: T, expected: T) !void { |
| 1448 | 1440 | ||
| 1449 | test "or > 128 bits" { | 1441 | test "or > 128 bits" { |
| 1450 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1442 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1451 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 1452 | 1443 | ||
| 1453 | try testOr(u140, 0, 1 << 139, 1 << 139); | 1444 | try testOr(u140, 0, 1 << 139, 1 << 139); |
| 1454 | try testOr(u140, (1 << 70) | 0xa, (1 << 69) | 0x5, (1 << 70) | (1 << 69) | 0xf); | 1445 | try testOr(u140, (1 << 70) | 0xa, (1 << 69) | 0x5, (1 << 70) | (1 << 69) | 0xf); |
| ... | @@ -1477,7 +1468,6 @@ fn testXor(comptime T: type, a: T, b: T, expected: T) !void { | ... | @@ -1477,7 +1468,6 @@ fn testXor(comptime T: type, a: T, b: T, expected: T) !void { |
| 1477 | 1468 | ||
| 1478 | test "xor > 128 bits" { | 1469 | test "xor > 128 bits" { |
| 1479 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1470 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1480 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 1481 | 1471 | ||
| 1482 | try testXor(u140, 0, maxInt(u140), maxInt(u140)); | 1472 | try testXor(u140, 0, maxInt(u140), maxInt(u140)); |
| 1483 | try testXor(u140, 1 << 139, 1 << 139, 0); | 1473 | try testXor(u140, 1 << 139, 1 << 139, 0); |
| ... | @@ -1506,7 +1496,6 @@ fn testNot(comptime T: type, a: T, expected: T) !void { | ... | @@ -1506,7 +1496,6 @@ fn testNot(comptime T: type, a: T, expected: T) !void { |
| 1506 | 1496 | ||
| 1507 | test "not > 128 bits" { | 1497 | test "not > 128 bits" { |
| 1508 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1498 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1509 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 1510 | 1499 | ||
| 1511 | try testNot(u140, 0, maxInt(u140)); | 1500 | try testNot(u140, 0, maxInt(u140)); |
| 1512 | try testNot(u140, maxInt(u140), 0); | 1501 | try testNot(u140, maxInt(u140), 0); |
| ... | @@ -1535,7 +1524,6 @@ fn testShl(comptime T: type, a: T, b: std.math.Log2Int(T), expected: T) !void { | ... | @@ -1535,7 +1524,6 @@ fn testShl(comptime T: type, a: T, b: std.math.Log2Int(T), expected: T) !void { |
| 1535 | 1524 | ||
| 1536 | test "shl > 128 bits" { | 1525 | test "shl > 128 bits" { |
| 1537 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1526 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1538 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 1539 | 1527 | ||
| 1540 | try testShl(u140, 1 << 5, 10, 1 << 15); | 1528 | try testShl(u140, 1 << 5, 10, 1 << 15); |
| 1541 | try testShl(u140, 3, 138, (1 << 139) | (1 << 138)); | 1529 | try testShl(u140, 3, 138, (1 << 139) | (1 << 138)); |
| ... | @@ -1564,7 +1552,6 @@ fn testShr(comptime T: type, a: T, b: std.math.Log2Int(T), expected: T) !void { | ... | @@ -1564,7 +1552,6 @@ fn testShr(comptime T: type, a: T, b: std.math.Log2Int(T), expected: T) !void { |
| 1564 | 1552 | ||
| 1565 | test "shr > 128 bits" { | 1553 | test "shr > 128 bits" { |
| 1566 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1554 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1567 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 1568 | 1555 | ||
| 1569 | try testShr(u140, 1 << 139, 39, 1 << 100); | 1556 | try testShr(u140, 1 << 139, 39, 1 << 100); |
| 1570 | try testShr(u140, (1 << 70) | 8, 3, (1 << 67) | 1); | 1557 | try testShr(u140, (1 << 70) | 8, 3, (1 << 67) | 1); |
| ... | @@ -1593,7 +1580,6 @@ fn testClz(comptime T: type, a: T, expected: u16) !void { | ... | @@ -1593,7 +1580,6 @@ fn testClz(comptime T: type, a: T, expected: u16) !void { |
| 1593 | 1580 | ||
| 1594 | test "@clz > 128 bits" { | 1581 | test "@clz > 128 bits" { |
| 1595 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1582 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1596 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 1597 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 1583 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 1598 | 1584 | ||
| 1599 | try testClz(u140, 0, 140); | 1585 | try testClz(u140, 0, 140); |
| ... | @@ -1623,7 +1609,6 @@ fn testCtz(comptime T: type, a: T, expected: u16) !void { | ... | @@ -1623,7 +1609,6 @@ fn testCtz(comptime T: type, a: T, expected: u16) !void { |
| 1623 | 1609 | ||
| 1624 | test "@ctz > 128 bits" { | 1610 | test "@ctz > 128 bits" { |
| 1625 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1611 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1626 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 1627 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 1612 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 1628 | 1613 | ||
| 1629 | try testCtz(u140, 0, 140); | 1614 | try testCtz(u140, 0, 140); |
| ... | @@ -1653,7 +1638,6 @@ fn testPopCount(comptime T: type, a: T, expected: u16) !void { | ... | @@ -1653,7 +1638,6 @@ fn testPopCount(comptime T: type, a: T, expected: u16) !void { |
| 1653 | 1638 | ||
| 1654 | test "@popCount > 128 bits" { | 1639 | test "@popCount > 128 bits" { |
| 1655 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1640 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1656 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 1657 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 1641 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 1658 | 1642 | ||
| 1659 | try testPopCount(u140, 0, 0); | 1643 | try testPopCount(u140, 0, 0); |
| ... | @@ -1683,7 +1667,6 @@ fn testBitReverse(comptime T: type, a: T, expected: T) !void { | ... | @@ -1683,7 +1667,6 @@ fn testBitReverse(comptime T: type, a: T, expected: T) !void { |
| 1683 | 1667 | ||
| 1684 | test "@bitReverse > 128 bits" { | 1668 | test "@bitReverse > 128 bits" { |
| 1685 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1669 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1686 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 1687 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 1670 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 1688 | 1671 | ||
| 1689 | try testBitReverse(u140, 1 << 139, 1); | 1672 | try testBitReverse(u140, 1 << 139, 1); |
| ... | @@ -1713,7 +1696,6 @@ fn testByteSwap(comptime T: type, a: T, expected: T) !void { | ... | @@ -1713,7 +1696,6 @@ fn testByteSwap(comptime T: type, a: T, expected: T) !void { |
| 1713 | 1696 | ||
| 1714 | test "@byteSwap > 128 bits" { | 1697 | test "@byteSwap > 128 bits" { |
| 1715 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1698 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1716 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 1717 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 1699 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 1718 | 1700 | ||
| 1719 | try testByteSwap(u144, 1 << 136, 1); | 1701 | try testByteSwap(u144, 1 << 136, 1); |
| ... | @@ -1743,7 +1725,6 @@ fn testMax(comptime T: type, a: T, b: T, expected: T) !void { | ... | @@ -1743,7 +1725,6 @@ fn testMax(comptime T: type, a: T, b: T, expected: T) !void { |
| 1743 | 1725 | ||
| 1744 | test "@max > 128 bits" { | 1726 | test "@max > 128 bits" { |
| 1745 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1727 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1746 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 1747 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 1728 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 1748 | 1729 | ||
| 1749 | try testMax(u140, 0, maxInt(u140), maxInt(u140)); | 1730 | try testMax(u140, 0, maxInt(u140), maxInt(u140)); |
| ... | @@ -1773,7 +1754,6 @@ fn testMin(comptime T: type, a: T, b: T, expected: T) !void { | ... | @@ -1773,7 +1754,6 @@ fn testMin(comptime T: type, a: T, b: T, expected: T) !void { |
| 1773 | 1754 | ||
| 1774 | test "@min > 128 bits" { | 1755 | test "@min > 128 bits" { |
| 1775 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1756 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1776 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 1777 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 1757 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 1778 | 1758 | ||
| 1779 | try testMin(u140, 0, maxInt(u140), 0); | 1759 | try testMin(u140, 0, maxInt(u140), 0); |
| ... | @@ -1803,7 +1783,6 @@ fn testAbs(comptime T: type, a: T, expected: anytype) !void { | ... | @@ -1803,7 +1783,6 @@ fn testAbs(comptime T: type, a: T, expected: anytype) !void { |
| 1803 | 1783 | ||
| 1804 | test "@abs > 128 bits" { | 1784 | test "@abs > 128 bits" { |
| 1805 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1785 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1806 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 1807 | 1786 | ||
| 1808 | try testAbs(u140, 0, 0); | 1787 | try testAbs(u140, 0, 0); |
| 1809 | try testAbs(u140, 1 << 139, 1 << 139); | 1788 | try testAbs(u140, 1 << 139, 1 << 139); |
| ... | @@ -1827,7 +1806,6 @@ fn testRem(comptime T: type, numerator: T, denominator: T, expected: T) !void { | ... | @@ -1827,7 +1806,6 @@ fn testRem(comptime T: type, numerator: T, denominator: T, expected: T) !void { |
| 1827 | 1806 | ||
| 1828 | test "@rem > 128 bits" { | 1807 | test "@rem > 128 bits" { |
| 1829 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1808 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1830 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 1831 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 1809 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 1832 | 1810 | ||
| 1833 | try testRem(u140, 0, maxInt(u140), 0); | 1811 | try testRem(u140, 0, maxInt(u140), 0); |
| ... | @@ -1855,7 +1833,6 @@ fn testMod(comptime T: type, numerator: T, denominator: T, expected: T) !void { | ... | @@ -1855,7 +1833,6 @@ fn testMod(comptime T: type, numerator: T, denominator: T, expected: T) !void { |
| 1855 | 1833 | ||
| 1856 | test "@mod > 128 bits" { | 1834 | test "@mod > 128 bits" { |
| 1857 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1835 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1858 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 1859 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 1836 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 1860 | 1837 | ||
| 1861 | try testMod(u140, 0, maxInt(u140), 0); | 1838 | try testMod(u140, 0, maxInt(u140), 0); |
| ... | @@ -1883,7 +1860,6 @@ fn testDivFloor(comptime T: type, numerator: T, denominator: T, expected: T) !vo | ... | @@ -1883,7 +1860,6 @@ fn testDivFloor(comptime T: type, numerator: T, denominator: T, expected: T) !vo |
| 1883 | 1860 | ||
| 1884 | test "@divFloor > 128 bits" { | 1861 | test "@divFloor > 128 bits" { |
| 1885 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1862 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1886 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 1887 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 1863 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 1888 | 1864 | ||
| 1889 | try testDivFloor(u140, 0, maxInt(u140), 0); | 1865 | try testDivFloor(u140, 0, maxInt(u140), 0); |
| ... | @@ -1912,7 +1888,6 @@ fn testDivCeil(comptime T: type, numerator: T, denominator: T, expected: T) !voi | ... | @@ -1912,7 +1888,6 @@ fn testDivCeil(comptime T: type, numerator: T, denominator: T, expected: T) !voi |
| 1912 | 1888 | ||
| 1913 | test "@divCeil > 128 bits" { | 1889 | test "@divCeil > 128 bits" { |
| 1914 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1890 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1915 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 1916 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 1891 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 1917 | 1892 | ||
| 1918 | try testDivCeil(u140, 0, maxInt(u140), 0); | 1893 | try testDivCeil(u140, 0, maxInt(u140), 0); |
| ... | @@ -1941,7 +1916,6 @@ fn testDivTrunc(comptime T: type, numerator: T, denominator: T, expected: T) !vo | ... | @@ -1941,7 +1916,6 @@ fn testDivTrunc(comptime T: type, numerator: T, denominator: T, expected: T) !vo |
| 1941 | 1916 | ||
| 1942 | test "@divTrunc > 128 bits" { | 1917 | test "@divTrunc > 128 bits" { |
| 1943 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1918 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1944 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 1945 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 1919 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 1946 | 1920 | ||
| 1947 | try testDivTrunc(u140, 0, maxInt(u140), 0); | 1921 | try testDivTrunc(u140, 0, maxInt(u140), 0); |
| ... | @@ -2166,14 +2140,8 @@ test "remainder division" { | ... | @@ -2166,14 +2140,8 @@ test "remainder division" { |
| 2166 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 2140 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 2167 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 2141 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 2168 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 2142 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 2169 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 2170 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 2143 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 2171 | 2144 | ||
| 2172 | if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) { | ||
| 2173 | // https://github.com/ziglang/zig/issues/12602 | ||
| 2174 | return error.SkipZigTest; | ||
| 2175 | } | ||
| 2176 | |||
| 2177 | if (builtin.zig_backend == .stage2_x86_64 and builtin.object_format == .coff and builtin.abi != .gnu) return error.SkipZigTest; | 2145 | if (builtin.zig_backend == .stage2_x86_64 and builtin.object_format == .coff and builtin.abi != .gnu) return error.SkipZigTest; |
| 2178 | 2146 | ||
| 2179 | try comptime remdiv(f16); | 2147 | try comptime remdiv(f16); |
| ... | @@ -2315,7 +2283,6 @@ test "@round f80" { | ... | @@ -2315,7 +2283,6 @@ test "@round f80" { |
| 2315 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 2283 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 2316 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 2284 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 2317 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 2285 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 2318 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 2319 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 2286 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 2320 | 2287 | ||
| 2321 | try testRound(f80, 12.0); | 2288 | try testRound(f80, 12.0); |
| ... | @@ -2326,7 +2293,6 @@ test "@round f128" { | ... | @@ -2326,7 +2293,6 @@ test "@round f128" { |
| 2326 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 2293 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 2327 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 2294 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 2328 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 2295 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 2329 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 2330 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 2296 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 2331 | 2297 | ||
| 2332 | try testRound(f128, 12.0); | 2298 | try testRound(f128, 12.0); |
| ... | @@ -2366,7 +2332,6 @@ test "NaN comparison" { | ... | @@ -2366,7 +2332,6 @@ test "NaN comparison" { |
| 2366 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 2332 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 2367 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 2333 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 2368 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 2334 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 2369 | if (builtin.cpu.arch.isArm() and builtin.target.abi.float() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234 | ||
| 2370 | 2335 | ||
| 2371 | try testNanEqNan(f16); | 2336 | try testNanEqNan(f16); |
| 2372 | try testNanEqNan(f32); | 2337 | try testNanEqNan(f32); |
test/behavior/maximum_minimum.zig-1| ... | @@ -115,7 +115,6 @@ test "@min/max for floats" { | ... | @@ -115,7 +115,6 @@ test "@min/max for floats" { |
| 115 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 115 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 116 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 116 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 117 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 117 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 118 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 119 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 118 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 120 | 119 | ||
| 121 | const S = struct { | 120 | const S = struct { |
test/behavior/muladd.zig-4| ... | @@ -49,7 +49,6 @@ test "@mulAdd f80" { | ... | @@ -49,7 +49,6 @@ test "@mulAdd f80" { |
| 49 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 49 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 50 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 50 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 51 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 51 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 52 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 53 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 52 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 54 | 53 | ||
| 55 | try comptime testMulAdd80(); | 54 | try comptime testMulAdd80(); |
| ... | @@ -68,7 +67,6 @@ test "@mulAdd f128" { | ... | @@ -68,7 +67,6 @@ test "@mulAdd f128" { |
| 68 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 67 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 69 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 68 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 70 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 69 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 71 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 72 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 70 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 73 | 71 | ||
| 74 | try comptime testMulAdd128(); | 72 | try comptime testMulAdd128(); |
| ... | @@ -169,7 +167,6 @@ test "vector f80" { | ... | @@ -169,7 +167,6 @@ test "vector f80" { |
| 169 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 167 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 170 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 168 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 171 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 169 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 172 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 173 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 170 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 174 | 171 | ||
| 175 | try comptime vector80(); | 172 | try comptime vector80(); |
| ... | @@ -194,7 +191,6 @@ test "vector f128" { | ... | @@ -194,7 +191,6 @@ test "vector f128" { |
| 194 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 191 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 195 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 192 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 196 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 193 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 197 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 198 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 194 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 199 | 195 | ||
| 200 | try comptime vector128(); | 196 | try comptime vector128(); |
test/behavior/packed-struct.zig-4| ... | @@ -404,7 +404,6 @@ test "nested packed struct field pointers" { | ... | @@ -404,7 +404,6 @@ test "nested packed struct field pointers" { |
| 404 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 404 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 405 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 405 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 406 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 406 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 407 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // ubsan unaligned pointer access | ||
| 408 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO | 407 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO |
| 409 | const S2 = packed struct { | 408 | const S2 = packed struct { |
| 410 | base: u8, | 409 | base: u8, |
| ... | @@ -579,7 +578,6 @@ test "packed struct fields modification" { | ... | @@ -579,7 +578,6 @@ test "packed struct fields modification" { |
| 579 | } | 578 | } |
| 580 | 579 | ||
| 581 | test "nested packed struct field access test" { | 580 | test "nested packed struct field access test" { |
| 582 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 583 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 581 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 584 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 582 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 585 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 583 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| ... | @@ -733,7 +731,6 @@ test "nested packed struct at non-zero offset 2" { | ... | @@ -733,7 +731,6 @@ test "nested packed struct at non-zero offset 2" { |
| 733 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 731 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 734 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 732 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 735 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 733 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 736 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 737 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 734 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 738 | 735 | ||
| 739 | const S = struct { | 736 | const S = struct { |
| ... | @@ -1171,7 +1168,6 @@ test "packed struct equality" { | ... | @@ -1171,7 +1168,6 @@ test "packed struct equality" { |
| 1171 | 1168 | ||
| 1172 | test "packed struct equality ignores padding bits" { | 1169 | test "packed struct equality ignores padding bits" { |
| 1173 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1170 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1174 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 1175 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 1171 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 1176 | 1172 | ||
| 1177 | const S = packed struct { b: bool }; | 1173 | const S = packed struct { b: bool }; |
test/behavior/pointers.zig+1-1| ... | @@ -275,7 +275,7 @@ test "compare equality of optional and non-optional pointer" { | ... | @@ -275,7 +275,7 @@ test "compare equality of optional and non-optional pointer" { |
| 275 | } | 275 | } |
| 276 | 276 | ||
| 277 | test "allowzero pointer and slice" { | 277 | test "allowzero pointer and slice" { |
| 278 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | 278 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; |
| 279 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 279 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 280 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 280 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 281 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 281 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
test/behavior/saturating_arithmetic.zig-7| ... | @@ -144,7 +144,6 @@ test "saturating multiplication <= 32 bits" { | ... | @@ -144,7 +144,6 @@ test "saturating multiplication <= 32 bits" { |
| 144 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 144 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 145 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 145 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 146 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 146 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 147 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 148 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 147 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 149 | 148 | ||
| 150 | try testSatMul(u8, 0, maxInt(u8), 0); | 149 | try testSatMul(u8, 0, maxInt(u8), 0); |
| ... | @@ -238,7 +237,6 @@ test "saturating multiplication" { | ... | @@ -238,7 +237,6 @@ test "saturating multiplication" { |
| 238 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 237 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 239 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 238 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 240 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 239 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 241 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 242 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 240 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 243 | 241 | ||
| 244 | const S = struct { | 242 | const S = struct { |
| ... | @@ -313,7 +311,6 @@ test "saturating shift-left" { | ... | @@ -313,7 +311,6 @@ test "saturating shift-left" { |
| 313 | 311 | ||
| 314 | test "saturating shift-left large rhs" { | 312 | test "saturating shift-left large rhs" { |
| 315 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 313 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 316 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 317 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 314 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 318 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 315 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 319 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | 316 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| ... | @@ -361,7 +358,6 @@ test "saturating shl uses the LHS type" { | ... | @@ -361,7 +358,6 @@ test "saturating shl uses the LHS type" { |
| 361 | 358 | ||
| 362 | test "sat add > 128 bits" { | 359 | test "sat add > 128 bits" { |
| 363 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 360 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 364 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 365 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 361 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 366 | 362 | ||
| 367 | try testSatAdd(u140, 0, 0, 0); | 363 | try testSatAdd(u140, 0, 0, 0); |
| ... | @@ -377,7 +373,6 @@ test "sat add > 128 bits" { | ... | @@ -377,7 +373,6 @@ test "sat add > 128 bits" { |
| 377 | 373 | ||
| 378 | test "sat sub > 128 bits" { | 374 | test "sat sub > 128 bits" { |
| 379 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 375 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 380 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 381 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 376 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 382 | 377 | ||
| 383 | try testSatSub(u140, 0, 1, 0); | 378 | try testSatSub(u140, 0, 1, 0); |
| ... | @@ -393,7 +388,6 @@ test "sat sub > 128 bits" { | ... | @@ -393,7 +388,6 @@ test "sat sub > 128 bits" { |
| 393 | 388 | ||
| 394 | test "sat mul > 128 bits" { | 389 | test "sat mul > 128 bits" { |
| 395 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 390 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 396 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 397 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 391 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 398 | 392 | ||
| 399 | try testSatMul(u140, 0, maxInt(u140), 0); | 393 | try testSatMul(u140, 0, maxInt(u140), 0); |
| ... | @@ -409,7 +403,6 @@ test "sat mul > 128 bits" { | ... | @@ -409,7 +403,6 @@ test "sat mul > 128 bits" { |
| 409 | 403 | ||
| 410 | test "sat shl > 128 bits" { | 404 | test "sat shl > 128 bits" { |
| 411 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 405 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 412 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 413 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 406 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 414 | 407 | ||
| 415 | try testSatShl(u140, 0, u8, 17, 0); | 408 | try testSatShl(u140, 0, u8, 17, 0); |
test/behavior/select.zig+14| ... | @@ -31,6 +31,20 @@ fn selectVectors() !void { | ... | @@ -31,6 +31,20 @@ fn selectVectors() !void { |
| 31 | _ = .{ &x, &y, &z }; | 31 | _ = .{ &x, &y, &z }; |
| 32 | const xyz = @select(f32, x, y, z); | 32 | const xyz = @select(f32, x, y, z); |
| 33 | try expect(mem.eql(f32, &@as([4]f32, xyz), &[4]f32{ 0.0, 312.1, -145.9, -3381.233 })); | 33 | try expect(mem.eql(f32, &@as([4]f32, xyz), &[4]f32{ 0.0, 312.1, -145.9, -3381.233 })); |
| 34 | |||
| 35 | var vec_u0: @Vector(4, u0) = @splat(0); | ||
| 36 | var mask_u0 = @Vector(4, bool){ true, false, true, false }; | ||
| 37 | var mask_empty = @Vector(0, i32){}; | ||
| 38 | var vec_empty = @Vector(0, i32){}; | ||
| 39 | _ = .{ &vec_u0, &mask_u0, &mask_empty, &vec_empty }; | ||
| 40 | const sel_u0 = @select(u0, mask_u0, vec_u0, vec_u0); | ||
| 41 | const sel_u0_undefined = @select(u0, mask_u0, undefined, undefined); | ||
| 42 | comptime if (sel_u0[0] != 0) unreachable; | ||
| 43 | comptime if (sel_u0_undefined[1] != 0) unreachable; | ||
| 44 | const sel_empty = @select(i32, mask_empty, vec_empty, vec_empty); | ||
| 45 | const sel_empty_undefined = @select(i32, @Vector(0, bool){}, undefined, undefined); | ||
| 46 | comptime if (@as(u0, @bitCast(sel_empty)) != 0) unreachable; | ||
| 47 | comptime if (@as(u0, @bitCast(sel_empty_undefined)) != 0) unreachable; | ||
| 34 | } | 48 | } |
| 35 | 49 | ||
| 36 | test "@select arrays" { | 50 | test "@select arrays" { |
test/behavior/shuffle.zig+20| ... | @@ -170,3 +170,23 @@ test "@shuffle bool 2" { | ... | @@ -170,3 +170,23 @@ test "@shuffle bool 2" { |
| 170 | try S.doTheTest(); | 170 | try S.doTheTest(); |
| 171 | try comptime S.doTheTest(); | 171 | try comptime S.doTheTest(); |
| 172 | } | 172 | } |
| 173 | |||
| 174 | test "@shuffle u0" { | ||
| 175 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | ||
| 176 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 177 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | ||
| 178 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 179 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | ||
| 180 | |||
| 181 | const S = struct { | ||
| 182 | fn doTheTest() !void { | ||
| 183 | var v: @Vector(4, u0) = @splat(0); | ||
| 184 | const mask = @Vector(4, i32){ undefined, 0, -1, 3 }; | ||
| 185 | _ = .{ &v, &mask }; | ||
| 186 | const res = @shuffle(u0, v, v, mask); | ||
| 187 | comptime if (!std.mem.eql(u0, &@as([4]u0, res), &[4]u0{ 0, 0, 0, 0 })) unreachable; | ||
| 188 | } | ||
| 189 | }; | ||
| 190 | try S.doTheTest(); | ||
| 191 | try comptime S.doTheTest(); | ||
| 192 | } |
test/behavior/slice.zig+82| ... | @@ -1089,3 +1089,85 @@ test "slice field alignment" { | ... | @@ -1089,3 +1089,85 @@ test "slice field alignment" { |
| 1089 | var arr: [10]u8 = @splat(0); | 1089 | var arr: [10]u8 = @splat(0); |
| 1090 | try S.doTheTest(&&arr); | 1090 | try S.doTheTest(&&arr); |
| 1091 | } | 1091 | } |
| 1092 | |||
| 1093 | test "directly deref slice with comptime-known length" { | ||
| 1094 | { | ||
| 1095 | const slice: []const u16 = &.{ 1, 2, 3 }; | ||
| 1096 | const array = slice.*; | ||
| 1097 | |||
| 1098 | comptime assert(@TypeOf(array) == [3]u16); | ||
| 1099 | comptime assert(array[0] == 1); | ||
| 1100 | comptime assert(array[1] == 2); | ||
| 1101 | comptime assert(array[2] == 3); | ||
| 1102 | } | ||
| 1103 | { | ||
| 1104 | const slice: [:0]const u16 = &.{ 1, 2, 3 }; | ||
| 1105 | const array = slice.*; | ||
| 1106 | |||
| 1107 | comptime assert(@TypeOf(array) == [3:0]u16); | ||
| 1108 | comptime assert(array[0] == 1); | ||
| 1109 | comptime assert(array[1] == 2); | ||
| 1110 | comptime assert(array[2] == 3); | ||
| 1111 | comptime assert(array[3] == 0); | ||
| 1112 | } | ||
| 1113 | } | ||
| 1114 | |||
| 1115 | test "address of dereferenced slice is array pointer" { | ||
| 1116 | { | ||
| 1117 | const slice: []const u16 = &.{ 1, 2, 3 }; | ||
| 1118 | const array_ptr = &slice.*; | ||
| 1119 | |||
| 1120 | comptime assert(@TypeOf(array_ptr) == *const [3]u16); | ||
| 1121 | comptime assert(array_ptr[0] == 1); | ||
| 1122 | comptime assert(array_ptr[1] == 2); | ||
| 1123 | comptime assert(array_ptr[2] == 3); | ||
| 1124 | } | ||
| 1125 | { | ||
| 1126 | const slice: [:0]const u16 = &.{ 1, 2, 3 }; | ||
| 1127 | const array_ptr = &slice.*; | ||
| 1128 | |||
| 1129 | comptime assert(@TypeOf(array_ptr) == *const [3:0]u16); | ||
| 1130 | comptime assert(array_ptr[0] == 1); | ||
| 1131 | comptime assert(array_ptr[1] == 2); | ||
| 1132 | comptime assert(array_ptr[2] == 3); | ||
| 1133 | comptime assert(array_ptr[3] == 0); | ||
| 1134 | } | ||
| 1135 | } | ||
| 1136 | |||
| 1137 | test "coerce slice with comptime-known length to array pointer" { | ||
| 1138 | { | ||
| 1139 | const slice: []const u16 = &.{ 1, 2, 3 }; | ||
| 1140 | const array_ptr: *const [3]u16 = slice; | ||
| 1141 | |||
| 1142 | comptime assert(array_ptr[0] == 1); | ||
| 1143 | comptime assert(array_ptr[1] == 2); | ||
| 1144 | comptime assert(array_ptr[2] == 3); | ||
| 1145 | } | ||
| 1146 | { | ||
| 1147 | const slice: [:0]const u16 = &.{ 1, 2, 3 }; | ||
| 1148 | const array_ptr: *const [3:0]u16 = slice; | ||
| 1149 | |||
| 1150 | comptime assert(array_ptr[0] == 1); | ||
| 1151 | comptime assert(array_ptr[1] == 2); | ||
| 1152 | comptime assert(array_ptr[2] == 3); | ||
| 1153 | comptime assert(array_ptr[3] == 0); | ||
| 1154 | } | ||
| 1155 | { | ||
| 1156 | const slice: [:0]const u16 = &.{ 1, 2, 3 }; | ||
| 1157 | const array_ptr: *const [3]u16 = slice; | ||
| 1158 | |||
| 1159 | comptime assert(array_ptr[0] == 1); | ||
| 1160 | comptime assert(array_ptr[1] == 2); | ||
| 1161 | comptime assert(array_ptr[2] == 3); | ||
| 1162 | } | ||
| 1163 | } | ||
| 1164 | |||
| 1165 | test "modify slice through coerced array pointer" { | ||
| 1166 | comptime { | ||
| 1167 | var array: [3]u16 = .{ 1, 2, 3 }; | ||
| 1168 | const slice: []u16 = &array; | ||
| 1169 | const array_ptr: *[3]u16 = slice; | ||
| 1170 | array_ptr[2] = 0; | ||
| 1171 | assert(slice[2] == 0); | ||
| 1172 | } | ||
| 1173 | } |
test/behavior/struct.zig+2-6| ... | @@ -535,7 +535,6 @@ test "zero-bit field in packed struct" { | ... | @@ -535,7 +535,6 @@ test "zero-bit field in packed struct" { |
| 535 | test "packed struct with non-ABI-aligned field" { | 535 | test "packed struct with non-ABI-aligned field" { |
| 536 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 536 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 537 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 537 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 538 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 539 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 538 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 540 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 539 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 541 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 540 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| ... | @@ -792,7 +791,6 @@ test "non-packed struct with u128 entry in union" { | ... | @@ -792,7 +791,6 @@ test "non-packed struct with u128 entry in union" { |
| 792 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 791 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 793 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 792 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 794 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 793 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 795 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 796 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 794 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 797 | 795 | ||
| 798 | const U = union(enum) { | 796 | const U = union(enum) { |
| ... | @@ -1539,7 +1537,6 @@ test "instantiate struct with comptime field" { | ... | @@ -1539,7 +1537,6 @@ test "instantiate struct with comptime field" { |
| 1539 | } | 1537 | } |
| 1540 | 1538 | ||
| 1541 | test "struct field pointer has correct alignment" { | 1539 | test "struct field pointer has correct alignment" { |
| 1542 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1543 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1540 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1544 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1541 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1545 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 1542 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| ... | @@ -1569,7 +1566,6 @@ test "struct field pointer has correct alignment" { | ... | @@ -1569,7 +1566,6 @@ test "struct field pointer has correct alignment" { |
| 1569 | } | 1566 | } |
| 1570 | 1567 | ||
| 1571 | test "extern struct field pointer has correct alignment" { | 1568 | test "extern struct field pointer has correct alignment" { |
| 1572 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1573 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1569 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1574 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1570 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1575 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 1571 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| ... | @@ -2007,7 +2003,6 @@ test "initiate global variable with runtime value" { | ... | @@ -2007,7 +2003,6 @@ test "initiate global variable with runtime value" { |
| 2007 | } | 2003 | } |
| 2008 | 2004 | ||
| 2009 | test "struct containing optional pointer to array of @This()" { | 2005 | test "struct containing optional pointer to array of @This()" { |
| 2010 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 2011 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 2006 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 2012 | 2007 | ||
| 2013 | const S = struct { | 2008 | const S = struct { |
| ... | @@ -2266,7 +2261,8 @@ test "struct contains aligned pointer to itself through type decl" { | ... | @@ -2266,7 +2261,8 @@ test "struct contains aligned pointer to itself through type decl" { |
| 2266 | 2261 | ||
| 2267 | test "struct contains underaligned field with overaligned pointer to itself" { | 2262 | test "struct contains underaligned field with overaligned pointer to itself" { |
| 2268 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 2263 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 2269 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | 2264 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; |
| 2265 | |||
| 2270 | const S = struct { | 2266 | const S = struct { |
| 2271 | ptr: *align(8) @This() align(1), | 2267 | ptr: *align(8) @This() align(1), |
| 2272 | }; | 2268 | }; |
test/behavior/switch.zig+1-1| ... | @@ -1267,7 +1267,7 @@ test "switch with complex item expressions" { | ... | @@ -1267,7 +1267,7 @@ test "switch with complex item expressions" { |
| 1267 | test "switch evaluation order" { | 1267 | test "switch evaluation order" { |
| 1268 | const eu: anyerror!u32 = 0; | 1268 | const eu: anyerror!u32 = 0; |
| 1269 | _ = eu catch |err| switch (err) { | 1269 | _ = eu catch |err| switch (err) { |
| 1270 | if (true) @compileError("unreachable") => unreachable, | 1270 | if (true) comptime unreachable => unreachable, |
| 1271 | else => unreachable, | 1271 | else => unreachable, |
| 1272 | }; | 1272 | }; |
| 1273 | } | 1273 | } |
test/behavior/switch_loop.zig+1-2| ... | @@ -223,7 +223,6 @@ test "unanalyzed continue with operand" { | ... | @@ -223,7 +223,6 @@ test "unanalyzed continue with operand" { |
| 223 | 223 | ||
| 224 | test "switch loop on larger than pointer integer" { | 224 | test "switch loop on larger than pointer integer" { |
| 225 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 225 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 226 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 227 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 226 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 228 | 227 | ||
| 229 | var entry: @Int(.unsigned, @bitSizeOf(usize) + 1) = undefined; | 228 | var entry: @Int(.unsigned, @bitSizeOf(usize) + 1) = undefined; |
| ... | @@ -268,7 +267,7 @@ test "switch loop on non-exhaustive enum" { | ... | @@ -268,7 +267,7 @@ test "switch loop on non-exhaustive enum" { |
| 268 | 267 | ||
| 269 | test "switch loop with discarded tag capture" { | 268 | test "switch loop with discarded tag capture" { |
| 270 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 269 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 271 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | 270 | |
| 272 | const S = struct { | 271 | const S = struct { |
| 273 | const U = union(enum) { | 272 | const U = union(enum) { |
| 274 | a: u32, | 273 | a: u32, |
test/behavior/switch_on_captured_error.zig+3-3| ... | @@ -243,7 +243,7 @@ test "switch on error union catch capture" { | ... | @@ -243,7 +243,7 @@ test "switch on error union catch capture" { |
| 243 | var a: error{}!u64 = 0; | 243 | var a: error{}!u64 = 0; |
| 244 | _ = &a; | 244 | _ = &a; |
| 245 | const b = a catch |err| switch (err) { | 245 | const b = a catch |err| switch (err) { |
| 246 | undefined => @compileError("unreachable"), | 246 | undefined => comptime unreachable, |
| 247 | }; | 247 | }; |
| 248 | try expectEqual(@as(u64, 0), b); | 248 | try expectEqual(@as(u64, 0), b); |
| 249 | } | 249 | } |
| ... | @@ -829,7 +829,7 @@ test "switch on error union if else capture" { | ... | @@ -829,7 +829,7 @@ test "switch on error union if else capture" { |
| 829 | var a: error{}!u64 = 0; | 829 | var a: error{}!u64 = 0; |
| 830 | _ = &a; | 830 | _ = &a; |
| 831 | const b = if (a) |x| x else |err| switch (err) { | 831 | const b = if (a) |x| x else |err| switch (err) { |
| 832 | undefined => @compileError("unreachable"), | 832 | undefined => comptime unreachable, |
| 833 | }; | 833 | }; |
| 834 | try expectEqual(@as(u64, 0), b); | 834 | try expectEqual(@as(u64, 0), b); |
| 835 | } | 835 | } |
| ... | @@ -840,7 +840,7 @@ test "switch on error union if else capture" { | ... | @@ -840,7 +840,7 @@ test "switch on error union if else capture" { |
| 840 | var a: error{}!u64 = 0; | 840 | var a: error{}!u64 = 0; |
| 841 | _ = &a; | 841 | _ = &a; |
| 842 | const b = if (a) |*x| x.* else |err| switch (err) { | 842 | const b = if (a) |*x| x.* else |err| switch (err) { |
| 843 | undefined => @compileError("unreachable"), | 843 | undefined => comptime unreachable, |
| 844 | }; | 844 | }; |
| 845 | try expectEqual(@as(u64, 0), b); | 845 | try expectEqual(@as(u64, 0), b); |
| 846 | } | 846 | } |
test/behavior/threadlocal.zig-5| ... | @@ -9,11 +9,6 @@ test "thread local variable" { | ... | @@ -9,11 +9,6 @@ test "thread local variable" { |
| 9 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 9 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 10 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO | 10 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO |
| 11 | 11 | ||
| 12 | if (builtin.zig_backend == .stage2_x86_64 and builtin.os.tag.isDarwin()) { | ||
| 13 | // Fails due to register hazards. | ||
| 14 | return error.SkipZigTest; | ||
| 15 | } | ||
| 16 | |||
| 17 | const S = struct { | 12 | const S = struct { |
| 18 | threadlocal var t: i32 = 1234; | 13 | threadlocal var t: i32 = 1234; |
| 19 | }; | 14 | }; |
test/behavior/truncate.zig-1| ... | @@ -49,7 +49,6 @@ fn testTruncate(comptime S: type, a: S, comptime D: type, expected: D) !void { | ... | @@ -49,7 +49,6 @@ fn testTruncate(comptime S: type, a: S, comptime D: type, expected: D) !void { |
| 49 | 49 | ||
| 50 | test "@truncate > 128 bits" { | 50 | test "@truncate > 128 bits" { |
| 51 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 51 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 52 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 53 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 52 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 54 | 53 | ||
| 55 | try testTruncate(u140, 0, u128, 0); | 54 | try testTruncate(u140, 0, u128, 0); |
test/behavior/union.zig+4-8| ... | @@ -1437,7 +1437,6 @@ test "coerce enum literal to union in result loc" { | ... | @@ -1437,7 +1437,6 @@ test "coerce enum literal to union in result loc" { |
| 1437 | } | 1437 | } |
| 1438 | 1438 | ||
| 1439 | test "defined-layout union field pointer has correct alignment" { | 1439 | test "defined-layout union field pointer has correct alignment" { |
| 1440 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1441 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1440 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1442 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1441 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1443 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 1442 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| ... | @@ -1472,7 +1471,6 @@ test "defined-layout union field pointer has correct alignment" { | ... | @@ -1472,7 +1471,6 @@ test "defined-layout union field pointer has correct alignment" { |
| 1472 | } | 1471 | } |
| 1473 | 1472 | ||
| 1474 | test "undefined-layout union field pointer has correct alignment" { | 1473 | test "undefined-layout union field pointer has correct alignment" { |
| 1475 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1476 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1474 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1477 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1475 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1478 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 1476 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| ... | @@ -1611,6 +1609,10 @@ fn littleToNativeEndian(comptime T: type, v: T) T { | ... | @@ -1611,6 +1609,10 @@ fn littleToNativeEndian(comptime T: type, v: T) T { |
| 1611 | } | 1609 | } |
| 1612 | 1610 | ||
| 1613 | test "reinterpret extern union" { | 1611 | test "reinterpret extern union" { |
| 1612 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .hexagon) return error.SkipZigTest; | ||
| 1613 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isRiscv32() and builtin.link_libc) return error.SkipZigTest; | ||
| 1614 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isWasm()) return error.SkipZigTest; | ||
| 1615 | |||
| 1614 | if (true) { | 1616 | if (true) { |
| 1615 | // https://github.com/ziglang/zig/issues/19389 | 1617 | // https://github.com/ziglang/zig/issues/19389 |
| 1616 | return error.SkipZigTest; | 1618 | return error.SkipZigTest; |
| ... | @@ -1678,8 +1680,6 @@ test "reinterpret extern union" { | ... | @@ -1678,8 +1680,6 @@ test "reinterpret extern union" { |
| 1678 | }; | 1680 | }; |
| 1679 | 1681 | ||
| 1680 | try comptime S.doTheTest(); | 1682 | try comptime S.doTheTest(); |
| 1681 | |||
| 1682 | if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO | ||
| 1683 | try S.doTheTest(); | 1683 | try S.doTheTest(); |
| 1684 | } | 1684 | } |
| 1685 | 1685 | ||
| ... | @@ -1758,8 +1758,6 @@ test "reinterpret packed union" { | ... | @@ -1758,8 +1758,6 @@ test "reinterpret packed union" { |
| 1758 | }; | 1758 | }; |
| 1759 | 1759 | ||
| 1760 | try comptime S.doTheTest(); | 1760 | try comptime S.doTheTest(); |
| 1761 | |||
| 1762 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1763 | try S.doTheTest(); | 1761 | try S.doTheTest(); |
| 1764 | } | 1762 | } |
| 1765 | 1763 | ||
| ... | @@ -1800,8 +1798,6 @@ test "reinterpret packed union inside packed struct" { | ... | @@ -1800,8 +1798,6 @@ test "reinterpret packed union inside packed struct" { |
| 1800 | }; | 1798 | }; |
| 1801 | 1799 | ||
| 1802 | try comptime S.doTheTest(); | 1800 | try comptime S.doTheTest(); |
| 1803 | |||
| 1804 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1805 | try S.doTheTest(); | 1801 | try S.doTheTest(); |
| 1806 | } | 1802 | } |
| 1807 | 1803 |
test/behavior/vector.zig+19-18| ... | @@ -128,13 +128,6 @@ test "vector float operators" { | ... | @@ -128,13 +128,6 @@ test "vector float operators" { |
| 128 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 128 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 129 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 129 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 130 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 130 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 131 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 132 | |||
| 133 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .aarch64) { | ||
| 134 | // Triggers an assertion with LLVM 18: | ||
| 135 | // https://github.com/ziglang/zig/issues/20680 | ||
| 136 | return error.SkipZigTest; | ||
| 137 | } | ||
| 138 | 131 | ||
| 139 | const S = struct { | 132 | const S = struct { |
| 140 | fn doTheTest(T: type) !void { | 133 | fn doTheTest(T: type) !void { |
| ... | @@ -280,7 +273,6 @@ test "array to vector with element type coercion" { | ... | @@ -280,7 +273,6 @@ test "array to vector with element type coercion" { |
| 280 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 273 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 281 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 274 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 282 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 275 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 283 | if (builtin.target.cpu.arch == .x86_64 and builtin.target.os.tag == .macos) return error.SkipZigTest; | ||
| 284 | 276 | ||
| 285 | const S = struct { | 277 | const S = struct { |
| 286 | fn doTheTest() !void { | 278 | fn doTheTest() !void { |
| ... | @@ -736,9 +728,7 @@ test "vector reduce operation" { | ... | @@ -736,9 +728,7 @@ test "vector reduce operation" { |
| 736 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 728 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 737 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 729 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 738 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 730 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 739 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 740 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 731 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 741 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; // https://github.com/llvm/llvm-project/issues/195562 | ||
| 742 | 732 | ||
| 743 | const S = struct { | 733 | const S = struct { |
| 744 | fn testReduce(comptime op: std.builtin.ReduceOp, x: anytype, expected: anytype) !void { | 734 | fn testReduce(comptime op: std.builtin.ReduceOp, x: anytype, expected: anytype) !void { |
| ... | @@ -776,6 +766,8 @@ test "vector reduce operation" { | ... | @@ -776,6 +766,8 @@ test "vector reduce operation" { |
| 776 | try testReduce(.Add, [4]f16{ -1.9, 5.1, -60.3, 100.0 }, @as(f16, 42.9)); | 766 | try testReduce(.Add, [4]f16{ -1.9, 5.1, -60.3, 100.0 }, @as(f16, 42.9)); |
| 777 | try testReduce(.Add, [4]f32{ -1.9, 5.1, -60.3, 100.0 }, @as(f32, 42.9)); | 767 | try testReduce(.Add, [4]f32{ -1.9, 5.1, -60.3, 100.0 }, @as(f32, 42.9)); |
| 778 | try testReduce(.Add, [4]f64{ -1.9, 5.1, -60.3, 100.0 }, @as(f64, 42.9)); | 768 | try testReduce(.Add, [4]f64{ -1.9, 5.1, -60.3, 100.0 }, @as(f64, 42.9)); |
| 769 | try testReduce(.Add, [4]f80{ -1.9, 5.1, -60.3, 100.0 }, @as(f80, 42.9)); | ||
| 770 | try testReduce(.Add, [4]f128{ -1.9, 5.1, -60.3, 100.0 }, @as(f128, 42.9)); | ||
| 779 | 771 | ||
| 780 | try testReduce(.And, [4]bool{ true, false, true, true }, @as(bool, false)); | 772 | try testReduce(.And, [4]bool{ true, false, true, true }, @as(bool, false)); |
| 781 | try testReduce(.And, [4]u1{ 1, 0, 1, 1 }, @as(u1, 0)); | 773 | try testReduce(.And, [4]u1{ 1, 0, 1, 1 }, @as(u1, 0)); |
| ... | @@ -794,6 +786,8 @@ test "vector reduce operation" { | ... | @@ -794,6 +786,8 @@ test "vector reduce operation" { |
| 794 | try testReduce(.Min, [4]f16{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f16, -100.0)); | 786 | try testReduce(.Min, [4]f16{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f16, -100.0)); |
| 795 | try testReduce(.Min, [4]f32{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f32, -100.0)); | 787 | try testReduce(.Min, [4]f32{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f32, -100.0)); |
| 796 | try testReduce(.Min, [4]f64{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f64, -100.0)); | 788 | try testReduce(.Min, [4]f64{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f64, -100.0)); |
| 789 | try testReduce(.Min, [4]f80{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f80, -100.0)); | ||
| 790 | try testReduce(.Min, [4]f128{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f128, -100.0)); | ||
| 797 | 791 | ||
| 798 | try testReduce(.Max, [4]i16{ -1, 2, 3, 4 }, @as(i16, 4)); | 792 | try testReduce(.Max, [4]i16{ -1, 2, 3, 4 }, @as(i16, 4)); |
| 799 | try testReduce(.Max, [4]u16{ 1, 2, 3, 4 }, @as(u16, 4)); | 793 | try testReduce(.Max, [4]u16{ 1, 2, 3, 4 }, @as(u16, 4)); |
| ... | @@ -806,6 +800,8 @@ test "vector reduce operation" { | ... | @@ -806,6 +800,8 @@ test "vector reduce operation" { |
| 806 | try testReduce(.Max, [4]f16{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f16, 10.0e9)); | 800 | try testReduce(.Max, [4]f16{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f16, 10.0e9)); |
| 807 | try testReduce(.Max, [4]f32{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f32, 10.0e9)); | 801 | try testReduce(.Max, [4]f32{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f32, 10.0e9)); |
| 808 | try testReduce(.Max, [4]f64{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f64, 10.0e9)); | 802 | try testReduce(.Max, [4]f64{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f64, 10.0e9)); |
| 803 | try testReduce(.Max, [4]f80{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f80, 10.0e9)); | ||
| 804 | try testReduce(.Max, [4]f128{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f128, 10.0e9)); | ||
| 809 | 805 | ||
| 810 | try testReduce(.Mul, [4]i16{ -1, 2, 3, 4 }, @as(i16, -24)); | 806 | try testReduce(.Mul, [4]i16{ -1, 2, 3, 4 }, @as(i16, -24)); |
| 811 | try testReduce(.Mul, [4]u16{ 1, 2, 3, 4 }, @as(u16, 24)); | 807 | try testReduce(.Mul, [4]u16{ 1, 2, 3, 4 }, @as(u16, 24)); |
| ... | @@ -818,6 +814,8 @@ test "vector reduce operation" { | ... | @@ -818,6 +814,8 @@ test "vector reduce operation" { |
| 818 | try testReduce(.Mul, [4]f16{ -1.9, 5.1, -60.3, 100.0 }, @as(f16, 58430.7)); | 814 | try testReduce(.Mul, [4]f16{ -1.9, 5.1, -60.3, 100.0 }, @as(f16, 58430.7)); |
| 819 | try testReduce(.Mul, [4]f32{ -1.9, 5.1, -60.3, 100.0 }, @as(f32, 58430.7)); | 815 | try testReduce(.Mul, [4]f32{ -1.9, 5.1, -60.3, 100.0 }, @as(f32, 58430.7)); |
| 820 | try testReduce(.Mul, [4]f64{ -1.9, 5.1, -60.3, 100.0 }, @as(f64, 58430.7)); | 816 | try testReduce(.Mul, [4]f64{ -1.9, 5.1, -60.3, 100.0 }, @as(f64, 58430.7)); |
| 817 | try testReduce(.Mul, [4]f80{ -1.9, 5.1, -60.3, 100.0 }, @as(f80, 58430.7)); | ||
| 818 | try testReduce(.Mul, [4]f128{ -1.9, 5.1, -60.3, 100.0 }, @as(f128, 58430.7)); | ||
| 821 | 819 | ||
| 822 | try testReduce(.Or, [4]bool{ false, true, false, false }, @as(bool, true)); | 820 | try testReduce(.Or, [4]bool{ false, true, false, false }, @as(bool, true)); |
| 823 | try testReduce(.Or, [4]u1{ 0, 1, 0, 0 }, @as(u1, 1)); | 821 | try testReduce(.Or, [4]u1{ 0, 1, 0, 0 }, @as(u1, 1)); |
| ... | @@ -825,6 +823,7 @@ test "vector reduce operation" { | ... | @@ -825,6 +823,7 @@ test "vector reduce operation" { |
| 825 | try testReduce(.Or, [4]u32{ 0xffff0000, 0xff00, 0xf0, 0xf }, ~@as(u32, 0)); | 823 | try testReduce(.Or, [4]u32{ 0xffff0000, 0xff00, 0xf0, 0xf }, ~@as(u32, 0)); |
| 826 | try testReduce(.Or, [4]u64{ 0xffff0000, 0xff00, 0xf0, 0xf }, @as(u64, 0xffffffff)); | 824 | try testReduce(.Or, [4]u64{ 0xffff0000, 0xff00, 0xf0, 0xf }, @as(u64, 0xffffffff)); |
| 827 | try testReduce(.Or, [4]u128{ 0xffff0000, 0xff00, 0xf0, 0xf }, @as(u128, 0xffffffff)); | 825 | try testReduce(.Or, [4]u128{ 0xffff0000, 0xff00, 0xf0, 0xf }, @as(u128, 0xffffffff)); |
| 826 | try testReduce(.Or, [4]u80{ 0xffff0000, 0xff00, 0xf0, 0xf }, @as(u80, 0xffffffff)); | ||
| 828 | 827 | ||
| 829 | try testReduce(.Xor, [4]bool{ true, true, true, false }, @as(bool, true)); | 828 | try testReduce(.Xor, [4]bool{ true, true, true, false }, @as(bool, true)); |
| 830 | try testReduce(.Xor, [4]u1{ 1, 1, 1, 0 }, @as(u1, 1)); | 829 | try testReduce(.Xor, [4]u1{ 1, 1, 1, 0 }, @as(u1, 1)); |
| ... | @@ -837,22 +836,32 @@ test "vector reduce operation" { | ... | @@ -837,22 +836,32 @@ test "vector reduce operation" { |
| 837 | const f16_nan = math.nan(f16); | 836 | const f16_nan = math.nan(f16); |
| 838 | const f32_nan = math.nan(f32); | 837 | const f32_nan = math.nan(f32); |
| 839 | const f64_nan = math.nan(f64); | 838 | const f64_nan = math.nan(f64); |
| 839 | const f80_nan = math.nan(f80); | ||
| 840 | const f128_nan = math.nan(f128); | ||
| 840 | 841 | ||
| 841 | try testReduce(.Add, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, f16_nan); | 842 | try testReduce(.Add, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, f16_nan); |
| 842 | try testReduce(.Add, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, f32_nan); | 843 | try testReduce(.Add, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, f32_nan); |
| 843 | try testReduce(.Add, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, f64_nan); | 844 | try testReduce(.Add, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, f64_nan); |
| 845 | try testReduce(.Add, [4]f80{ -1.9, 5.1, f80_nan, 100.0 }, f80_nan); | ||
| 846 | try testReduce(.Add, [4]f128{ -1.9, 5.1, f128_nan, 100.0 }, f128_nan); | ||
| 844 | 847 | ||
| 845 | try testReduce(.Min, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, @as(f16, -1.9)); | 848 | try testReduce(.Min, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, @as(f16, -1.9)); |
| 846 | try testReduce(.Min, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, @as(f32, -1.9)); | 849 | try testReduce(.Min, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, @as(f32, -1.9)); |
| 847 | try testReduce(.Min, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, @as(f64, -1.9)); | 850 | try testReduce(.Min, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, @as(f64, -1.9)); |
| 851 | try testReduce(.Min, [4]f80{ -1.9, 5.1, f80_nan, 100.0 }, @as(f80, -1.9)); | ||
| 852 | try testReduce(.Min, [4]f128{ -1.9, 5.1, f128_nan, 100.0 }, @as(f128, -1.9)); | ||
| 848 | 853 | ||
| 849 | try testReduce(.Max, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, @as(f16, 100.0)); | 854 | try testReduce(.Max, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, @as(f16, 100.0)); |
| 850 | try testReduce(.Max, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, @as(f32, 100.0)); | 855 | try testReduce(.Max, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, @as(f32, 100.0)); |
| 851 | try testReduce(.Max, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, @as(f64, 100.0)); | 856 | try testReduce(.Max, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, @as(f64, 100.0)); |
| 857 | try testReduce(.Max, [4]f80{ -1.9, 5.1, f80_nan, 100.0 }, @as(f80, 100.0)); | ||
| 858 | try testReduce(.Max, [4]f128{ -1.9, 5.1, f128_nan, 100.0 }, @as(f128, 100.0)); | ||
| 852 | 859 | ||
| 853 | try testReduce(.Mul, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, f16_nan); | 860 | try testReduce(.Mul, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, f16_nan); |
| 854 | try testReduce(.Mul, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, f32_nan); | 861 | try testReduce(.Mul, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, f32_nan); |
| 855 | try testReduce(.Mul, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, f64_nan); | 862 | try testReduce(.Mul, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, f64_nan); |
| 863 | try testReduce(.Mul, [4]f80{ -1.9, 5.1, f80_nan, 100.0 }, f80_nan); | ||
| 864 | try testReduce(.Mul, [4]f128{ -1.9, 5.1, f128_nan, 100.0 }, f128_nan); | ||
| 856 | } | 865 | } |
| 857 | }; | 866 | }; |
| 858 | 867 | ||
| ... | @@ -1321,11 +1330,6 @@ test "byte vector initialized in inline function" { | ... | @@ -1321,11 +1330,6 @@ test "byte vector initialized in inline function" { |
| 1321 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 1330 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 1322 | if (builtin.cpu.arch == .hexagon and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; | 1331 | if (builtin.cpu.arch == .hexagon and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; |
| 1323 | 1332 | ||
| 1324 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64 and comptime builtin.cpu.has(.x86, .avx512f)) { | ||
| 1325 | // TODO https://github.com/ziglang/zig/issues/13279 | ||
| 1326 | return error.SkipZigTest; | ||
| 1327 | } | ||
| 1328 | |||
| 1329 | const S = struct { | 1333 | const S = struct { |
| 1330 | fn boolx4(e0: bool, e1: bool, e2: bool, e3: bool) @Vector(4, bool) { | 1334 | fn boolx4(e0: bool, e1: bool, e2: bool, e3: bool) @Vector(4, bool) { |
| 1331 | return .{ e0, e1, e2, e3 }; | 1335 | return .{ e0, e1, e2, e3 }; |
| ... | @@ -1437,7 +1441,6 @@ test "store packed vector element" { | ... | @@ -1437,7 +1441,6 @@ test "store packed vector element" { |
| 1437 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1441 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1438 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1442 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1439 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1443 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1440 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1441 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 1444 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 1442 | 1445 | ||
| 1443 | var v = @Vector(4, u1){ 1, 1, 1, 1 }; | 1446 | var v = @Vector(4, u1){ 1, 1, 1, 1 }; |
| ... | @@ -1469,7 +1472,6 @@ test "store vector with memset" { | ... | @@ -1469,7 +1472,6 @@ test "store vector with memset" { |
| 1469 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1472 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1470 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1473 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1471 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO | 1474 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO |
| 1472 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1473 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 1475 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 1474 | 1476 | ||
| 1475 | var a: [5]@Vector(2, i1) = undefined; | 1477 | var a: [5]@Vector(2, i1) = undefined; |
| ... | @@ -1610,7 +1612,6 @@ test "bitcast vector to array of smaller vectors" { | ... | @@ -1610,7 +1612,6 @@ test "bitcast vector to array of smaller vectors" { |
| 1610 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1612 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1611 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1613 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1612 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 1614 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 1613 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 1614 | 1615 | ||
| 1615 | const u8x32 = @Vector(32, u8); | 1616 | const u8x32 = @Vector(32, u8); |
| 1616 | const u8x64 = @Vector(64, u8); | 1617 | const u8x64 = @Vector(64, u8); |
test/behavior/widening.zig-1| ... | @@ -41,7 +41,6 @@ test "float widening" { | ... | @@ -41,7 +41,6 @@ test "float widening" { |
| 41 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 41 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 42 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | 42 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 43 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | 43 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 44 | if (builtin.target.cpu.arch == .x86_64 and builtin.target.os.tag == .macos) return error.SkipZigTest; | ||
| 45 | 44 | ||
| 46 | var a: f16 = 12.34; | 45 | var a: f16 = 12.34; |
| 47 | var b: f32 = a; | 46 | var b: f32 = a; |
test/behavior/x86_64/unary.zig+1-1| ... | @@ -56,7 +56,7 @@ fn unary(comptime op: anytype, comptime opts: struct { | ... | @@ -56,7 +56,7 @@ fn unary(comptime op: anytype, comptime opts: struct { |
| 56 | f32 => libc_name ++ "f", | 56 | f32 => libc_name ++ "f", |
| 57 | f64 => libc_name, | 57 | f64 => libc_name, |
| 58 | f80 => "__" ++ libc_name ++ "x", | 58 | f80 => "__" ++ libc_name ++ "x", |
| 59 | f128 => libc_name ++ "q", | 59 | f128 => libc_name ++ "f128", |
| 60 | else => break :libc, | 60 | else => break :libc, |
| 61 | }, | 61 | }, |
| 62 | .library_name = switch (@import("builtin").object_format) { | 62 | .library_name = switch (@import("builtin").object_format) { |
test/c_abi/cfuncs.c+601-40| ... | @@ -77,7 +77,7 @@ static void assert_or_panic(bool ok) { | ... | @@ -77,7 +77,7 @@ static void assert_or_panic(bool ok) { |
| 77 | # define ZIG_NO_COMPLEX | 77 | # define ZIG_NO_COMPLEX |
| 78 | #endif | 78 | #endif |
| 79 | 79 | ||
| 80 | #ifdef ZIG_PPC32 | 80 | #ifdef __powerpc__ |
| 81 | # define ZIG_NO_COMPLEX | 81 | # define ZIG_NO_COMPLEX |
| 82 | #endif | 82 | #endif |
| 83 | 83 | ||
| ... | @@ -191,9 +191,6 @@ void zig_struct_i128(struct i128); | ... | @@ -191,9 +191,6 @@ void zig_struct_i128(struct i128); |
| 191 | #endif | 191 | #endif |
| 192 | void zig_five_integers(int32_t, int32_t, int32_t, int32_t, int32_t); | 192 | void zig_five_integers(int32_t, int32_t, int32_t, int32_t, int32_t); |
| 193 | 193 | ||
| 194 | void zig_f32(float); | ||
| 195 | void zig_f64(double); | ||
| 196 | void zig_longdouble(long double); | ||
| 197 | void zig_five_floats(float, float, float, float, float); | 194 | void zig_five_floats(float, float, float, float, float); |
| 198 | 195 | ||
| 199 | bool zig_ret_bool(); | 196 | bool zig_ret_bool(); |
| ... | @@ -219,7 +216,203 @@ float complex zig_cmultf(float complex a, float complex b); | ... | @@ -219,7 +216,203 @@ float complex zig_cmultf(float complex a, float complex b); |
| 219 | double complex zig_cmultd(double complex a, double complex b); | 216 | double complex zig_cmultd(double complex a, double complex b); |
| 220 | #endif | 217 | #endif |
| 221 | 218 | ||
| 222 | #if defined(ZIG_BACKEND_STAGE2_X86_64) || defined(ZIG_PPC32) || defined(__wasm__) | 219 | float zig_ret_f32(void); |
| 220 | void zig_f32(float, size_t); | ||
| 221 | void zig_1_f32(size_t, float, size_t); | ||
| 222 | void zig_2_f32(size_t, size_t, float, size_t); | ||
| 223 | void zig_3_f32(size_t, size_t, size_t, float, size_t); | ||
| 224 | void zig_4_f32(size_t, size_t, size_t, size_t, float, size_t); | ||
| 225 | void zig_5_f32(size_t, size_t, size_t, size_t, size_t, float, size_t); | ||
| 226 | void zig_6_f32(size_t, size_t, size_t, size_t, size_t, size_t, float, size_t); | ||
| 227 | void zig_7_f32(size_t, size_t, size_t, size_t, size_t, size_t, size_t, float, size_t); | ||
| 228 | void zig_8_f32(size_t, size_t, size_t, size_t, size_t, size_t, size_t, size_t, float, size_t); | ||
| 229 | |||
| 230 | float c_ret_f32(void) { | ||
| 231 | return 11; | ||
| 232 | } | ||
| 233 | void c_f32(float f, size_t i) { | ||
| 234 | assert_or_panic(f == 12); | ||
| 235 | assert_or_panic(i == 1); | ||
| 236 | } | ||
| 237 | void c_1_f32(size_t a0, float f, size_t i) { | ||
| 238 | assert_or_panic(f == 13); | ||
| 239 | assert_or_panic(i == 2); | ||
| 240 | } | ||
| 241 | void c_2_f32(size_t a0, size_t a1, float f, size_t i) { | ||
| 242 | assert_or_panic(f == 14); | ||
| 243 | assert_or_panic(i == 3); | ||
| 244 | } | ||
| 245 | void c_3_f32(size_t a0, size_t a1, size_t a2, float f, size_t i) { | ||
| 246 | assert_or_panic(f == 15); | ||
| 247 | assert_or_panic(i == 4); | ||
| 248 | } | ||
| 249 | void c_4_f32(size_t a0, size_t a1, size_t a2, size_t a3, float f, size_t i) { | ||
| 250 | assert_or_panic(f == 16); | ||
| 251 | assert_or_panic(i == 5); | ||
| 252 | } | ||
| 253 | void c_5_f32(size_t a0, size_t a1, size_t a2, size_t a3, size_t a4, float f, size_t i) { | ||
| 254 | assert_or_panic(f == 17); | ||
| 255 | assert_or_panic(i == 6); | ||
| 256 | } | ||
| 257 | void c_6_f32(size_t a0, size_t a1, size_t a2, size_t a3, size_t a4, size_t a5, float f, size_t i) { | ||
| 258 | assert_or_panic(f == 18); | ||
| 259 | assert_or_panic(i == 7); | ||
| 260 | } | ||
| 261 | void c_7_f32(size_t a0, size_t a1, size_t a2, size_t a3, size_t a4, size_t a5, size_t a6, float f, size_t i) { | ||
| 262 | assert_or_panic(f == 19); | ||
| 263 | assert_or_panic(i == 8); | ||
| 264 | } | ||
| 265 | void c_8_f32(size_t a0, size_t a1, size_t a2, size_t a3, size_t a4, size_t a5, size_t a6, size_t a7, float f, size_t i) { | ||
| 266 | assert_or_panic(f == 20); | ||
| 267 | assert_or_panic(i == 9); | ||
| 268 | } | ||
| 269 | void c_test_f32(void) { | ||
| 270 | float f = zig_ret_f32(); | ||
| 271 | assert_or_panic(f == 1); | ||
| 272 | zig_f32(2, 1); | ||
| 273 | zig_1_f32(0, 3, 2); | ||
| 274 | zig_2_f32(0, 1, 4, 3); | ||
| 275 | zig_3_f32(0, 1, 2, 5, 4); | ||
| 276 | zig_4_f32(0, 1, 2, 3, 6, 5); | ||
| 277 | zig_5_f32(0, 1, 2, 3, 4, 7, 6); | ||
| 278 | zig_6_f32(0, 1, 2, 3, 4, 5, 8, 7); | ||
| 279 | zig_7_f32(0, 1, 2, 3, 4, 5, 6, 9, 8); | ||
| 280 | zig_8_f32(0, 1, 2, 3, 4, 5, 6, 7, 10, 9); | ||
| 281 | } | ||
| 282 | |||
| 283 | double zig_ret_f64(void); | ||
| 284 | void zig_f64(double, size_t); | ||
| 285 | void zig_1_f64(size_t, double, size_t); | ||
| 286 | void zig_2_f64(size_t, size_t, double, size_t); | ||
| 287 | void zig_3_f64(size_t, size_t, size_t, double, size_t); | ||
| 288 | void zig_4_f64(size_t, size_t, size_t, size_t, double, size_t); | ||
| 289 | void zig_5_f64(size_t, size_t, size_t, size_t, size_t, double, size_t); | ||
| 290 | void zig_6_f64(size_t, size_t, size_t, size_t, size_t, size_t, double, size_t); | ||
| 291 | void zig_7_f64(size_t, size_t, size_t, size_t, size_t, size_t, size_t, double, size_t); | ||
| 292 | void zig_8_f64(size_t, size_t, size_t, size_t, size_t, size_t, size_t, size_t, double, size_t); | ||
| 293 | |||
| 294 | double c_ret_f64(void) { | ||
| 295 | return 11; | ||
| 296 | } | ||
| 297 | void c_f64(double f, size_t i) { | ||
| 298 | assert_or_panic(f == 12); | ||
| 299 | assert_or_panic(i == 1); | ||
| 300 | } | ||
| 301 | void c_1_f64(size_t a0, double f, size_t i) { | ||
| 302 | assert_or_panic(f == 13); | ||
| 303 | assert_or_panic(i == 2); | ||
| 304 | } | ||
| 305 | void c_2_f64(size_t a0, size_t a1, double f, size_t i) { | ||
| 306 | assert_or_panic(f == 14); | ||
| 307 | assert_or_panic(i == 3); | ||
| 308 | } | ||
| 309 | void c_3_f64(size_t a0, size_t a1, size_t a2, double f, size_t i) { | ||
| 310 | assert_or_panic(f == 15); | ||
| 311 | assert_or_panic(i == 4); | ||
| 312 | } | ||
| 313 | void c_4_f64(size_t a0, size_t a1, size_t a2, size_t a3, double f, size_t i) { | ||
| 314 | assert_or_panic(f == 16); | ||
| 315 | assert_or_panic(i == 5); | ||
| 316 | } | ||
| 317 | void c_5_f64(size_t a0, size_t a1, size_t a2, size_t a3, size_t a4, double f, size_t i) { | ||
| 318 | assert_or_panic(f == 17); | ||
| 319 | assert_or_panic(i == 6); | ||
| 320 | } | ||
| 321 | void c_6_f64(size_t a0, size_t a1, size_t a2, size_t a3, size_t a4, size_t a5, double f, size_t i) { | ||
| 322 | assert_or_panic(f == 18); | ||
| 323 | assert_or_panic(i == 7); | ||
| 324 | } | ||
| 325 | void c_7_f64(size_t a0, size_t a1, size_t a2, size_t a3, size_t a4, size_t a5, size_t a6, double f, size_t i) { | ||
| 326 | assert_or_panic(f == 19); | ||
| 327 | assert_or_panic(i == 8); | ||
| 328 | } | ||
| 329 | void c_8_f64(size_t a0, size_t a1, size_t a2, size_t a3, size_t a4, size_t a5, size_t a6, size_t a7, double f, size_t i) { | ||
| 330 | assert_or_panic(f == 20); | ||
| 331 | assert_or_panic(i == 9); | ||
| 332 | } | ||
| 333 | void c_test_f64(void) { | ||
| 334 | double f = zig_ret_f64(); | ||
| 335 | assert_or_panic(f == 1); | ||
| 336 | zig_f64(2, 1); | ||
| 337 | zig_1_f64(0, 3, 2); | ||
| 338 | zig_2_f64(0, 1, 4, 3); | ||
| 339 | zig_3_f64(0, 1, 2, 5, 4); | ||
| 340 | zig_4_f64(0, 1, 2, 3, 6, 5); | ||
| 341 | zig_5_f64(0, 1, 2, 3, 4, 7, 6); | ||
| 342 | zig_6_f64(0, 1, 2, 3, 4, 5, 8, 7); | ||
| 343 | zig_7_f64(0, 1, 2, 3, 4, 5, 6, 9, 8); | ||
| 344 | zig_8_f64(0, 1, 2, 3, 4, 5, 6, 7, 10, 9); | ||
| 345 | } | ||
| 346 | |||
| 347 | long double zig_ret_longdouble(void); | ||
| 348 | void zig_longdouble(long double, size_t); | ||
| 349 | void zig_1_longdouble(size_t, long double, size_t); | ||
| 350 | void zig_2_longdouble(size_t, size_t, long double, size_t); | ||
| 351 | void zig_3_longdouble(size_t, size_t, size_t, long double, size_t); | ||
| 352 | void zig_4_longdouble(size_t, size_t, size_t, size_t, long double, size_t); | ||
| 353 | void zig_5_longdouble(size_t, size_t, size_t, size_t, size_t, long double, size_t); | ||
| 354 | void zig_6_longdouble(size_t, size_t, size_t, size_t, size_t, size_t, long double, size_t); | ||
| 355 | void zig_7_longdouble(size_t, size_t, size_t, size_t, size_t, size_t, size_t, long double, size_t); | ||
| 356 | void zig_8_longdouble(size_t, size_t, size_t, size_t, size_t, size_t, size_t, size_t, long double, size_t); | ||
| 357 | |||
| 358 | long double c_ret_longdouble(void) { | ||
| 359 | return 11; | ||
| 360 | } | ||
| 361 | void c_longdouble(long double f, size_t i) { | ||
| 362 | assert_or_panic(f == 12); | ||
| 363 | assert_or_panic(i == 1); | ||
| 364 | } | ||
| 365 | void c_1_longdouble(size_t a0, long double f, size_t i) { | ||
| 366 | assert_or_panic(f == 13); | ||
| 367 | assert_or_panic(i == 2); | ||
| 368 | } | ||
| 369 | void c_2_longdouble(size_t a0, size_t a1, long double f, size_t i) { | ||
| 370 | assert_or_panic(f == 14); | ||
| 371 | assert_or_panic(i == 3); | ||
| 372 | } | ||
| 373 | void c_3_longdouble(size_t a0, size_t a1, size_t a2, long double f, size_t i) { | ||
| 374 | assert_or_panic(f == 15); | ||
| 375 | assert_or_panic(i == 4); | ||
| 376 | } | ||
| 377 | void c_4_longdouble(size_t a0, size_t a1, size_t a2, size_t a3, long double f, size_t i) { | ||
| 378 | assert_or_panic(f == 16); | ||
| 379 | assert_or_panic(i == 5); | ||
| 380 | } | ||
| 381 | void c_5_longdouble(size_t a0, size_t a1, size_t a2, size_t a3, size_t a4, long double f, size_t i) { | ||
| 382 | assert_or_panic(f == 17); | ||
| 383 | assert_or_panic(i == 6); | ||
| 384 | } | ||
| 385 | void c_6_longdouble(size_t a0, size_t a1, size_t a2, size_t a3, size_t a4, size_t a5, long double f, size_t i) { | ||
| 386 | assert_or_panic(f == 18); | ||
| 387 | assert_or_panic(i == 7); | ||
| 388 | } | ||
| 389 | void c_7_longdouble(size_t a0, size_t a1, size_t a2, size_t a3, size_t a4, size_t a5, size_t a6, long double f, size_t i) { | ||
| 390 | assert_or_panic(f == 19); | ||
| 391 | assert_or_panic(i == 8); | ||
| 392 | } | ||
| 393 | void c_8_longdouble(size_t a0, size_t a1, size_t a2, size_t a3, size_t a4, size_t a5, size_t a6, size_t a7, long double f, size_t i) { | ||
| 394 | assert_or_panic(f == 20); | ||
| 395 | assert_or_panic(i == 9); | ||
| 396 | } | ||
| 397 | void c_test_longdouble(void) { | ||
| 398 | long double f = zig_ret_longdouble(); | ||
| 399 | assert_or_panic(f == 1); | ||
| 400 | zig_longdouble(2, 1); | ||
| 401 | zig_1_longdouble(0, 3, 2); | ||
| 402 | zig_2_longdouble(0, 1, 4, 3); | ||
| 403 | zig_3_longdouble(0, 1, 2, 5, 4); | ||
| 404 | zig_4_longdouble(0, 1, 2, 3, 6, 5); | ||
| 405 | zig_5_longdouble(0, 1, 2, 3, 4, 7, 6); | ||
| 406 | zig_6_longdouble(0, 1, 2, 3, 4, 5, 8, 7); | ||
| 407 | zig_7_longdouble(0, 1, 2, 3, 4, 5, 6, 9, 8); | ||
| 408 | zig_8_longdouble(0, 1, 2, 3, 4, 5, 6, 7, 10, 9); | ||
| 409 | } | ||
| 410 | |||
| 411 | #ifndef __hexagon__ | ||
| 412 | #ifndef __loongarch__ | ||
| 413 | #ifndef __mips__ | ||
| 414 | #ifndef ZIG_PPC64 | ||
| 415 | #if !(defined(__i386__) && defined(_WIN32)) | ||
| 223 | 416 | ||
| 224 | typedef bool Vector_2_bool __attribute__((ext_vector_type(2))); | 417 | typedef bool Vector_2_bool __attribute__((ext_vector_type(2))); |
| 225 | 418 | ||
| ... | @@ -4468,6 +4661,10 @@ void c_test_vector_512_bool(void) { | ... | @@ -4468,6 +4661,10 @@ void c_test_vector_512_bool(void) { |
| 4468 | }); | 4661 | }); |
| 4469 | } | 4662 | } |
| 4470 | 4663 | ||
| 4664 | #endif | ||
| 4665 | #endif | ||
| 4666 | #endif | ||
| 4667 | #endif | ||
| 4471 | #endif | 4668 | #endif |
| 4472 | 4669 | ||
| 4473 | typedef uint8_t Vector_1_u8 __attribute__((vector_size(1 * sizeof(uint8_t)))); | 4670 | typedef uint8_t Vector_1_u8 __attribute__((vector_size(1 * sizeof(uint8_t)))); |
| ... | @@ -14997,6 +15194,242 @@ void c_test_struct_f32_f32_f32_f32_f32(void) { | ... | @@ -14997,6 +15194,242 @@ void c_test_struct_f32_f32_f32_f32_f32(void) { |
| 14997 | zig_struct_f32_f32_f32_f32_f32((struct Struct_f32_f32_f32_f32_f32){ .a = 6, .b = 7, .c = 8, .d = 9, .e = 10 }, 11); | 15194 | zig_struct_f32_f32_f32_f32_f32((struct Struct_f32_f32_f32_f32_f32){ .a = 6, .b = 7, .c = 8, .d = 9, .e = 10 }, 11); |
| 14998 | } | 15195 | } |
| 14999 | 15196 | ||
| 15197 | struct Struct_f32 zig_ret_struct_void_f32(void); | ||
| 15198 | void zig_struct_void_f32(struct Struct_f32, size_t); | ||
| 15199 | |||
| 15200 | struct Struct_f32 c_ret_struct_void_f32(void) { | ||
| 15201 | return (struct Struct_f32){ .a = 4 }; | ||
| 15202 | } | ||
| 15203 | void c_struct_void_f32(struct Struct_f32 s, size_t i) { | ||
| 15204 | assert_or_panic(s.a == 5); | ||
| 15205 | assert_or_panic(i == 6); | ||
| 15206 | } | ||
| 15207 | void c_test_struct_void_f32(void) { | ||
| 15208 | struct Struct_f32 s = zig_ret_struct_void_f32(); | ||
| 15209 | assert_or_panic(s.a == 1); | ||
| 15210 | zig_struct_void_f32((struct Struct_f32){ .a = 2 }, 3); | ||
| 15211 | } | ||
| 15212 | |||
| 15213 | struct Struct_array_1_f32 { | ||
| 15214 | float a[1]; | ||
| 15215 | }; | ||
| 15216 | |||
| 15217 | struct Struct_array_1_f32 zig_ret_struct_array_1_f32(void); | ||
| 15218 | void zig_struct_array_1_f32(struct Struct_array_1_f32, size_t); | ||
| 15219 | |||
| 15220 | struct Struct_array_1_f32 c_ret_struct_array_1_f32(void) { | ||
| 15221 | return (struct Struct_array_1_f32){ .a = { 4 } }; | ||
| 15222 | } | ||
| 15223 | void c_struct_array_1_f32(struct Struct_array_1_f32 s, size_t i) { | ||
| 15224 | assert_or_panic(s.a[0] == 5); | ||
| 15225 | assert_or_panic(i == 6); | ||
| 15226 | } | ||
| 15227 | void c_test_struct_array_1_f32(void) { | ||
| 15228 | struct Struct_array_1_f32 s = zig_ret_struct_array_1_f32(); | ||
| 15229 | assert_or_panic(s.a[0] == 1); | ||
| 15230 | zig_struct_array_1_f32((struct Struct_array_1_f32){ .a = { 2 } }, 3); | ||
| 15231 | } | ||
| 15232 | |||
| 15233 | struct Struct_array_2_f32 { | ||
| 15234 | float a[2]; | ||
| 15235 | }; | ||
| 15236 | |||
| 15237 | struct Struct_array_2_f32 zig_ret_struct_array_2_f32(void); | ||
| 15238 | void zig_struct_array_2_f32(struct Struct_array_2_f32, size_t); | ||
| 15239 | |||
| 15240 | struct Struct_array_2_f32 c_ret_struct_array_2_f32(void) { | ||
| 15241 | return (struct Struct_array_2_f32){ .a = { 6, 7 } }; | ||
| 15242 | } | ||
| 15243 | void c_struct_array_2_f32(struct Struct_array_2_f32 s, size_t i) { | ||
| 15244 | assert_or_panic(s.a[0] == 8); | ||
| 15245 | assert_or_panic(s.a[1] == 9); | ||
| 15246 | assert_or_panic(i == 10); | ||
| 15247 | } | ||
| 15248 | void c_test_struct_array_2_f32(void) { | ||
| 15249 | struct Struct_array_2_f32 s = zig_ret_struct_array_2_f32(); | ||
| 15250 | assert_or_panic(s.a[0] == 1); | ||
| 15251 | assert_or_panic(s.a[1] == 2); | ||
| 15252 | zig_struct_array_2_f32((struct Struct_array_2_f32){ .a = { 3, 4 } }, 5); | ||
| 15253 | } | ||
| 15254 | |||
| 15255 | struct Struct_array_3_f32 { | ||
| 15256 | float a[3]; | ||
| 15257 | }; | ||
| 15258 | |||
| 15259 | struct Struct_array_3_f32 zig_ret_struct_array_3_f32(void); | ||
| 15260 | void zig_struct_array_3_f32(struct Struct_array_3_f32, size_t); | ||
| 15261 | |||
| 15262 | struct Struct_array_3_f32 c_ret_struct_array_3_f32(void) { | ||
| 15263 | return (struct Struct_array_3_f32){ .a = { 8, 9, 10 } }; | ||
| 15264 | } | ||
| 15265 | void c_struct_array_3_f32(struct Struct_array_3_f32 s, size_t i) { | ||
| 15266 | assert_or_panic(s.a[0] == 11); | ||
| 15267 | assert_or_panic(s.a[1] == 12); | ||
| 15268 | assert_or_panic(s.a[2] == 13); | ||
| 15269 | assert_or_panic(i == 14); | ||
| 15270 | } | ||
| 15271 | void c_test_struct_array_3_f32(void) { | ||
| 15272 | struct Struct_array_3_f32 s = zig_ret_struct_array_3_f32(); | ||
| 15273 | assert_or_panic(s.a[0] == 1); | ||
| 15274 | assert_or_panic(s.a[1] == 2); | ||
| 15275 | assert_or_panic(s.a[2] == 3); | ||
| 15276 | zig_struct_array_3_f32((struct Struct_array_3_f32){ .a = { 4, 5, 6 } }, 7); | ||
| 15277 | } | ||
| 15278 | |||
| 15279 | struct Struct_array_4_f32 { | ||
| 15280 | float a[4]; | ||
| 15281 | }; | ||
| 15282 | |||
| 15283 | struct Struct_array_4_f32 zig_ret_struct_array_4_f32(void); | ||
| 15284 | void zig_struct_array_4_f32(struct Struct_array_4_f32, size_t); | ||
| 15285 | |||
| 15286 | struct Struct_array_4_f32 c_ret_struct_array_4_f32(void) { | ||
| 15287 | return (struct Struct_array_4_f32){ .a = { 10, 11, 12, 13 } }; | ||
| 15288 | } | ||
| 15289 | void c_struct_array_4_f32(struct Struct_array_4_f32 s, size_t i) { | ||
| 15290 | assert_or_panic(s.a[0] == 14); | ||
| 15291 | assert_or_panic(s.a[1] == 15); | ||
| 15292 | assert_or_panic(s.a[2] == 16); | ||
| 15293 | assert_or_panic(s.a[3] == 17); | ||
| 15294 | assert_or_panic(i == 18); | ||
| 15295 | } | ||
| 15296 | void c_test_struct_array_4_f32(void) { | ||
| 15297 | struct Struct_array_4_f32 s = zig_ret_struct_array_4_f32(); | ||
| 15298 | assert_or_panic(s.a[0] == 1); | ||
| 15299 | assert_or_panic(s.a[1] == 2); | ||
| 15300 | assert_or_panic(s.a[2] == 3); | ||
| 15301 | assert_or_panic(s.a[3] == 4); | ||
| 15302 | zig_struct_array_4_f32((struct Struct_array_4_f32){ .a = { 5, 6, 7, 8 } }, 9); | ||
| 15303 | } | ||
| 15304 | |||
| 15305 | struct Struct_array_5_f32 { | ||
| 15306 | float a[5]; | ||
| 15307 | }; | ||
| 15308 | |||
| 15309 | struct Struct_array_5_f32 zig_ret_struct_array_5_f32(void); | ||
| 15310 | void zig_struct_array_5_f32(struct Struct_array_5_f32, size_t); | ||
| 15311 | |||
| 15312 | struct Struct_array_5_f32 c_ret_struct_array_5_f32(void) { | ||
| 15313 | return (struct Struct_array_5_f32){ .a = { 12, 13, 14, 15, 16 } }; | ||
| 15314 | } | ||
| 15315 | void c_struct_array_5_f32(struct Struct_array_5_f32 s, size_t i) { | ||
| 15316 | assert_or_panic(s.a[0] == 17); | ||
| 15317 | assert_or_panic(s.a[1] == 18); | ||
| 15318 | assert_or_panic(s.a[2] == 19); | ||
| 15319 | assert_or_panic(s.a[3] == 20); | ||
| 15320 | assert_or_panic(s.a[4] == 21); | ||
| 15321 | assert_or_panic(i == 22); | ||
| 15322 | } | ||
| 15323 | void c_test_struct_array_5_f32(void) { | ||
| 15324 | struct Struct_array_5_f32 s = zig_ret_struct_array_5_f32(); | ||
| 15325 | assert_or_panic(s.a[0] == 1); | ||
| 15326 | assert_or_panic(s.a[1] == 2); | ||
| 15327 | assert_or_panic(s.a[2] == 3); | ||
| 15328 | assert_or_panic(s.a[3] == 4); | ||
| 15329 | assert_or_panic(s.a[4] == 5); | ||
| 15330 | zig_struct_array_5_f32((struct Struct_array_5_f32){ .a = { 6, 7, 8, 9, 10 } }, 11); | ||
| 15331 | } | ||
| 15332 | |||
| 15333 | struct Struct_array_1_f32 zig_ret_struct_array_0_sentinel_f32(void); | ||
| 15334 | void zig_struct_array_0_sentinel_f32(struct Struct_array_1_f32, size_t); | ||
| 15335 | |||
| 15336 | struct Struct_array_1_f32 c_ret_struct_array_0_sentinel_f32(void) { | ||
| 15337 | return (struct Struct_array_1_f32){ .a = { 0x1e1 } }; | ||
| 15338 | } | ||
| 15339 | void c_struct_array_0_sentinel_f32(struct Struct_array_1_f32 s, size_t i) { | ||
| 15340 | assert_or_panic(s.a[0] == 0x1e1); | ||
| 15341 | assert_or_panic(i == 2); | ||
| 15342 | } | ||
| 15343 | void c_test_struct_array_0_sentinel_f32(void) { | ||
| 15344 | struct Struct_array_1_f32 s = zig_ret_struct_array_0_sentinel_f32(); | ||
| 15345 | assert_or_panic(s.a[0] == 0x1e1); | ||
| 15346 | zig_struct_array_0_sentinel_f32((struct Struct_array_1_f32){ .a = { 0x1e1 } }, 1); | ||
| 15347 | } | ||
| 15348 | |||
| 15349 | struct Struct_array_2_f32 zig_ret_struct_array_1_sentinel_f32(void); | ||
| 15350 | void zig_struct_array_1_sentinel_f32(struct Struct_array_2_f32, size_t); | ||
| 15351 | |||
| 15352 | struct Struct_array_2_f32 c_ret_struct_array_1_sentinel_f32(void) { | ||
| 15353 | return (struct Struct_array_2_f32){ .a = { 4, 0x1e1 } }; | ||
| 15354 | } | ||
| 15355 | void c_struct_array_1_sentinel_f32(struct Struct_array_2_f32 s, size_t i) { | ||
| 15356 | assert_or_panic(s.a[0] == 5); | ||
| 15357 | assert_or_panic(s.a[1] == 0x1e1); | ||
| 15358 | assert_or_panic(i == 6); | ||
| 15359 | } | ||
| 15360 | void c_test_struct_array_1_sentinel_f32(void) { | ||
| 15361 | struct Struct_array_2_f32 s = zig_ret_struct_array_1_sentinel_f32(); | ||
| 15362 | assert_or_panic(s.a[0] == 1); | ||
| 15363 | assert_or_panic(s.a[1] == 0x1e1); | ||
| 15364 | zig_struct_array_1_sentinel_f32((struct Struct_array_2_f32){ .a = { 2, 0x1e1 } }, 3); | ||
| 15365 | } | ||
| 15366 | |||
| 15367 | struct Struct_array_3_f32 zig_ret_struct_array_2_sentinel_f32(void); | ||
| 15368 | void zig_struct_array_2_sentinel_f32(struct Struct_array_3_f32, size_t); | ||
| 15369 | |||
| 15370 | struct Struct_array_3_f32 c_ret_struct_array_2_sentinel_f32(void) { | ||
| 15371 | return (struct Struct_array_3_f32){ .a = { 6, 7, 0x1e1 } }; | ||
| 15372 | } | ||
| 15373 | void c_struct_array_2_sentinel_f32(struct Struct_array_3_f32 s, size_t i) { | ||
| 15374 | assert_or_panic(s.a[0] == 8); | ||
| 15375 | assert_or_panic(s.a[1] == 9); | ||
| 15376 | assert_or_panic(s.a[2] == 0x1e1); | ||
| 15377 | assert_or_panic(i == 10); | ||
| 15378 | } | ||
| 15379 | void c_test_struct_array_2_sentinel_f32(void) { | ||
| 15380 | struct Struct_array_3_f32 s = zig_ret_struct_array_2_sentinel_f32(); | ||
| 15381 | assert_or_panic(s.a[0] == 1); | ||
| 15382 | assert_or_panic(s.a[1] == 2); | ||
| 15383 | assert_or_panic(s.a[2] == 0x1e1); | ||
| 15384 | zig_struct_array_2_sentinel_f32((struct Struct_array_3_f32){ .a = { 3, 4, 0x1e1 } }, 5); | ||
| 15385 | } | ||
| 15386 | |||
| 15387 | struct Struct_array_4_f32 zig_ret_struct_array_3_sentinel_f32(void); | ||
| 15388 | void zig_struct_array_3_sentinel_f32(struct Struct_array_4_f32, size_t); | ||
| 15389 | |||
| 15390 | struct Struct_array_4_f32 c_ret_struct_array_3_sentinel_f32(void) { | ||
| 15391 | return (struct Struct_array_4_f32){ .a = { 8, 9, 10, 0x1e1 } }; | ||
| 15392 | } | ||
| 15393 | void c_struct_array_3_sentinel_f32(struct Struct_array_4_f32 s, size_t i) { | ||
| 15394 | assert_or_panic(s.a[0] == 11); | ||
| 15395 | assert_or_panic(s.a[1] == 12); | ||
| 15396 | assert_or_panic(s.a[2] == 13); | ||
| 15397 | assert_or_panic(s.a[3] == 0x1e1); | ||
| 15398 | assert_or_panic(i == 14); | ||
| 15399 | } | ||
| 15400 | void c_test_struct_array_3_sentinel_f32(void) { | ||
| 15401 | struct Struct_array_4_f32 s = zig_ret_struct_array_3_sentinel_f32(); | ||
| 15402 | assert_or_panic(s.a[0] == 1); | ||
| 15403 | assert_or_panic(s.a[1] == 2); | ||
| 15404 | assert_or_panic(s.a[2] == 3); | ||
| 15405 | assert_or_panic(s.a[3] == 0x1e1); | ||
| 15406 | zig_struct_array_3_sentinel_f32((struct Struct_array_4_f32){ .a = { 4, 5, 6, 0x1e1 } }, 7); | ||
| 15407 | } | ||
| 15408 | |||
| 15409 | struct Struct_array_5_f32 zig_ret_struct_array_4_sentinel_f32(void); | ||
| 15410 | void zig_struct_array_4_sentinel_f32(struct Struct_array_5_f32, size_t); | ||
| 15411 | |||
| 15412 | struct Struct_array_5_f32 c_ret_struct_array_4_sentinel_f32(void) { | ||
| 15413 | return (struct Struct_array_5_f32){ .a = { 10, 11, 12, 13, 0x1e1 } }; | ||
| 15414 | } | ||
| 15415 | void c_struct_array_4_sentinel_f32(struct Struct_array_5_f32 s, size_t i) { | ||
| 15416 | assert_or_panic(s.a[0] == 14); | ||
| 15417 | assert_or_panic(s.a[1] == 15); | ||
| 15418 | assert_or_panic(s.a[2] == 16); | ||
| 15419 | assert_or_panic(s.a[3] == 17); | ||
| 15420 | assert_or_panic(s.a[4] == 0x1e1); | ||
| 15421 | assert_or_panic(i == 18); | ||
| 15422 | } | ||
| 15423 | void c_test_struct_array_4_sentinel_f32(void) { | ||
| 15424 | struct Struct_array_5_f32 s = zig_ret_struct_array_4_sentinel_f32(); | ||
| 15425 | assert_or_panic(s.a[0] == 1); | ||
| 15426 | assert_or_panic(s.a[1] == 2); | ||
| 15427 | assert_or_panic(s.a[2] == 3); | ||
| 15428 | assert_or_panic(s.a[3] == 4); | ||
| 15429 | assert_or_panic(s.a[4] == 0x1e1); | ||
| 15430 | zig_struct_array_4_sentinel_f32((struct Struct_array_5_f32){ .a = { 5, 6, 7, 8, 0x1e1 } }, 9); | ||
| 15431 | } | ||
| 15432 | |||
| 15000 | struct Struct_f32a8 { | 15433 | struct Struct_f32a8 { |
| 15001 | alignas(8) float a; | 15434 | alignas(8) float a; |
| 15002 | }; | 15435 | }; |
| ... | @@ -15212,6 +15645,146 @@ void c_test_struct_f64_f64_f64_f64_f64(void) { | ... | @@ -15212,6 +15645,146 @@ void c_test_struct_f64_f64_f64_f64_f64(void) { |
| 15212 | zig_struct_f64_f64_f64_f64_f64((struct Struct_f64_f64_f64_f64_f64){ .a = 6, .b = 7, .c = 8, .d = 9, .e = 10 }, 11); | 15645 | zig_struct_f64_f64_f64_f64_f64((struct Struct_f64_f64_f64_f64_f64){ .a = 6, .b = 7, .c = 8, .d = 9, .e = 10 }, 11); |
| 15213 | } | 15646 | } |
| 15214 | 15647 | ||
| 15648 | struct Struct_array_1_f64 { | ||
| 15649 | double a[1]; | ||
| 15650 | }; | ||
| 15651 | |||
| 15652 | struct Struct_array_1_f64 zig_ret_struct_array_1_f64(void); | ||
| 15653 | void zig_struct_array_1_f64(struct Struct_array_1_f64, size_t); | ||
| 15654 | |||
| 15655 | struct Struct_array_1_f64 c_ret_struct_array_1_f64(void) { | ||
| 15656 | return (struct Struct_array_1_f64){ .a = { 4 } }; | ||
| 15657 | } | ||
| 15658 | void c_struct_array_1_f64(struct Struct_array_1_f64 s, size_t i) { | ||
| 15659 | assert_or_panic(s.a[0] == 5); | ||
| 15660 | assert_or_panic(i == 6); | ||
| 15661 | } | ||
| 15662 | void c_test_struct_array_1_f64(void) { | ||
| 15663 | struct Struct_array_1_f64 s = zig_ret_struct_array_1_f64(); | ||
| 15664 | assert_or_panic(s.a[0] == 1); | ||
| 15665 | zig_struct_array_1_f64((struct Struct_array_1_f64){ .a = { 2 } }, 3); | ||
| 15666 | } | ||
| 15667 | |||
| 15668 | struct Struct_array_2_f64 { | ||
| 15669 | double a[2]; | ||
| 15670 | }; | ||
| 15671 | |||
| 15672 | struct Struct_array_2_f64 zig_ret_struct_array_2_f64(void); | ||
| 15673 | void zig_struct_array_2_f64(struct Struct_array_2_f64, size_t); | ||
| 15674 | |||
| 15675 | struct Struct_array_2_f64 c_ret_struct_array_2_f64(void) { | ||
| 15676 | return (struct Struct_array_2_f64){ .a = { 6, 7 } }; | ||
| 15677 | } | ||
| 15678 | void c_struct_array_2_f64(struct Struct_array_2_f64 s, size_t i) { | ||
| 15679 | assert_or_panic(s.a[0] == 8); | ||
| 15680 | assert_or_panic(s.a[1] == 9); | ||
| 15681 | assert_or_panic(i == 10); | ||
| 15682 | } | ||
| 15683 | void c_test_struct_array_2_f64(void) { | ||
| 15684 | struct Struct_array_2_f64 s = zig_ret_struct_array_2_f64(); | ||
| 15685 | assert_or_panic(s.a[0] == 1); | ||
| 15686 | assert_or_panic(s.a[1] == 2); | ||
| 15687 | zig_struct_array_2_f64((struct Struct_array_2_f64){ .a = { 3, 4 } }, 5); | ||
| 15688 | } | ||
| 15689 | |||
| 15690 | struct Struct_array_3_f64 { | ||
| 15691 | double a[3]; | ||
| 15692 | }; | ||
| 15693 | |||
| 15694 | struct Struct_array_3_f64 zig_ret_struct_array_3_f64(void); | ||
| 15695 | void zig_struct_array_3_f64(struct Struct_array_3_f64, size_t); | ||
| 15696 | |||
| 15697 | struct Struct_array_3_f64 c_ret_struct_array_3_f64(void) { | ||
| 15698 | return (struct Struct_array_3_f64){ .a = { 8, 9, 10 } }; | ||
| 15699 | } | ||
| 15700 | void c_struct_array_3_f64(struct Struct_array_3_f64 s, size_t i) { | ||
| 15701 | assert_or_panic(s.a[0] == 11); | ||
| 15702 | assert_or_panic(s.a[1] == 12); | ||
| 15703 | assert_or_panic(s.a[2] == 13); | ||
| 15704 | assert_or_panic(i == 14); | ||
| 15705 | } | ||
| 15706 | void c_test_struct_array_3_f64(void) { | ||
| 15707 | struct Struct_array_3_f64 s = zig_ret_struct_array_3_f64(); | ||
| 15708 | assert_or_panic(s.a[0] == 1); | ||
| 15709 | assert_or_panic(s.a[1] == 2); | ||
| 15710 | assert_or_panic(s.a[2] == 3); | ||
| 15711 | zig_struct_array_3_f64((struct Struct_array_3_f64){ .a = { 4, 5, 6 } }, 7); | ||
| 15712 | } | ||
| 15713 | |||
| 15714 | struct Struct_array_4_f64 { | ||
| 15715 | double a[4]; | ||
| 15716 | }; | ||
| 15717 | |||
| 15718 | struct Struct_array_4_f64 zig_ret_struct_array_4_f64(void); | ||
| 15719 | void zig_struct_array_4_f64(struct Struct_array_4_f64, size_t); | ||
| 15720 | |||
| 15721 | struct Struct_array_4_f64 c_ret_struct_array_4_f64(void) { | ||
| 15722 | return (struct Struct_array_4_f64){ .a = { 10, 11, 12, 13 } }; | ||
| 15723 | } | ||
| 15724 | void c_struct_array_4_f64(struct Struct_array_4_f64 s, size_t i) { | ||
| 15725 | assert_or_panic(s.a[0] == 14); | ||
| 15726 | assert_or_panic(s.a[1] == 15); | ||
| 15727 | assert_or_panic(s.a[2] == 16); | ||
| 15728 | assert_or_panic(s.a[3] == 17); | ||
| 15729 | assert_or_panic(i == 18); | ||
| 15730 | } | ||
| 15731 | void c_test_struct_array_4_f64(void) { | ||
| 15732 | struct Struct_array_4_f64 s = zig_ret_struct_array_4_f64(); | ||
| 15733 | assert_or_panic(s.a[0] == 1); | ||
| 15734 | assert_or_panic(s.a[1] == 2); | ||
| 15735 | assert_or_panic(s.a[2] == 3); | ||
| 15736 | assert_or_panic(s.a[3] == 4); | ||
| 15737 | zig_struct_array_4_f64((struct Struct_array_4_f64){ .a = { 5, 6, 7, 8 } }, 9); | ||
| 15738 | } | ||
| 15739 | |||
| 15740 | struct Struct_array_5_f64 { | ||
| 15741 | double a[5]; | ||
| 15742 | }; | ||
| 15743 | |||
| 15744 | struct Struct_array_5_f64 zig_ret_struct_array_5_f64(void); | ||
| 15745 | void zig_struct_array_5_f64(struct Struct_array_5_f64, size_t); | ||
| 15746 | |||
| 15747 | struct Struct_array_5_f64 c_ret_struct_array_5_f64(void) { | ||
| 15748 | return (struct Struct_array_5_f64){ .a = { 12, 13, 14, 15, 16 } }; | ||
| 15749 | } | ||
| 15750 | void c_struct_array_5_f64(struct Struct_array_5_f64 s, size_t i) { | ||
| 15751 | assert_or_panic(s.a[0] == 17); | ||
| 15752 | assert_or_panic(s.a[1] == 18); | ||
| 15753 | assert_or_panic(s.a[2] == 19); | ||
| 15754 | assert_or_panic(s.a[3] == 20); | ||
| 15755 | assert_or_panic(s.a[4] == 21); | ||
| 15756 | assert_or_panic(i == 22); | ||
| 15757 | } | ||
| 15758 | void c_test_struct_array_5_f64(void) { | ||
| 15759 | struct Struct_array_5_f64 s = zig_ret_struct_array_5_f64(); | ||
| 15760 | assert_or_panic(s.a[0] == 1); | ||
| 15761 | assert_or_panic(s.a[1] == 2); | ||
| 15762 | assert_or_panic(s.a[2] == 3); | ||
| 15763 | assert_or_panic(s.a[3] == 4); | ||
| 15764 | assert_or_panic(s.a[4] == 5); | ||
| 15765 | zig_struct_array_5_f64((struct Struct_array_5_f64){ .a = { 6, 7, 8, 9, 10 } }, 11); | ||
| 15766 | } | ||
| 15767 | |||
| 15768 | union Union_f64 { | ||
| 15769 | double a; | ||
| 15770 | }; | ||
| 15771 | |||
| 15772 | union Union_f64 zig_ret_union_f64(void); | ||
| 15773 | void zig_union_f64(union Union_f64, size_t); | ||
| 15774 | |||
| 15775 | union Union_f64 c_ret_union_f64(void) { | ||
| 15776 | return (union Union_f64){ .a = 4 }; | ||
| 15777 | } | ||
| 15778 | void c_union_f64(union Union_f64 s, size_t i) { | ||
| 15779 | assert_or_panic(s.a == 5); | ||
| 15780 | assert_or_panic(i == 6); | ||
| 15781 | } | ||
| 15782 | void c_test_union_f64(void) { | ||
| 15783 | union Union_f64 s = zig_ret_union_f64(); | ||
| 15784 | assert_or_panic(s.a == 1); | ||
| 15785 | zig_union_f64((union Union_f64){ .a = 2 }, 3); | ||
| 15786 | } | ||
| 15787 | |||
| 15215 | struct Struct_u32_Union_u32_u32u32 { | 15788 | struct Struct_u32_Union_u32_u32u32 { |
| 15216 | uint32_t a; | 15789 | uint32_t a; |
| 15217 | union { | 15790 | union { |
| ... | @@ -15326,9 +15899,6 @@ void run_c_tests(void) { | ... | @@ -15326,9 +15899,6 @@ void run_c_tests(void) { |
| 15326 | 15899 | ||
| 15327 | zig_five_integers(12, 34, 56, 78, 90); | 15900 | zig_five_integers(12, 34, 56, 78, 90); |
| 15328 | 15901 | ||
| 15329 | zig_f32(12.34f); | ||
| 15330 | zig_f64(56.78); | ||
| 15331 | zig_longdouble(12.34l); | ||
| 15332 | zig_five_floats(1.0f, 2.0f, 3.0f, 4.0f, 5.0f); | 15902 | zig_five_floats(1.0f, 2.0f, 3.0f, 4.0f, 5.0f); |
| 15333 | 15903 | ||
| 15334 | zig_ptr((void *)0xdeadbeefL); | 15904 | zig_ptr((void *)0xdeadbeefL); |
| ... | @@ -15377,8 +15947,7 @@ void run_c_tests(void) { | ... | @@ -15377,8 +15947,7 @@ void run_c_tests(void) { |
| 15377 | #if !(defined(__i386__) && defined(_WIN32)) | 15947 | #if !(defined(__i386__) && defined(_WIN32)) |
| 15378 | #ifndef __loongarch__ | 15948 | #ifndef __loongarch__ |
| 15379 | #ifndef ZIG_MIPS64 | 15949 | #ifndef ZIG_MIPS64 |
| 15380 | #ifndef __powerpc__ | 15950 | #ifndef ZIG_PPC32 |
| 15381 | #ifndef __s390x__ | ||
| 15382 | { | 15951 | { |
| 15383 | struct Struct_i32_i32 s = {1, 2}; | 15952 | struct Struct_i32_i32 s = {1, 2}; |
| 15384 | zig_struct_i32_i32(s); | 15953 | zig_struct_i32_i32(s); |
| ... | @@ -15387,13 +15956,11 @@ void run_c_tests(void) { | ... | @@ -15387,13 +15956,11 @@ void run_c_tests(void) { |
| 15387 | #endif | 15956 | #endif |
| 15388 | #endif | 15957 | #endif |
| 15389 | #endif | 15958 | #endif |
| 15390 | #endif | ||
| 15391 | 15959 | ||
| 15392 | #ifndef __hexagon__ | 15960 | #ifndef __hexagon__ |
| 15393 | #ifndef __loongarch__ | 15961 | #ifndef __loongarch__ |
| 15394 | #ifndef ZIG_MIPS64 | 15962 | #ifndef ZIG_MIPS64 |
| 15395 | #ifndef __powerpc__ | 15963 | #ifndef ZIG_PPC32 |
| 15396 | #ifndef __s390x__ | ||
| 15397 | { | 15964 | { |
| 15398 | struct BigStruct s = {1, 2, 3, 4, 5}; | 15965 | struct BigStruct s = {1, 2, 3, 4, 5}; |
| 15399 | zig_big_struct(s); | 15966 | zig_big_struct(s); |
| ... | @@ -15402,7 +15969,6 @@ void run_c_tests(void) { | ... | @@ -15402,7 +15969,6 @@ void run_c_tests(void) { |
| 15402 | #endif | 15969 | #endif |
| 15403 | #endif | 15970 | #endif |
| 15404 | #endif | 15971 | #endif |
| 15405 | #endif | ||
| 15406 | 15972 | ||
| 15407 | #ifndef ZIG_NO_I128 | 15973 | #ifndef ZIG_NO_I128 |
| 15408 | { | 15974 | { |
| ... | @@ -15426,8 +15992,7 @@ void run_c_tests(void) { | ... | @@ -15426,8 +15992,7 @@ void run_c_tests(void) { |
| 15426 | #ifndef __i386__ | 15992 | #ifndef __i386__ |
| 15427 | #ifndef __loongarch__ | 15993 | #ifndef __loongarch__ |
| 15428 | #ifndef ZIG_MIPS64 | 15994 | #ifndef ZIG_MIPS64 |
| 15429 | #ifndef __powerpc__ | 15995 | #ifndef ZIG_PPC32 |
| 15430 | #ifndef __s390x__ | ||
| 15431 | { | 15996 | { |
| 15432 | struct SplitStructInts s = {1234, 100, 1337}; | 15997 | struct SplitStructInts s = {1234, 100, 1337}; |
| 15433 | zig_split_struct_ints(s); | 15998 | zig_split_struct_ints(s); |
| ... | @@ -15437,13 +16002,11 @@ void run_c_tests(void) { | ... | @@ -15437,13 +16002,11 @@ void run_c_tests(void) { |
| 15437 | #endif | 16002 | #endif |
| 15438 | #endif | 16003 | #endif |
| 15439 | #endif | 16004 | #endif |
| 15440 | #endif | ||
| 15441 | 16005 | ||
| 15442 | #ifndef __hexagon__ | 16006 | #ifndef __hexagon__ |
| 15443 | #ifndef __loongarch__ | 16007 | #ifndef __loongarch__ |
| 15444 | #ifndef ZIG_MIPS64 | 16008 | #ifndef ZIG_MIPS64 |
| 15445 | #ifndef __powerpc__ | 16009 | #ifndef ZIG_PPC32 |
| 15446 | #ifndef __s390x__ | ||
| 15447 | { | 16010 | { |
| 15448 | struct MedStructMixed s = {1234, 100.0f, 1337.0f}; | 16011 | struct MedStructMixed s = {1234, 100.0f, 1337.0f}; |
| 15449 | zig_med_struct_mixed(s); | 16012 | zig_med_struct_mixed(s); |
| ... | @@ -15452,14 +16015,12 @@ void run_c_tests(void) { | ... | @@ -15452,14 +16015,12 @@ void run_c_tests(void) { |
| 15452 | #endif | 16015 | #endif |
| 15453 | #endif | 16016 | #endif |
| 15454 | #endif | 16017 | #endif |
| 15455 | #endif | ||
| 15456 | 16018 | ||
| 15457 | #ifndef __hexagon__ | 16019 | #ifndef __hexagon__ |
| 15458 | #ifndef __i386__ | 16020 | #ifndef __i386__ |
| 15459 | #ifndef __loongarch__ | 16021 | #ifndef __loongarch__ |
| 15460 | #ifndef ZIG_MIPS64 | 16022 | #ifndef ZIG_MIPS64 |
| 15461 | #ifndef __powerpc__ | 16023 | #ifndef ZIG_PPC32 |
| 15462 | #ifndef __s390x__ | ||
| 15463 | { | 16024 | { |
| 15464 | struct SplitStructMixed s = {1234, 100, 1337.0f}; | 16025 | struct SplitStructMixed s = {1234, 100, 1337.0f}; |
| 15465 | zig_split_struct_mixed(s); | 16026 | zig_split_struct_mixed(s); |
| ... | @@ -15469,13 +16030,11 @@ void run_c_tests(void) { | ... | @@ -15469,13 +16030,11 @@ void run_c_tests(void) { |
| 15469 | #endif | 16030 | #endif |
| 15470 | #endif | 16031 | #endif |
| 15471 | #endif | 16032 | #endif |
| 15472 | #endif | ||
| 15473 | 16033 | ||
| 15474 | #ifndef __hexagon__ | 16034 | #ifndef __hexagon__ |
| 15475 | #ifndef __loongarch__ | 16035 | #ifndef __loongarch__ |
| 15476 | #ifndef ZIG_MIPS64 | 16036 | #ifndef ZIG_MIPS64 |
| 15477 | #ifndef __powerpc__ | 16037 | #ifndef ZIG_PPC32 |
| 15478 | #ifndef __s390x__ | ||
| 15479 | { | 16038 | { |
| 15480 | struct BigStruct s = {30, 31, 32, 33, 34}; | 16039 | struct BigStruct s = {30, 31, 32, 33, 34}; |
| 15481 | struct BigStruct res = zig_big_struct_both(s); | 16040 | struct BigStruct res = zig_big_struct_both(s); |
| ... | @@ -15488,7 +16047,6 @@ void run_c_tests(void) { | ... | @@ -15488,7 +16047,6 @@ void run_c_tests(void) { |
| 15488 | #endif | 16047 | #endif |
| 15489 | #endif | 16048 | #endif |
| 15490 | #endif | 16049 | #endif |
| 15491 | #endif | ||
| 15492 | #endif | 16050 | #endif |
| 15493 | 16051 | ||
| 15494 | { | 16052 | { |
| ... | @@ -15550,18 +16108,6 @@ void c_struct_i128(struct i128 x) { | ... | @@ -15550,18 +16108,6 @@ void c_struct_i128(struct i128 x) { |
| 15550 | } | 16108 | } |
| 15551 | #endif | 16109 | #endif |
| 15552 | 16110 | ||
| 15553 | void c_f32(float x) { | ||
| 15554 | assert_or_panic(x == 12.34f); | ||
| 15555 | } | ||
| 15556 | |||
| 15557 | void c_f64(double x) { | ||
| 15558 | assert_or_panic(x == 56.78); | ||
| 15559 | } | ||
| 15560 | |||
| 15561 | void c_long_double(long double x) { | ||
| 15562 | assert_or_panic(x == 12.34l); | ||
| 15563 | } | ||
| 15564 | |||
| 15565 | void c_ptr(void *x) { | 16111 | void c_ptr(void *x) { |
| 15566 | assert_or_panic(x == (void *)0xdeadbeefL); | 16112 | assert_or_panic(x == (void *)0xdeadbeefL); |
| 15567 | } | 16113 | } |
| ... | @@ -16078,6 +16624,16 @@ struct ByRef __attribute__((sysv_abi)) c_explict_sys_v(struct ByRef in) { | ... | @@ -16078,6 +16624,16 @@ struct ByRef __attribute__((sysv_abi)) c_explict_sys_v(struct ByRef in) { |
| 16078 | } | 16624 | } |
| 16079 | #endif | 16625 | #endif |
| 16080 | 16626 | ||
| 16627 | #if defined __x86_64__ || defined __aarch64__ | ||
| 16628 | int __attribute__((preserve_none)) c_preserve_none(int x) { | ||
| 16629 | return x + 1; | ||
| 16630 | } | ||
| 16631 | int __attribute__((preserve_none)) zig_preserve_none(int); | ||
| 16632 | void c_preserve_none_check(void) { | ||
| 16633 | assert_or_panic(zig_preserve_none(41) == 42); | ||
| 16634 | } | ||
| 16635 | #endif | ||
| 16636 | |||
| 16081 | struct byval_tail_callsite_attr_Point { | 16637 | struct byval_tail_callsite_attr_Point { |
| 16082 | double x; | 16638 | double x; |
| 16083 | double y; | 16639 | double y; |
| ... | @@ -16212,7 +16768,13 @@ void __attribute__((vectorcall)) c_vectorcall_check(int a, float b, double c, vo | ... | @@ -16212,7 +16768,13 @@ void __attribute__((vectorcall)) c_vectorcall_check(int a, float b, double c, vo |
| 16212 | } | 16768 | } |
| 16213 | #endif | 16769 | #endif |
| 16214 | 16770 | ||
| 16215 | #if defined(__x86_64__) && defined(_WIN64) | 16771 | void c_x86_64_sysv_uint_int_uint_int(unsigned a, int b, unsigned c, int d) { |
| 16772 | assert_or_panic(a == 1); | ||
| 16773 | assert_or_panic(b == -2); | ||
| 16774 | assert_or_panic(c == 3); | ||
| 16775 | assert_or_panic(d == -4); | ||
| 16776 | } | ||
| 16777 | |||
| 16216 | void c_win64_varargs_u64_f64_u64_f64(uint64_t a, double b, uint64_t c, double d) { | 16778 | void c_win64_varargs_u64_f64_u64_f64(uint64_t a, double b, uint64_t c, double d) { |
| 16217 | assert_or_panic(a == UINT64_C(0x3ff0000000000000)); | 16779 | assert_or_panic(a == UINT64_C(0x3ff0000000000000)); |
| 16218 | assert_or_panic(b == 2.0); | 16780 | assert_or_panic(b == 2.0); |
| ... | @@ -16225,4 +16787,3 @@ void c_win64_varargs_f64_u64_f64_u64(double a, uint64_t b, double c, uint64_t d) | ... | @@ -16225,4 +16787,3 @@ void c_win64_varargs_f64_u64_f64_u64(double a, uint64_t b, double c, uint64_t d) |
| 16225 | assert_or_panic(c == 7.0); | 16787 | assert_or_panic(c == 7.0); |
| 16226 | assert_or_panic(d == UINT64_C(0x4020000000000000)); | 16788 | assert_or_panic(d == UINT64_C(0x4020000000000000)); |
| 16227 | } | 16789 | } |
| 16228 | #endif |
test/c_abi/main.zig+1049-286| ... | @@ -13,7 +13,7 @@ const expectEqual = std.testing.expectEqual; | ... | @@ -13,7 +13,7 @@ const expectEqual = std.testing.expectEqual; |
| 13 | const have_i128 = builtin.cpu.arch != .x86 and !builtin.cpu.arch.isArm() and | 13 | const have_i128 = builtin.cpu.arch != .x86 and !builtin.cpu.arch.isArm() and |
| 14 | !builtin.cpu.arch.isMIPS() and !builtin.cpu.arch.isPowerPC32() and builtin.cpu.arch != .riscv32 and | 14 | !builtin.cpu.arch.isMIPS() and !builtin.cpu.arch.isPowerPC32() and builtin.cpu.arch != .riscv32 and |
| 15 | builtin.cpu.arch != .hexagon and | 15 | builtin.cpu.arch != .hexagon and |
| 16 | builtin.cpu.arch != .s390x; // https://github.com/llvm/llvm-project/issues/168460 | 16 | builtin.cpu.arch != .s390x; |
| 17 | 17 | ||
| 18 | const have_f128 = builtin.cpu.arch.isWasm() or (builtin.cpu.arch.isX86() and !builtin.os.tag.isDarwin() and builtin.abi != .msvc); | 18 | const have_f128 = builtin.cpu.arch.isWasm() or (builtin.cpu.arch.isX86() and !builtin.os.tag.isDarwin() and builtin.abi != .msvc); |
| 19 | const have_f80 = builtin.cpu.arch.isX86() and builtin.abi != .msvc; | 19 | const have_f80 = builtin.cpu.arch.isX86() and builtin.abi != .msvc; |
| ... | @@ -104,10 +104,6 @@ export fn zig_struct_u128(a: U128) void { | ... | @@ -104,10 +104,6 @@ export fn zig_struct_u128(a: U128) void { |
| 104 | expect(a.value == 0xfffffffffffffffc) catch @panic("test failure: zig_struct_u128"); | 104 | expect(a.value == 0xfffffffffffffffc) catch @panic("test failure: zig_struct_u128"); |
| 105 | } | 105 | } |
| 106 | 106 | ||
| 107 | extern fn c_f32(f32) void; | ||
| 108 | extern fn c_f64(f64) void; | ||
| 109 | extern fn c_long_double(c_longdouble) void; | ||
| 110 | |||
| 111 | // On windows x64, the first 4 are passed via registers, others on the stack. | 107 | // On windows x64, the first 4 are passed via registers, others on the stack. |
| 112 | extern fn c_five_floats(f32, f32, f32, f32, f32) void; | 108 | extern fn c_five_floats(f32, f32, f32, f32, f32) void; |
| 113 | 109 | ||
| ... | @@ -120,28 +116,9 @@ export fn zig_five_floats(a: f32, b: f32, c: f32, d: f32, e: f32) void { | ... | @@ -120,28 +116,9 @@ export fn zig_five_floats(a: f32, b: f32, c: f32, d: f32, e: f32) void { |
| 120 | } | 116 | } |
| 121 | 117 | ||
| 122 | test "floats" { | 118 | test "floats" { |
| 123 | c_f32(12.34); | ||
| 124 | c_f64(56.78); | ||
| 125 | c_five_floats(1.0, 2.0, 3.0, 4.0, 5.0); | 119 | c_five_floats(1.0, 2.0, 3.0, 4.0, 5.0); |
| 126 | } | 120 | } |
| 127 | 121 | ||
| 128 | test "long double" { | ||
| 129 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | ||
| 130 | |||
| 131 | c_long_double(12.34); | ||
| 132 | } | ||
| 133 | |||
| 134 | export fn zig_f32(x: f32) void { | ||
| 135 | expect(x == 12.34) catch @panic("test failure: zig_f32"); | ||
| 136 | } | ||
| 137 | export fn zig_f64(x: f64) void { | ||
| 138 | expect(x == 56.78) catch @panic("test failure: zig_f64"); | ||
| 139 | } | ||
| 140 | export fn zig_longdouble(x: c_longdouble) void { | ||
| 141 | if (!builtin.target.cpu.arch.isWasm()) return; // waiting for #1481 | ||
| 142 | expect(x == 12.34) catch @panic("test failure: zig_longdouble"); | ||
| 143 | } | ||
| 144 | |||
| 145 | extern fn c_ptr(*anyopaque) void; | 122 | extern fn c_ptr(*anyopaque) void; |
| 146 | 123 | ||
| 147 | test "pointer" { | 124 | test "pointer" { |
| ... | @@ -184,7 +161,7 @@ extern fn c_cmultf(a: ComplexFloat, b: ComplexFloat) ComplexFloat; | ... | @@ -184,7 +161,7 @@ extern fn c_cmultf(a: ComplexFloat, b: ComplexFloat) ComplexFloat; |
| 184 | extern fn c_cmultd(a: ComplexDouble, b: ComplexDouble) ComplexDouble; | 161 | extern fn c_cmultd(a: ComplexDouble, b: ComplexDouble) ComplexDouble; |
| 185 | 162 | ||
| 186 | const complex_abi_compatible = builtin.cpu.arch != .x86 and !builtin.cpu.arch.isMIPS() and | 163 | const complex_abi_compatible = builtin.cpu.arch != .x86 and !builtin.cpu.arch.isMIPS() and |
| 187 | !builtin.cpu.arch.isArm() and !builtin.cpu.arch.isPowerPC32() and !builtin.cpu.arch.isRISCV() and | 164 | !builtin.cpu.arch.isArm() and !builtin.cpu.arch.isPowerPC() and !builtin.cpu.arch.isRISCV() and |
| 188 | builtin.cpu.arch != .hexagon and | 165 | builtin.cpu.arch != .hexagon and |
| 189 | builtin.cpu.arch != .s390x and | 166 | builtin.cpu.arch != .s390x and |
| 190 | !(builtin.cpu.arch.isLoongArch() and builtin.abi.float() == .soft); | 167 | !(builtin.cpu.arch.isLoongArch() and builtin.abi.float() == .soft); |
| ... | @@ -269,10 +246,217 @@ export fn zig_cmultd_comp(a_r: f64, a_i: f64, b_r: f64, b_i: f64) ComplexDouble | ... | @@ -269,10 +246,217 @@ export fn zig_cmultd_comp(a_r: f64, a_i: f64, b_r: f64, b_i: f64) ComplexDouble |
| 269 | return .{ .real = 1.5, .imag = 13.5 }; | 246 | return .{ .real = 1.5, .imag = 13.5 }; |
| 270 | } | 247 | } |
| 271 | 248 | ||
| 249 | export fn zig_ret_f32() f32 { | ||
| 250 | return 1; | ||
| 251 | } | ||
| 252 | export fn zig_f32(f: f32, i: usize) void { | ||
| 253 | expect(f == 2) catch @panic("test failure"); | ||
| 254 | expect(i == 1) catch @panic("test failure"); | ||
| 255 | } | ||
| 256 | export fn zig_1_f32(_: usize, f: f32, i: usize) void { | ||
| 257 | expect(f == 3) catch @panic("test failure"); | ||
| 258 | expect(i == 2) catch @panic("test failure"); | ||
| 259 | } | ||
| 260 | export fn zig_2_f32(_: usize, _: usize, f: f32, i: usize) void { | ||
| 261 | expect(f == 4) catch @panic("test failure"); | ||
| 262 | expect(i == 3) catch @panic("test failure"); | ||
| 263 | } | ||
| 264 | export fn zig_3_f32(_: usize, _: usize, _: usize, f: f32, i: usize) void { | ||
| 265 | expect(f == 5) catch @panic("test failure"); | ||
| 266 | expect(i == 4) catch @panic("test failure"); | ||
| 267 | } | ||
| 268 | export fn zig_4_f32(_: usize, _: usize, _: usize, _: usize, f: f32, i: usize) void { | ||
| 269 | expect(f == 6) catch @panic("test failure"); | ||
| 270 | expect(i == 5) catch @panic("test failure"); | ||
| 271 | } | ||
| 272 | export fn zig_5_f32(_: usize, _: usize, _: usize, _: usize, _: usize, f: f32, i: usize) void { | ||
| 273 | expect(f == 7) catch @panic("test failure"); | ||
| 274 | expect(i == 6) catch @panic("test failure"); | ||
| 275 | } | ||
| 276 | export fn zig_6_f32(_: usize, _: usize, _: usize, _: usize, _: usize, _: usize, f: f32, i: usize) void { | ||
| 277 | expect(f == 8) catch @panic("test failure"); | ||
| 278 | expect(i == 7) catch @panic("test failure"); | ||
| 279 | } | ||
| 280 | export fn zig_7_f32(_: usize, _: usize, _: usize, _: usize, _: usize, _: usize, _: usize, f: f32, i: usize) void { | ||
| 281 | expect(f == 9) catch @panic("test failure"); | ||
| 282 | expect(i == 8) catch @panic("test failure"); | ||
| 283 | } | ||
| 284 | export fn zig_8_f32(_: usize, _: usize, _: usize, _: usize, _: usize, _: usize, _: usize, _: usize, f: f32, i: usize) void { | ||
| 285 | expect(f == 10) catch @panic("test failure"); | ||
| 286 | expect(i == 9) catch @panic("test failure"); | ||
| 287 | } | ||
| 288 | |||
| 289 | extern fn c_ret_f32() f32; | ||
| 290 | extern fn c_f32(f32, usize) void; | ||
| 291 | extern fn c_1_f32(usize, f32, usize) void; | ||
| 292 | extern fn c_2_f32(usize, usize, f32, usize) void; | ||
| 293 | extern fn c_3_f32(usize, usize, usize, f32, usize) void; | ||
| 294 | extern fn c_4_f32(usize, usize, usize, usize, f32, usize) void; | ||
| 295 | extern fn c_5_f32(usize, usize, usize, usize, usize, f32, usize) void; | ||
| 296 | extern fn c_6_f32(usize, usize, usize, usize, usize, usize, f32, usize) void; | ||
| 297 | extern fn c_7_f32(usize, usize, usize, usize, usize, usize, usize, f32, usize) void; | ||
| 298 | extern fn c_8_f32(usize, usize, usize, usize, usize, usize, usize, usize, f32, usize) void; | ||
| 299 | extern fn c_test_f32() void; | ||
| 300 | |||
| 301 | test "f32" { | ||
| 302 | const f = c_ret_f32(); | ||
| 303 | try expect(f == 11); | ||
| 304 | c_f32(12, 1); | ||
| 305 | c_1_f32(0, 13, 2); | ||
| 306 | c_2_f32(0, 1, 14, 3); | ||
| 307 | c_3_f32(0, 1, 2, 15, 4); | ||
| 308 | c_4_f32(0, 1, 2, 3, 16, 5); | ||
| 309 | c_5_f32(0, 1, 2, 3, 4, 17, 6); | ||
| 310 | c_6_f32(0, 1, 2, 3, 4, 5, 18, 7); | ||
| 311 | c_7_f32(0, 1, 2, 3, 4, 5, 6, 19, 8); | ||
| 312 | c_8_f32(0, 1, 2, 3, 4, 5, 6, 7, 20, 9); | ||
| 313 | c_test_f32(); | ||
| 314 | } | ||
| 315 | |||
| 316 | export fn zig_ret_f64() f64 { | ||
| 317 | return 1; | ||
| 318 | } | ||
| 319 | export fn zig_f64(f: f64, i: usize) void { | ||
| 320 | expect(f == 2) catch @panic("test failure"); | ||
| 321 | expect(i == 1) catch @panic("test failure"); | ||
| 322 | } | ||
| 323 | export fn zig_1_f64(_: usize, f: f64, i: usize) void { | ||
| 324 | expect(f == 3) catch @panic("test failure"); | ||
| 325 | expect(i == 2) catch @panic("test failure"); | ||
| 326 | } | ||
| 327 | export fn zig_2_f64(_: usize, _: usize, f: f64, i: usize) void { | ||
| 328 | expect(f == 4) catch @panic("test failure"); | ||
| 329 | expect(i == 3) catch @panic("test failure"); | ||
| 330 | } | ||
| 331 | export fn zig_3_f64(_: usize, _: usize, _: usize, f: f64, i: usize) void { | ||
| 332 | expect(f == 5) catch @panic("test failure"); | ||
| 333 | expect(i == 4) catch @panic("test failure"); | ||
| 334 | } | ||
| 335 | export fn zig_4_f64(_: usize, _: usize, _: usize, _: usize, f: f64, i: usize) void { | ||
| 336 | expect(f == 6) catch @panic("test failure"); | ||
| 337 | expect(i == 5) catch @panic("test failure"); | ||
| 338 | } | ||
| 339 | export fn zig_5_f64(_: usize, _: usize, _: usize, _: usize, _: usize, f: f64, i: usize) void { | ||
| 340 | expect(f == 7) catch @panic("test failure"); | ||
| 341 | expect(i == 6) catch @panic("test failure"); | ||
| 342 | } | ||
| 343 | export fn zig_6_f64(_: usize, _: usize, _: usize, _: usize, _: usize, _: usize, f: f64, i: usize) void { | ||
| 344 | expect(f == 8) catch @panic("test failure"); | ||
| 345 | expect(i == 7) catch @panic("test failure"); | ||
| 346 | } | ||
| 347 | export fn zig_7_f64(_: usize, _: usize, _: usize, _: usize, _: usize, _: usize, _: usize, f: f64, i: usize) void { | ||
| 348 | expect(f == 9) catch @panic("test failure"); | ||
| 349 | expect(i == 8) catch @panic("test failure"); | ||
| 350 | } | ||
| 351 | export fn zig_8_f64(_: usize, _: usize, _: usize, _: usize, _: usize, _: usize, _: usize, _: usize, f: f64, i: usize) void { | ||
| 352 | expect(f == 10) catch @panic("test failure"); | ||
| 353 | expect(i == 9) catch @panic("test failure"); | ||
| 354 | } | ||
| 355 | |||
| 356 | extern fn c_ret_f64() f64; | ||
| 357 | extern fn c_f64(f64, usize) void; | ||
| 358 | extern fn c_1_f64(usize, f64, usize) void; | ||
| 359 | extern fn c_2_f64(usize, usize, f64, usize) void; | ||
| 360 | extern fn c_3_f64(usize, usize, usize, f64, usize) void; | ||
| 361 | extern fn c_4_f64(usize, usize, usize, usize, f64, usize) void; | ||
| 362 | extern fn c_5_f64(usize, usize, usize, usize, usize, f64, usize) void; | ||
| 363 | extern fn c_6_f64(usize, usize, usize, usize, usize, usize, f64, usize) void; | ||
| 364 | extern fn c_7_f64(usize, usize, usize, usize, usize, usize, usize, f64, usize) void; | ||
| 365 | extern fn c_8_f64(usize, usize, usize, usize, usize, usize, usize, usize, f64, usize) void; | ||
| 366 | extern fn c_test_f64() void; | ||
| 367 | |||
| 368 | test "f64" { | ||
| 369 | const f = c_ret_f64(); | ||
| 370 | try expect(f == 11); | ||
| 371 | c_f64(12, 1); | ||
| 372 | c_1_f64(0, 13, 2); | ||
| 373 | c_2_f64(0, 1, 14, 3); | ||
| 374 | c_3_f64(0, 1, 2, 15, 4); | ||
| 375 | c_4_f64(0, 1, 2, 3, 16, 5); | ||
| 376 | c_5_f64(0, 1, 2, 3, 4, 17, 6); | ||
| 377 | c_6_f64(0, 1, 2, 3, 4, 5, 18, 7); | ||
| 378 | c_7_f64(0, 1, 2, 3, 4, 5, 6, 19, 8); | ||
| 379 | c_8_f64(0, 1, 2, 3, 4, 5, 6, 7, 20, 9); | ||
| 380 | c_test_f64(); | ||
| 381 | } | ||
| 382 | |||
| 383 | export fn zig_ret_longdouble() c_longdouble { | ||
| 384 | return 1; | ||
| 385 | } | ||
| 386 | export fn zig_longdouble(f: c_longdouble, i: usize) void { | ||
| 387 | expect(f == 2) catch @panic("test failure"); | ||
| 388 | expect(i == 1) catch @panic("test failure"); | ||
| 389 | } | ||
| 390 | export fn zig_1_longdouble(_: usize, f: c_longdouble, i: usize) void { | ||
| 391 | expect(f == 3) catch @panic("test failure"); | ||
| 392 | expect(i == 2) catch @panic("test failure"); | ||
| 393 | } | ||
| 394 | export fn zig_2_longdouble(_: usize, _: usize, f: c_longdouble, i: usize) void { | ||
| 395 | expect(f == 4) catch @panic("test failure"); | ||
| 396 | expect(i == 3) catch @panic("test failure"); | ||
| 397 | } | ||
| 398 | export fn zig_3_longdouble(_: usize, _: usize, _: usize, f: c_longdouble, i: usize) void { | ||
| 399 | expect(f == 5) catch @panic("test failure"); | ||
| 400 | expect(i == 4) catch @panic("test failure"); | ||
| 401 | } | ||
| 402 | export fn zig_4_longdouble(_: usize, _: usize, _: usize, _: usize, f: c_longdouble, i: usize) void { | ||
| 403 | expect(f == 6) catch @panic("test failure"); | ||
| 404 | expect(i == 5) catch @panic("test failure"); | ||
| 405 | } | ||
| 406 | export fn zig_5_longdouble(_: usize, _: usize, _: usize, _: usize, _: usize, f: c_longdouble, i: usize) void { | ||
| 407 | expect(f == 7) catch @panic("test failure"); | ||
| 408 | expect(i == 6) catch @panic("test failure"); | ||
| 409 | } | ||
| 410 | export fn zig_6_longdouble(_: usize, _: usize, _: usize, _: usize, _: usize, _: usize, f: c_longdouble, i: usize) void { | ||
| 411 | expect(f == 8) catch @panic("test failure"); | ||
| 412 | expect(i == 7) catch @panic("test failure"); | ||
| 413 | } | ||
| 414 | export fn zig_7_longdouble(_: usize, _: usize, _: usize, _: usize, _: usize, _: usize, _: usize, f: c_longdouble, i: usize) void { | ||
| 415 | expect(f == 9) catch @panic("test failure"); | ||
| 416 | expect(i == 8) catch @panic("test failure"); | ||
| 417 | } | ||
| 418 | export fn zig_8_longdouble(_: usize, _: usize, _: usize, _: usize, _: usize, _: usize, _: usize, _: usize, f: c_longdouble, i: usize) void { | ||
| 419 | expect(f == 10) catch @panic("test failure"); | ||
| 420 | expect(i == 9) catch @panic("test failure"); | ||
| 421 | } | ||
| 422 | |||
| 423 | extern fn c_ret_longdouble() c_longdouble; | ||
| 424 | extern fn @"c_longdouble"(c_longdouble, usize) void; | ||
| 425 | extern fn c_1_longdouble(usize, c_longdouble, usize) void; | ||
| 426 | extern fn c_2_longdouble(usize, usize, c_longdouble, usize) void; | ||
| 427 | extern fn c_3_longdouble(usize, usize, usize, c_longdouble, usize) void; | ||
| 428 | extern fn c_4_longdouble(usize, usize, usize, usize, c_longdouble, usize) void; | ||
| 429 | extern fn c_5_longdouble(usize, usize, usize, usize, usize, c_longdouble, usize) void; | ||
| 430 | extern fn c_6_longdouble(usize, usize, usize, usize, usize, usize, c_longdouble, usize) void; | ||
| 431 | extern fn c_7_longdouble(usize, usize, usize, usize, usize, usize, usize, c_longdouble, usize) void; | ||
| 432 | extern fn c_8_longdouble(usize, usize, usize, usize, usize, usize, usize, usize, c_longdouble, usize) void; | ||
| 433 | extern fn c_test_longdouble() void; | ||
| 434 | |||
| 435 | test "long double" { | ||
| 436 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | ||
| 437 | |||
| 438 | const f = c_ret_longdouble(); | ||
| 439 | try expect(f == 11); | ||
| 440 | @"c_longdouble"(12, 1); | ||
| 441 | c_1_longdouble(0, 13, 2); | ||
| 442 | c_2_longdouble(0, 1, 14, 3); | ||
| 443 | c_3_longdouble(0, 1, 2, 15, 4); | ||
| 444 | c_4_longdouble(0, 1, 2, 3, 16, 5); | ||
| 445 | c_5_longdouble(0, 1, 2, 3, 4, 17, 6); | ||
| 446 | c_6_longdouble(0, 1, 2, 3, 4, 5, 18, 7); | ||
| 447 | c_7_longdouble(0, 1, 2, 3, 4, 5, 6, 19, 8); | ||
| 448 | c_8_longdouble(0, 1, 2, 3, 4, 5, 6, 7, 20, 9); | ||
| 449 | c_test_longdouble(); | ||
| 450 | } | ||
| 451 | |||
| 272 | comptime { | 452 | comptime { |
| 273 | skip: { | 453 | skip: { |
| 274 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64) break :skip; | 454 | if (builtin.zig_backend == .stage2_wasm) break :skip; |
| 275 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isPowerPC64()) break :skip; | 455 | if (builtin.cpu.arch == .hexagon) break :skip; |
| 456 | if (builtin.cpu.arch == .loongarch64) break :skip; | ||
| 457 | if (builtin.cpu.arch.isMIPS()) break :skip; | ||
| 458 | if (builtin.cpu.arch.isPowerPC64()) break :skip; | ||
| 459 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) break :skip; | ||
| 276 | 460 | ||
| 277 | _ = struct { | 461 | _ = struct { |
| 278 | export fn zig_ret_vector_2_bool() @Vector(2, bool) { | 462 | export fn zig_ret_vector_2_bool() @Vector(2, bool) { |
| ... | @@ -294,7 +478,14 @@ extern fn c_vector_2_bool(@Vector(2, bool)) void; | ... | @@ -294,7 +478,14 @@ extern fn c_vector_2_bool(@Vector(2, bool)) void; |
| 294 | extern fn c_test_vector_2_bool() void; | 478 | extern fn c_test_vector_2_bool() void; |
| 295 | 479 | ||
| 296 | test "@Vector(2, bool)" { | 480 | test "@Vector(2, bool)" { |
| 297 | if (builtin.zig_backend == .stage2_llvm and (builtin.cpu.arch != .powerpc and builtin.cpu.arch != .wasm32)) return error.SkipZigTest; | 481 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 482 | if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest; | ||
| 483 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 484 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | ||
| 485 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | ||
| 486 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | ||
| 487 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | ||
| 488 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest; | ||
| 298 | 489 | ||
| 299 | const vec = c_ret_vector_2_bool(); | 490 | const vec = c_ret_vector_2_bool(); |
| 300 | try expect(vec[0] == true); | 491 | try expect(vec[0] == true); |
| ... | @@ -308,8 +499,12 @@ test "@Vector(2, bool)" { | ... | @@ -308,8 +499,12 @@ test "@Vector(2, bool)" { |
| 308 | 499 | ||
| 309 | comptime { | 500 | comptime { |
| 310 | skip: { | 501 | skip: { |
| 311 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64) break :skip; | 502 | if (builtin.zig_backend == .stage2_wasm) break :skip; |
| 312 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isPowerPC64()) break :skip; | 503 | if (builtin.cpu.arch == .hexagon) break :skip; |
| 504 | if (builtin.cpu.arch == .loongarch64) break :skip; | ||
| 505 | if (builtin.cpu.arch.isMIPS()) break :skip; | ||
| 506 | if (builtin.cpu.arch.isPowerPC64()) break :skip; | ||
| 507 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) break :skip; | ||
| 313 | 508 | ||
| 314 | _ = struct { | 509 | _ = struct { |
| 315 | export fn zig_ret_vector_4_bool() @Vector(4, bool) { | 510 | export fn zig_ret_vector_4_bool() @Vector(4, bool) { |
| ... | @@ -335,7 +530,14 @@ extern fn c_vector_4_bool(@Vector(4, bool)) void; | ... | @@ -335,7 +530,14 @@ extern fn c_vector_4_bool(@Vector(4, bool)) void; |
| 335 | extern fn c_test_vector_4_bool() void; | 530 | extern fn c_test_vector_4_bool() void; |
| 336 | 531 | ||
| 337 | test "@Vector(4, bool)" { | 532 | test "@Vector(4, bool)" { |
| 338 | if (builtin.zig_backend == .stage2_llvm and (builtin.cpu.arch != .powerpc and builtin.cpu.arch != .wasm32)) return error.SkipZigTest; | 533 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 534 | if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest; | ||
| 535 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 536 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | ||
| 537 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | ||
| 538 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | ||
| 539 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | ||
| 540 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest; | ||
| 339 | 541 | ||
| 340 | const vec = c_ret_vector_4_bool(); | 542 | const vec = c_ret_vector_4_bool(); |
| 341 | try expect(vec[0] == true); | 543 | try expect(vec[0] == true); |
| ... | @@ -353,8 +555,12 @@ test "@Vector(4, bool)" { | ... | @@ -353,8 +555,12 @@ test "@Vector(4, bool)" { |
| 353 | 555 | ||
| 354 | comptime { | 556 | comptime { |
| 355 | skip: { | 557 | skip: { |
| 356 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64) break :skip; | 558 | if (builtin.zig_backend == .stage2_wasm) break :skip; |
| 357 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isPowerPC64()) break :skip; | 559 | if (builtin.cpu.arch == .hexagon) break :skip; |
| 560 | if (builtin.cpu.arch == .loongarch64) break :skip; | ||
| 561 | if (builtin.cpu.arch.isMIPS()) break :skip; | ||
| 562 | if (builtin.cpu.arch.isPowerPC64()) break :skip; | ||
| 563 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) break :skip; | ||
| 358 | 564 | ||
| 359 | _ = struct { | 565 | _ = struct { |
| 360 | export fn zig_ret_vector_8_bool() @Vector(8, bool) { | 566 | export fn zig_ret_vector_8_bool() @Vector(8, bool) { |
| ... | @@ -388,7 +594,14 @@ extern fn c_vector_8_bool(@Vector(8, bool)) void; | ... | @@ -388,7 +594,14 @@ extern fn c_vector_8_bool(@Vector(8, bool)) void; |
| 388 | extern fn c_test_vector_8_bool() void; | 594 | extern fn c_test_vector_8_bool() void; |
| 389 | 595 | ||
| 390 | test "@Vector(8, bool)" { | 596 | test "@Vector(8, bool)" { |
| 391 | if (builtin.zig_backend == .stage2_llvm and (builtin.cpu.arch != .powerpc and builtin.cpu.arch != .wasm32)) return error.SkipZigTest; | 597 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 598 | if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest; | ||
| 599 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 600 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | ||
| 601 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | ||
| 602 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | ||
| 603 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | ||
| 604 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest; | ||
| 392 | 605 | ||
| 393 | const vec = c_ret_vector_8_bool(); | 606 | const vec = c_ret_vector_8_bool(); |
| 394 | try expect(vec[0] == false); | 607 | try expect(vec[0] == false); |
| ... | @@ -414,8 +627,12 @@ test "@Vector(8, bool)" { | ... | @@ -414,8 +627,12 @@ test "@Vector(8, bool)" { |
| 414 | 627 | ||
| 415 | comptime { | 628 | comptime { |
| 416 | skip: { | 629 | skip: { |
| 417 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64) break :skip; | 630 | if (builtin.zig_backend == .stage2_wasm) break :skip; |
| 418 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isPowerPC64()) break :skip; | 631 | if (builtin.cpu.arch == .hexagon) break :skip; |
| 632 | if (builtin.cpu.arch == .loongarch64) break :skip; | ||
| 633 | if (builtin.cpu.arch.isMIPS()) break :skip; | ||
| 634 | if (builtin.cpu.arch.isPowerPC64()) break :skip; | ||
| 635 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) break :skip; | ||
| 419 | 636 | ||
| 420 | _ = struct { | 637 | _ = struct { |
| 421 | export fn zig_ret_vector_16_bool() @Vector(16, bool) { | 638 | export fn zig_ret_vector_16_bool() @Vector(16, bool) { |
| ... | @@ -465,7 +682,14 @@ extern fn c_vector_16_bool(@Vector(16, bool)) void; | ... | @@ -465,7 +682,14 @@ extern fn c_vector_16_bool(@Vector(16, bool)) void; |
| 465 | extern fn c_test_vector_16_bool() void; | 682 | extern fn c_test_vector_16_bool() void; |
| 466 | 683 | ||
| 467 | test "@Vector(16, bool)" { | 684 | test "@Vector(16, bool)" { |
| 468 | if (builtin.zig_backend == .stage2_llvm and (builtin.cpu.arch != .powerpc and builtin.cpu.arch != .wasm32)) return error.SkipZigTest; | 685 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 686 | if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest; | ||
| 687 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 688 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | ||
| 689 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | ||
| 690 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | ||
| 691 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | ||
| 692 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest; | ||
| 469 | 693 | ||
| 470 | const vec = c_ret_vector_16_bool(); | 694 | const vec = c_ret_vector_16_bool(); |
| 471 | try expect(vec[0] == true); | 695 | try expect(vec[0] == true); |
| ... | @@ -507,8 +731,12 @@ test "@Vector(16, bool)" { | ... | @@ -507,8 +731,12 @@ test "@Vector(16, bool)" { |
| 507 | 731 | ||
| 508 | comptime { | 732 | comptime { |
| 509 | skip: { | 733 | skip: { |
| 510 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64) break :skip; | 734 | if (builtin.zig_backend == .stage2_wasm) break :skip; |
| 511 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isPowerPC64()) break :skip; | 735 | if (builtin.cpu.arch == .hexagon) break :skip; |
| 736 | if (builtin.cpu.arch == .loongarch64) break :skip; | ||
| 737 | if (builtin.cpu.arch.isMIPS()) break :skip; | ||
| 738 | if (builtin.cpu.arch.isPowerPC64()) break :skip; | ||
| 739 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) break :skip; | ||
| 512 | 740 | ||
| 513 | _ = struct { | 741 | _ = struct { |
| 514 | export fn zig_ret_vector_32_bool() @Vector(32, bool) { | 742 | export fn zig_ret_vector_32_bool() @Vector(32, bool) { |
| ... | @@ -590,7 +818,14 @@ extern fn c_vector_32_bool(@Vector(32, bool)) void; | ... | @@ -590,7 +818,14 @@ extern fn c_vector_32_bool(@Vector(32, bool)) void; |
| 590 | extern fn c_test_vector_32_bool() void; | 818 | extern fn c_test_vector_32_bool() void; |
| 591 | 819 | ||
| 592 | test "@Vector(32, bool)" { | 820 | test "@Vector(32, bool)" { |
| 593 | if (builtin.zig_backend == .stage2_llvm and (builtin.cpu.arch != .powerpc and builtin.cpu.arch != .wasm32)) return error.SkipZigTest; | 821 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 822 | if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest; | ||
| 823 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 824 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | ||
| 825 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | ||
| 826 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | ||
| 827 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | ||
| 828 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest; | ||
| 594 | 829 | ||
| 595 | const vec = c_ret_vector_32_bool(); | 830 | const vec = c_ret_vector_32_bool(); |
| 596 | try expect(vec[0] == true); | 831 | try expect(vec[0] == true); |
| ... | @@ -664,8 +899,12 @@ test "@Vector(32, bool)" { | ... | @@ -664,8 +899,12 @@ test "@Vector(32, bool)" { |
| 664 | 899 | ||
| 665 | comptime { | 900 | comptime { |
| 666 | skip: { | 901 | skip: { |
| 667 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64) break :skip; | 902 | if (builtin.zig_backend == .stage2_wasm) break :skip; |
| 668 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isPowerPC64()) break :skip; | 903 | if (builtin.cpu.arch == .hexagon) break :skip; |
| 904 | if (builtin.cpu.arch == .loongarch64) break :skip; | ||
| 905 | if (builtin.cpu.arch.isMIPS()) break :skip; | ||
| 906 | if (builtin.cpu.arch.isPowerPC64()) break :skip; | ||
| 907 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) break :skip; | ||
| 669 | 908 | ||
| 670 | _ = struct { | 909 | _ = struct { |
| 671 | export fn zig_ret_vector_64_bool() @Vector(64, bool) { | 910 | export fn zig_ret_vector_64_bool() @Vector(64, bool) { |
| ... | @@ -811,7 +1050,12 @@ extern fn c_vector_64_bool(@Vector(64, bool)) void; | ... | @@ -811,7 +1050,12 @@ extern fn c_vector_64_bool(@Vector(64, bool)) void; |
| 811 | extern fn c_test_vector_64_bool() void; | 1050 | extern fn c_test_vector_64_bool() void; |
| 812 | 1051 | ||
| 813 | test "@Vector(64, bool)" { | 1052 | test "@Vector(64, bool)" { |
| 814 | if (builtin.zig_backend == .stage2_llvm and (builtin.cpu.arch != .powerpc and builtin.cpu.arch != .wasm32)) return error.SkipZigTest; | 1053 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 1054 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | ||
| 1055 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | ||
| 1056 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | ||
| 1057 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | ||
| 1058 | if (builtin.cpu.arch == .x86) return error.SkipZigTest; | ||
| 815 | 1059 | ||
| 816 | const vec = c_ret_vector_64_bool(); | 1060 | const vec = c_ret_vector_64_bool(); |
| 817 | try expect(vec[0] == false); | 1061 | try expect(vec[0] == false); |
| ... | @@ -949,8 +1193,12 @@ test "@Vector(64, bool)" { | ... | @@ -949,8 +1193,12 @@ test "@Vector(64, bool)" { |
| 949 | 1193 | ||
| 950 | comptime { | 1194 | comptime { |
| 951 | skip: { | 1195 | skip: { |
| 952 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64) break :skip; | 1196 | if (builtin.zig_backend == .stage2_wasm) break :skip; |
| 953 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isPowerPC64()) break :skip; | 1197 | if (builtin.cpu.arch == .hexagon) break :skip; |
| 1198 | if (builtin.cpu.arch == .loongarch64) break :skip; | ||
| 1199 | if (builtin.cpu.arch.isMIPS()) break :skip; | ||
| 1200 | if (builtin.cpu.arch.isPowerPC64()) break :skip; | ||
| 1201 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) break :skip; | ||
| 954 | 1202 | ||
| 955 | _ = struct { | 1203 | _ = struct { |
| 956 | export fn zig_ret_vector_128_bool() @Vector(128, bool) { | 1204 | export fn zig_ret_vector_128_bool() @Vector(128, bool) { |
| ... | @@ -1224,7 +1472,12 @@ extern fn c_vector_128_bool(@Vector(128, bool)) void; | ... | @@ -1224,7 +1472,12 @@ extern fn c_vector_128_bool(@Vector(128, bool)) void; |
| 1224 | extern fn c_test_vector_128_bool() void; | 1472 | extern fn c_test_vector_128_bool() void; |
| 1225 | 1473 | ||
| 1226 | test "@Vector(128, bool)" { | 1474 | test "@Vector(128, bool)" { |
| 1227 | if (builtin.zig_backend == .stage2_llvm and (builtin.cpu.arch != .powerpc and builtin.cpu.arch != .wasm32)) return error.SkipZigTest; | 1475 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 1476 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | ||
| 1477 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | ||
| 1478 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | ||
| 1479 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | ||
| 1480 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest; | ||
| 1228 | 1481 | ||
| 1229 | const vec = c_ret_vector_128_bool(); | 1482 | const vec = c_ret_vector_128_bool(); |
| 1230 | try expect(vec[0] == false); | 1483 | try expect(vec[0] == false); |
| ... | @@ -1490,8 +1743,12 @@ test "@Vector(128, bool)" { | ... | @@ -1490,8 +1743,12 @@ test "@Vector(128, bool)" { |
| 1490 | 1743 | ||
| 1491 | comptime { | 1744 | comptime { |
| 1492 | skip: { | 1745 | skip: { |
| 1493 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64) break :skip; | 1746 | if (builtin.zig_backend == .stage2_wasm) break :skip; |
| 1494 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isPowerPC64()) break :skip; | 1747 | if (builtin.cpu.arch == .hexagon) break :skip; |
| 1748 | if (builtin.cpu.arch == .loongarch64) break :skip; | ||
| 1749 | if (builtin.cpu.arch.isMIPS()) break :skip; | ||
| 1750 | if (builtin.cpu.arch.isPowerPC64()) break :skip; | ||
| 1751 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) break :skip; | ||
| 1495 | 1752 | ||
| 1496 | _ = struct { | 1753 | _ = struct { |
| 1497 | export fn zig_ret_vector_256_bool() @Vector(256, bool) { | 1754 | export fn zig_ret_vector_256_bool() @Vector(256, bool) { |
| ... | @@ -2021,7 +2278,12 @@ extern fn c_vector_256_bool(@Vector(256, bool)) void; | ... | @@ -2021,7 +2278,12 @@ extern fn c_vector_256_bool(@Vector(256, bool)) void; |
| 2021 | extern fn c_test_vector_256_bool() void; | 2278 | extern fn c_test_vector_256_bool() void; |
| 2022 | 2279 | ||
| 2023 | test "@Vector(256, bool)" { | 2280 | test "@Vector(256, bool)" { |
| 2024 | if (builtin.zig_backend == .stage2_llvm and (builtin.cpu.arch != .powerpc and builtin.cpu.arch != .wasm32)) return error.SkipZigTest; | 2281 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 2282 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | ||
| 2283 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | ||
| 2284 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | ||
| 2285 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | ||
| 2286 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest; | ||
| 2025 | 2287 | ||
| 2026 | const vec = c_ret_vector_256_bool(); | 2288 | const vec = c_ret_vector_256_bool(); |
| 2027 | try expect(vec[0] == true); | 2289 | try expect(vec[0] == true); |
| ... | @@ -2543,8 +2805,12 @@ test "@Vector(256, bool)" { | ... | @@ -2543,8 +2805,12 @@ test "@Vector(256, bool)" { |
| 2543 | 2805 | ||
| 2544 | comptime { | 2806 | comptime { |
| 2545 | skip: { | 2807 | skip: { |
| 2546 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64) break :skip; | 2808 | if (builtin.zig_backend == .stage2_wasm) break :skip; |
| 2547 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isPowerPC64()) break :skip; | 2809 | if (builtin.cpu.arch == .hexagon) break :skip; |
| 2810 | if (builtin.cpu.arch == .loongarch64) break :skip; | ||
| 2811 | if (builtin.cpu.arch.isMIPS()) break :skip; | ||
| 2812 | if (builtin.cpu.arch.isPowerPC64()) break :skip; | ||
| 2813 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) break :skip; | ||
| 2548 | 2814 | ||
| 2549 | _ = struct { | 2815 | _ = struct { |
| 2550 | export fn zig_ret_vector_512_bool() @Vector(512, bool) { | 2816 | export fn zig_ret_vector_512_bool() @Vector(512, bool) { |
| ... | @@ -3586,7 +3852,12 @@ extern fn c_vector_512_bool(@Vector(512, bool)) void; | ... | @@ -3586,7 +3852,12 @@ extern fn c_vector_512_bool(@Vector(512, bool)) void; |
| 3586 | extern fn c_test_vector_512_bool() void; | 3852 | extern fn c_test_vector_512_bool() void; |
| 3587 | 3853 | ||
| 3588 | test "@Vector(512, bool)" { | 3854 | test "@Vector(512, bool)" { |
| 3589 | if (builtin.zig_backend == .stage2_llvm and (builtin.cpu.arch != .powerpc and builtin.cpu.arch != .wasm32)) return error.SkipZigTest; | 3855 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 3856 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | ||
| 3857 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | ||
| 3858 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | ||
| 3859 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | ||
| 3860 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest; | ||
| 3590 | 3861 | ||
| 3591 | const vec = c_ret_vector_512_bool(); | 3862 | const vec = c_ret_vector_512_bool(); |
| 3592 | try expect(vec[0] == false); | 3863 | try expect(vec[0] == false); |
| ... | @@ -4660,7 +4931,7 @@ test "@Vector(2, u8)" { | ... | @@ -4660,7 +4931,7 @@ test "@Vector(2, u8)" { |
| 4660 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 4931 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 4661 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | 4932 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; |
| 4662 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 4933 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 4663 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64) return error.SkipZigTest; | 4934 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64 and builtin.os.tag == .windows) return error.SkipZigTest; |
| 4664 | 4935 | ||
| 4665 | const v = c_ret_vector_2_u8(); | 4936 | const v = c_ret_vector_2_u8(); |
| 4666 | try expect(v[0] == 9); | 4937 | try expect(v[0] == 9); |
| ... | @@ -4689,7 +4960,6 @@ test "@Vector(3, u8)" { | ... | @@ -4689,7 +4960,6 @@ test "@Vector(3, u8)" { |
| 4689 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 4960 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 4690 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | 4961 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; |
| 4691 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 4962 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 4692 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64 and builtin.os.tag != .windows) return error.SkipZigTest; | ||
| 4693 | 4963 | ||
| 4694 | const v = c_ret_vector_3_u8(); | 4964 | const v = c_ret_vector_3_u8(); |
| 4695 | try expect(v[0] == 19); | 4965 | try expect(v[0] == 19); |
| ... | @@ -4732,7 +5002,7 @@ test "@Vector(4, u8)" { | ... | @@ -4732,7 +5002,7 @@ test "@Vector(4, u8)" { |
| 4732 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 5002 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 4733 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | 5003 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; |
| 4734 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 5004 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 4735 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64) return error.SkipZigTest; | 5005 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64 and builtin.os.tag == .windows) return error.SkipZigTest; |
| 4736 | 5006 | ||
| 4737 | const v = c_ret_vector_4_u8(); | 5007 | const v = c_ret_vector_4_u8(); |
| 4738 | try expect(v[0] == 41); | 5008 | try expect(v[0] == 41); |
| ... | @@ -4766,7 +5036,6 @@ test "@Vector(6, u8)" { | ... | @@ -4766,7 +5036,6 @@ test "@Vector(6, u8)" { |
| 4766 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 5036 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 4767 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | 5037 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; |
| 4768 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 5038 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 4769 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64 and builtin.os.tag != .windows) return error.SkipZigTest; | ||
| 4770 | 5039 | ||
| 4771 | const v = c_ret_vector_6_u8(); | 5040 | const v = c_ret_vector_6_u8(); |
| 4772 | try expect(v[0] == 53); | 5041 | try expect(v[0] == 53); |
| ... | @@ -4956,7 +5225,6 @@ test "@Vector(24, u8)" { | ... | @@ -4956,7 +5225,6 @@ test "@Vector(24, u8)" { |
| 4956 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 5225 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 4957 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | 5226 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; |
| 4958 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 5227 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 4959 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 4960 | 5228 | ||
| 4961 | const v = c_ret_vector_24_u8(); | 5229 | const v = c_ret_vector_24_u8(); |
| 4962 | try expect(v[0] == 57); | 5230 | try expect(v[0] == 57); |
| ... | @@ -5040,7 +5308,6 @@ test "@Vector(32, u8)" { | ... | @@ -5040,7 +5308,6 @@ test "@Vector(32, u8)" { |
| 5040 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; | 5308 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; |
| 5041 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 5309 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 5042 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 5310 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 5043 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 5044 | 5311 | ||
| 5045 | const v = c_ret_vector_32_u8(); | 5312 | const v = c_ret_vector_32_u8(); |
| 5046 | try expect(v[0] == 69); | 5313 | try expect(v[0] == 69); |
| ... | @@ -5150,7 +5417,6 @@ test "@Vector(48, u8)" { | ... | @@ -5150,7 +5417,6 @@ test "@Vector(48, u8)" { |
| 5150 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 5417 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 5151 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | 5418 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; |
| 5152 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 5419 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 5153 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 5154 | 5420 | ||
| 5155 | const v = c_ret_vector_48_u8(); | 5421 | const v = c_ret_vector_48_u8(); |
| 5156 | try expect(v[0] == 29); | 5422 | try expect(v[0] == 29); |
| ... | @@ -5293,7 +5559,6 @@ test "@Vector(64, u8)" { | ... | @@ -5293,7 +5559,6 @@ test "@Vector(64, u8)" { |
| 5293 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; | 5559 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; |
| 5294 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 5560 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 5295 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 5561 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 5296 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 5297 | 5562 | ||
| 5298 | const v = c_ret_vector_64_u8(); | 5563 | const v = c_ret_vector_64_u8(); |
| 5299 | try expect(v[0] == 53); | 5564 | try expect(v[0] == 53); |
| ... | @@ -5488,7 +5753,6 @@ test "@Vector(96, u8)" { | ... | @@ -5488,7 +5753,6 @@ test "@Vector(96, u8)" { |
| 5488 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 5753 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 5489 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | 5754 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; |
| 5490 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 5755 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 5491 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 5492 | 5756 | ||
| 5493 | const v = c_ret_vector_96_u8(); | 5757 | const v = c_ret_vector_96_u8(); |
| 5494 | try expect(v[0] == 82); | 5758 | try expect(v[0] == 82); |
| ... | @@ -5751,7 +6015,6 @@ test "@Vector(128, u8)" { | ... | @@ -5751,7 +6015,6 @@ test "@Vector(128, u8)" { |
| 5751 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 6015 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 5752 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; | 6016 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; |
| 5753 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 6017 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 5754 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 5755 | 6018 | ||
| 5756 | const v = c_ret_vector_128_u8(); | 6019 | const v = c_ret_vector_128_u8(); |
| 5757 | try expect(v[0] == 30); | 6020 | try expect(v[0] == 30); |
| ... | @@ -6116,7 +6379,6 @@ test "@Vector(192, u8)" { | ... | @@ -6116,7 +6379,6 @@ test "@Vector(192, u8)" { |
| 6116 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 6379 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 6117 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | 6380 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; |
| 6118 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 6381 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 6119 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 6120 | 6382 | ||
| 6121 | const v = c_ret_vector_192_u8(); | 6383 | const v = c_ret_vector_192_u8(); |
| 6122 | try expect(v[0] == 70); | 6384 | try expect(v[0] == 70); |
| ... | @@ -6617,7 +6879,6 @@ test "@Vector(256, u8)" { | ... | @@ -6617,7 +6879,6 @@ test "@Vector(256, u8)" { |
| 6617 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 6879 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 6618 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; | 6880 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; |
| 6619 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 6881 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 6620 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 6621 | 6882 | ||
| 6622 | const v = c_ret_vector_256_u8(); | 6883 | const v = c_ret_vector_256_u8(); |
| 6623 | try expect(v[0] == 66); | 6884 | try expect(v[0] == 66); |
| ... | @@ -7322,7 +7583,6 @@ test "@Vector(384, u8)" { | ... | @@ -7322,7 +7583,6 @@ test "@Vector(384, u8)" { |
| 7322 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 7583 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 7323 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | 7584 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; |
| 7324 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 7585 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 7325 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 7326 | 7586 | ||
| 7327 | const v = c_ret_vector_384_u8(); | 7587 | const v = c_ret_vector_384_u8(); |
| 7328 | try expect(v[0] == 46); | 7588 | try expect(v[0] == 46); |
| ... | @@ -8299,7 +8559,6 @@ test "@Vector(512, u8)" { | ... | @@ -8299,7 +8559,6 @@ test "@Vector(512, u8)" { |
| 8299 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 8559 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 8300 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; | 8560 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; |
| 8301 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 8561 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 8302 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 8303 | 8562 | ||
| 8304 | const v = c_ret_vector_512_u8(); | 8563 | const v = c_ret_vector_512_u8(); |
| 8305 | try expect(v[0] == 38); | 8564 | try expect(v[0] == 38); |
| ... | @@ -8893,7 +9152,7 @@ test "@Vector(2, u16)" { | ... | @@ -8893,7 +9152,7 @@ test "@Vector(2, u16)" { |
| 8893 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 9152 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 8894 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | 9153 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; |
| 8895 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 9154 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 8896 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64) return error.SkipZigTest; | 9155 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64 and builtin.os.tag == .windows) return error.SkipZigTest; |
| 8897 | 9156 | ||
| 8898 | const v = c_ret_vector_2_u16(); | 9157 | const v = c_ret_vector_2_u16(); |
| 8899 | try expect(v[0] == 9); | 9158 | try expect(v[0] == 9); |
| ... | @@ -8921,7 +9180,6 @@ test "@Vector(3, u16)" { | ... | @@ -8921,7 +9180,6 @@ test "@Vector(3, u16)" { |
| 8921 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 9180 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 8922 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | 9181 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; |
| 8923 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 9182 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 8924 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64 and builtin.os.tag != .windows) return error.SkipZigTest; | ||
| 8925 | 9183 | ||
| 8926 | const v = c_ret_vector_3_u16(); | 9184 | const v = c_ret_vector_3_u16(); |
| 8927 | try expect(v[0] == 19); | 9185 | try expect(v[0] == 19); |
| ... | @@ -9070,7 +9328,6 @@ test "@Vector(12, u16)" { | ... | @@ -9070,7 +9328,6 @@ test "@Vector(12, u16)" { |
| 9070 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 9328 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 9071 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | 9329 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; |
| 9072 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 9330 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 9073 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 9074 | 9331 | ||
| 9075 | const v = c_ret_vector_12_u16(); | 9332 | const v = c_ret_vector_12_u16(); |
| 9076 | try expect(v[0] == 121); | 9333 | try expect(v[0] == 121); |
| ... | @@ -9120,7 +9377,6 @@ test "@Vector(16, u16)" { | ... | @@ -9120,7 +9377,6 @@ test "@Vector(16, u16)" { |
| 9120 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; | 9377 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; |
| 9121 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 9378 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 9122 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 9379 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 9123 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 9124 | 9380 | ||
| 9125 | const v = c_ret_vector_16_u16(); | 9381 | const v = c_ret_vector_16_u16(); |
| 9126 | try expect(v[0] == 177); | 9382 | try expect(v[0] == 177); |
| ... | @@ -9186,7 +9442,6 @@ test "@Vector(24, u16)" { | ... | @@ -9186,7 +9442,6 @@ test "@Vector(24, u16)" { |
| 9186 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 9442 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 9187 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | 9443 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; |
| 9188 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 9444 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 9189 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 9190 | 9445 | ||
| 9191 | const v = c_ret_vector_24_u16(); | 9446 | const v = c_ret_vector_24_u16(); |
| 9192 | try expect(v[0] == 257); | 9447 | try expect(v[0] == 257); |
| ... | @@ -9270,7 +9525,6 @@ test "@Vector(32, u16)" { | ... | @@ -9270,7 +9525,6 @@ test "@Vector(32, u16)" { |
| 9270 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; | 9525 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; |
| 9271 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 9526 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 9272 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 9527 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 9273 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 9274 | 9528 | ||
| 9275 | const v = c_ret_vector_32_u16(); | 9529 | const v = c_ret_vector_32_u16(); |
| 9276 | try expect(v[0] == 369); | 9530 | try expect(v[0] == 369); |
| ... | @@ -9380,7 +9634,6 @@ test "@Vector(48, u16)" { | ... | @@ -9380,7 +9634,6 @@ test "@Vector(48, u16)" { |
| 9380 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 9634 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 9381 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | 9635 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; |
| 9382 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 9636 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 9383 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 9384 | 9637 | ||
| 9385 | const v = c_ret_vector_48_u16(); | 9638 | const v = c_ret_vector_48_u16(); |
| 9386 | try expect(v[0] == 529); | 9639 | try expect(v[0] == 529); |
| ... | @@ -9524,7 +9777,6 @@ test "@Vector(64, u16)" { | ... | @@ -9524,7 +9777,6 @@ test "@Vector(64, u16)" { |
| 9524 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 9777 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 9525 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; | 9778 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; |
| 9526 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 9779 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 9527 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 9528 | 9780 | ||
| 9529 | const v = c_ret_vector_64_u16(); | 9781 | const v = c_ret_vector_64_u16(); |
| 9530 | try expect(v[0] == 753); | 9782 | try expect(v[0] == 753); |
| ... | @@ -9719,7 +9971,6 @@ test "@Vector(96, u16)" { | ... | @@ -9719,7 +9971,6 @@ test "@Vector(96, u16)" { |
| 9719 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 9971 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 9720 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | 9972 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; |
| 9721 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 9973 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 9722 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 9723 | 9974 | ||
| 9724 | const v = c_ret_vector_96_u16(); | 9975 | const v = c_ret_vector_96_u16(); |
| 9725 | try expect(v[0] == 1082); | 9976 | try expect(v[0] == 1082); |
| ... | @@ -9982,7 +10233,6 @@ test "@Vector(128, u16)" { | ... | @@ -9982,7 +10233,6 @@ test "@Vector(128, u16)" { |
| 9982 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 10233 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 9983 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; | 10234 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; |
| 9984 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 10235 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 9985 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 9986 | 10236 | ||
| 9987 | const v = c_ret_vector_128_u16(); | 10237 | const v = c_ret_vector_128_u16(); |
| 9988 | try expect(v[0] == 1530); | 10238 | try expect(v[0] == 1530); |
| ... | @@ -10347,7 +10597,6 @@ test "@Vector(192, u16)" { | ... | @@ -10347,7 +10597,6 @@ test "@Vector(192, u16)" { |
| 10347 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 10597 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 10348 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | 10598 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; |
| 10349 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 10599 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 10350 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 10351 | 10600 | ||
| 10352 | const v = c_ret_vector_192_u16(); | 10601 | const v = c_ret_vector_192_u16(); |
| 10353 | try expect(v[0] == 2170); | 10602 | try expect(v[0] == 2170); |
| ... | @@ -10848,7 +11097,6 @@ test "@Vector(256, u16)" { | ... | @@ -10848,7 +11097,6 @@ test "@Vector(256, u16)" { |
| 10848 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 11097 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 10849 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; | 11098 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; |
| 10850 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 11099 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 10851 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 10852 | 11100 | ||
| 10853 | const v = c_ret_vector_256_u16(); | 11101 | const v = c_ret_vector_256_u16(); |
| 10854 | try expect(v[0] == 3066); | 11102 | try expect(v[0] == 3066); |
| ... | @@ -11265,7 +11513,6 @@ test "@Vector(6, u32)" { | ... | @@ -11265,7 +11513,6 @@ test "@Vector(6, u32)" { |
| 11265 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 11513 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 11266 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | 11514 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; |
| 11267 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 11515 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 11268 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 11269 | 11516 | ||
| 11270 | const v = c_ret_vector_6_u32(); | 11517 | const v = c_ret_vector_6_u32(); |
| 11271 | try expect(v[0] == 53); | 11518 | try expect(v[0] == 53); |
| ... | @@ -11301,7 +11548,6 @@ test "@Vector(8, u32)" { | ... | @@ -11301,7 +11548,6 @@ test "@Vector(8, u32)" { |
| 11301 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; | 11548 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; |
| 11302 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 11549 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 11303 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 11550 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 11304 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 11305 | 11551 | ||
| 11306 | const v = c_ret_vector_8_u32(); | 11552 | const v = c_ret_vector_8_u32(); |
| 11307 | try expect(v[0] == 81); | 11553 | try expect(v[0] == 81); |
| ... | @@ -11344,7 +11590,6 @@ test "@Vector(12, u32)" { | ... | @@ -11344,7 +11590,6 @@ test "@Vector(12, u32)" { |
| 11344 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 11590 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 11345 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | 11591 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; |
| 11346 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 11592 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 11347 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 11348 | 11593 | ||
| 11349 | const v = c_ret_vector_12_u32(); | 11594 | const v = c_ret_vector_12_u32(); |
| 11350 | try expect(v[0] == 121); | 11595 | try expect(v[0] == 121); |
| ... | @@ -11394,7 +11639,6 @@ test "@Vector(16, u32)" { | ... | @@ -11394,7 +11639,6 @@ test "@Vector(16, u32)" { |
| 11394 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; | 11639 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; |
| 11395 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 11640 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 11396 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 11641 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 11397 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 11398 | 11642 | ||
| 11399 | const v = c_ret_vector_16_u32(); | 11643 | const v = c_ret_vector_16_u32(); |
| 11400 | try expect(v[0] == 177); | 11644 | try expect(v[0] == 177); |
| ... | @@ -11460,7 +11704,6 @@ test "@Vector(24, u32)" { | ... | @@ -11460,7 +11704,6 @@ test "@Vector(24, u32)" { |
| 11460 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 11704 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 11461 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | 11705 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; |
| 11462 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 11706 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 11463 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 11464 | 11707 | ||
| 11465 | const v = c_ret_vector_24_u32(); | 11708 | const v = c_ret_vector_24_u32(); |
| 11466 | try expect(v[0] == 257); | 11709 | try expect(v[0] == 257); |
| ... | @@ -11545,7 +11788,6 @@ test "@Vector(32, u32)" { | ... | @@ -11545,7 +11788,6 @@ test "@Vector(32, u32)" { |
| 11545 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 11788 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 11546 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; | 11789 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; |
| 11547 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 11790 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 11548 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 11549 | 11791 | ||
| 11550 | const v = c_ret_vector_32_u32(); | 11792 | const v = c_ret_vector_32_u32(); |
| 11551 | try expect(v[0] == 369); | 11793 | try expect(v[0] == 369); |
| ... | @@ -11655,7 +11897,6 @@ test "@Vector(48, u32)" { | ... | @@ -11655,7 +11897,6 @@ test "@Vector(48, u32)" { |
| 11655 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 11897 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 11656 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | 11898 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; |
| 11657 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 11899 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 11658 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 11659 | 11900 | ||
| 11660 | const v = c_ret_vector_48_u32(); | 11901 | const v = c_ret_vector_48_u32(); |
| 11661 | try expect(v[0] == 529); | 11902 | try expect(v[0] == 529); |
| ... | @@ -11799,7 +12040,6 @@ test "@Vector(64, u32)" { | ... | @@ -11799,7 +12040,6 @@ test "@Vector(64, u32)" { |
| 11799 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 12040 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 11800 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; | 12041 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; |
| 11801 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 12042 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 11802 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 11803 | 12043 | ||
| 11804 | const v = c_ret_vector_64_u32(); | 12044 | const v = c_ret_vector_64_u32(); |
| 11805 | try expect(v[0] == 753); | 12045 | try expect(v[0] == 753); |
| ... | @@ -11994,7 +12234,6 @@ test "@Vector(96, u32)" { | ... | @@ -11994,7 +12234,6 @@ test "@Vector(96, u32)" { |
| 11994 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 12234 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 11995 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | 12235 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; |
| 11996 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 12236 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 11997 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 11998 | 12237 | ||
| 11999 | const v = c_ret_vector_96_u32(); | 12238 | const v = c_ret_vector_96_u32(); |
| 12000 | try expect(v[0] == 1082); | 12239 | try expect(v[0] == 1082); |
| ... | @@ -12257,7 +12496,6 @@ test "@Vector(128, u32)" { | ... | @@ -12257,7 +12496,6 @@ test "@Vector(128, u32)" { |
| 12257 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 12496 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 12258 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; | 12497 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; |
| 12259 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 12498 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 12260 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 12261 | 12499 | ||
| 12262 | const v = c_ret_vector_128_u32(); | 12500 | const v = c_ret_vector_128_u32(); |
| 12263 | try expect(v[0] == 1530); | 12501 | try expect(v[0] == 1530); |
| ... | @@ -12414,8 +12652,6 @@ extern fn c_vector_1_u64(@Vector(1, u64), usize) void; | ... | @@ -12414,8 +12652,6 @@ extern fn c_vector_1_u64(@Vector(1, u64), usize) void; |
| 12414 | extern fn c_test_vector_1_u64() void; | 12652 | extern fn c_test_vector_1_u64() void; |
| 12415 | 12653 | ||
| 12416 | test "@Vector(1, u64)" { | 12654 | test "@Vector(1, u64)" { |
| 12417 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64 and builtin.os.tag != .windows) return error.SkipZigTest; | ||
| 12418 | |||
| 12419 | const v = c_ret_vector_1_u64(); | 12655 | const v = c_ret_vector_1_u64(); |
| 12420 | try expect(v[0] == 3); | 12656 | try expect(v[0] == 3); |
| 12421 | c_vector_1_u64(.{4}, 1); | 12657 | c_vector_1_u64(.{4}, 1); |
| ... | @@ -12464,7 +12700,6 @@ test "@Vector(3, u64)" { | ... | @@ -12464,7 +12700,6 @@ test "@Vector(3, u64)" { |
| 12464 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 12700 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 12465 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | 12701 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; |
| 12466 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 12702 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 12467 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 12468 | 12703 | ||
| 12469 | const v = c_ret_vector_3_u64(); | 12704 | const v = c_ret_vector_3_u64(); |
| 12470 | try expect(v[0] == 19); | 12705 | try expect(v[0] == 19); |
| ... | @@ -12493,7 +12728,6 @@ test "@Vector(4, u64)" { | ... | @@ -12493,7 +12728,6 @@ test "@Vector(4, u64)" { |
| 12493 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; | 12728 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; |
| 12494 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 12729 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 12495 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 12730 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 12496 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 12497 | 12731 | ||
| 12498 | const v = c_ret_vector_4_u64(); | 12732 | const v = c_ret_vector_4_u64(); |
| 12499 | try expect(v[0] == 33); | 12733 | try expect(v[0] == 33); |
| ... | @@ -12560,7 +12794,6 @@ test "@Vector(8, u64)" { | ... | @@ -12560,7 +12794,6 @@ test "@Vector(8, u64)" { |
| 12560 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; | 12794 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; |
| 12561 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 12795 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 12562 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 12796 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 12563 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 12564 | 12797 | ||
| 12565 | const v = c_ret_vector_8_u64(); | 12798 | const v = c_ret_vector_8_u64(); |
| 12566 | try expect(v[0] == 81); | 12799 | try expect(v[0] == 81); |
| ... | @@ -12652,7 +12885,6 @@ test "@Vector(16, u64)" { | ... | @@ -12652,7 +12885,6 @@ test "@Vector(16, u64)" { |
| 12652 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 12885 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 12653 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; | 12886 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; |
| 12654 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 12887 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 12655 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 12656 | 12888 | ||
| 12657 | const v = c_ret_vector_16_u64(); | 12889 | const v = c_ret_vector_16_u64(); |
| 12658 | try expect(v[0] == 177); | 12890 | try expect(v[0] == 177); |
| ... | @@ -12801,7 +13033,6 @@ test "@Vector(32, u64)" { | ... | @@ -12801,7 +13033,6 @@ test "@Vector(32, u64)" { |
| 12801 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 13033 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 12802 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; | 13034 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; |
| 12803 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 13035 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 12804 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 12805 | 13036 | ||
| 12806 | const v = c_ret_vector_32_u64(); | 13037 | const v = c_ret_vector_32_u64(); |
| 12807 | try expect(v[0] == 369); | 13038 | try expect(v[0] == 369); |
| ... | @@ -13053,7 +13284,6 @@ test "@Vector(64, u64)" { | ... | @@ -13053,7 +13284,6 @@ test "@Vector(64, u64)" { |
| 13053 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 13284 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 13054 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; | 13285 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; |
| 13055 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 13286 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 13056 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 13057 | 13287 | ||
| 13058 | const v = c_ret_vector_64_u64(); | 13288 | const v = c_ret_vector_64_u64(); |
| 13059 | try expect(v[0] == 753); | 13289 | try expect(v[0] == 753); |
| ... | @@ -13147,7 +13377,6 @@ test "@Vector(1, f32)" { | ... | @@ -13147,7 +13377,6 @@ test "@Vector(1, f32)" { |
| 13147 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 13377 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 13148 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | 13378 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; |
| 13149 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 13379 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 13150 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64 and builtin.os.tag != .windows) return error.SkipZigTest; | ||
| 13151 | 13380 | ||
| 13152 | const v = c_ret_vector_1_f32(); | 13381 | const v = c_ret_vector_1_f32(); |
| 13153 | try expect(v[0] == 3); | 13382 | try expect(v[0] == 3); |
| ... | @@ -13269,7 +13498,6 @@ test "@Vector(6, f32)" { | ... | @@ -13269,7 +13498,6 @@ test "@Vector(6, f32)" { |
| 13269 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 13498 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 13270 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | 13499 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; |
| 13271 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 13500 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 13272 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 13273 | 13501 | ||
| 13274 | const v = c_ret_vector_6_f32(); | 13502 | const v = c_ret_vector_6_f32(); |
| 13275 | try expect(v[0] == 53); | 13503 | try expect(v[0] == 53); |
| ... | @@ -13306,7 +13534,6 @@ test "@Vector(8, f32)" { | ... | @@ -13306,7 +13534,6 @@ test "@Vector(8, f32)" { |
| 13306 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 13534 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 13307 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; | 13535 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; |
| 13308 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 13536 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 13309 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 13310 | 13537 | ||
| 13311 | const v = c_ret_vector_8_f32(); | 13538 | const v = c_ret_vector_8_f32(); |
| 13312 | try expect(v[0] == 81); | 13539 | try expect(v[0] == 81); |
| ... | @@ -13349,7 +13576,6 @@ test "@Vector(12, f32)" { | ... | @@ -13349,7 +13576,6 @@ test "@Vector(12, f32)" { |
| 13349 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 13576 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 13350 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | 13577 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; |
| 13351 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 13578 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 13352 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 13353 | 13579 | ||
| 13354 | const v = c_ret_vector_12_f32(); | 13580 | const v = c_ret_vector_12_f32(); |
| 13355 | try expect(v[0] == 121); | 13581 | try expect(v[0] == 121); |
| ... | @@ -13400,7 +13626,6 @@ test "@Vector(16, f32)" { | ... | @@ -13400,7 +13626,6 @@ test "@Vector(16, f32)" { |
| 13400 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 13626 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 13401 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; | 13627 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; |
| 13402 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 13628 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 13403 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 13404 | 13629 | ||
| 13405 | const v = c_ret_vector_16_f32(); | 13630 | const v = c_ret_vector_16_f32(); |
| 13406 | try expect(v[0] == 177); | 13631 | try expect(v[0] == 177); |
| ... | @@ -13466,7 +13691,6 @@ test "@Vector(24, f32)" { | ... | @@ -13466,7 +13691,6 @@ test "@Vector(24, f32)" { |
| 13466 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 13691 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 13467 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | 13692 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; |
| 13468 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 13693 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 13469 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 13470 | 13694 | ||
| 13471 | const v = c_ret_vector_24_f32(); | 13695 | const v = c_ret_vector_24_f32(); |
| 13472 | try expect(v[0] == 257); | 13696 | try expect(v[0] == 257); |
| ... | @@ -13551,7 +13775,6 @@ test "@Vector(32, f32)" { | ... | @@ -13551,7 +13775,6 @@ test "@Vector(32, f32)" { |
| 13551 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 13775 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 13552 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; | 13776 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; |
| 13553 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 13777 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 13554 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 13555 | 13778 | ||
| 13556 | const v = c_ret_vector_32_f32(); | 13779 | const v = c_ret_vector_32_f32(); |
| 13557 | try expect(v[0] == 369); | 13780 | try expect(v[0] == 369); |
| ... | @@ -13661,7 +13884,6 @@ test "@Vector(48, f32)" { | ... | @@ -13661,7 +13884,6 @@ test "@Vector(48, f32)" { |
| 13661 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 13884 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 13662 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | 13885 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; |
| 13663 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 13886 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 13664 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 13665 | 13887 | ||
| 13666 | const v = c_ret_vector_48_f32(); | 13888 | const v = c_ret_vector_48_f32(); |
| 13667 | try expect(v[0] == 529); | 13889 | try expect(v[0] == 529); |
| ... | @@ -13805,7 +14027,6 @@ test "@Vector(64, f32)" { | ... | @@ -13805,7 +14027,6 @@ test "@Vector(64, f32)" { |
| 13805 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 14027 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 13806 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; | 14028 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; |
| 13807 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 14029 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 13808 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 13809 | 14030 | ||
| 13810 | const v = c_ret_vector_64_f32(); | 14031 | const v = c_ret_vector_64_f32(); |
| 13811 | try expect(v[0] == 753); | 14032 | try expect(v[0] == 753); |
| ... | @@ -14000,7 +14221,6 @@ test "@Vector(96, f32)" { | ... | @@ -14000,7 +14221,6 @@ test "@Vector(96, f32)" { |
| 14000 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 14221 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 14001 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | 14222 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; |
| 14002 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 14223 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 14003 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 14004 | 14224 | ||
| 14005 | const v = c_ret_vector_96_f32(); | 14225 | const v = c_ret_vector_96_f32(); |
| 14006 | try expect(v[0] == 1082); | 14226 | try expect(v[0] == 1082); |
| ... | @@ -14263,7 +14483,6 @@ test "@Vector(128, f32)" { | ... | @@ -14263,7 +14483,6 @@ test "@Vector(128, f32)" { |
| 14263 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 14483 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 14264 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; | 14484 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; |
| 14265 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 14485 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 14266 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 14267 | 14486 | ||
| 14268 | const v = c_ret_vector_128_f32(); | 14487 | const v = c_ret_vector_128_f32(); |
| 14269 | try expect(v[0] == 1530); | 14488 | try expect(v[0] == 1530); |
| ... | @@ -14471,7 +14690,6 @@ test "@Vector(3, f64)" { | ... | @@ -14471,7 +14690,6 @@ test "@Vector(3, f64)" { |
| 14471 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 14690 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 14472 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | 14691 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; |
| 14473 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 14692 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 14474 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 14475 | 14693 | ||
| 14476 | const v = c_ret_vector_3_f64(); | 14694 | const v = c_ret_vector_3_f64(); |
| 14477 | try expect(v[0] == 19); | 14695 | try expect(v[0] == 19); |
| ... | @@ -14500,8 +14718,6 @@ test "@Vector(4, f64)" { | ... | @@ -14500,8 +14718,6 @@ test "@Vector(4, f64)" { |
| 14500 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 14718 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 14501 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; | 14719 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; |
| 14502 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 14720 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 14503 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 14504 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/35899 | ||
| 14505 | 14721 | ||
| 14506 | const v = c_ret_vector_4_f64(); | 14722 | const v = c_ret_vector_4_f64(); |
| 14507 | try expect(v[0] == 33); | 14723 | try expect(v[0] == 33); |
| ... | @@ -14534,7 +14750,6 @@ test "@Vector(6, f64)" { | ... | @@ -14534,7 +14750,6 @@ test "@Vector(6, f64)" { |
| 14534 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 14750 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 14535 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | 14751 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; |
| 14536 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 14752 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 14537 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 14538 | 14753 | ||
| 14539 | const v = c_ret_vector_6_f64(); | 14754 | const v = c_ret_vector_6_f64(); |
| 14540 | try expect(v[0] == 53); | 14755 | try expect(v[0] == 53); |
| ... | @@ -14570,8 +14785,6 @@ test "@Vector(8, f64)" { | ... | @@ -14570,8 +14785,6 @@ test "@Vector(8, f64)" { |
| 14570 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 14785 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 14571 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; | 14786 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; |
| 14572 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 14787 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 14573 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 14574 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/35899 | ||
| 14575 | 14788 | ||
| 14576 | const v = c_ret_vector_8_f64(); | 14789 | const v = c_ret_vector_8_f64(); |
| 14577 | try expect(v[0] == 81); | 14790 | try expect(v[0] == 81); |
| ... | @@ -14614,7 +14827,6 @@ test "@Vector(12, f64)" { | ... | @@ -14614,7 +14827,6 @@ test "@Vector(12, f64)" { |
| 14614 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 14827 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 14615 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | 14828 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; |
| 14616 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 14829 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 14617 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 14618 | 14830 | ||
| 14619 | const v = c_ret_vector_12_f64(); | 14831 | const v = c_ret_vector_12_f64(); |
| 14620 | try expect(v[0] == 121); | 14832 | try expect(v[0] == 121); |
| ... | @@ -14665,7 +14877,6 @@ test "@Vector(16, f64)" { | ... | @@ -14665,7 +14877,6 @@ test "@Vector(16, f64)" { |
| 14665 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 14877 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 14666 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; | 14878 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; |
| 14667 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 14879 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 14668 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 14669 | 14880 | ||
| 14670 | const v = c_ret_vector_16_f64(); | 14881 | const v = c_ret_vector_16_f64(); |
| 14671 | try expect(v[0] == 177); | 14882 | try expect(v[0] == 177); |
| ... | @@ -14731,7 +14942,6 @@ test "@Vector(24, f64)" { | ... | @@ -14731,7 +14942,6 @@ test "@Vector(24, f64)" { |
| 14731 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 14942 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 14732 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | 14943 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; |
| 14733 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 14944 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 14734 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 14735 | 14945 | ||
| 14736 | const v = c_ret_vector_24_f64(); | 14946 | const v = c_ret_vector_24_f64(); |
| 14737 | try expect(v[0] == 257); | 14947 | try expect(v[0] == 257); |
| ... | @@ -14816,7 +15026,6 @@ test "@Vector(32, f64)" { | ... | @@ -14816,7 +15026,6 @@ test "@Vector(32, f64)" { |
| 14816 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 15026 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 14817 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; | 15027 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; |
| 14818 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 15028 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 14819 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 14820 | 15029 | ||
| 14821 | const v = c_ret_vector_32_f64(); | 15030 | const v = c_ret_vector_32_f64(); |
| 14822 | try expect(v[0] == 369); | 15031 | try expect(v[0] == 369); |
| ... | @@ -14926,7 +15135,6 @@ test "@Vector(48, f64)" { | ... | @@ -14926,7 +15135,6 @@ test "@Vector(48, f64)" { |
| 14926 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 15135 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 14927 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | 15136 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; |
| 14928 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 15137 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 14929 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 14930 | 15138 | ||
| 14931 | const v = c_ret_vector_48_f64(); | 15139 | const v = c_ret_vector_48_f64(); |
| 14932 | try expect(v[0] == 529); | 15140 | try expect(v[0] == 529); |
| ... | @@ -15070,7 +15278,6 @@ test "@Vector(64, f64)" { | ... | @@ -15070,7 +15278,6 @@ test "@Vector(64, f64)" { |
| 15070 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 15278 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 15071 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; | 15279 | if (builtin.cpu.arch.isMIPS32()) return error.SkipZigTest; |
| 15072 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; | 15280 | if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest; |
| 15073 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 15074 | 15281 | ||
| 15075 | const v = c_ret_vector_64_f64(); | 15282 | const v = c_ret_vector_64_f64(); |
| 15076 | try expect(v[0] == 753); | 15283 | try expect(v[0] == 753); |
| ... | @@ -15165,7 +15372,6 @@ extern fn c_test_struct_u8() void; | ... | @@ -15165,7 +15372,6 @@ extern fn c_test_struct_u8() void; |
| 15165 | test "struct u8" { | 15372 | test "struct u8" { |
| 15166 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | 15373 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; |
| 15167 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; | 15374 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; |
| 15168 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 15169 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest; | 15375 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest; |
| 15170 | 15376 | ||
| 15171 | const s = c_ret_struct_u8(); | 15377 | const s = c_ret_struct_u8(); |
| ... | @@ -15196,8 +15402,7 @@ test "struct u8, u8" { | ... | @@ -15196,8 +15402,7 @@ test "struct u8, u8" { |
| 15196 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 15402 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 15197 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 15403 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 15198 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | 15404 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; |
| 15199 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | 15405 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; |
| 15200 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 15201 | if (builtin.cpu.arch == .x86) return error.SkipZigTest; | 15406 | if (builtin.cpu.arch == .x86) return error.SkipZigTest; |
| 15202 | 15407 | ||
| 15203 | const s = c_ret_struct_u8_u8(); | 15408 | const s = c_ret_struct_u8_u8(); |
| ... | @@ -15231,8 +15436,7 @@ test "struct u8, u8, u8" { | ... | @@ -15231,8 +15436,7 @@ test "struct u8, u8, u8" { |
| 15231 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 15436 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 15232 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 15437 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 15233 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | 15438 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; |
| 15234 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | 15439 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; |
| 15235 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 15236 | if (builtin.cpu.arch == .x86) return error.SkipZigTest; | 15440 | if (builtin.cpu.arch == .x86) return error.SkipZigTest; |
| 15237 | 15441 | ||
| 15238 | const s = c_ret_struct_u8_u8_u8(); | 15442 | const s = c_ret_struct_u8_u8_u8(); |
| ... | @@ -15269,8 +15473,7 @@ test "struct u8, u8, u8, u8" { | ... | @@ -15269,8 +15473,7 @@ test "struct u8, u8, u8, u8" { |
| 15269 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 15473 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 15270 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 15474 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 15271 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | 15475 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; |
| 15272 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | 15476 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; |
| 15273 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 15274 | if (builtin.cpu.arch == .x86) return error.SkipZigTest; | 15477 | if (builtin.cpu.arch == .x86) return error.SkipZigTest; |
| 15275 | 15478 | ||
| 15276 | const s = c_ret_struct_u8_u8_u8_u8(); | 15479 | const s = c_ret_struct_u8_u8_u8_u8(); |
| ... | @@ -15301,7 +15504,6 @@ extern fn c_test_struct_u16() void; | ... | @@ -15301,7 +15504,6 @@ extern fn c_test_struct_u16() void; |
| 15301 | test "struct u16" { | 15504 | test "struct u16" { |
| 15302 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | 15505 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; |
| 15303 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; | 15506 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; |
| 15304 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 15305 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest; | 15507 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest; |
| 15306 | 15508 | ||
| 15307 | const s = c_ret_struct_u16(); | 15509 | const s = c_ret_struct_u16(); |
| ... | @@ -15332,8 +15534,7 @@ test "struct u16, u16" { | ... | @@ -15332,8 +15534,7 @@ test "struct u16, u16" { |
| 15332 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 15534 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 15333 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 15535 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 15334 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | 15536 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; |
| 15335 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | 15537 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; |
| 15336 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 15337 | if (builtin.cpu.arch == .x86) return error.SkipZigTest; | 15538 | if (builtin.cpu.arch == .x86) return error.SkipZigTest; |
| 15338 | 15539 | ||
| 15339 | const s = c_ret_struct_u16_u16(); | 15540 | const s = c_ret_struct_u16_u16(); |
| ... | @@ -15367,9 +15568,8 @@ test "struct u16, u16, u16" { | ... | @@ -15367,9 +15568,8 @@ test "struct u16, u16, u16" { |
| 15367 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 15568 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 15368 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 15569 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 15369 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | 15570 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; |
| 15370 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | 15571 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; |
| 15371 | if (builtin.cpu.arch.isRiscv32()) return error.SkipZigTest; | 15572 | if (builtin.cpu.arch.isRiscv32()) return error.SkipZigTest; |
| 15372 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 15373 | if (builtin.cpu.arch == .x86) return error.SkipZigTest; | 15573 | if (builtin.cpu.arch == .x86) return error.SkipZigTest; |
| 15374 | 15574 | ||
| 15375 | const s = c_ret_struct_u16_u16_u16(); | 15575 | const s = c_ret_struct_u16_u16_u16(); |
| ... | @@ -15406,9 +15606,8 @@ test "struct u16, u16, u16, u16" { | ... | @@ -15406,9 +15606,8 @@ test "struct u16, u16, u16, u16" { |
| 15406 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 15606 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 15407 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 15607 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 15408 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | 15608 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; |
| 15409 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | 15609 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; |
| 15410 | if (builtin.cpu.arch.isRiscv32()) return error.SkipZigTest; | 15610 | if (builtin.cpu.arch.isRiscv32()) return error.SkipZigTest; |
| 15411 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 15412 | if (builtin.cpu.arch == .x86) return error.SkipZigTest; | 15611 | if (builtin.cpu.arch == .x86) return error.SkipZigTest; |
| 15413 | 15612 | ||
| 15414 | const s = c_ret_struct_u16_u16_u16_u16(); | 15613 | const s = c_ret_struct_u16_u16_u16_u16(); |
| ... | @@ -15439,7 +15638,6 @@ extern fn c_test_struct_u32() void; | ... | @@ -15439,7 +15638,6 @@ extern fn c_test_struct_u32() void; |
| 15439 | test "struct u32" { | 15638 | test "struct u32" { |
| 15440 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | 15639 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; |
| 15441 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; | 15640 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; |
| 15442 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 15443 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest; | 15641 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest; |
| 15444 | 15642 | ||
| 15445 | const s = c_ret_struct_u32(); | 15643 | const s = c_ret_struct_u32(); |
| ... | @@ -15469,9 +15667,8 @@ extern fn c_test_struct_u32_u32() void; | ... | @@ -15469,9 +15667,8 @@ extern fn c_test_struct_u32_u32() void; |
| 15469 | test "struct u32, u32" { | 15667 | test "struct u32, u32" { |
| 15470 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 15668 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 15471 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | 15669 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; |
| 15472 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | 15670 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; |
| 15473 | if (builtin.cpu.arch.isRiscv32()) return error.SkipZigTest; | 15671 | if (builtin.cpu.arch.isRiscv32()) return error.SkipZigTest; |
| 15474 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 15475 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest; | 15672 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest; |
| 15476 | 15673 | ||
| 15477 | const s = c_ret_struct_u32_u32(); | 15674 | const s = c_ret_struct_u32_u32(); |
| ... | @@ -15505,8 +15702,7 @@ test "struct u32, u32, u32" { | ... | @@ -15505,8 +15702,7 @@ test "struct u32, u32, u32" { |
| 15505 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 15702 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 15506 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 15703 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 15507 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | 15704 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; |
| 15508 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | 15705 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; |
| 15509 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 15510 | 15706 | ||
| 15511 | const s = c_ret_struct_u32_u32_u32(); | 15707 | const s = c_ret_struct_u32_u32_u32(); |
| 15512 | try expect(s.a == 8); | 15708 | try expect(s.a == 8); |
| ... | @@ -15542,8 +15738,7 @@ test "struct u32, u32, u32, u32" { | ... | @@ -15542,8 +15738,7 @@ test "struct u32, u32, u32, u32" { |
| 15542 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 15738 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 15543 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 15739 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 15544 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | 15740 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; |
| 15545 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | 15741 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; |
| 15546 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 15547 | 15742 | ||
| 15548 | const s = c_ret_struct_u32_u32_u32_u32(); | 15743 | const s = c_ret_struct_u32_u32_u32_u32(); |
| 15549 | try expect(s.a == 10); | 15744 | try expect(s.a == 10); |
| ... | @@ -15573,7 +15768,6 @@ extern fn c_test_struct_u64() void; | ... | @@ -15573,7 +15768,6 @@ extern fn c_test_struct_u64() void; |
| 15573 | test "struct u64" { | 15768 | test "struct u64" { |
| 15574 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; | 15769 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; |
| 15575 | if (builtin.cpu.arch.isRiscv32()) return error.SkipZigTest; | 15770 | if (builtin.cpu.arch.isRiscv32()) return error.SkipZigTest; |
| 15576 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 15577 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest; | 15771 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest; |
| 15578 | 15772 | ||
| 15579 | const s = c_ret_struct_u64(); | 15773 | const s = c_ret_struct_u64(); |
| ... | @@ -15651,7 +15845,6 @@ extern fn c_test_struct_u64_u64() void; | ... | @@ -15651,7 +15845,6 @@ extern fn c_test_struct_u64_u64() void; |
| 15651 | test "struct u64, u64" { | 15845 | test "struct u64, u64" { |
| 15652 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 15846 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 15653 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; | 15847 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; |
| 15654 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 15655 | 15848 | ||
| 15656 | const s = c_ret_struct_u64_u64(); | 15849 | const s = c_ret_struct_u64_u64(); |
| 15657 | try expect(s.a == 21); | 15850 | try expect(s.a == 21); |
| ... | @@ -15691,8 +15884,7 @@ extern fn c_test_struct_u64_u64_u64() void; | ... | @@ -15691,8 +15884,7 @@ extern fn c_test_struct_u64_u64_u64() void; |
| 15691 | test "struct u64, u64, u64" { | 15884 | test "struct u64, u64, u64" { |
| 15692 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 15885 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 15693 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 15886 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 15694 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | 15887 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; |
| 15695 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 15696 | 15888 | ||
| 15697 | const s = c_ret_struct_u64_u64_u64(); | 15889 | const s = c_ret_struct_u64_u64_u64(); |
| 15698 | try expect(s.a == 8); | 15890 | try expect(s.a == 8); |
| ... | @@ -15727,8 +15919,7 @@ extern fn c_test_struct_u64_u64_u64_u64() void; | ... | @@ -15727,8 +15919,7 @@ extern fn c_test_struct_u64_u64_u64_u64() void; |
| 15727 | test "struct u64, u64, u64, u64" { | 15919 | test "struct u64, u64, u64, u64" { |
| 15728 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 15920 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 15729 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 15921 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 15730 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | 15922 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; |
| 15731 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 15732 | 15923 | ||
| 15733 | const s = c_ret_struct_u64_u64_u64_u64(); | 15924 | const s = c_ret_struct_u64_u64_u64_u64(); |
| 15734 | try expect(s.a == 10); | 15925 | try expect(s.a == 10); |
| ... | @@ -15757,8 +15948,7 @@ extern fn c_test_struct_f32() void; | ... | @@ -15757,8 +15948,7 @@ extern fn c_test_struct_f32() void; |
| 15757 | 15948 | ||
| 15758 | test "struct f32" { | 15949 | test "struct f32" { |
| 15759 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | 15950 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; |
| 15760 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; | 15951 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; |
| 15761 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 15762 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest; | 15952 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest; |
| 15763 | 15953 | ||
| 15764 | const s = c_ret_struct_f32(); | 15954 | const s = c_ret_struct_f32(); |
| ... | @@ -15791,7 +15981,6 @@ test "struct f32, f32" { | ... | @@ -15791,7 +15981,6 @@ test "struct f32, f32" { |
| 15791 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | 15981 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; |
| 15792 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | 15982 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; |
| 15793 | if (builtin.cpu.arch.isRiscv32()) return error.SkipZigTest; | 15983 | if (builtin.cpu.arch.isRiscv32()) return error.SkipZigTest; |
| 15794 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 15795 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest; | 15984 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest; |
| 15796 | 15985 | ||
| 15797 | const s = c_ret_struct_f32_f32(); | 15986 | const s = c_ret_struct_f32_f32(); |
| ... | @@ -15827,7 +16016,6 @@ test "struct f32, f32, f32" { | ... | @@ -15827,7 +16016,6 @@ test "struct f32, f32, f32" { |
| 15827 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 16016 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 15828 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | 16017 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; |
| 15829 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | 16018 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; |
| 15830 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 15831 | 16019 | ||
| 15832 | const s = c_ret_struct_f32_f32_f32(); | 16020 | const s = c_ret_struct_f32_f32_f32(); |
| 15833 | try expect(s.a == 8); | 16021 | try expect(s.a == 8); |
| ... | @@ -15865,7 +16053,6 @@ test "struct f32, f32, f32, f32" { | ... | @@ -15865,7 +16053,6 @@ test "struct f32, f32, f32, f32" { |
| 15865 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 16053 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 15866 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | 16054 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; |
| 15867 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | 16055 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; |
| 15868 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 15869 | 16056 | ||
| 15870 | const s = c_ret_struct_f32_f32_f32_f32(); | 16057 | const s = c_ret_struct_f32_f32_f32_f32(); |
| 15871 | try expect(s.a == 10); | 16058 | try expect(s.a == 10); |
| ... | @@ -15905,7 +16092,6 @@ test "struct f32, f32, f32, f32, f32" { | ... | @@ -15905,7 +16092,6 @@ test "struct f32, f32, f32, f32, f32" { |
| 15905 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 16092 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 15906 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | 16093 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; |
| 15907 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | 16094 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; |
| 15908 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 15909 | 16095 | ||
| 15910 | const s = c_ret_struct_f32_f32_f32_f32_f32(); | 16096 | const s = c_ret_struct_f32_f32_f32_f32_f32(); |
| 15911 | try expect(s.a == 12); | 16097 | try expect(s.a == 12); |
| ... | @@ -15917,31 +16103,408 @@ test "struct f32, f32, f32, f32, f32" { | ... | @@ -15917,31 +16103,408 @@ test "struct f32, f32, f32, f32, f32" { |
| 15917 | c_test_struct_f32_f32_f32_f32_f32(); | 16103 | c_test_struct_f32_f32_f32_f32_f32(); |
| 15918 | } | 16104 | } |
| 15919 | 16105 | ||
| 15920 | const Struct_f32a8 = extern struct { | 16106 | const Struct_void_f32 = extern struct { |
| 15921 | a: f32 align(8), | 16107 | _: void = {}, |
| 16108 | a: f32, | ||
| 15922 | }; | 16109 | }; |
| 15923 | 16110 | ||
| 15924 | export fn zig_ret_struct_f32a8() Struct_f32a8 { | 16111 | export fn zig_ret_struct_void_f32() Struct_void_f32 { |
| 15925 | return .{ .a = 1.25 }; | 16112 | return .{ .a = 1 }; |
| 15926 | } | 16113 | } |
| 15927 | export fn zig_struct_f32a8(s: Struct_f32a8, f: f32) void { | 16114 | export fn zig_struct_void_f32(s: Struct_void_f32, i: usize) void { |
| 15928 | expect(s.a == 2.75) catch @panic("test failure"); | 16115 | expect(s.a == 2) catch @panic("test failure"); |
| 15929 | expect(f == 3.5) catch @panic("test failure"); | 16116 | expect(i == 3) catch @panic("test failure"); |
| 15930 | } | 16117 | } |
| 15931 | 16118 | ||
| 15932 | extern fn c_ret_struct_f32a8() Struct_f32a8; | 16119 | extern fn c_ret_struct_void_f32() Struct_void_f32; |
| 15933 | extern fn c_struct_f32a8(Struct_f32a8, f32) void; | 16120 | extern fn c_struct_void_f32(Struct_void_f32, usize) void; |
| 15934 | extern fn c_test_struct_f32a8() void; | 16121 | extern fn c_test_struct_void_f32() void; |
| 15935 | 16122 | ||
| 15936 | test "struct f32 align(8)" { | 16123 | test "struct void, f32" { |
| 15937 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 15938 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | ||
| 15939 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | ||
| 15940 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | 16124 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; |
| 15941 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | 16125 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; |
| 15942 | if (builtin.cpu.arch.isRiscv32()) return error.SkipZigTest; | 16126 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest; |
| 15943 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | 16127 | |
| 15944 | if (builtin.cpu.arch == .x86) return error.SkipZigTest; | 16128 | const s = c_ret_struct_void_f32(); |
| 16129 | try expect(s.a == 4); | ||
| 16130 | c_struct_void_f32(.{ .a = 5 }, 6); | ||
| 16131 | c_test_struct_void_f32(); | ||
| 16132 | } | ||
| 16133 | |||
| 16134 | const Struct_array_1_f32 = extern struct { | ||
| 16135 | a: [1]f32, | ||
| 16136 | }; | ||
| 16137 | |||
| 16138 | export fn zig_ret_struct_array_1_f32() Struct_array_1_f32 { | ||
| 16139 | return .{ .a = .{1} }; | ||
| 16140 | } | ||
| 16141 | export fn zig_struct_array_1_f32(s: Struct_array_1_f32, i: usize) void { | ||
| 16142 | expect(s.a[0] == 2) catch @panic("test failure"); | ||
| 16143 | expect(i == 3) catch @panic("test failure"); | ||
| 16144 | } | ||
| 16145 | |||
| 16146 | extern fn c_ret_struct_array_1_f32() Struct_array_1_f32; | ||
| 16147 | extern fn c_struct_array_1_f32(Struct_array_1_f32, usize) void; | ||
| 16148 | extern fn c_test_struct_array_1_f32() void; | ||
| 16149 | |||
| 16150 | test "struct [1]f32" { | ||
| 16151 | if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest; | ||
| 16152 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 16153 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | ||
| 16154 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | ||
| 16155 | if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest; | ||
| 16156 | |||
| 16157 | const s = c_ret_struct_array_1_f32(); | ||
| 16158 | try expect(s.a[0] == 4); | ||
| 16159 | c_struct_array_1_f32(.{ .a = .{5} }, 6); | ||
| 16160 | c_test_struct_array_1_f32(); | ||
| 16161 | } | ||
| 16162 | |||
| 16163 | const Struct_array_2_f32 = extern struct { | ||
| 16164 | a: [2]f32, | ||
| 16165 | }; | ||
| 16166 | |||
| 16167 | export fn zig_ret_struct_array_2_f32() Struct_array_2_f32 { | ||
| 16168 | return .{ .a = .{ 1, 2 } }; | ||
| 16169 | } | ||
| 16170 | export fn zig_struct_array_2_f32(s: Struct_array_2_f32, i: usize) void { | ||
| 16171 | expect(s.a[0] == 3) catch @panic("test failure"); | ||
| 16172 | expect(s.a[1] == 4) catch @panic("test failure"); | ||
| 16173 | expect(i == 5) catch @panic("test failure"); | ||
| 16174 | } | ||
| 16175 | |||
| 16176 | extern fn c_ret_struct_array_2_f32() Struct_array_2_f32; | ||
| 16177 | extern fn c_struct_array_2_f32(Struct_array_2_f32, usize) void; | ||
| 16178 | extern fn c_test_struct_array_2_f32() void; | ||
| 16179 | |||
| 16180 | test "struct [2]f32" { | ||
| 16181 | if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest; | ||
| 16182 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 16183 | if (builtin.cpu.arch == .loongarch64 and builtin.abi.float() == .hard) return error.SkipZigTest; | ||
| 16184 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | ||
| 16185 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | ||
| 16186 | if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest; | ||
| 16187 | |||
| 16188 | const s = c_ret_struct_array_2_f32(); | ||
| 16189 | try expect(s.a[0] == 6); | ||
| 16190 | try expect(s.a[1] == 7); | ||
| 16191 | c_struct_array_2_f32(.{ .a = .{ 8, 9 } }, 10); | ||
| 16192 | c_test_struct_array_2_f32(); | ||
| 16193 | } | ||
| 16194 | |||
| 16195 | const Struct_array_3_f32 = extern struct { | ||
| 16196 | a: [3]f32, | ||
| 16197 | }; | ||
| 16198 | |||
| 16199 | export fn zig_ret_struct_array_3_f32() Struct_array_3_f32 { | ||
| 16200 | return .{ .a = .{ 1, 2, 3 } }; | ||
| 16201 | } | ||
| 16202 | export fn zig_struct_array_3_f32(s: Struct_array_3_f32, i: usize) void { | ||
| 16203 | expect(s.a[0] == 4) catch @panic("test failure"); | ||
| 16204 | expect(s.a[1] == 5) catch @panic("test failure"); | ||
| 16205 | expect(s.a[2] == 6) catch @panic("test failure"); | ||
| 16206 | expect(i == 7) catch @panic("test failure"); | ||
| 16207 | } | ||
| 16208 | |||
| 16209 | extern fn c_ret_struct_array_3_f32() Struct_array_3_f32; | ||
| 16210 | extern fn c_struct_array_3_f32(Struct_array_3_f32, usize) void; | ||
| 16211 | extern fn c_test_struct_array_3_f32() void; | ||
| 16212 | |||
| 16213 | test "struct [3]f32" { | ||
| 16214 | if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest; | ||
| 16215 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 16216 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | ||
| 16217 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | ||
| 16218 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | ||
| 16219 | |||
| 16220 | const s = c_ret_struct_array_3_f32(); | ||
| 16221 | try expect(s.a[0] == 8); | ||
| 16222 | try expect(s.a[1] == 9); | ||
| 16223 | try expect(s.a[2] == 10); | ||
| 16224 | c_struct_array_3_f32(.{ .a = .{ 11, 12, 13 } }, 14); | ||
| 16225 | c_test_struct_array_3_f32(); | ||
| 16226 | } | ||
| 16227 | |||
| 16228 | const Struct_array_4_f32 = extern struct { | ||
| 16229 | a: [4]f32, | ||
| 16230 | }; | ||
| 16231 | |||
| 16232 | export fn zig_ret_struct_array_4_f32() Struct_array_4_f32 { | ||
| 16233 | return .{ .a = .{ 1, 2, 3, 4 } }; | ||
| 16234 | } | ||
| 16235 | export fn zig_struct_array_4_f32(s: Struct_array_4_f32, i: usize) void { | ||
| 16236 | expect(s.a[0] == 5) catch @panic("test failure"); | ||
| 16237 | expect(s.a[1] == 6) catch @panic("test failure"); | ||
| 16238 | expect(s.a[2] == 7) catch @panic("test failure"); | ||
| 16239 | expect(s.a[3] == 8) catch @panic("test failure"); | ||
| 16240 | expect(i == 9) catch @panic("test failure"); | ||
| 16241 | } | ||
| 16242 | |||
| 16243 | extern fn c_ret_struct_array_4_f32() Struct_array_4_f32; | ||
| 16244 | extern fn c_struct_array_4_f32(Struct_array_4_f32, usize) void; | ||
| 16245 | extern fn c_test_struct_array_4_f32() void; | ||
| 16246 | |||
| 16247 | test "struct [4]f32" { | ||
| 16248 | if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest; | ||
| 16249 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 16250 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | ||
| 16251 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | ||
| 16252 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | ||
| 16253 | |||
| 16254 | const s = c_ret_struct_array_4_f32(); | ||
| 16255 | try expect(s.a[0] == 10); | ||
| 16256 | try expect(s.a[1] == 11); | ||
| 16257 | try expect(s.a[2] == 12); | ||
| 16258 | try expect(s.a[3] == 13); | ||
| 16259 | c_struct_array_4_f32(.{ .a = .{ 14, 15, 16, 17 } }, 18); | ||
| 16260 | c_test_struct_array_4_f32(); | ||
| 16261 | } | ||
| 16262 | |||
| 16263 | const Struct_array_5_f32 = extern struct { | ||
| 16264 | a: [5]f32, | ||
| 16265 | }; | ||
| 16266 | |||
| 16267 | export fn zig_ret_struct_array_5_f32() Struct_array_5_f32 { | ||
| 16268 | return .{ .a = .{ 1, 2, 3, 4, 5 } }; | ||
| 16269 | } | ||
| 16270 | export fn zig_struct_array_5_f32(s: Struct_array_5_f32, i: usize) void { | ||
| 16271 | expect(s.a[0] == 6) catch @panic("test failure"); | ||
| 16272 | expect(s.a[1] == 7) catch @panic("test failure"); | ||
| 16273 | expect(s.a[2] == 8) catch @panic("test failure"); | ||
| 16274 | expect(s.a[3] == 9) catch @panic("test failure"); | ||
| 16275 | expect(s.a[4] == 10) catch @panic("test failure"); | ||
| 16276 | expect(i == 11) catch @panic("test failure"); | ||
| 16277 | } | ||
| 16278 | |||
| 16279 | extern fn c_ret_struct_array_5_f32() Struct_array_5_f32; | ||
| 16280 | extern fn c_struct_array_5_f32(Struct_array_5_f32, usize) void; | ||
| 16281 | extern fn c_test_struct_array_5_f32() void; | ||
| 16282 | |||
| 16283 | test "struct [5]f32" { | ||
| 16284 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 16285 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | ||
| 16286 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | ||
| 16287 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | ||
| 16288 | |||
| 16289 | const s = c_ret_struct_array_5_f32(); | ||
| 16290 | try expect(s.a[0] == 12); | ||
| 16291 | try expect(s.a[1] == 13); | ||
| 16292 | try expect(s.a[2] == 14); | ||
| 16293 | try expect(s.a[3] == 15); | ||
| 16294 | try expect(s.a[4] == 16); | ||
| 16295 | c_struct_array_5_f32(.{ .a = .{ 17, 18, 19, 20, 21 } }, 22); | ||
| 16296 | c_test_struct_array_5_f32(); | ||
| 16297 | } | ||
| 16298 | |||
| 16299 | const Struct_array_0_sentinel_f32 = extern struct { | ||
| 16300 | a: [0:0x1e1]f32, | ||
| 16301 | }; | ||
| 16302 | |||
| 16303 | export fn zig_ret_struct_array_0_sentinel_f32() Struct_array_0_sentinel_f32 { | ||
| 16304 | return .{ .a = .{} }; | ||
| 16305 | } | ||
| 16306 | export fn zig_struct_array_0_sentinel_f32(s: Struct_array_0_sentinel_f32, i: usize) void { | ||
| 16307 | var sentinel_index: usize = 0; | ||
| 16308 | _ = &sentinel_index; | ||
| 16309 | expect(s.a[sentinel_index] == 0x1e1) catch @panic("test failure"); | ||
| 16310 | expect(i == 1) catch @panic("test failure"); | ||
| 16311 | } | ||
| 16312 | |||
| 16313 | extern fn c_ret_struct_array_0_sentinel_f32() Struct_array_0_sentinel_f32; | ||
| 16314 | extern fn c_struct_array_0_sentinel_f32(Struct_array_0_sentinel_f32, usize) void; | ||
| 16315 | extern fn c_test_struct_array_0_sentinel_f32() void; | ||
| 16316 | |||
| 16317 | test "struct [0:sentinel]f32" { | ||
| 16318 | if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest; | ||
| 16319 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 16320 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | ||
| 16321 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | ||
| 16322 | if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest; | ||
| 16323 | |||
| 16324 | var sentinel_index: usize = 0; | ||
| 16325 | _ = &sentinel_index; | ||
| 16326 | const s = c_ret_struct_array_0_sentinel_f32(); | ||
| 16327 | try expect(s.a[sentinel_index] == 0x1e1); | ||
| 16328 | c_struct_array_0_sentinel_f32(.{ .a = .{} }, 2); | ||
| 16329 | c_test_struct_array_0_sentinel_f32(); | ||
| 16330 | } | ||
| 16331 | |||
| 16332 | const Struct_array_1_sentinel_f32 = extern struct { | ||
| 16333 | a: [1:0x1e1]f32, | ||
| 16334 | }; | ||
| 16335 | |||
| 16336 | export fn zig_ret_struct_array_1_sentinel_f32() Struct_array_1_sentinel_f32 { | ||
| 16337 | return .{ .a = .{1} }; | ||
| 16338 | } | ||
| 16339 | export fn zig_struct_array_1_sentinel_f32(s: Struct_array_1_sentinel_f32, i: usize) void { | ||
| 16340 | var sentinel_index: usize = 1; | ||
| 16341 | _ = &sentinel_index; | ||
| 16342 | expect(s.a[0] == 2) catch @panic("test failure"); | ||
| 16343 | expect(s.a[sentinel_index] == 0x1e1) catch @panic("test failure"); | ||
| 16344 | expect(i == 3) catch @panic("test failure"); | ||
| 16345 | } | ||
| 16346 | |||
| 16347 | extern fn c_ret_struct_array_1_sentinel_f32() Struct_array_1_sentinel_f32; | ||
| 16348 | extern fn c_struct_array_1_sentinel_f32(Struct_array_1_sentinel_f32, usize) void; | ||
| 16349 | extern fn c_test_struct_array_1_sentinel_f32() void; | ||
| 16350 | |||
| 16351 | test "struct [1:sentinel]f32" { | ||
| 16352 | if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest; | ||
| 16353 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 16354 | if (builtin.cpu.arch == .loongarch64 and builtin.abi.float() == .hard) return error.SkipZigTest; | ||
| 16355 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | ||
| 16356 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | ||
| 16357 | if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest; | ||
| 16358 | |||
| 16359 | var sentinel_index: usize = 1; | ||
| 16360 | _ = &sentinel_index; | ||
| 16361 | const s = c_ret_struct_array_1_sentinel_f32(); | ||
| 16362 | try expect(s.a[0] == 4); | ||
| 16363 | try expect(s.a[sentinel_index] == 0x1e1); | ||
| 16364 | c_struct_array_1_sentinel_f32(.{ .a = .{5} }, 6); | ||
| 16365 | c_test_struct_array_1_sentinel_f32(); | ||
| 16366 | } | ||
| 16367 | |||
| 16368 | const Struct_array_2_sentinel_f32 = extern struct { | ||
| 16369 | a: [2:0x1e1]f32, | ||
| 16370 | }; | ||
| 16371 | |||
| 16372 | export fn zig_ret_struct_array_2_sentinel_f32() Struct_array_2_sentinel_f32 { | ||
| 16373 | return .{ .a = .{ 1, 2 } }; | ||
| 16374 | } | ||
| 16375 | export fn zig_struct_array_2_sentinel_f32(s: Struct_array_2_sentinel_f32, i: usize) void { | ||
| 16376 | var sentinel_index: usize = 2; | ||
| 16377 | _ = &sentinel_index; | ||
| 16378 | expect(s.a[0] == 3) catch @panic("test failure"); | ||
| 16379 | expect(s.a[1] == 4) catch @panic("test failure"); | ||
| 16380 | expect(s.a[sentinel_index] == 0x1e1) catch @panic("test failure"); | ||
| 16381 | expect(i == 5) catch @panic("test failure"); | ||
| 16382 | } | ||
| 16383 | |||
| 16384 | extern fn c_ret_struct_array_2_sentinel_f32() Struct_array_2_sentinel_f32; | ||
| 16385 | extern fn c_struct_array_2_sentinel_f32(Struct_array_2_sentinel_f32, usize) void; | ||
| 16386 | extern fn c_test_struct_array_2_sentinel_f32() void; | ||
| 16387 | |||
| 16388 | test "struct [2:sentinel]f32" { | ||
| 16389 | if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest; | ||
| 16390 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 16391 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | ||
| 16392 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | ||
| 16393 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | ||
| 16394 | |||
| 16395 | var sentinel_index: usize = 2; | ||
| 16396 | _ = &sentinel_index; | ||
| 16397 | const s = c_ret_struct_array_2_sentinel_f32(); | ||
| 16398 | try expect(s.a[0] == 6); | ||
| 16399 | try expect(s.a[1] == 7); | ||
| 16400 | try expect(s.a[sentinel_index] == 0x1e1); | ||
| 16401 | c_struct_array_2_sentinel_f32(.{ .a = .{ 8, 9 } }, 10); | ||
| 16402 | c_test_struct_array_2_sentinel_f32(); | ||
| 16403 | } | ||
| 16404 | |||
| 16405 | const Struct_array_3_sentinel_f32 = extern struct { | ||
| 16406 | a: [3:0x1e1]f32, | ||
| 16407 | }; | ||
| 16408 | |||
| 16409 | export fn zig_ret_struct_array_3_sentinel_f32() Struct_array_3_sentinel_f32 { | ||
| 16410 | return .{ .a = .{ 1, 2, 3 } }; | ||
| 16411 | } | ||
| 16412 | export fn zig_struct_array_3_sentinel_f32(s: Struct_array_3_sentinel_f32, i: usize) void { | ||
| 16413 | var sentinel_index: usize = 3; | ||
| 16414 | _ = &sentinel_index; | ||
| 16415 | expect(s.a[0] == 4) catch @panic("test failure"); | ||
| 16416 | expect(s.a[1] == 5) catch @panic("test failure"); | ||
| 16417 | expect(s.a[2] == 6) catch @panic("test failure"); | ||
| 16418 | expect(s.a[sentinel_index] == 0x1e1) catch @panic("test failure"); | ||
| 16419 | expect(i == 7) catch @panic("test failure"); | ||
| 16420 | } | ||
| 16421 | |||
| 16422 | extern fn c_ret_struct_array_3_sentinel_f32() Struct_array_3_sentinel_f32; | ||
| 16423 | extern fn c_struct_array_3_sentinel_f32(Struct_array_3_sentinel_f32, usize) void; | ||
| 16424 | extern fn c_test_struct_array_3_sentinel_f32() void; | ||
| 16425 | |||
| 16426 | test "struct [3:sentinel]f32" { | ||
| 16427 | if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest; | ||
| 16428 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 16429 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | ||
| 16430 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | ||
| 16431 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | ||
| 16432 | |||
| 16433 | var sentinel_index: usize = 3; | ||
| 16434 | _ = &sentinel_index; | ||
| 16435 | const s = c_ret_struct_array_3_sentinel_f32(); | ||
| 16436 | try expect(s.a[0] == 8); | ||
| 16437 | try expect(s.a[1] == 9); | ||
| 16438 | try expect(s.a[2] == 10); | ||
| 16439 | try expect(s.a[sentinel_index] == 0x1e1); | ||
| 16440 | c_struct_array_3_sentinel_f32(.{ .a = .{ 11, 12, 13 } }, 14); | ||
| 16441 | c_test_struct_array_3_sentinel_f32(); | ||
| 16442 | } | ||
| 16443 | |||
| 16444 | const Struct_array_4_sentinel_f32 = extern struct { | ||
| 16445 | a: [4:0x1e1]f32, | ||
| 16446 | }; | ||
| 16447 | |||
| 16448 | export fn zig_ret_struct_array_4_sentinel_f32() Struct_array_4_sentinel_f32 { | ||
| 16449 | return .{ .a = .{ 1, 2, 3, 4 } }; | ||
| 16450 | } | ||
| 16451 | export fn zig_struct_array_4_sentinel_f32(s: Struct_array_4_sentinel_f32, i: usize) void { | ||
| 16452 | var sentinel_index: usize = 4; | ||
| 16453 | _ = &sentinel_index; | ||
| 16454 | expect(s.a[0] == 5) catch @panic("test failure"); | ||
| 16455 | expect(s.a[1] == 6) catch @panic("test failure"); | ||
| 16456 | expect(s.a[2] == 7) catch @panic("test failure"); | ||
| 16457 | expect(s.a[3] == 8) catch @panic("test failure"); | ||
| 16458 | expect(s.a[sentinel_index] == 0x1e1) catch @panic("test failure"); | ||
| 16459 | expect(i == 9) catch @panic("test failure"); | ||
| 16460 | } | ||
| 16461 | |||
| 16462 | extern fn c_ret_struct_array_4_sentinel_f32() Struct_array_4_sentinel_f32; | ||
| 16463 | extern fn c_struct_array_4_sentinel_f32(Struct_array_4_sentinel_f32, usize) void; | ||
| 16464 | extern fn c_test_struct_array_4_sentinel_f32() void; | ||
| 16465 | |||
| 16466 | test "struct [4:sentinel]f32" { | ||
| 16467 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 16468 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | ||
| 16469 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | ||
| 16470 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | ||
| 16471 | |||
| 16472 | var sentinel_index: usize = 4; | ||
| 16473 | _ = &sentinel_index; | ||
| 16474 | const s = c_ret_struct_array_4_sentinel_f32(); | ||
| 16475 | try expect(s.a[0] == 10); | ||
| 16476 | try expect(s.a[1] == 11); | ||
| 16477 | try expect(s.a[2] == 12); | ||
| 16478 | try expect(s.a[3] == 13); | ||
| 16479 | try expect(s.a[sentinel_index] == 0x1e1); | ||
| 16480 | c_struct_array_4_sentinel_f32(.{ .a = .{ 14, 15, 16, 17 } }, 18); | ||
| 16481 | c_test_struct_array_4_sentinel_f32(); | ||
| 16482 | } | ||
| 16483 | |||
| 16484 | const Struct_f32a8 = extern struct { | ||
| 16485 | a: f32 align(8), | ||
| 16486 | }; | ||
| 16487 | |||
| 16488 | export fn zig_ret_struct_f32a8() Struct_f32a8 { | ||
| 16489 | return .{ .a = 1.25 }; | ||
| 16490 | } | ||
| 16491 | export fn zig_struct_f32a8(s: Struct_f32a8, f: f32) void { | ||
| 16492 | expect(s.a == 2.75) catch @panic("test failure"); | ||
| 16493 | expect(f == 3.5) catch @panic("test failure"); | ||
| 16494 | } | ||
| 16495 | |||
| 16496 | extern fn c_ret_struct_f32a8() Struct_f32a8; | ||
| 16497 | extern fn c_struct_f32a8(Struct_f32a8, f32) void; | ||
| 16498 | extern fn c_test_struct_f32a8() void; | ||
| 16499 | |||
| 16500 | test "struct f32 align(8)" { | ||
| 16501 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 16502 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | ||
| 16503 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | ||
| 16504 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | ||
| 16505 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | ||
| 16506 | if (builtin.cpu.arch.isRiscv32()) return error.SkipZigTest; | ||
| 16507 | if (builtin.cpu.arch == .x86) return error.SkipZigTest; | ||
| 15945 | 16508 | ||
| 15946 | const s = c_ret_struct_f32a8(); | 16509 | const s = c_ret_struct_f32a8(); |
| 15947 | try expect(s.a == 4.125); | 16510 | try expect(s.a == 4.125); |
| ... | @@ -15974,7 +16537,6 @@ test "struct f32 align(8), f32 align(8)" { | ... | @@ -15974,7 +16537,6 @@ test "struct f32 align(8), f32 align(8)" { |
| 15974 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | 16537 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; |
| 15975 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | 16538 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; |
| 15976 | if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest; | 16539 | if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest; |
| 15977 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 15978 | if (builtin.cpu.arch == .x86) return error.SkipZigTest; | 16540 | if (builtin.cpu.arch == .x86) return error.SkipZigTest; |
| 15979 | 16541 | ||
| 15980 | const s = c_ret_struct_f32a8_f32a8(); | 16542 | const s = c_ret_struct_f32a8_f32a8(); |
| ... | @@ -16007,8 +16569,7 @@ test "struct {f32, f32}, f32" { | ... | @@ -16007,8 +16569,7 @@ test "struct {f32, f32}, f32" { |
| 16007 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 16569 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 16008 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 16570 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 16009 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | 16571 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; |
| 16010 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; | 16572 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; |
| 16011 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 16012 | 16573 | ||
| 16013 | const s = c_ret_struct_f32f32_f32(); | 16574 | const s = c_ret_struct_f32f32_f32(); |
| 16014 | try expect(s.a.b == 1.0); | 16575 | try expect(s.a.b == 1.0); |
| ... | @@ -16041,8 +16602,7 @@ test "struct f32, {f32, f32}" { | ... | @@ -16041,8 +16602,7 @@ test "struct f32, {f32, f32}" { |
| 16041 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 16602 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 16042 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 16603 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 16043 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | 16604 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; |
| 16044 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; | 16605 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; |
| 16045 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 16046 | 16606 | ||
| 16047 | const s = c_ret_struct_f32_f32f32(); | 16607 | const s = c_ret_struct_f32_f32f32(); |
| 16048 | try expect(s.a == 1.0); | 16608 | try expect(s.a == 1.0); |
| ... | @@ -16070,9 +16630,8 @@ extern fn c_test_struct_f64() void; | ... | @@ -16070,9 +16630,8 @@ extern fn c_test_struct_f64() void; |
| 16070 | 16630 | ||
| 16071 | test "struct f64" { | 16631 | test "struct f64" { |
| 16072 | if (builtin.cpu.arch.isArm() and builtin.abi.float() == .soft) return error.SkipZigTest; | 16632 | if (builtin.cpu.arch.isArm() and builtin.abi.float() == .soft) return error.SkipZigTest; |
| 16073 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; | 16633 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; |
| 16074 | if (builtin.cpu.arch.isRiscv32()) return error.SkipZigTest; | 16634 | if (builtin.cpu.arch.isRiscv32()) return error.SkipZigTest; |
| 16075 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 16076 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest; | 16635 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest; |
| 16077 | 16636 | ||
| 16078 | const s = c_ret_struct_f64(); | 16637 | const s = c_ret_struct_f64(); |
| ... | @@ -16102,8 +16661,7 @@ extern fn c_test_struct_f64_f64() void; | ... | @@ -16102,8 +16661,7 @@ extern fn c_test_struct_f64_f64() void; |
| 16102 | test "struct f64, f64" { | 16661 | test "struct f64, f64" { |
| 16103 | if (builtin.cpu.arch.isArm() and builtin.abi.float() == .soft) return error.SkipZigTest; | 16662 | if (builtin.cpu.arch.isArm() and builtin.abi.float() == .soft) return error.SkipZigTest; |
| 16104 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 16663 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 16105 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; | 16664 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; |
| 16106 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 16107 | 16665 | ||
| 16108 | const s = c_ret_struct_f64_f64(); | 16666 | const s = c_ret_struct_f64_f64(); |
| 16109 | try expect(s.a == 6); | 16667 | try expect(s.a == 6); |
| ... | @@ -16135,8 +16693,7 @@ extern fn c_test_struct_f64_f64_f64() void; | ... | @@ -16135,8 +16693,7 @@ extern fn c_test_struct_f64_f64_f64() void; |
| 16135 | test "struct f64, f64, f64" { | 16693 | test "struct f64, f64, f64" { |
| 16136 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 16694 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 16137 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 16695 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 16138 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; | 16696 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; |
| 16139 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 16140 | 16697 | ||
| 16141 | const s = c_ret_struct_f64_f64_f64(); | 16698 | const s = c_ret_struct_f64_f64_f64(); |
| 16142 | try expect(s.a == 8); | 16699 | try expect(s.a == 8); |
| ... | @@ -16171,8 +16728,7 @@ extern fn c_test_struct_f64_f64_f64_f64() void; | ... | @@ -16171,8 +16728,7 @@ extern fn c_test_struct_f64_f64_f64_f64() void; |
| 16171 | test "struct f64, f64, f64, f64" { | 16728 | test "struct f64, f64, f64, f64" { |
| 16172 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 16729 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 16173 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 16730 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 16174 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; | 16731 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; |
| 16175 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 16176 | 16732 | ||
| 16177 | const s = c_ret_struct_f64_f64_f64_f64(); | 16733 | const s = c_ret_struct_f64_f64_f64_f64(); |
| 16178 | try expect(s.a == 10); | 16734 | try expect(s.a == 10); |
| ... | @@ -16210,8 +16766,7 @@ extern fn c_test_struct_f64_f64_f64_f64_f64() void; | ... | @@ -16210,8 +16766,7 @@ extern fn c_test_struct_f64_f64_f64_f64_f64() void; |
| 16210 | test "struct f64, f64, f64, f64, f64" { | 16766 | test "struct f64, f64, f64, f64, f64" { |
| 16211 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 16767 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 16212 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 16768 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 16213 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; | 16769 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; |
| 16214 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 16215 | 16770 | ||
| 16216 | const s = c_ret_struct_f64_f64_f64_f64_f64(); | 16771 | const s = c_ret_struct_f64_f64_f64_f64_f64(); |
| 16217 | try expect(s.a == 12); | 16772 | try expect(s.a == 12); |
| ... | @@ -16223,6 +16778,201 @@ test "struct f64, f64, f64, f64, f64" { | ... | @@ -16223,6 +16778,201 @@ test "struct f64, f64, f64, f64, f64" { |
| 16223 | c_test_struct_f64_f64_f64_f64_f64(); | 16778 | c_test_struct_f64_f64_f64_f64_f64(); |
| 16224 | } | 16779 | } |
| 16225 | 16780 | ||
| 16781 | const Struct_array_1_f64 = extern struct { | ||
| 16782 | a: [1]f64, | ||
| 16783 | }; | ||
| 16784 | |||
| 16785 | export fn zig_ret_struct_array_1_f64() Struct_array_1_f64 { | ||
| 16786 | return .{ .a = .{1} }; | ||
| 16787 | } | ||
| 16788 | export fn zig_struct_array_1_f64(s: Struct_array_1_f64, i: usize) void { | ||
| 16789 | expect(s.a[0] == 2) catch @panic("test failure"); | ||
| 16790 | expect(i == 3) catch @panic("test failure"); | ||
| 16791 | } | ||
| 16792 | |||
| 16793 | extern fn c_ret_struct_array_1_f64() Struct_array_1_f64; | ||
| 16794 | extern fn c_struct_array_1_f64(Struct_array_1_f64, usize) void; | ||
| 16795 | extern fn c_test_struct_array_1_f64() void; | ||
| 16796 | |||
| 16797 | test "struct [1]f64" { | ||
| 16798 | if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest; | ||
| 16799 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 16800 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | ||
| 16801 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | ||
| 16802 | if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest; | ||
| 16803 | |||
| 16804 | const s = c_ret_struct_array_1_f64(); | ||
| 16805 | try expect(s.a[0] == 4); | ||
| 16806 | c_struct_array_1_f64(.{ .a = .{5} }, 6); | ||
| 16807 | c_test_struct_array_1_f64(); | ||
| 16808 | } | ||
| 16809 | |||
| 16810 | const Struct_array_2_f64 = extern struct { | ||
| 16811 | a: [2]f64, | ||
| 16812 | }; | ||
| 16813 | |||
| 16814 | export fn zig_ret_struct_array_2_f64() Struct_array_2_f64 { | ||
| 16815 | return .{ .a = .{ 1, 2 } }; | ||
| 16816 | } | ||
| 16817 | export fn zig_struct_array_2_f64(s: Struct_array_2_f64, i: usize) void { | ||
| 16818 | expect(s.a[0] == 3) catch @panic("test failure"); | ||
| 16819 | expect(s.a[1] == 4) catch @panic("test failure"); | ||
| 16820 | expect(i == 5) catch @panic("test failure"); | ||
| 16821 | } | ||
| 16822 | |||
| 16823 | extern fn c_ret_struct_array_2_f64() Struct_array_2_f64; | ||
| 16824 | extern fn c_struct_array_2_f64(Struct_array_2_f64, usize) void; | ||
| 16825 | extern fn c_test_struct_array_2_f64() void; | ||
| 16826 | |||
| 16827 | test "struct [2]f64" { | ||
| 16828 | if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest; | ||
| 16829 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 16830 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | ||
| 16831 | if (builtin.cpu.arch == .loongarch64 and builtin.abi.float() == .hard) return error.SkipZigTest; | ||
| 16832 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | ||
| 16833 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | ||
| 16834 | if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest; | ||
| 16835 | |||
| 16836 | const s = c_ret_struct_array_2_f64(); | ||
| 16837 | try expect(s.a[0] == 6); | ||
| 16838 | try expect(s.a[1] == 7); | ||
| 16839 | c_struct_array_2_f64(.{ .a = .{ 8, 9 } }, 10); | ||
| 16840 | c_test_struct_array_2_f64(); | ||
| 16841 | } | ||
| 16842 | |||
| 16843 | const Struct_array_3_f64 = extern struct { | ||
| 16844 | a: [3]f64, | ||
| 16845 | }; | ||
| 16846 | |||
| 16847 | export fn zig_ret_struct_array_3_f64() Struct_array_3_f64 { | ||
| 16848 | return .{ .a = .{ 1, 2, 3 } }; | ||
| 16849 | } | ||
| 16850 | export fn zig_struct_array_3_f64(s: Struct_array_3_f64, i: usize) void { | ||
| 16851 | expect(s.a[0] == 4) catch @panic("test failure"); | ||
| 16852 | expect(s.a[1] == 5) catch @panic("test failure"); | ||
| 16853 | expect(s.a[2] == 6) catch @panic("test failure"); | ||
| 16854 | expect(i == 7) catch @panic("test failure"); | ||
| 16855 | } | ||
| 16856 | |||
| 16857 | extern fn c_ret_struct_array_3_f64() Struct_array_3_f64; | ||
| 16858 | extern fn c_struct_array_3_f64(Struct_array_3_f64, usize) void; | ||
| 16859 | extern fn c_test_struct_array_3_f64() void; | ||
| 16860 | |||
| 16861 | test "struct [3]f64" { | ||
| 16862 | if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest; | ||
| 16863 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 16864 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | ||
| 16865 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | ||
| 16866 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | ||
| 16867 | |||
| 16868 | const s = c_ret_struct_array_3_f64(); | ||
| 16869 | try expect(s.a[0] == 8); | ||
| 16870 | try expect(s.a[1] == 9); | ||
| 16871 | try expect(s.a[2] == 10); | ||
| 16872 | c_struct_array_3_f64(.{ .a = .{ 11, 12, 13 } }, 14); | ||
| 16873 | c_test_struct_array_3_f64(); | ||
| 16874 | } | ||
| 16875 | |||
| 16876 | const Struct_array_4_f64 = extern struct { | ||
| 16877 | a: [4]f64, | ||
| 16878 | }; | ||
| 16879 | |||
| 16880 | export fn zig_ret_struct_array_4_f64() Struct_array_4_f64 { | ||
| 16881 | return .{ .a = .{ 1, 2, 3, 4 } }; | ||
| 16882 | } | ||
| 16883 | export fn zig_struct_array_4_f64(s: Struct_array_4_f64, i: usize) void { | ||
| 16884 | expect(s.a[0] == 5) catch @panic("test failure"); | ||
| 16885 | expect(s.a[1] == 6) catch @panic("test failure"); | ||
| 16886 | expect(s.a[2] == 7) catch @panic("test failure"); | ||
| 16887 | expect(s.a[3] == 8) catch @panic("test failure"); | ||
| 16888 | expect(i == 9) catch @panic("test failure"); | ||
| 16889 | } | ||
| 16890 | |||
| 16891 | extern fn c_ret_struct_array_4_f64() Struct_array_4_f64; | ||
| 16892 | extern fn c_struct_array_4_f64(Struct_array_4_f64, usize) void; | ||
| 16893 | extern fn c_test_struct_array_4_f64() void; | ||
| 16894 | |||
| 16895 | test "struct [4]f64" { | ||
| 16896 | if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest; | ||
| 16897 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 16898 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | ||
| 16899 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | ||
| 16900 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | ||
| 16901 | |||
| 16902 | const s = c_ret_struct_array_4_f64(); | ||
| 16903 | try expect(s.a[0] == 10); | ||
| 16904 | try expect(s.a[1] == 11); | ||
| 16905 | try expect(s.a[2] == 12); | ||
| 16906 | try expect(s.a[3] == 13); | ||
| 16907 | c_struct_array_4_f64(.{ .a = .{ 14, 15, 16, 17 } }, 18); | ||
| 16908 | c_test_struct_array_4_f64(); | ||
| 16909 | } | ||
| 16910 | |||
| 16911 | const Struct_array_5_f64 = extern struct { | ||
| 16912 | a: [5]f64, | ||
| 16913 | }; | ||
| 16914 | |||
| 16915 | export fn zig_ret_struct_array_5_f64() Struct_array_5_f64 { | ||
| 16916 | return .{ .a = .{ 1, 2, 3, 4, 5 } }; | ||
| 16917 | } | ||
| 16918 | export fn zig_struct_array_5_f64(s: Struct_array_5_f64, i: usize) void { | ||
| 16919 | expect(s.a[0] == 6) catch @panic("test failure"); | ||
| 16920 | expect(s.a[1] == 7) catch @panic("test failure"); | ||
| 16921 | expect(s.a[2] == 8) catch @panic("test failure"); | ||
| 16922 | expect(s.a[3] == 9) catch @panic("test failure"); | ||
| 16923 | expect(s.a[4] == 10) catch @panic("test failure"); | ||
| 16924 | expect(i == 11) catch @panic("test failure"); | ||
| 16925 | } | ||
| 16926 | |||
| 16927 | extern fn c_ret_struct_array_5_f64() Struct_array_5_f64; | ||
| 16928 | extern fn c_struct_array_5_f64(Struct_array_5_f64, usize) void; | ||
| 16929 | extern fn c_test_struct_array_5_f64() void; | ||
| 16930 | |||
| 16931 | test "struct [5]f64" { | ||
| 16932 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | ||
| 16933 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | ||
| 16934 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | ||
| 16935 | |||
| 16936 | const s = c_ret_struct_array_5_f64(); | ||
| 16937 | try expect(s.a[0] == 12); | ||
| 16938 | try expect(s.a[1] == 13); | ||
| 16939 | try expect(s.a[2] == 14); | ||
| 16940 | try expect(s.a[3] == 15); | ||
| 16941 | try expect(s.a[4] == 16); | ||
| 16942 | c_struct_array_5_f64(.{ .a = .{ 17, 18, 19, 20, 21 } }, 22); | ||
| 16943 | c_test_struct_array_5_f64(); | ||
| 16944 | } | ||
| 16945 | |||
| 16946 | const Union_f64 = extern union { | ||
| 16947 | a: f64, | ||
| 16948 | }; | ||
| 16949 | |||
| 16950 | export fn zig_ret_union_f64() Union_f64 { | ||
| 16951 | return .{ .a = 1 }; | ||
| 16952 | } | ||
| 16953 | export fn zig_union_f64(s: Union_f64, i: usize) void { | ||
| 16954 | expect(s.a == 2) catch @panic("test failure"); | ||
| 16955 | expect(i == 3) catch @panic("test failure"); | ||
| 16956 | } | ||
| 16957 | |||
| 16958 | extern fn c_ret_union_f64() Union_f64; | ||
| 16959 | extern fn c_union_f64(Union_f64, usize) void; | ||
| 16960 | extern fn c_test_union_f64() void; | ||
| 16961 | |||
| 16962 | test "union f64" { | ||
| 16963 | if (builtin.cpu.arch.isArm() and builtin.abi.float() == .soft) return error.SkipZigTest; | ||
| 16964 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | ||
| 16965 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | ||
| 16966 | if (builtin.cpu.arch.isRiscv32()) return error.SkipZigTest; | ||
| 16967 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 16968 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest; | ||
| 16969 | |||
| 16970 | const s = c_ret_union_f64(); | ||
| 16971 | try expect(s.a == 4); | ||
| 16972 | c_union_f64(.{ .a = 5 }, 6); | ||
| 16973 | c_test_union_f64(); | ||
| 16974 | } | ||
| 16975 | |||
| 16226 | const Struct_u32_Union_u32_u32u32 = extern struct { | 16976 | const Struct_u32_Union_u32_u32u32 = extern struct { |
| 16227 | a: u32, | 16977 | a: u32, |
| 16228 | b: extern union { | 16978 | b: extern union { |
| ... | @@ -16250,8 +17000,7 @@ test "struct{u32,union{u32,struct{u32,u32}}}" { | ... | @@ -16250,8 +17000,7 @@ test "struct{u32,union{u32,struct{u32,u32}}}" { |
| 16250 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 17000 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 16251 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; | 17001 | if (builtin.cpu.arch == .loongarch64) return error.SkipZigTest; |
| 16252 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | 17002 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; |
| 16253 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | 17003 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; |
| 16254 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 16255 | 17004 | ||
| 16256 | const s = c_ret_struct_u32_union_u32_u32u32(); | 17005 | const s = c_ret_struct_u32_union_u32_u32u32(); |
| 16257 | try expect(s.a == 1); | 17006 | try expect(s.a == 1); |
| ... | @@ -16269,11 +17018,10 @@ extern fn c_mut_struct_i32_i32(Struct_i32_i32) Struct_i32_i32; | ... | @@ -16269,11 +17018,10 @@ extern fn c_mut_struct_i32_i32(Struct_i32_i32) Struct_i32_i32; |
| 16269 | extern fn c_struct_i32_i32(Struct_i32_i32) void; | 17018 | extern fn c_struct_i32_i32(Struct_i32_i32) void; |
| 16270 | 17019 | ||
| 16271 | test "struct i32 i32" { | 17020 | test "struct i32 i32" { |
| 17021 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; | ||
| 16272 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | 17022 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; |
| 16273 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | 17023 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; |
| 16274 | if (builtin.cpu.arch.isRiscv32()) return error.SkipZigTest; | 17024 | if (builtin.cpu.arch.isRiscv32()) return error.SkipZigTest; |
| 16275 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; | ||
| 16276 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 16277 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest; | 17025 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest; |
| 16278 | 17026 | ||
| 16279 | const s: Struct_i32_i32 = .{ | 17027 | const s: Struct_i32_i32 = .{ |
| ... | @@ -16303,11 +17051,10 @@ const BigStruct = extern struct { | ... | @@ -16303,11 +17051,10 @@ const BigStruct = extern struct { |
| 16303 | extern fn c_big_struct(BigStruct) void; | 17051 | extern fn c_big_struct(BigStruct) void; |
| 16304 | 17052 | ||
| 16305 | test "big struct" { | 17053 | test "big struct" { |
| 16306 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | ||
| 16307 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | ||
| 16308 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; | ||
| 16309 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 17054 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 16310 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | 17055 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; |
| 17056 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | ||
| 17057 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; | ||
| 16311 | 17058 | ||
| 16312 | const s = BigStruct{ | 17059 | const s = BigStruct{ |
| 16313 | .a = 1, | 17060 | .a = 1, |
| ... | @@ -16333,10 +17080,9 @@ const BigUnion = extern union { | ... | @@ -16333,10 +17080,9 @@ const BigUnion = extern union { |
| 16333 | extern fn c_big_union(BigUnion) void; | 17080 | extern fn c_big_union(BigUnion) void; |
| 16334 | 17081 | ||
| 16335 | test "big union" { | 17082 | test "big union" { |
| 16336 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; | ||
| 16337 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; | ||
| 16338 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 17083 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 16339 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | 17084 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; |
| 17085 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; | ||
| 16340 | 17086 | ||
| 16341 | const x = BigUnion{ | 17087 | const x = BigUnion{ |
| 16342 | .a = BigStruct{ | 17088 | .a = BigStruct{ |
| ... | @@ -16368,11 +17114,10 @@ extern fn c_med_struct_mixed(MedStructMixed) void; | ... | @@ -16368,11 +17114,10 @@ extern fn c_med_struct_mixed(MedStructMixed) void; |
| 16368 | extern fn c_ret_med_struct_mixed() MedStructMixed; | 17114 | extern fn c_ret_med_struct_mixed() MedStructMixed; |
| 16369 | 17115 | ||
| 16370 | test "medium struct of ints and floats" { | 17116 | test "medium struct of ints and floats" { |
| 16371 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | ||
| 16372 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | ||
| 16373 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; | ||
| 16374 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 17117 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 16375 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | 17118 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; |
| 17119 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | ||
| 17120 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; | ||
| 16376 | 17121 | ||
| 16377 | const s = MedStructMixed{ | 17122 | const s = MedStructMixed{ |
| 16378 | .a = 1234, | 17123 | .a = 1234, |
| ... | @@ -16448,12 +17193,11 @@ const SplitStructInt = extern struct { | ... | @@ -16448,12 +17193,11 @@ const SplitStructInt = extern struct { |
| 16448 | extern fn c_split_struct_ints(SplitStructInt) void; | 17193 | extern fn c_split_struct_ints(SplitStructInt) void; |
| 16449 | 17194 | ||
| 16450 | test "split struct of ints" { | 17195 | test "split struct of ints" { |
| 16451 | if (builtin.cpu.arch == .x86) return error.SkipZigTest; | ||
| 16452 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | ||
| 16453 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | ||
| 16454 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; | ||
| 16455 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 17196 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 16456 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | 17197 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; |
| 17198 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | ||
| 17199 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; | ||
| 17200 | if (builtin.cpu.arch == .x86) return error.SkipZigTest; | ||
| 16457 | 17201 | ||
| 16458 | const s = SplitStructInt{ | 17202 | const s = SplitStructInt{ |
| 16459 | .a = 1234, | 17203 | .a = 1234, |
| ... | @@ -16478,12 +17222,11 @@ extern fn c_split_struct_mixed(SplitStructMixed) void; | ... | @@ -16478,12 +17222,11 @@ extern fn c_split_struct_mixed(SplitStructMixed) void; |
| 16478 | extern fn c_ret_split_struct_mixed() SplitStructMixed; | 17222 | extern fn c_ret_split_struct_mixed() SplitStructMixed; |
| 16479 | 17223 | ||
| 16480 | test "split struct of ints and floats" { | 17224 | test "split struct of ints and floats" { |
| 16481 | if (builtin.cpu.arch == .x86) return error.SkipZigTest; | ||
| 16482 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | ||
| 16483 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | ||
| 16484 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; | ||
| 16485 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 17225 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 16486 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | 17226 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; |
| 17227 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | ||
| 17228 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; | ||
| 17229 | if (builtin.cpu.arch == .x86) return error.SkipZigTest; | ||
| 16487 | 17230 | ||
| 16488 | const s = SplitStructMixed{ | 17231 | const s = SplitStructMixed{ |
| 16489 | .a = 1234, | 17232 | .a = 1234, |
| ... | @@ -16506,11 +17249,10 @@ export fn zig_split_struct_mixed(x: SplitStructMixed) void { | ... | @@ -16506,11 +17249,10 @@ export fn zig_split_struct_mixed(x: SplitStructMixed) void { |
| 16506 | extern fn c_big_struct_both(BigStruct) BigStruct; | 17249 | extern fn c_big_struct_both(BigStruct) BigStruct; |
| 16507 | 17250 | ||
| 16508 | test "sret and byval together" { | 17251 | test "sret and byval together" { |
| 16509 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | ||
| 16510 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | ||
| 16511 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; | ||
| 16512 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 17252 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 16513 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | 17253 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; |
| 17254 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | ||
| 17255 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; | ||
| 16514 | 17256 | ||
| 16515 | const s = BigStruct{ | 17257 | const s = BigStruct{ |
| 16516 | .a = 1, | 17258 | .a = 1, |
| ... | @@ -16620,12 +17362,11 @@ extern fn c_struct_with_array(StructWithArray) void; | ... | @@ -16620,12 +17362,11 @@ extern fn c_struct_with_array(StructWithArray) void; |
| 16620 | extern fn c_ret_struct_with_array() StructWithArray; | 17362 | extern fn c_ret_struct_with_array() StructWithArray; |
| 16621 | 17363 | ||
| 16622 | test "Struct with array as padding." { | 17364 | test "Struct with array as padding." { |
| 16623 | if (builtin.cpu.arch == .x86) return error.SkipZigTest; | ||
| 16624 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | ||
| 16625 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | ||
| 16626 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; | ||
| 16627 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 17365 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 16628 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | 17366 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; |
| 17367 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | ||
| 17368 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; | ||
| 17369 | if (builtin.cpu.arch == .x86) return error.SkipZigTest; | ||
| 16629 | 17370 | ||
| 16630 | c_struct_with_array(.{ .a = 1, .padding = undefined, .b = 2 }); | 17371 | c_struct_with_array(.{ .a = 1, .padding = undefined, .b = 2 }); |
| 16631 | 17372 | ||
| ... | @@ -16649,11 +17390,10 @@ extern fn c_float_array_struct(FloatArrayStruct) void; | ... | @@ -16649,11 +17390,10 @@ extern fn c_float_array_struct(FloatArrayStruct) void; |
| 16649 | extern fn c_ret_float_array_struct() FloatArrayStruct; | 17390 | extern fn c_ret_float_array_struct() FloatArrayStruct; |
| 16650 | 17391 | ||
| 16651 | test "Float array like struct" { | 17392 | test "Float array like struct" { |
| 16652 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | ||
| 16653 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; | ||
| 16654 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; | ||
| 16655 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 17393 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 16656 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | 17394 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; |
| 17395 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | ||
| 17396 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | ||
| 16657 | 17397 | ||
| 16658 | c_float_array_struct(.{ | 17398 | c_float_array_struct(.{ |
| 16659 | .origin = .{ | 17399 | .origin = .{ |
| ... | @@ -16684,37 +17424,37 @@ pub inline fn expectOk(c_err: c_int) !void { | ... | @@ -16684,37 +17424,37 @@ pub inline fn expectOk(c_err: c_int) !void { |
| 16684 | /// Tests for Double + Char struct | 17424 | /// Tests for Double + Char struct |
| 16685 | const DC = extern struct { v1: f64, v2: u8 }; | 17425 | const DC = extern struct { v1: f64, v2: u8 }; |
| 16686 | test "DC: Zig passes to C" { | 17426 | test "DC: Zig passes to C" { |
| 17427 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | ||
| 17428 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; | ||
| 16687 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | 17429 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; |
| 17430 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; | ||
| 16688 | if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest; | 17431 | if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest; |
| 16689 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | 17432 | |
| 16690 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; | ||
| 16691 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | ||
| 16692 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 16693 | try expectOk(c_assert_DC(.{ .v1 = -0.25, .v2 = 15 })); | 17433 | try expectOk(c_assert_DC(.{ .v1 = -0.25, .v2 = 15 })); |
| 16694 | } | 17434 | } |
| 16695 | test "DC: Zig returns to C" { | 17435 | test "DC: Zig returns to C" { |
| 17436 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; | ||
| 16696 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | 17437 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; |
| 17438 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; | ||
| 16697 | if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest; | 17439 | if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest; |
| 16698 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | 17440 | |
| 16699 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; | ||
| 16700 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 16701 | try expectOk(c_assert_ret_DC()); | 17441 | try expectOk(c_assert_ret_DC()); |
| 16702 | } | 17442 | } |
| 16703 | test "DC: C passes to Zig" { | 17443 | test "DC: C passes to Zig" { |
| 17444 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | ||
| 17445 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; | ||
| 16704 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | 17446 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; |
| 17447 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; | ||
| 16705 | if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest; | 17448 | if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest; |
| 16706 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | 17449 | |
| 16707 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; | ||
| 16708 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | ||
| 16709 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 16710 | try expectOk(c_send_DC()); | 17450 | try expectOk(c_send_DC()); |
| 16711 | } | 17451 | } |
| 16712 | test "DC: C returns to Zig" { | 17452 | test "DC: C returns to Zig" { |
| 17453 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; | ||
| 16713 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | 17454 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; |
| 17455 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; | ||
| 16714 | if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest; | 17456 | if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest; |
| 16715 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | 17457 | |
| 16716 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; | ||
| 16717 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 16718 | try expectEqual(DC{ .v1 = -0.25, .v2 = 15 }, c_ret_DC()); | 17458 | try expectEqual(DC{ .v1 = -0.25, .v2 = 15 }, c_ret_DC()); |
| 16719 | } | 17459 | } |
| 16720 | 17460 | ||
| ... | @@ -16739,36 +17479,35 @@ const CFF = extern struct { v1: u8, v2: f32, v3: f32 }; | ... | @@ -16739,36 +17479,35 @@ const CFF = extern struct { v1: u8, v2: f32, v3: f32 }; |
| 16739 | test "CFF: Zig passes to C" { | 17479 | test "CFF: Zig passes to C" { |
| 16740 | if (builtin.target.cpu.arch == .x86) return error.SkipZigTest; | 17480 | if (builtin.target.cpu.arch == .x86) return error.SkipZigTest; |
| 16741 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | 17481 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; |
| 16742 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | 17482 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; |
| 16743 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; | 17483 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; |
| 16744 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 17484 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 16745 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | 17485 | |
| 16746 | try expectOk(c_assert_CFF(.{ .v1 = 39, .v2 = 0.875, .v3 = 1.0 })); | 17486 | try expectOk(c_assert_CFF(.{ .v1 = 39, .v2 = 0.875, .v3 = 1.0 })); |
| 16747 | } | 17487 | } |
| 16748 | test "CFF: Zig returns to C" { | 17488 | test "CFF: Zig returns to C" { |
| 16749 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | 17489 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; |
| 16750 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | 17490 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; |
| 16751 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; | 17491 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; |
| 16752 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | 17492 | |
| 16753 | try expectOk(c_assert_ret_CFF()); | 17493 | try expectOk(c_assert_ret_CFF()); |
| 16754 | } | 17494 | } |
| 16755 | test "CFF: C passes to Zig" { | 17495 | test "CFF: C passes to Zig" { |
| 16756 | if (builtin.target.cpu.arch == .x86) return error.SkipZigTest; | ||
| 16757 | if (builtin.cpu.arch.isRISCV() and builtin.mode != .Debug) return error.SkipZigTest; | ||
| 16758 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | ||
| 16759 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | ||
| 16760 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; | ||
| 16761 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 17496 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 16762 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | 17497 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; |
| 17498 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | ||
| 17499 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; | ||
| 17500 | if (builtin.cpu.arch.isRISCV() and builtin.mode != .debug) return error.SkipZigTest; | ||
| 17501 | if (builtin.target.cpu.arch == .x86) return error.SkipZigTest; | ||
| 16763 | 17502 | ||
| 16764 | try expectOk(c_send_CFF()); | 17503 | try expectOk(c_send_CFF()); |
| 16765 | } | 17504 | } |
| 16766 | test "CFF: C returns to Zig" { | 17505 | test "CFF: C returns to Zig" { |
| 16767 | if (builtin.cpu.arch.isRISCV() and builtin.mode != .Debug) return error.SkipZigTest; | ||
| 16768 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | ||
| 16769 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | ||
| 16770 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; | 17506 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; |
| 16771 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | 17507 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; |
| 17508 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; | ||
| 17509 | if (builtin.cpu.arch.isRISCV() and builtin.mode != .debug) return error.SkipZigTest; | ||
| 17510 | |||
| 16772 | try expectEqual(CFF{ .v1 = 39, .v2 = 0.875, .v3 = 1.0 }, c_ret_CFF()); | 17511 | try expectEqual(CFF{ .v1 = 39, .v2 = 0.875, .v3 = 1.0 }, c_ret_CFF()); |
| 16773 | } | 17512 | } |
| 16774 | pub extern fn c_assert_CFF(lv: CFF) c_int; | 17513 | pub extern fn c_assert_CFF(lv: CFF) c_int; |
| ... | @@ -16791,35 +17530,35 @@ pub export fn zig_ret_CFF() CFF { | ... | @@ -16791,35 +17530,35 @@ pub export fn zig_ret_CFF() CFF { |
| 16791 | const PD = extern struct { v1: ?*anyopaque, v2: f64 }; | 17530 | const PD = extern struct { v1: ?*anyopaque, v2: f64 }; |
| 16792 | 17531 | ||
| 16793 | test "PD: Zig passes to C" { | 17532 | test "PD: Zig passes to C" { |
| 16794 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | ||
| 16795 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | ||
| 16796 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; | ||
| 16797 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 17533 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 16798 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | 17534 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; |
| 17535 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | ||
| 17536 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; | ||
| 16799 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest; | 17537 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest; |
| 17538 | |||
| 16800 | try expectOk(c_assert_PD(.{ .v1 = null, .v2 = 0.5 })); | 17539 | try expectOk(c_assert_PD(.{ .v1 = null, .v2 = 0.5 })); |
| 16801 | } | 17540 | } |
| 16802 | test "PD: Zig returns to C" { | 17541 | test "PD: Zig returns to C" { |
| 16803 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | ||
| 16804 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | ||
| 16805 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; | 17542 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; |
| 16806 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | 17543 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; |
| 17544 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; | ||
| 17545 | |||
| 16807 | try expectOk(c_assert_ret_PD()); | 17546 | try expectOk(c_assert_ret_PD()); |
| 16808 | } | 17547 | } |
| 16809 | test "PD: C passes to Zig" { | 17548 | test "PD: C passes to Zig" { |
| 16810 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | ||
| 16811 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | ||
| 16812 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; | ||
| 16813 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 17549 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 16814 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | 17550 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; |
| 17551 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | ||
| 17552 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; | ||
| 16815 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest; | 17553 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest; |
| 17554 | |||
| 16816 | try expectOk(c_send_PD()); | 17555 | try expectOk(c_send_PD()); |
| 16817 | } | 17556 | } |
| 16818 | test "PD: C returns to Zig" { | 17557 | test "PD: C returns to Zig" { |
| 16819 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | ||
| 16820 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | ||
| 16821 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; | 17558 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; |
| 16822 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | 17559 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; |
| 17560 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; | ||
| 17561 | |||
| 16823 | try expectEqual(PD{ .v1 = null, .v2 = 0.5 }, c_ret_PD()); | 17562 | try expectEqual(PD{ .v1 = null, .v2 = 0.5 }, c_ret_PD()); |
| 16824 | } | 17563 | } |
| 16825 | pub extern fn c_assert_PD(lv: PD) c_int; | 17564 | pub extern fn c_assert_PD(lv: PD) c_int; |
| ... | @@ -16853,7 +17592,6 @@ extern fn c_modify_by_ref_param(ByRef) ByRef; | ... | @@ -16853,7 +17592,6 @@ extern fn c_modify_by_ref_param(ByRef) ByRef; |
| 16853 | test "C function modifies by ref param" { | 17592 | test "C function modifies by ref param" { |
| 16854 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; | 17593 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; |
| 16855 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; | 17594 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; |
| 16856 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 16857 | 17595 | ||
| 16858 | const res = c_modify_by_ref_param(.{ .val = 1, .arr = undefined }); | 17596 | const res = c_modify_by_ref_param(.{ .val = 1, .arr = undefined }); |
| 16859 | try expect(res.val == 42); | 17597 | try expect(res.val == 42); |
| ... | @@ -16874,11 +17612,10 @@ const ByVal = extern struct { | ... | @@ -16874,11 +17612,10 @@ const ByVal = extern struct { |
| 16874 | 17612 | ||
| 16875 | extern fn c_func_ptr_byval(*anyopaque, *anyopaque, ByVal, c_ulong, *anyopaque, c_ulong) void; | 17613 | extern fn c_func_ptr_byval(*anyopaque, *anyopaque, ByVal, c_ulong, *anyopaque, c_ulong) void; |
| 16876 | test "C function that takes byval struct called via function pointer" { | 17614 | test "C function that takes byval struct called via function pointer" { |
| 17615 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | ||
| 17616 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; | ||
| 16877 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | 17617 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; |
| 16878 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; | 17618 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; |
| 16879 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; | ||
| 16880 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | ||
| 16881 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 16882 | 17619 | ||
| 16883 | var fn_ptr = &c_func_ptr_byval; | 17620 | var fn_ptr = &c_func_ptr_byval; |
| 16884 | _ = &fn_ptr; | 17621 | _ = &fn_ptr; |
| ... | @@ -16897,17 +17634,16 @@ test "C function that takes byval struct called via function pointer" { | ... | @@ -16897,17 +17634,16 @@ test "C function that takes byval struct called via function pointer" { |
| 16897 | 17634 | ||
| 16898 | extern fn c_f16(f16) f16; | 17635 | extern fn c_f16(f16) f16; |
| 16899 | test "f16 bare" { | 17636 | test "f16 bare" { |
| 16900 | if (builtin.cpu.arch == .x86_64) return error.SkipZigTest; | 17637 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; |
| 16901 | if (builtin.cpu.arch == .x86) return error.SkipZigTest; | ||
| 16902 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 17638 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 16903 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; | 17639 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; |
| 16904 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | 17640 | if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest; |
| 17641 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | ||
| 16905 | if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest; | 17642 | if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest; |
| 16906 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | 17643 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; |
| 16907 | if (builtin.cpu.arch.isWasm()) return error.SkipZigTest; | 17644 | if (builtin.cpu.arch.isWasm()) return error.SkipZigTest; |
| 16908 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | 17645 | if (builtin.cpu.arch == .x86) return error.SkipZigTest; |
| 16909 | 17646 | if (builtin.cpu.arch == .x86_64) return error.SkipZigTest; | |
| 16910 | if (builtin.cpu.arch.isArm()) return error.SkipZigTest; | ||
| 16911 | 17647 | ||
| 16912 | const a = c_f16(12); | 17648 | const a = c_f16(12); |
| 16913 | try expect(a == 34); | 17649 | try expect(a == 34); |
| ... | @@ -16918,9 +17654,9 @@ const f16_struct = extern struct { | ... | @@ -16918,9 +17654,9 @@ const f16_struct = extern struct { |
| 16918 | }; | 17654 | }; |
| 16919 | extern fn c_f16_struct(f16_struct) f16_struct; | 17655 | extern fn c_f16_struct(f16_struct) f16_struct; |
| 16920 | test "f16 struct" { | 17656 | test "f16 struct" { |
| 17657 | if (builtin.cpu.arch.isArm() and builtin.mode != .debug) return error.SkipZigTest; | ||
| 16921 | if (builtin.target.cpu.arch.isMIPS64()) return error.SkipZigTest; | 17658 | if (builtin.target.cpu.arch.isMIPS64()) return error.SkipZigTest; |
| 16922 | if (builtin.target.cpu.arch.isPowerPC32()) return error.SkipZigTest; | 17659 | if (builtin.target.cpu.arch.isPowerPC32()) return error.SkipZigTest; |
| 16923 | if (builtin.cpu.arch.isArm() and builtin.mode != .Debug) return error.SkipZigTest; | ||
| 16924 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | 17660 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; |
| 16925 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest; | 17661 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest; |
| 16926 | 17662 | ||
| ... | @@ -17027,11 +17763,10 @@ const Coord2 = extern struct { | ... | @@ -17027,11 +17763,10 @@ const Coord2 = extern struct { |
| 17027 | 17763 | ||
| 17028 | extern fn stdcall_coord2(Coord2, Coord2, Coord2) callconv(stdcall_callconv) Coord2; | 17764 | extern fn stdcall_coord2(Coord2, Coord2, Coord2) callconv(stdcall_callconv) Coord2; |
| 17029 | test "Stdcall ABI structs" { | 17765 | test "Stdcall ABI structs" { |
| 17766 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | ||
| 17767 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; | ||
| 17030 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | 17768 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; |
| 17031 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | 17769 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; |
| 17032 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; | ||
| 17033 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | ||
| 17034 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | ||
| 17035 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest; | 17770 | if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest; |
| 17036 | 17771 | ||
| 17037 | const res = stdcall_coord2( | 17772 | const res = stdcall_coord2( |
| ... | @@ -17045,10 +17780,9 @@ test "Stdcall ABI structs" { | ... | @@ -17045,10 +17780,9 @@ test "Stdcall ABI structs" { |
| 17045 | 17780 | ||
| 17046 | extern fn stdcall_big_union(BigUnion) callconv(stdcall_callconv) void; | 17781 | extern fn stdcall_big_union(BigUnion) callconv(stdcall_callconv) void; |
| 17047 | test "Stdcall ABI big union" { | 17782 | test "Stdcall ABI big union" { |
| 17048 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; | ||
| 17049 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; | ||
| 17050 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 17783 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 17051 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | 17784 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; |
| 17785 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; | ||
| 17052 | 17786 | ||
| 17053 | const x = BigUnion{ | 17787 | const x = BigUnion{ |
| 17054 | .a = BigStruct{ | 17788 | .a = BigStruct{ |
| ... | @@ -17120,11 +17854,10 @@ const byval_tail_callsite_attr = struct { | ... | @@ -17120,11 +17854,10 @@ const byval_tail_callsite_attr = struct { |
| 17120 | }; | 17854 | }; |
| 17121 | 17855 | ||
| 17122 | test "byval tail callsite attribute" { | 17856 | test "byval tail callsite attribute" { |
| 17123 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | ||
| 17124 | if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest; | ||
| 17125 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; | ||
| 17126 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; | 17857 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; |
| 17127 | if (builtin.cpu.arch == .s390x) return error.SkipZigTest; | 17858 | if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; |
| 17859 | if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; | ||
| 17860 | if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | ||
| 17128 | 17861 | ||
| 17129 | // Originally reported at https://github.com/ziglang/zig/issues/16290 | 17862 | // Originally reported at https://github.com/ziglang/zig/issues/16290 |
| 17130 | // the bug was that the extern function had the byval attribute, but | 17863 | // the bug was that the extern function had the byval attribute, but |
| ... | @@ -17268,11 +18001,19 @@ test "x86 vectorcall calling convention" { | ... | @@ -17268,11 +18001,19 @@ test "x86 vectorcall calling convention" { |
| 17268 | static.c_vectorcall_check(1, 2.0, 3.0, @ptrFromInt(4), 5.0, 6.0, 7.0, 8.0, 9.0, 10); | 18001 | static.c_vectorcall_check(1, 2.0, 3.0, @ptrFromInt(4), 5.0, 6.0, 7.0, 8.0, 9.0, 10); |
| 17269 | } | 18002 | } |
| 17270 | 18003 | ||
| 18004 | extern fn c_x86_64_sysv_uint_int_uint_int(a: u8, b: i8, c: u16, d: i16) void; | ||
| 18005 | |||
| 18006 | test "x86_64 sysv args" { | ||
| 18007 | if (std.lang.CallingConvention.c != .x86_64_sysv) return error.SkipZigTest; | ||
| 18008 | |||
| 18009 | c_x86_64_sysv_uint_int_uint_int(1, -2, 3, -4); | ||
| 18010 | } | ||
| 18011 | |||
| 17271 | extern fn c_win64_varargs_u64_f64_u64_f64(...) void; | 18012 | extern fn c_win64_varargs_u64_f64_u64_f64(...) void; |
| 17272 | extern fn c_win64_varargs_f64_u64_f64_u64(...) void; | 18013 | extern fn c_win64_varargs_f64_u64_f64_u64(...) void; |
| 17273 | 18014 | ||
| 17274 | test "win64 varargs" { | 18015 | test "win64 varargs" { |
| 17275 | if (builtin.cpu.arch != .x86_64 or builtin.os.tag != .windows) return error.SkipZigTest; | 18016 | if (std.lang.CallingConvention.c != .x86_64_win) return error.SkipZigTest; |
| 17276 | 18017 | ||
| 17277 | const Opv = extern struct {}; | 18018 | const Opv = extern struct {}; |
| 17278 | c_win64_varargs_u64_f64_u64_f64( | 18019 | c_win64_varargs_u64_f64_u64_f64( |
| ... | @@ -17298,3 +18039,25 @@ test "win64 varargs" { | ... | @@ -17298,3 +18039,25 @@ test "win64 varargs" { |
| 17298 | @as(Opv, .{}), | 18039 | @as(Opv, .{}), |
| 17299 | ); | 18040 | ); |
| 17300 | } | 18041 | } |
| 18042 | |||
| 18043 | const preserve_none_cc: ?std.lang.CallingConvention = if (builtin.zig_backend != .stage2_llvm) | ||
| 18044 | null | ||
| 18045 | else switch (builtin.cpu.arch) { | ||
| 18046 | .x86_64 => .{ .x86_64_preserve_none = .{} }, | ||
| 18047 | .aarch64, .aarch64_be => .{ .aarch64_preserve_none = .{} }, | ||
| 18048 | else => null, | ||
| 18049 | }; | ||
| 18050 | |||
| 18051 | export fn zig_preserve_none(x: i32) callconv(preserve_none_cc orelse .c) i32 { | ||
| 18052 | return x + 1; | ||
| 18053 | } | ||
| 18054 | |||
| 18055 | test "preserve_none calling convention" { | ||
| 18056 | if (preserve_none_cc == null) return error.SkipZigTest; | ||
| 18057 | const static = struct { | ||
| 18058 | extern fn c_preserve_none(x: i32) callconv(preserve_none_cc.?) i32; | ||
| 18059 | extern fn c_preserve_none_check() void; | ||
| 18060 | }; | ||
| 18061 | try expect(static.c_preserve_none(41) == 42); | ||
| 18062 | static.c_preserve_none_check(); | ||
| 18063 | } |
test/cases/compile_errors/bad_panic_call_signature.zig+1| ... | @@ -15,6 +15,7 @@ pub const panic = struct { | ... | @@ -15,6 +15,7 @@ pub const panic = struct { |
| 15 | pub const castToNull = simple_panic.castToNull; | 15 | pub const castToNull = simple_panic.castToNull; |
| 16 | pub const incorrectAlignment = simple_panic.incorrectAlignment; | 16 | pub const incorrectAlignment = simple_panic.incorrectAlignment; |
| 17 | pub const invalidErrorCode = simple_panic.invalidErrorCode; | 17 | pub const invalidErrorCode = simple_panic.invalidErrorCode; |
| 18 | pub const unexpectedErrorCode = simple_panic.unexpectedErrorCode; | ||
| 18 | pub const integerOutOfBounds = simple_panic.integerOutOfBounds; | 19 | pub const integerOutOfBounds = simple_panic.integerOutOfBounds; |
| 19 | pub const integerOverflow = simple_panic.integerOverflow; | 20 | pub const integerOverflow = simple_panic.integerOverflow; |
| 20 | pub const shlOverflow = simple_panic.shlOverflow; | 21 | pub const shlOverflow = simple_panic.shlOverflow; |
test/cases/compile_errors/bad_panic_generic_signature.zig+1| ... | @@ -11,6 +11,7 @@ pub const panic = struct { | ... | @@ -11,6 +11,7 @@ pub const panic = struct { |
| 11 | pub const castToNull = simple_panic.castToNull; | 11 | pub const castToNull = simple_panic.castToNull; |
| 12 | pub const incorrectAlignment = simple_panic.incorrectAlignment; | 12 | pub const incorrectAlignment = simple_panic.incorrectAlignment; |
| 13 | pub const invalidErrorCode = simple_panic.invalidErrorCode; | 13 | pub const invalidErrorCode = simple_panic.invalidErrorCode; |
| 14 | pub const unexpectedErrorCode = simple_panic.unexpectedErrorCode; | ||
| 14 | pub const integerOutOfBounds = simple_panic.integerOutOfBounds; | 15 | pub const integerOutOfBounds = simple_panic.integerOutOfBounds; |
| 15 | pub const integerOverflow = simple_panic.integerOverflow; | 16 | pub const integerOverflow = simple_panic.integerOverflow; |
| 16 | pub const shlOverflow = simple_panic.shlOverflow; | 17 | pub const shlOverflow = simple_panic.shlOverflow; |
test/cases/compile_errors/callconv_preserve_none_on_unsupported_platform.zig created+16| ... | @@ -0,0 +1,16 @@ | ||
| 1 | const F1 = fn () callconv(.{ .x86_64_preserve_none = .{} }) void; | ||
| 2 | const F2 = fn () callconv(.{ .aarch64_preserve_none = .{} }) void; | ||
| 3 | export fn entry1() void { | ||
| 4 | const a: F1 = undefined; | ||
| 5 | _ = a; | ||
| 6 | } | ||
| 7 | export fn entry2() void { | ||
| 8 | const a: F2 = undefined; | ||
| 9 | _ = a; | ||
| 10 | } | ||
| 11 | |||
| 12 | // error | ||
| 13 | // target=riscv64-linux-none | ||
| 14 | // | ||
| 15 | // :1:28: error: calling convention 'x86_64_preserve_none' only available on architectures 'x86_64' | ||
| 16 | // :2:28: error: calling convention 'aarch64_preserve_none' only available on architectures 'aarch64', 'aarch64_be' | ||
test/cases/compile_errors/capture_by_ref_discard.zig+5| ... | @@ -16,9 +16,14 @@ export fn d() void { | ... | @@ -16,9 +16,14 @@ export fn d() void { |
| 16 | while (null) |*_| {} | 16 | while (null) |*_| {} |
| 17 | } | 17 | } |
| 18 | 18 | ||
| 19 | export fn e() void { | ||
| 20 | if (0) |*_| {} else |err| switch (err) {} | ||
| 21 | } | ||
| 22 | |||
| 19 | // error | 23 | // error |
| 20 | // | 24 | // |
| 21 | // :2:16: error: pointer modifier invalid on discard | 25 | // :2:16: error: pointer modifier invalid on discard |
| 22 | // :7:18: error: pointer modifier invalid on discard | 26 | // :7:18: error: pointer modifier invalid on discard |
| 23 | // :12:16: error: pointer modifier invalid on discard | 27 | // :12:16: error: pointer modifier invalid on discard |
| 24 | // :16:19: error: pointer modifier invalid on discard | 28 | // :16:19: error: pointer modifier invalid on discard |
| 29 | // :20:13: error: pointer modifier invalid on discard |
test/cases/compile_errors/coerce_pointers_with_uncoercable_child_pointers.zig+14| ... | @@ -28,6 +28,16 @@ export fn entry5() void { | ... | @@ -28,6 +28,16 @@ export fn entry5() void { |
| 28 | _ = q; | 28 | _ = q; |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | export fn entry6(p: **[3]u8) void { | ||
| 32 | const q: *[]u8 = p; | ||
| 33 | _ = q; | ||
| 34 | } | ||
| 35 | |||
| 36 | export fn entry7(p: *[]u8) void { | ||
| 37 | const q: **[3]u8 = p; | ||
| 38 | _ = q; | ||
| 39 | } | ||
| 40 | |||
| 31 | // error | 41 | // error |
| 32 | // | 42 | // |
| 33 | // :3:22: error: expected type '**i32', found '**u32' | 43 | // :3:22: error: expected type '**i32', found '**u32' |
| ... | @@ -50,3 +60,7 @@ export fn entry5() void { | ... | @@ -50,3 +60,7 @@ export fn entry5() void { |
| 50 | // :27:24: note: pointer type child '*[1:42]u8' cannot cast into pointer type child '*[1]u8' | 60 | // :27:24: note: pointer type child '*[1:42]u8' cannot cast into pointer type child '*[1]u8' |
| 51 | // :27:24: note: pointer type child '[1:42]u8' cannot cast into pointer type child '[1]u8' | 61 | // :27:24: note: pointer type child '[1:42]u8' cannot cast into pointer type child '[1]u8' |
| 52 | // :27:24: note: source array cannot be guaranteed to maintain '42' sentinel | 62 | // :27:24: note: source array cannot be guaranteed to maintain '42' sentinel |
| 63 | // :32:22: error: expected type '*[]u8', found '**[3]u8' | ||
| 64 | // :32:22: note: pointer type child '*[3]u8' cannot cast into pointer type child '[]u8' | ||
| 65 | // :37:24: error: expected type '**[3]u8', found '*[]u8' | ||
| 66 | // :37:24: note: pointer type child '[]u8' cannot cast into pointer type child '*[3]u8' |
test/cases/compile_errors/coercion_from_vector_element_to_c_ptr.zig created+11| ... | @@ -0,0 +1,11 @@ | ||
| 1 | export fn foo() void { | ||
| 2 | var size: @Vector(4, c_int) = undefined; | ||
| 3 | bar(&size[0]); | ||
| 4 | } | ||
| 5 | extern fn bar([*c]c_int) void; | ||
| 6 | |||
| 7 | // error | ||
| 8 | // | ||
| 9 | // 3:9: error: expected type '[*c]c_int', found '*align(4:0:4:0) c_int' | ||
| 10 | // 3:9: note: pointer host size '4' cannot cast into pointer host size '0' | ||
| 11 | // 5:15: note: parameter type declared here | ||
test/cases/compile_errors/deref_slice_and_get_len_field.zig+1-1| ... | @@ -6,4 +6,4 @@ export fn entry() void { | ... | @@ -6,4 +6,4 @@ export fn entry() void { |
| 6 | 6 | ||
| 7 | // error | 7 | // error |
| 8 | // | 8 | // |
| 9 | // :3:10: error: index syntax required for slice type '[]u8' | 9 | // :3:10: error: index syntax required to access runtime-known slice |
test/cases/compile_errors/deref_slice_with_undef_len.zig created+23| ... | @@ -0,0 +1,23 @@ | ||
| 1 | export fn entry2() void { | ||
| 2 | comptime var slice: []const u16 = &.{ 1, 2, 3 }; | ||
| 3 | slice.len = undefined; | ||
| 4 | _ = slice.*; | ||
| 5 | } | ||
| 6 | |||
| 7 | export fn entry3() void { | ||
| 8 | comptime var slice: []const u16 = &.{ 1, 2, 3 }; | ||
| 9 | slice.len = undefined; | ||
| 10 | _ = &slice.*; | ||
| 11 | } | ||
| 12 | |||
| 13 | export fn entry4() void { | ||
| 14 | comptime var slice: []const u8 = "hello"; | ||
| 15 | slice.len = undefined; | ||
| 16 | @compileError(slice); | ||
| 17 | } | ||
| 18 | |||
| 19 | // error | ||
| 20 | // | ||
| 21 | // :4:14: error: cannot dereference slice with undefined length | ||
| 22 | // :10:15: error: cannot dereference slice with undefined length | ||
| 23 | // :16:19: error: use of slice with undefined length here causes illegal behavior | ||
test/cases/compile_errors/dereference_slice.zig+1-1| ... | @@ -7,4 +7,4 @@ comptime { | ... | @@ -7,4 +7,4 @@ comptime { |
| 7 | 7 | ||
| 8 | // error | 8 | // error |
| 9 | // | 9 | // |
| 10 | // :2:13: error: index syntax required for slice type '[]i32' | 10 | // :2:13: error: index syntax required to access runtime-known slice |
test/cases/compile_errors/duplicate_boolean_switch_value.zig+2-2| ... | @@ -17,7 +17,7 @@ comptime { | ... | @@ -17,7 +17,7 @@ comptime { |
| 17 | 17 | ||
| 18 | // error | 18 | // error |
| 19 | // | 19 | // |
| 20 | // :5:9: error: duplicate switch value | 20 | // :5:9: error: duplicate switch value 'true' |
| 21 | // :3:9: note: previous value here | 21 | // :3:9: note: previous value here |
| 22 | // :13:9: error: duplicate switch value | 22 | // :13:9: error: duplicate switch value 'false' |
| 23 | // :11:9: note: previous value here | 23 | // :11:9: note: previous value here |
test/cases/compile_errors/duplicate_error_in_switch.zig+1-1| ... | @@ -16,5 +16,5 @@ fn foo(x: i32) !void { | ... | @@ -16,5 +16,5 @@ fn foo(x: i32) !void { |
| 16 | 16 | ||
| 17 | // error | 17 | // error |
| 18 | // | 18 | // |
| 19 | // :5:9: error: duplicate switch value | 19 | // :5:9: error: duplicate switch value 'error.Foo' |
| 20 | // :3:9: note: previous value here | 20 | // :3:9: note: previous value here |
test/cases/compile_errors/ignored_deferred_function_call.zig+2-2| ... | @@ -14,6 +14,6 @@ fn bar2() anyerror { | ... | @@ -14,6 +14,6 @@ fn bar2() anyerror { |
| 14 | 14 | ||
| 15 | // error | 15 | // error |
| 16 | // | 16 | // |
| 17 | // :2:14: error: error union is ignored | 17 | // :2:14: error: error union of type 'anyerror!i32' is ignored |
| 18 | // :2:14: note: consider using 'try', 'catch', or 'if' | 18 | // :2:14: note: consider using 'try', 'catch', or 'if' |
| 19 | // :9:15: error: error set is ignored | 19 | // :9:15: error: error set of type 'anyerror' is ignored |
test/cases/compile_errors/ignored_expression_in_while_continuation.zig+4-4| ... | @@ -24,10 +24,10 @@ fn bad2() anyerror { | ... | @@ -24,10 +24,10 @@ fn bad2() anyerror { |
| 24 | 24 | ||
| 25 | // error | 25 | // error |
| 26 | // | 26 | // |
| 27 | // :2:24: error: error union is ignored | 27 | // :2:24: error: error union of type 'anyerror!void' is ignored |
| 28 | // :2:24: note: consider using 'try', 'catch', or 'if' | 28 | // :2:24: note: consider using 'try', 'catch', or 'if' |
| 29 | // :7:25: error: error union is ignored | 29 | // :7:25: error: error union of type 'anyerror!void' is ignored |
| 30 | // :7:25: note: consider using 'try', 'catch', or 'if' | 30 | // :7:25: note: consider using 'try', 'catch', or 'if' |
| 31 | // :12:25: error: error union is ignored | 31 | // :12:25: error: error union of type 'anyerror!void' is ignored |
| 32 | // :12:25: note: consider using 'try', 'catch', or 'if' | 32 | // :12:25: note: consider using 'try', 'catch', or 'if' |
| 33 | // :19:25: error: error set is ignored | 33 | // :19:25: error: error set of type 'anyerror' is ignored |
test/cases/compile_errors/initialize_empty_union.zig-31| ... | @@ -28,25 +28,6 @@ export fn init5() void { | ... | @@ -28,25 +28,6 @@ export fn init5() void { |
| 28 | _ = @as(U5, undefined); | 28 | _ = @as(U5, undefined); |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | export fn deref0(ptr: *const U0) void { | ||
| 32 | _ = ptr.*; | ||
| 33 | } | ||
| 34 | export fn deref1(ptr: *const U1) void { | ||
| 35 | _ = ptr.*; | ||
| 36 | } | ||
| 37 | export fn deref2(ptr: *const U2) void { | ||
| 38 | _ = ptr.*; | ||
| 39 | } | ||
| 40 | export fn deref3(ptr: *const U3) void { | ||
| 41 | _ = ptr.*; | ||
| 42 | } | ||
| 43 | export fn deref4(ptr: *const U4) void { | ||
| 44 | _ = ptr.*; | ||
| 45 | } | ||
| 46 | export fn deref5(ptr: *const U5) void { | ||
| 47 | _ = ptr.*; | ||
| 48 | } | ||
| 49 | |||
| 50 | // error | 31 | // error |
| 51 | // | 32 | // |
| 52 | // :13:17: error: expected type 'tmp.U0', found '@TypeOf(undefined)' | 33 | // :13:17: error: expected type 'tmp.U0', found '@TypeOf(undefined)' |
| ... | @@ -67,15 +48,3 @@ export fn deref5(ptr: *const U5) void { | ... | @@ -67,15 +48,3 @@ export fn deref5(ptr: *const U5) void { |
| 67 | // :28:17: error: expected type 'tmp.U5', found '@TypeOf(undefined)' | 48 | // :28:17: error: expected type 'tmp.U5', found '@TypeOf(undefined)' |
| 68 | // :28:17: note: cannot coerce to uninstantiable type 'tmp.U5' | 49 | // :28:17: note: cannot coerce to uninstantiable type 'tmp.U5' |
| 69 | // :10:12: note: union declared here | 50 | // :10:12: note: union declared here |
| 70 | // :32:12: error: cannot load uninstantiable type 'tmp.U0' | ||
| 71 | // :5:12: note: union declared here | ||
| 72 | // :35:12: error: cannot load uninstantiable type 'tmp.U1' | ||
| 73 | // :6:12: note: union declared here | ||
| 74 | // :38:12: error: cannot load uninstantiable type 'tmp.U2' | ||
| 75 | // :7:12: note: union declared here | ||
| 76 | // :41:12: error: cannot load uninstantiable type 'tmp.U3' | ||
| 77 | // :8:12: note: union declared here | ||
| 78 | // :44:12: error: cannot load uninstantiable type 'tmp.U4' | ||
| 79 | // :9:12: note: union declared here | ||
| 80 | // :47:12: error: cannot load uninstantiable type 'tmp.U5' | ||
| 81 | // :10:12: note: union declared here |
test/cases/compile_errors/invalid_float_casts.zig+1-1| ... | @@ -22,6 +22,6 @@ export fn qux() void { | ... | @@ -22,6 +22,6 @@ export fn qux() void { |
| 22 | // error | 22 | // error |
| 23 | // | 23 | // |
| 24 | // :4:40: error: unable to cast runtime value to 'comptime_float' | 24 | // :4:40: error: unable to cast runtime value to 'comptime_float' |
| 25 | // :9:18: error: expected integer type, found 'f32' | 25 | // :9:18: error: expected integer result type, found 'f32' |
| 26 | // :14:32: error: expected integer type, found 'f32' | 26 | // :14:32: error: expected integer type, found 'f32' |
| 27 | // :19:29: error: expected float or vector type, found 'u32' | 27 | // :19:29: error: expected float or vector type, found 'u32' |
test/cases/compile_errors/invalid_int_casts.zig+7-3| ... | @@ -8,6 +8,9 @@ export fn bar() void { | ... | @@ -8,6 +8,9 @@ export fn bar() void { |
| 8 | _ = &a; | 8 | _ = &a; |
| 9 | _ = @as(u32, @floatFromInt(a)); | 9 | _ = @as(u32, @floatFromInt(a)); |
| 10 | } | 10 | } |
| 11 | export fn bar2() void { | ||
| 12 | _ = @as(comptime_int, @floatFromInt(2)); | ||
| 13 | } | ||
| 11 | export fn baz() void { | 14 | export fn baz() void { |
| 12 | var a: u32 = 2; | 15 | var a: u32 = 2; |
| 13 | _ = &a; | 16 | _ = &a; |
| ... | @@ -22,6 +25,7 @@ export fn qux() void { | ... | @@ -22,6 +25,7 @@ export fn qux() void { |
| 22 | // error | 25 | // error |
| 23 | // | 26 | // |
| 24 | // :4:36: error: unable to cast runtime value to 'comptime_int' | 27 | // :4:36: error: unable to cast runtime value to 'comptime_int' |
| 25 | // :9:18: error: expected float type, found 'u32' | 28 | // :9:18: error: expected float result type, found 'u32' |
| 26 | // :14:32: error: expected float type, found 'u32' | 29 | // :12:27: error: expected float result type, found 'comptime_int' |
| 27 | // :19:27: error: expected integer or vector, found 'f32' | 30 | // :17:32: error: expected float type, found 'u32' |
| 31 | // :22:27: error: expected integer or vector, found 'f32' |
test/cases/compile_errors/invalid_member_of_builtin_enum.zig+1-1| ... | @@ -6,5 +6,5 @@ export fn entry() void { | ... | @@ -6,5 +6,5 @@ export fn entry() void { |
| 6 | 6 | ||
| 7 | // error | 7 | // error |
| 8 | // | 8 | // |
| 9 | // :3:35: error: enum 'lang.OptimizeMode' has no member named 'x86' | 9 | // :3:35: error: enum 'lang.Optimize' has no member named 'x86' |
| 10 | // : note: enum declared here | 10 | // : note: enum declared here |
test/cases/compile_errors/slice_to_array_pointer.zig created+70| ... | @@ -0,0 +1,70 @@ | ||
| 1 | export fn entry1() void { | ||
| 2 | var array: [2]u16 = .{ 1, 2 }; | ||
| 3 | const slice: []const u16 = &array; | ||
| 4 | foo(slice); | ||
| 5 | } | ||
| 6 | |||
| 7 | export fn entry2() void { | ||
| 8 | const slice: []const u16 = undefined; | ||
| 9 | foo(slice); | ||
| 10 | } | ||
| 11 | |||
| 12 | export fn entry3() void { | ||
| 13 | comptime var slice: []const u16 = &.{ 1, 2 }; | ||
| 14 | slice.len = undefined; | ||
| 15 | foo(slice); | ||
| 16 | } | ||
| 17 | |||
| 18 | export fn entry4() void { | ||
| 19 | const slice: []const u16 = &.{ 1, 2, 3 }; | ||
| 20 | foo(slice); | ||
| 21 | } | ||
| 22 | |||
| 23 | export fn entry5() void { | ||
| 24 | const slice: []const u8 = &.{ 1, 2 }; | ||
| 25 | foo(slice); | ||
| 26 | } | ||
| 27 | |||
| 28 | fn foo(x: *const [2]u16) void { | ||
| 29 | _ = x; | ||
| 30 | } | ||
| 31 | |||
| 32 | export fn entry6() void { | ||
| 33 | const slice: [:0]const u16 = &.{ 1, 2, 3 }; | ||
| 34 | bar(slice); | ||
| 35 | } | ||
| 36 | |||
| 37 | export fn entry7() void { | ||
| 38 | const slice: [:1]const u16 = &.{ 1, 2 }; | ||
| 39 | bar(slice); | ||
| 40 | } | ||
| 41 | |||
| 42 | export fn entry8() void { | ||
| 43 | const slice: []const u16 = &.{ 1, 2 }; | ||
| 44 | bar(slice); | ||
| 45 | } | ||
| 46 | |||
| 47 | fn bar(x: *const [2:0]u16) void { | ||
| 48 | _ = x; | ||
| 49 | } | ||
| 50 | |||
| 51 | // error | ||
| 52 | // | ||
| 53 | // :4:9: error: coercion from slice to array pointer type '*const [2]u16' requires length to be known at compile-time | ||
| 54 | // :9:9: error: slice with undefined length cannot cast into array pointer type '*const [2]u16' | ||
| 55 | // :9:9: note: length of slice must be defined and match length of array type | ||
| 56 | // :15:9: error: slice with undefined length cannot cast into array pointer type '*const [2]u16' | ||
| 57 | // :15:9: note: length of slice must be defined and match length of array type | ||
| 58 | // :20:9: error: slice of length 3 cannot cast into array pointer type '*const [2]u16' | ||
| 59 | // :20:9: note: length of slice must match length of array type | ||
| 60 | // :25:9: error: expected type '*const [2]u16', found '[]const u8' | ||
| 61 | // :25:9: note: pointer type child 'u8' cannot cast into pointer type child 'u16' | ||
| 62 | // :28:11: note: parameter type declared here | ||
| 63 | // :34:9: error: slice of length 3 cannot cast into array pointer type '*const [2:0]u16' | ||
| 64 | // :34:9: note: length of slice must match length of array type | ||
| 65 | // :39:9: error: expected type '*const [2:0]u16', found '[:1]const u16' | ||
| 66 | // :39:9: note: pointer sentinel '1' cannot cast into pointer sentinel '0' | ||
| 67 | // :47:11: note: parameter type declared here | ||
| 68 | // :44:9: error: expected type '*const [2:0]u16', found '[]const u16' | ||
| 69 | // :44:9: note: destination pointer requires '0' sentinel | ||
| 70 | // :47:11: note: parameter type declared here | ||
test/cases/compile_errors/switch_expression-duplicate_enumeration_prong.zig+2-1| ... | @@ -20,5 +20,6 @@ export fn entry() usize { | ... | @@ -20,5 +20,6 @@ export fn entry() usize { |
| 20 | 20 | ||
| 21 | // error | 21 | // error |
| 22 | // | 22 | // |
| 23 | // :13:15: error: duplicate switch value | 23 | // :13:15: error: duplicate switch value '.Two' |
| 24 | // :10:15: note: previous value here | 24 | // :10:15: note: previous value here |
| 25 | // :1:16: note: enum declared here |
test/cases/compile_errors/switch_expression-duplicate_enumeration_prong_when_else_present.zig+2-1| ... | @@ -21,5 +21,6 @@ export fn entry() usize { | ... | @@ -21,5 +21,6 @@ export fn entry() usize { |
| 21 | 21 | ||
| 22 | // error | 22 | // error |
| 23 | // | 23 | // |
| 24 | // :13:15: error: duplicate switch value | 24 | // :13:15: error: duplicate switch value '.Two' |
| 25 | // :10:15: note: previous value here | 25 | // :10:15: note: previous value here |
| 26 | // :1:16: note: enum declared here |
test/cases/compile_errors/switch_expression-duplicate_error_prong.zig+2-2| ... | @@ -25,7 +25,7 @@ export fn entry() usize { | ... | @@ -25,7 +25,7 @@ export fn entry() usize { |
| 25 | 25 | ||
| 26 | // error | 26 | // error |
| 27 | // | 27 | // |
| 28 | // :8:9: error: duplicate switch value | 28 | // :8:9: error: duplicate switch value 'error.Foo' |
| 29 | // :5:9: note: previous value here | 29 | // :5:9: note: previous value here |
| 30 | // :16:9: error: duplicate switch value | 30 | // :16:9: error: duplicate switch value 'error.Foo' |
| 31 | // :13:9: note: previous value here | 31 | // :13:9: note: previous value here |
test/cases/compile_errors/switch_expression-duplicate_error_prong_when_else_present.zig+2-2| ... | @@ -27,7 +27,7 @@ export fn entry() usize { | ... | @@ -27,7 +27,7 @@ export fn entry() usize { |
| 27 | 27 | ||
| 28 | // error | 28 | // error |
| 29 | // | 29 | // |
| 30 | // :8:9: error: duplicate switch value | 30 | // :8:9: error: duplicate switch value 'error.Foo' |
| 31 | // :5:9: note: previous value here | 31 | // :5:9: note: previous value here |
| 32 | // :17:9: error: duplicate switch value | 32 | // :17:9: error: duplicate switch value 'error.Foo' |
| 33 | // :14:9: note: previous value here | 33 | // :14:9: note: previous value here |
test/cases/compile_errors/switch_expression-duplicate_or_overlapping_integer_value.zig deleted-16| ... | @@ -1,16 +0,0 @@ | ||
| 1 | fn foo(x: u8) u8 { | ||
| 2 | return switch (x) { | ||
| 3 | 0...100 => @as(u8, 0), | ||
| 4 | 101...200 => 1, | ||
| 5 | 201, 203...207 => 2, | ||
| 6 | 206...255 => 3, | ||
| 7 | }; | ||
| 8 | } | ||
| 9 | export fn entry() usize { | ||
| 10 | return @sizeOf(@TypeOf(&foo)); | ||
| 11 | } | ||
| 12 | |||
| 13 | // error | ||
| 14 | // | ||
| 15 | // :6:12: error: duplicate switch value | ||
| 16 | // :5:17: note: previous value here | ||
test/cases/compile_errors/switch_expression-duplicate_type.zig+1-1| ... | @@ -13,5 +13,5 @@ export fn entry() usize { | ... | @@ -13,5 +13,5 @@ export fn entry() usize { |
| 13 | 13 | ||
| 14 | // error | 14 | // error |
| 15 | // | 15 | // |
| 16 | // :6:9: error: duplicate switch value | 16 | // :6:9: error: duplicate switch value 'u32' |
| 17 | // :4:9: note: previous value here | 17 | // :4:9: note: previous value here |
test/cases/compile_errors/switch_expression-duplicate_type_struct_alias.zig+2-1| ... | @@ -17,5 +17,6 @@ export fn entry() usize { | ... | @@ -17,5 +17,6 @@ export fn entry() usize { |
| 17 | 17 | ||
| 18 | // error | 18 | // error |
| 19 | // | 19 | // |
| 20 | // :10:9: error: duplicate switch value | 20 | // :10:9: error: duplicate switch value 'tmp.Test' |
| 21 | // :8:9: note: previous value here | 21 | // :8:9: note: previous value here |
| 22 | // :1:14: note: struct declared here |
test/cases/compile_errors/switch_on_invalid_type.zig created+103| ... | @@ -0,0 +1,103 @@ | ||
| 1 | const AutoUnion = union { a: u8 }; | ||
| 2 | export fn entry1() void { | ||
| 3 | switch (@as(AutoUnion, .{ .a = 123 })) { | ||
| 4 | else => {}, | ||
| 5 | } | ||
| 6 | } | ||
| 7 | |||
| 8 | const ExternUnion = union { a: u8 }; | ||
| 9 | export fn entry2() void { | ||
| 10 | switch (@as(ExternUnion, .{ .a = 123 })) { | ||
| 11 | else => {}, | ||
| 12 | } | ||
| 13 | } | ||
| 14 | |||
| 15 | const AutoStruct = struct { a: u8 }; | ||
| 16 | export fn entry3() void { | ||
| 17 | switch (@as(AutoStruct, .{ .a = 123 })) { | ||
| 18 | else => {}, | ||
| 19 | } | ||
| 20 | } | ||
| 21 | |||
| 22 | const ExternStruct = extern struct { a: u8 }; | ||
| 23 | export fn entry4() void { | ||
| 24 | switch (@as(ExternStruct, .{ .a = 123 })) { | ||
| 25 | else => {}, | ||
| 26 | } | ||
| 27 | } | ||
| 28 | |||
| 29 | export fn entry5() void { | ||
| 30 | switch (@as([]const u16, &.{ 1, 2, 3 })) { | ||
| 31 | else => {}, | ||
| 32 | } | ||
| 33 | } | ||
| 34 | |||
| 35 | export fn entry6() void { | ||
| 36 | switch (@as([3]u16, .{ 1, 2, 3 })) { | ||
| 37 | else => {}, | ||
| 38 | } | ||
| 39 | } | ||
| 40 | |||
| 41 | export fn entry7() void { | ||
| 42 | switch (@as(@Vector(3, u16), .{ 1, 2, 3 })) { | ||
| 43 | else => {}, | ||
| 44 | } | ||
| 45 | } | ||
| 46 | |||
| 47 | export fn entry8() void { | ||
| 48 | switch (@as(?u16, 123)) { | ||
| 49 | else => {}, | ||
| 50 | } | ||
| 51 | } | ||
| 52 | |||
| 53 | export fn entry9() void { | ||
| 54 | switch (@as(anyerror!u16, 123)) { | ||
| 55 | else => {}, | ||
| 56 | } | ||
| 57 | } | ||
| 58 | |||
| 59 | export fn entry10() void { | ||
| 60 | switch (@as(f32, 123)) { | ||
| 61 | else => {}, | ||
| 62 | } | ||
| 63 | } | ||
| 64 | |||
| 65 | export fn entry11() void { | ||
| 66 | switch (@as(comptime_float, 123)) { | ||
| 67 | else => {}, | ||
| 68 | } | ||
| 69 | } | ||
| 70 | |||
| 71 | export fn entry12() void { | ||
| 72 | switch (undefined) { | ||
| 73 | else => {}, | ||
| 74 | } | ||
| 75 | } | ||
| 76 | |||
| 77 | export fn entry13() void { | ||
| 78 | switch (null) { | ||
| 79 | else => {}, | ||
| 80 | } | ||
| 81 | } | ||
| 82 | |||
| 83 | // error | ||
| 84 | // | ||
| 85 | // :3:13: error: switch on union with no attached enum | ||
| 86 | // :1:19: note: consider 'union(enum)' here | ||
| 87 | // :10:13: error: switch on union with no attached enum | ||
| 88 | // :8:21: note: consider 'union(enum)' here | ||
| 89 | // :17:13: error: switch on non-packed struct | ||
| 90 | // :15:20: note: struct declared here | ||
| 91 | // :24:13: error: switch on non-packed struct | ||
| 92 | // :22:29: note: struct declared here | ||
| 93 | // :30:13: error: switch on type '[]const u16' | ||
| 94 | // :36:13: error: switch on type '[3]u16' | ||
| 95 | // :42:13: error: switch on type '@Vector(3, u16)' | ||
| 96 | // :48:13: error: switch on optional type '?u16' | ||
| 97 | // :48:13: note: consider using '.?', 'orelse', or 'if' | ||
| 98 | // :54:13: error: switch on error union type 'anyerror!u16' | ||
| 99 | // :54:13: note: consider using 'try', 'catch', or 'if' | ||
| 100 | // :60:13: error: switch on type 'f32' | ||
| 101 | // :66:13: error: switch on type 'comptime_float' | ||
| 102 | // :72:13: error: switch on type '@TypeOf(undefined)' | ||
| 103 | // :78:13: error: switch on type '@TypeOf(null)' | ||
test/cases/compile_errors/switch_on_non_packed_struct.zig deleted-25| ... | @@ -1,25 +0,0 @@ | ||
| 1 | const Auto = struct { | ||
| 2 | a: u8, | ||
| 3 | }; | ||
| 4 | export fn entry1(a: u8) void { | ||
| 5 | const s: Auto = .{ .a = a }; | ||
| 6 | switch (s) { | ||
| 7 | else => {}, | ||
| 8 | } | ||
| 9 | } | ||
| 10 | |||
| 11 | const Extern = extern struct { | ||
| 12 | a: u8, | ||
| 13 | }; | ||
| 14 | export fn entry2(s: Extern) void { | ||
| 15 | switch (s) { | ||
| 16 | else => {}, | ||
| 17 | } | ||
| 18 | } | ||
| 19 | |||
| 20 | // error | ||
| 21 | // | ||
| 22 | // :6:13: error: switch on struct with auto layout | ||
| 23 | // :1:14: note: consider 'packed struct' here | ||
| 24 | // :15:13: error: switch on struct with extern layout | ||
| 25 | // :11:23: note: consider 'packed struct' here | ||
test/cases/compile_errors/switch_on_union_with_nonexhaustive_tag_is_exhaustive.zig created+56| ... | @@ -0,0 +1,56 @@ | ||
| 1 | const E = enum(u8) { | ||
| 2 | a, | ||
| 3 | b, | ||
| 4 | _, | ||
| 5 | }; | ||
| 6 | const U = union(E) { | ||
| 7 | a, | ||
| 8 | b, | ||
| 9 | }; | ||
| 10 | fn foo() U { | ||
| 11 | return undefined; | ||
| 12 | } | ||
| 13 | |||
| 14 | export fn entry1() void { | ||
| 15 | const u = foo(); | ||
| 16 | switch (u) { | ||
| 17 | .a => {}, | ||
| 18 | } | ||
| 19 | } | ||
| 20 | export fn entry2() void { | ||
| 21 | const u = foo(); | ||
| 22 | switch (u) { | ||
| 23 | .a => {}, | ||
| 24 | .b => {}, | ||
| 25 | else => {}, | ||
| 26 | } | ||
| 27 | } | ||
| 28 | export fn entry3() void { | ||
| 29 | const u = foo(); | ||
| 30 | switch (u) { | ||
| 31 | .a => {}, | ||
| 32 | .b => {}, | ||
| 33 | _ => {}, | ||
| 34 | } | ||
| 35 | } | ||
| 36 | export fn entry4() void { | ||
| 37 | const u = foo(); | ||
| 38 | switch (u) { | ||
| 39 | .a => {}, | ||
| 40 | else => {}, | ||
| 41 | _ => {}, | ||
| 42 | } | ||
| 43 | } | ||
| 44 | |||
| 45 | // error | ||
| 46 | // | ||
| 47 | // :16:5: error: switch must handle all possibilities | ||
| 48 | // :3:5: note: unhandled enumeration value: 'b' | ||
| 49 | // :1:11: note: enum 'tmp.E' declared here | ||
| 50 | // :25:14: error: unreachable else prong; all cases already handled | ||
| 51 | // :30:5: error: '_' prong only allowed when switching on non-exhaustive enums | ||
| 52 | // :33:9: note: '_' prong here | ||
| 53 | // :30:5: note: consider using 'else' | ||
| 54 | // :38:5: error: '_' prong only allowed when switching on non-exhaustive enums | ||
| 55 | // :41:9: note: '_' prong here | ||
| 56 | // :38:5: note: consider using 'else' | ||
test/cases/compile_errors/switch_with_overlapping_case_ranges.zig+36-6| ... | @@ -28,13 +28,43 @@ export fn entry4(x: u8) void { | ... | @@ -28,13 +28,43 @@ export fn entry4(x: u8) void { |
| 28 | } | 28 | } |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | export fn entry5(x: u8) void { | ||
| 32 | switch (x) { | ||
| 33 | 0...255 => {}, | ||
| 34 | 4...120 => {}, | ||
| 35 | } | ||
| 36 | } | ||
| 37 | |||
| 38 | export fn entry6(x: u8) void { | ||
| 39 | switch (x) { | ||
| 40 | 0...130 => {}, | ||
| 41 | 120...255 => {}, | ||
| 42 | } | ||
| 43 | } | ||
| 44 | |||
| 45 | export fn entry7(x: u8) void { | ||
| 46 | switch (x) { | ||
| 47 | 2 => {}, | ||
| 48 | 0...255 => {}, | ||
| 49 | } | ||
| 50 | } | ||
| 51 | |||
| 31 | // error | 52 | // error |
| 32 | // | 53 | // |
| 33 | // :4:10: error: duplicate switch value | 54 | // :4:10: error: duplicate switch ranges |
| 34 | // :3:10: note: previous value here | 55 | // :3:10: note: overlaps with previous range here |
| 35 | // :11:10: error: duplicate switch value | 56 | // :3:10: note: ranges overlap from '1' to '2' |
| 36 | // :10:13: note: previous value here | 57 | // :11:10: error: duplicate switch value '5' |
| 37 | // :17:10: error: duplicate switch value | 58 | // :10:13: note: previous value inside range here |
| 59 | // :17:10: error: duplicate switch value '5' | ||
| 38 | // :18:9: note: previous value here | 60 | // :18:9: note: previous value here |
| 39 | // :27:10: error: duplicate switch value | 61 | // :27:10: error: duplicate switch value '6' |
| 40 | // :26:9: note: previous value here | 62 | // :26:9: note: previous value here |
| 63 | // :34:10: error: duplicate switch ranges | ||
| 64 | // :33:10: note: overlaps with previous range here | ||
| 65 | // :33:10: note: ranges overlap from '4' to '120' | ||
| 66 | // :41:12: error: duplicate switch ranges | ||
| 67 | // :40:10: note: overlaps with previous range here | ||
| 68 | // :40:10: note: ranges overlap from '120' to '130' | ||
| 69 | // :48:10: error: duplicate switch value '2' | ||
| 70 | // :47:9: note: previous value here |
test/cases/safety/@errorCast error not present in destination.zig	+1-1| ... | @@ -2,7 +2,7 @@ const std = @import("std"); | ... | @@ -2,7 +2,7 @@ const std = @import("std"); |
| 2 | 2 | ||
| 3 | pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn { | 3 | pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn { |
| 4 | _ = stack_trace; | 4 | _ = stack_trace; |
| 5 | if (std.mem.eql(u8, message, "invalid error code")) { | 5 | if (std.mem.eql(u8, message, "unexpected error code, found error.B")) { |
| 6 | std.process.exit(0); | 6 | std.process.exit(0); |
| 7 | } | 7 | } |
| 8 | std.process.exit(1); | 8 | std.process.exit(1); |
test/cases/safety/@errorCast error union casted to disjoint set.zig	+1-1| ... | @@ -2,7 +2,7 @@ const std = @import("std"); | ... | @@ -2,7 +2,7 @@ const std = @import("std"); |
| 2 | 2 | ||
| 3 | pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn { | 3 | pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn { |
| 4 | _ = stack_trace; | 4 | _ = stack_trace; |
| 5 | if (std.mem.eql(u8, message, "invalid error code")) { | 5 | if (std.mem.eql(u8, message, "unexpected error code, found error.Bar")) { |
| 6 | std.process.exit(0); | 6 | std.process.exit(0); |
| 7 | } | 7 | } |
| 8 | std.process.exit(1); | 8 | std.process.exit(1); |
test/cases/safety/load_uninstantiable_enum.zig created+20| ... | @@ -0,0 +1,20 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | |||
| 3 | pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn { | ||
| 4 | _ = stack_trace; | ||
| 5 | if (std.mem.eql(u8, message, "attempt to load uninstantiable type")) { | ||
| 6 | std.process.exit(0); | ||
| 7 | } | ||
| 8 | std.process.exit(1); | ||
| 9 | } | ||
| 10 | |||
| 11 | const E = enum {}; | ||
| 12 | pub fn main() error{TestFailed}!void { | ||
| 13 | const bytes: [32]u8 = @splat(0); | ||
| 14 | const ptr: *const E = @ptrCast(&bytes); | ||
| 15 | _ = ptr.*; | ||
| 16 | return error.TestFailed; | ||
| 17 | } | ||
| 18 | // run | ||
| 19 | // backend=selfhosted,llvm | ||
| 20 | // target=x86_64-linux,aarch64-linux,wasm32-wasi | ||
test/cases/safety/load_uninstantiable_enum_from_slice.zig created+21| ... | @@ -0,0 +1,21 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | |||
| 3 | pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn { | ||
| 4 | _ = stack_trace; | ||
| 5 | if (std.mem.eql(u8, message, "attempt to load uninstantiable type")) { | ||
| 6 | std.process.exit(0); | ||
| 7 | } | ||
| 8 | std.process.exit(1); | ||
| 9 | } | ||
| 10 | |||
| 11 | const E = enum {}; | ||
| 12 | pub fn main() error{TestFailed}!void { | ||
| 13 | const bytes: [32]u8 = @splat(0); | ||
| 14 | const ptr: *const [1]E = @ptrCast(&bytes); | ||
| 15 | const slice: []const E = ptr; | ||
| 16 | _ = slice[0]; | ||
| 17 | return error.TestFailed; | ||
| 18 | } | ||
| 19 | // run | ||
| 20 | // backend=selfhosted,llvm | ||
| 21 | // target=x86_64-linux,aarch64-linux,wasm32-wasi | ||
test/cases/safety/load_uninstantiable_union.zig created+23| ... | @@ -0,0 +1,23 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | |||
| 3 | pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn { | ||
| 4 | _ = stack_trace; | ||
| 5 | if (std.mem.eql(u8, message, "attempt to load uninstantiable type")) { | ||
| 6 | std.process.exit(0); | ||
| 7 | } | ||
| 8 | std.process.exit(1); | ||
| 9 | } | ||
| 10 | |||
| 11 | const U = union { | ||
| 12 | foo: struct { a: u8, b: noreturn, }, | ||
| 13 | bar: enum {}, | ||
| 14 | }; | ||
| 15 | pub fn main() error{TestFailed}!void { | ||
| 16 | const bytes: [32]u8 = @splat(0); | ||
| 17 | const ptr: *const U = @ptrCast(&bytes); | ||
| 18 | _ = ptr.*; | ||
| 19 | return error.TestFailed; | ||
| 20 | } | ||
| 21 | // run | ||
| 22 | // backend=selfhosted,llvm | ||
| 23 | // target=x86_64-linux,aarch64-linux,wasm32-wasi | ||
test/cases/safety/load_uninstantiable_union_from_slice.zig created+24| ... | @@ -0,0 +1,24 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | |||
| 3 | pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn { | ||
| 4 | _ = stack_trace; | ||
| 5 | if (std.mem.eql(u8, message, "attempt to load uninstantiable type")) { | ||
| 6 | std.process.exit(0); | ||
| 7 | } | ||
| 8 | std.process.exit(1); | ||
| 9 | } | ||
| 10 | |||
| 11 | const U = union { | ||
| 12 | foo: struct { a: u8, b: noreturn, }, | ||
| 13 | bar: enum {}, | ||
| 14 | }; | ||
| 15 | pub fn main() error{TestFailed}!void { | ||
| 16 | const bytes: [32]u8 = @splat(0); | ||
| 17 | const ptr: *const [1]U = @ptrCast(&bytes); | ||
| 18 | const slice: []const U = ptr; | ||
| 19 | _ = slice[0]; | ||
| 20 | return error.TestFailed; | ||
| 21 | } | ||
| 22 | // run | ||
| 23 | // backend=selfhosted,llvm | ||
| 24 | // target=x86_64-linux,aarch64-linux,wasm32-wasi | ||
test/error_traces.zig+41-2| ... | @@ -1,7 +1,10 @@ | ... | @@ -1,7 +1,10 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const Context = @import("tests.zig").ErrorTracesContext; | ||
| 2 | 3 | ||
| 3 | pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target.Os.Tag) void { | 4 | pub fn addCases(cases: *Context, params: *const Context.CaseParameters, target: *const std.Target) void { |
| 4 | cases.addCase(.{ | 5 | cases.addCase(.{ |
| 6 | .params = params, | ||
| 7 | .target = target, | ||
| 5 | .name = "return", | 8 | .name = "return", |
| 6 | .source = | 9 | .source = |
| 7 | \\pub fn main() !void { | 10 | \\pub fn main() !void { |
| ... | @@ -17,6 +20,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. | ... | @@ -17,6 +20,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. |
| 17 | }); | 20 | }); |
| 18 | 21 | ||
| 19 | cases.addCase(.{ | 22 | cases.addCase(.{ |
| 23 | .params = params, | ||
| 24 | .target = target, | ||
| 20 | .name = "try return", | 25 | .name = "try return", |
| 21 | .source = | 26 | .source = |
| 22 | \\fn foo() !void { | 27 | \\fn foo() !void { |
| ... | @@ -44,6 +49,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. | ... | @@ -44,6 +49,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. |
| 44 | }, | 49 | }, |
| 45 | }); | 50 | }); |
| 46 | cases.addCase(.{ | 51 | cases.addCase(.{ |
| 52 | .params = params, | ||
| 53 | .target = target, | ||
| 47 | .name = "non-error return pops error trace", | 54 | .name = "non-error return pops error trace", |
| 48 | .source = | 55 | .source = |
| 49 | \\fn bar() !void { | 56 | \\fn bar() !void { |
| ... | @@ -70,6 +77,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. | ... | @@ -70,6 +77,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. |
| 70 | }); | 77 | }); |
| 71 | 78 | ||
| 72 | cases.addCase(.{ | 79 | cases.addCase(.{ |
| 80 | .params = params, | ||
| 81 | .target = target, | ||
| 73 | .name = "continue in while loop", | 82 | .name = "continue in while loop", |
| 74 | .source = | 83 | .source = |
| 75 | \\fn foo() !void { | 84 | \\fn foo() !void { |
| ... | @@ -93,6 +102,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. | ... | @@ -93,6 +102,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. |
| 93 | }); | 102 | }); |
| 94 | 103 | ||
| 95 | cases.addCase(.{ | 104 | cases.addCase(.{ |
| 105 | .params = params, | ||
| 106 | .target = target, | ||
| 96 | .name = "for loop pops error return trace", | 107 | .name = "for loop pops error return trace", |
| 97 | .source = | 108 | .source = |
| 98 | \\fn foo() !void { return error.FooError; } | 109 | \\fn foo() !void { return error.FooError; } |
| ... | @@ -123,6 +134,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. | ... | @@ -123,6 +134,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. |
| 123 | }); | 134 | }); |
| 124 | 135 | ||
| 125 | cases.addCase(.{ | 136 | cases.addCase(.{ |
| 137 | .params = params, | ||
| 138 | .target = target, | ||
| 126 | .name = "implicit continue in for loop pops stale error return trace", | 139 | .name = "implicit continue in for loop pops stale error return trace", |
| 127 | .source = | 140 | .source = |
| 128 | \\fn foo() !void { return error.FooError; } | 141 | \\fn foo() !void { return error.FooError; } |
| ... | @@ -154,6 +167,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. | ... | @@ -154,6 +167,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. |
| 154 | }); | 167 | }); |
| 155 | 168 | ||
| 156 | cases.addCase(.{ | 169 | cases.addCase(.{ |
| 170 | .params = params, | ||
| 171 | .target = target, | ||
| 157 | .name = "while loop pops error return trace", | 172 | .name = "while loop pops error return trace", |
| 158 | .source = | 173 | .source = |
| 159 | \\fn foo() !void { return error.FooError; } | 174 | \\fn foo() !void { return error.FooError; } |
| ... | @@ -186,6 +201,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. | ... | @@ -186,6 +201,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. |
| 186 | }); | 201 | }); |
| 187 | 202 | ||
| 188 | cases.addCase(.{ | 203 | cases.addCase(.{ |
| 204 | .params = params, | ||
| 205 | .target = target, | ||
| 189 | .name = "implicit continue in while loop pops stale error return trace", | 206 | .name = "implicit continue in while loop pops stale error return trace", |
| 190 | .source = | 207 | .source = |
| 191 | \\fn foo() !void { return error.FooError; } | 208 | \\fn foo() !void { return error.FooError; } |
| ... | @@ -219,6 +236,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. | ... | @@ -219,6 +236,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. |
| 219 | }); | 236 | }); |
| 220 | 237 | ||
| 221 | cases.addCase(.{ | 238 | cases.addCase(.{ |
| 239 | .params = params, | ||
| 240 | .target = target, | ||
| 222 | .name = "try return + handled catch/if-else", | 241 | .name = "try return + handled catch/if-else", |
| 223 | .source = | 242 | .source = |
| 224 | \\fn foo() !void { | 243 | \\fn foo() !void { |
| ... | @@ -251,6 +270,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. | ... | @@ -251,6 +270,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. |
| 251 | }); | 270 | }); |
| 252 | 271 | ||
| 253 | cases.addCase(.{ | 272 | cases.addCase(.{ |
| 273 | .params = params, | ||
| 274 | .target = target, | ||
| 254 | .name = "break from inline loop pops error return trace", | 275 | .name = "break from inline loop pops error return trace", |
| 255 | .source = | 276 | .source = |
| 256 | \\fn foo() !void { return error.FooBar; } | 277 | \\fn foo() !void { return error.FooBar; } |
| ... | @@ -276,6 +297,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. | ... | @@ -276,6 +297,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. |
| 276 | }); | 297 | }); |
| 277 | 298 | ||
| 278 | cases.addCase(.{ | 299 | cases.addCase(.{ |
| 300 | .params = params, | ||
| 301 | .target = target, | ||
| 279 | .name = "catch and re-throw error", | 302 | .name = "catch and re-throw error", |
| 280 | .source = | 303 | .source = |
| 281 | \\fn foo() !void { | 304 | \\fn foo() !void { |
| ... | @@ -304,6 +327,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. | ... | @@ -304,6 +327,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. |
| 304 | }); | 327 | }); |
| 305 | 328 | ||
| 306 | cases.addCase(.{ | 329 | cases.addCase(.{ |
| 330 | .params = params, | ||
| 331 | .target = target, | ||
| 307 | .name = "errors stored in var do not contribute to error trace", | 332 | .name = "errors stored in var do not contribute to error trace", |
| 308 | .source = | 333 | .source = |
| 309 | \\fn foo() !void { | 334 | \\fn foo() !void { |
| ... | @@ -328,6 +353,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. | ... | @@ -328,6 +353,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. |
| 328 | }); | 353 | }); |
| 329 | 354 | ||
| 330 | cases.addCase(.{ | 355 | cases.addCase(.{ |
| 356 | .params = params, | ||
| 357 | .target = target, | ||
| 331 | .name = "error stored in const has trace preserved for duration of block", | 358 | .name = "error stored in const has trace preserved for duration of block", |
| 332 | .source = | 359 | .source = |
| 333 | \\fn foo() !void { return error.TheSkyIsFalling; } | 360 | \\fn foo() !void { return error.TheSkyIsFalling; } |
| ... | @@ -376,6 +403,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. | ... | @@ -376,6 +403,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. |
| 376 | }); | 403 | }); |
| 377 | 404 | ||
| 378 | cases.addCase(.{ | 405 | cases.addCase(.{ |
| 406 | .params = params, | ||
| 407 | .target = target, | ||
| 379 | .name = "error passed to function has its trace preserved for duration of the call", | 408 | .name = "error passed to function has its trace preserved for duration of the call", |
| 380 | .source = | 409 | .source = |
| 381 | \\pub fn expectError(expected_error: anyerror, actual_error: anyerror!void) !void { | 410 | \\pub fn expectError(expected_error: anyerror, actual_error: anyerror!void) !void { |
| ... | @@ -418,6 +447,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. | ... | @@ -418,6 +447,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. |
| 418 | }); | 447 | }); |
| 419 | 448 | ||
| 420 | cases.addCase(.{ | 449 | cases.addCase(.{ |
| 450 | .params = params, | ||
| 451 | .target = target, | ||
| 421 | .name = "try return from within catch", | 452 | .name = "try return from within catch", |
| 422 | .source = | 453 | .source = |
| 423 | \\fn foo() !void { | 454 | \\fn foo() !void { |
| ... | @@ -455,6 +486,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. | ... | @@ -455,6 +486,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. |
| 455 | }); | 486 | }); |
| 456 | 487 | ||
| 457 | cases.addCase(.{ | 488 | cases.addCase(.{ |
| 489 | .params = params, | ||
| 490 | .target = target, | ||
| 458 | .name = "try return from within if-else", | 491 | .name = "try return from within if-else", |
| 459 | .source = | 492 | .source = |
| 460 | \\fn foo() !void { | 493 | \\fn foo() !void { |
| ... | @@ -492,6 +525,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. | ... | @@ -492,6 +525,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. |
| 492 | }); | 525 | }); |
| 493 | 526 | ||
| 494 | cases.addCase(.{ | 527 | cases.addCase(.{ |
| 528 | .params = params, | ||
| 529 | .target = target, | ||
| 495 | .name = "try try return return", | 530 | .name = "try try return return", |
| 496 | .source = | 531 | .source = |
| 497 | \\fn foo() !void { | 532 | \\fn foo() !void { |
| ... | @@ -534,6 +569,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. | ... | @@ -534,6 +569,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. |
| 534 | }); | 569 | }); |
| 535 | 570 | ||
| 536 | cases.addCase(.{ | 571 | cases.addCase(.{ |
| 572 | .params = params, | ||
| 573 | .target = target, | ||
| 537 | .name = "error union switch with call operand", | 574 | .name = "error union switch with call operand", |
| 538 | .source = | 575 | .source = |
| 539 | \\pub fn main() !void { | 576 | \\pub fn main() !void { |
| ... | @@ -579,6 +616,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. | ... | @@ -579,6 +616,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. |
| 579 | }); | 616 | }); |
| 580 | 617 | ||
| 581 | cases.addCase(.{ | 618 | cases.addCase(.{ |
| 619 | .params = params, | ||
| 620 | .target = target, | ||
| 582 | .name = "trace through inline call", | 621 | .name = "trace through inline call", |
| 583 | // The main function has two inline calls to ensure | 622 | // The main function has two inline calls to ensure |
| 584 | // that inlinees in PDBs are properly deduplicated. | 623 | // that inlinees in PDBs are properly deduplicated. |
| ... | @@ -595,7 +634,7 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. | ... | @@ -595,7 +634,7 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. |
| 595 | \\} | 634 | \\} |
| 596 | , | 635 | , |
| 597 | .expect_error = "ThisIsSoSad", | 636 | .expect_error = "ThisIsSoSad", |
| 598 | .expect_trace = switch (os) { | 637 | .expect_trace = switch (target.os.tag) { |
| 599 | // LLVM doesn't emit column info in the binary annotations for inlinee callees in PDBs, | 638 | // LLVM doesn't emit column info in the binary annotations for inlinee callees in PDBs, |
| 600 | // so our expected result is slightly different for Windows than on other operating | 639 | // so our expected result is slightly different for Windows than on other operating |
| 601 | // systems. | 640 | // systems. |
test/incremental/change_panic_handler_explicit+6| ... | @@ -23,6 +23,7 @@ pub const panic = struct { | ... | @@ -23,6 +23,7 @@ pub const panic = struct { |
| 23 | pub const castToNull = no_panic.castToNull; | 23 | pub const castToNull = no_panic.castToNull; |
| 24 | pub const incorrectAlignment = no_panic.incorrectAlignment; | 24 | pub const incorrectAlignment = no_panic.incorrectAlignment; |
| 25 | pub const invalidErrorCode = no_panic.invalidErrorCode; | 25 | pub const invalidErrorCode = no_panic.invalidErrorCode; |
| 26 | pub const unexpectedErrorCode = no_panic.unexpectedErrorCode; | ||
| 26 | pub const integerOutOfBounds = no_panic.integerOutOfBounds; | 27 | pub const integerOutOfBounds = no_panic.integerOutOfBounds; |
| 27 | pub const shlOverflow = no_panic.shlOverflow; | 28 | pub const shlOverflow = no_panic.shlOverflow; |
| 28 | pub const shrOverflow = no_panic.shrOverflow; | 29 | pub const shrOverflow = no_panic.shrOverflow; |
| ... | @@ -36,6 +37,7 @@ pub const panic = struct { | ... | @@ -36,6 +37,7 @@ pub const panic = struct { |
| 36 | pub const copyLenMismatch = no_panic.copyLenMismatch; | 37 | pub const copyLenMismatch = no_panic.copyLenMismatch; |
| 37 | pub const memcpyAlias = no_panic.memcpyAlias; | 38 | pub const memcpyAlias = no_panic.memcpyAlias; |
| 38 | pub const noreturnReturned = no_panic.noreturnReturned; | 39 | pub const noreturnReturned = no_panic.noreturnReturned; |
| 40 | pub const loadUninstantiableType = no_panic.loadUninstantiableType; | ||
| 39 | }; | 41 | }; |
| 40 | fn myPanic(msg: []const u8, _: ?usize) noreturn { | 42 | fn myPanic(msg: []const u8, _: ?usize) noreturn { |
| 41 | var stdout_writer = std.Io.File.stdout().writerStreaming(io, &.{}); | 43 | var stdout_writer = std.Io.File.stdout().writerStreaming(io, &.{}); |
| ... | @@ -71,6 +73,7 @@ pub const panic = struct { | ... | @@ -71,6 +73,7 @@ pub const panic = struct { |
| 71 | pub const castToNull = no_panic.castToNull; | 73 | pub const castToNull = no_panic.castToNull; |
| 72 | pub const incorrectAlignment = no_panic.incorrectAlignment; | 74 | pub const incorrectAlignment = no_panic.incorrectAlignment; |
| 73 | pub const invalidErrorCode = no_panic.invalidErrorCode; | 75 | pub const invalidErrorCode = no_panic.invalidErrorCode; |
| 76 | pub const unexpectedErrorCode = no_panic.unexpectedErrorCode; | ||
| 74 | pub const integerOutOfBounds = no_panic.integerOutOfBounds; | 77 | pub const integerOutOfBounds = no_panic.integerOutOfBounds; |
| 75 | pub const shlOverflow = no_panic.shlOverflow; | 78 | pub const shlOverflow = no_panic.shlOverflow; |
| 76 | pub const shrOverflow = no_panic.shrOverflow; | 79 | pub const shrOverflow = no_panic.shrOverflow; |
| ... | @@ -84,6 +87,7 @@ pub const panic = struct { | ... | @@ -84,6 +87,7 @@ pub const panic = struct { |
| 84 | pub const copyLenMismatch = no_panic.copyLenMismatch; | 87 | pub const copyLenMismatch = no_panic.copyLenMismatch; |
| 85 | pub const memcpyAlias = no_panic.memcpyAlias; | 88 | pub const memcpyAlias = no_panic.memcpyAlias; |
| 86 | pub const noreturnReturned = no_panic.noreturnReturned; | 89 | pub const noreturnReturned = no_panic.noreturnReturned; |
| 90 | pub const loadUninstantiableType = no_panic.loadUninstantiableType; | ||
| 87 | }; | 91 | }; |
| 88 | fn myPanic(msg: []const u8, _: ?usize) noreturn { | 92 | fn myPanic(msg: []const u8, _: ?usize) noreturn { |
| 89 | var stdout_writer = std.Io.File.stdout().writerStreaming(io, &.{}); | 93 | var stdout_writer = std.Io.File.stdout().writerStreaming(io, &.{}); |
| ... | @@ -119,6 +123,7 @@ pub const panic = struct { | ... | @@ -119,6 +123,7 @@ pub const panic = struct { |
| 119 | pub const castToNull = no_panic.castToNull; | 123 | pub const castToNull = no_panic.castToNull; |
| 120 | pub const incorrectAlignment = no_panic.incorrectAlignment; | 124 | pub const incorrectAlignment = no_panic.incorrectAlignment; |
| 121 | pub const invalidErrorCode = no_panic.invalidErrorCode; | 125 | pub const invalidErrorCode = no_panic.invalidErrorCode; |
| 126 | pub const unexpectedErrorCode = no_panic.unexpectedErrorCode; | ||
| 122 | pub const integerOutOfBounds = no_panic.integerOutOfBounds; | 127 | pub const integerOutOfBounds = no_panic.integerOutOfBounds; |
| 123 | pub const shlOverflow = no_panic.shlOverflow; | 128 | pub const shlOverflow = no_panic.shlOverflow; |
| 124 | pub const shrOverflow = no_panic.shrOverflow; | 129 | pub const shrOverflow = no_panic.shrOverflow; |
| ... | @@ -132,6 +137,7 @@ pub const panic = struct { | ... | @@ -132,6 +137,7 @@ pub const panic = struct { |
| 132 | pub const copyLenMismatch = no_panic.copyLenMismatch; | 137 | pub const copyLenMismatch = no_panic.copyLenMismatch; |
| 133 | pub const memcpyAlias = no_panic.memcpyAlias; | 138 | pub const memcpyAlias = no_panic.memcpyAlias; |
| 134 | pub const noreturnReturned = no_panic.noreturnReturned; | 139 | pub const noreturnReturned = no_panic.noreturnReturned; |
| 140 | pub const loadUninstantiableType = no_panic.loadUninstantiableType; | ||
| 135 | }; | 141 | }; |
| 136 | fn myPanicNew(msg: []const u8, _: ?usize) noreturn { | 142 | fn myPanicNew(msg: []const u8, _: ?usize) noreturn { |
| 137 | var stdout_writer = std.Io.File.stdout().writerStreaming(io, &.{}); | 143 | var stdout_writer = std.Io.File.stdout().writerStreaming(io, &.{}); |
test/incremental/temporary_analysis_error_in_generic_signature created+46| ... | @@ -0,0 +1,46 @@ | ||
| 1 | #update=initial version | ||
| 2 | #file=main.zig | ||
| 3 | //! The original repro here depends on re-analysis order, which depends on | ||
| 4 | //! declaration order, so this exact declaration order must be used. | ||
| 5 | const Foo = struct { x: u8 }; | ||
| 6 | pub fn main(init: std.process.Init) !void { | ||
| 7 | const c = bar('Z').x; | ||
| 8 | try std.Io.File.stdout().writeStreamingAll(init.io, &.{ c, '\n' }); | ||
| 9 | } | ||
| 10 | fn bar(comptime x: u8) @This().Foo { | ||
| 11 | return .{ .x = x }; | ||
| 12 | } | ||
| 13 | const std = @import("std"); | ||
| 14 | #expect_stdout="Z\n" | ||
| 15 | |||
| 16 | #update=change generic signature to use non-existent member | ||
| 17 | #file=main.zig | ||
| 18 | //! The original repro here depends on re-analysis order, which depends on | ||
| 19 | //! declaration order, so this exact declaration order must be used. | ||
| 20 | const Foo = struct { x: u8 }; | ||
| 21 | pub fn main(init: std.process.Init) !void { | ||
| 22 | const c = bar('Z').x; | ||
| 23 | try std.Io.File.stdout().writeStreamingAll(init.io, &.{ c, '\n' }); | ||
| 24 | } | ||
| 25 | fn bar(comptime x: u8) @This().FooAlias { | ||
| 26 | return .{ .x = x }; | ||
| 27 | } | ||
| 28 | const std = @import("std"); | ||
| 29 | #expect_error=main.zig:8:31: error: root source file struct 'main' has no member named 'FooAlias' | ||
| 30 | #expect_error=main.zig:1:1: note: struct declared here | ||
| 31 | |||
| 32 | #update=add that member, fixing the error | ||
| 33 | #file=main.zig | ||
| 34 | //! The original repro here depends on re-analysis order, which depends on | ||
| 35 | //! declaration order, so this exact declaration order must be used. | ||
| 36 | const Foo = struct { x: u8 }; | ||
| 37 | const FooAlias = Foo; | ||
| 38 | pub fn main(init: std.process.Init) !void { | ||
| 39 | const c = bar('Z').x; | ||
| 40 | try std.Io.File.stdout().writeStreamingAll(init.io, &.{ c, '\n' }); | ||
| 41 | } | ||
| 42 | fn bar(comptime x: u8) @This().FooAlias { | ||
| 43 | return .{ .x = x }; | ||
| 44 | } | ||
| 45 | const std = @import("std"); | ||
| 46 | #expect_stdout="Z\n" | ||
test/llvm_ir.zig+20| ... | @@ -116,6 +116,26 @@ pub fn addCases(cases: *tests.LlvmIrContext) void { | ... | @@ -116,6 +116,26 @@ pub fn addCases(cases: *tests.LlvmIrContext) void { |
| 116 | "null_pointer_is_valid", | 116 | "null_pointer_is_valid", |
| 117 | "store i16 42, ptr", | 117 | "store i16 42, ptr", |
| 118 | }, .{}); | 118 | }, .{}); |
| 119 | |||
| 120 | cases.addMatches("load and store bool", | ||
| 121 | \\export fn foo(a: *bool, b: *align(2) bool) void { | ||
| 122 | \\ const tmp = a.*; | ||
| 123 | \\ a.* = b.*; | ||
| 124 | \\ b.* = tmp; | ||
| 125 | \\} | ||
| 126 | , &.{ | ||
| 127 | // TODO: this should all be one multiline string literal, but `-femit-llvm-ir` is currently | ||
| 128 | // emitting CRLF on Windows, which is a pain to handle here. In future that option will emit | ||
| 129 | // unoptimized LLVM IR emitted directly from Zig, so that bug will go away. | ||
| 130 | " %3 = load i8, ptr %0, align 1", | ||
| 131 | " %4 = trunc nuw i8 %3 to i1", | ||
| 132 | " %5 = load i8, ptr %1, align 2", | ||
| 133 | " %6 = trunc nuw i8 %5 to i1", | ||
| 134 | " %7 = zext i1 %6 to i8", | ||
| 135 | " store i8 %7, ptr %0, align 1", | ||
| 136 | " %8 = zext i1 %4 to i8", | ||
| 137 | " store i8 %8, ptr %1, align 2", | ||
| 138 | }, .{ .strip = true }); | ||
| 119 | } | 139 | } |
| 120 | 140 | ||
| 121 | const std = @import("std"); | 141 | const std = @import("std"); |
test/llvm_targets.zig+2-2| ... | @@ -106,9 +106,9 @@ const targets = [_]std.Target.Query{ | ... | @@ -106,9 +106,9 @@ const targets = [_]std.Target.Query{ |
| 106 | .{ .cpu_arch = .lanai, .os_tag = .freestanding, .abi = .none }, | 106 | .{ .cpu_arch = .lanai, .os_tag = .freestanding, .abi = .none }, |
| 107 | 107 | ||
| 108 | .{ .cpu_arch = .loongarch32, .os_tag = .freestanding, .abi = .none }, | 108 | .{ .cpu_arch = .loongarch32, .os_tag = .freestanding, .abi = .none }, |
| 109 | // .{ .cpu_arch = .loongarch32, .os_tag = .linux, .abi = .gnu }, | 109 | .{ .cpu_arch = .loongarch32, .os_tag = .linux, .abi = .gnu }, |
| 110 | // .{ .cpu_arch = .loongarch32, .os_tag = .linux, .abi = .gnuf32 }, | 110 | // .{ .cpu_arch = .loongarch32, .os_tag = .linux, .abi = .gnuf32 }, |
| 111 | // .{ .cpu_arch = .loongarch32, .os_tag = .linux, .abi = .gnusf }, | 111 | .{ .cpu_arch = .loongarch32, .os_tag = .linux, .abi = .gnusf }, |
| 112 | // .{ .cpu_arch = .loongarch32, .os_tag = .linux, .abi = .musl }, | 112 | // .{ .cpu_arch = .loongarch32, .os_tag = .linux, .abi = .musl }, |
| 113 | // .{ .cpu_arch = .loongarch32, .os_tag = .linux, .abi = .muslf32 }, | 113 | // .{ .cpu_arch = .loongarch32, .os_tag = .linux, .abi = .muslf32 }, |
| 114 | // .{ .cpu_arch = .loongarch32, .os_tag = .linux, .abi = .muslsf }, | 114 | // .{ .cpu_arch = .loongarch32, .os_tag = .linux, .abi = .muslsf }, |
test/src/Cases.zig+2-2| ... | @@ -491,7 +491,7 @@ pub fn lowerToBuildSteps( | ... | @@ -491,7 +491,7 @@ pub fn lowerToBuildSteps( |
| 491 | 491 | ||
| 492 | for (self.cases.items) |case| { | 492 | for (self.cases.items) |case| { |
| 493 | for (options.test_filters) |test_filter| { | 493 | for (options.test_filters) |test_filter| { |
| 494 | if (std.mem.indexOf(u8, case.name, test_filter)) |_| break; | 494 | if (std.mem.find(u8, case.name, test_filter)) |_| break; |
| 495 | } else if (options.test_filters.len > 0) continue; | 495 | } else if (options.test_filters.len > 0) continue; |
| 496 | 496 | ||
| 497 | if (case.case.? == .Error and options.skip_compile_errors) continue; | 497 | if (case.case.? == .Error and options.skip_compile_errors) continue; |
| ... | @@ -524,7 +524,7 @@ pub fn lowerToBuildSteps( | ... | @@ -524,7 +524,7 @@ pub fn lowerToBuildSteps( |
| 524 | 524 | ||
| 525 | if (options.test_target_filters.len > 0) { | 525 | if (options.test_target_filters.len > 0) { |
| 526 | for (options.test_target_filters) |filter| { | 526 | for (options.test_target_filters) |filter| { |
| 527 | if (std.mem.indexOf(u8, triple_txt, filter) != null) break; | 527 | if (std.mem.find(u8, triple_txt, filter) != null) break; |
| 528 | } else continue; | 528 | } else continue; |
| 529 | } | 529 | } |
| 530 | 530 |
test/src/Debugger.zig+2-2| ... | @@ -2384,13 +2384,13 @@ fn addTest( | ... | @@ -2384,13 +2384,13 @@ fn addTest( |
| 2384 | ) void { | 2384 | ) void { |
| 2385 | if (db.options.test_filters.len > 0) { | 2385 | if (db.options.test_filters.len > 0) { |
| 2386 | for (db.options.test_filters) |test_filter| { | 2386 | for (db.options.test_filters) |test_filter| { |
| 2387 | if (std.mem.indexOf(u8, name, test_filter) != null) break; | 2387 | if (std.mem.find(u8, name, test_filter) != null) break; |
| 2388 | } else return; | 2388 | } else return; |
| 2389 | } | 2389 | } |
| 2390 | if (db.options.test_target_filters.len > 0) { | 2390 | if (db.options.test_target_filters.len > 0) { |
| 2391 | const triple_txt = target.resolved.query.zigTriple(db.b.allocator) catch @panic("OOM"); | 2391 | const triple_txt = target.resolved.query.zigTriple(db.b.allocator) catch @panic("OOM"); |
| 2392 | for (db.options.test_target_filters) |filter| { | 2392 | for (db.options.test_target_filters) |filter| { |
| 2393 | if (std.mem.indexOf(u8, triple_txt, filter) != null) break; | 2393 | if (std.mem.find(u8, triple_txt, filter) != null) break; |
| 2394 | } else return; | 2394 | } else return; |
| 2395 | } | 2395 | } |
| 2396 | const files_wf = db.b.addWriteFiles(); | 2396 | const files_wf = db.b.addWriteFiles(); |
test/src/ErrorTrace.zig+120-53| ... | @@ -1,11 +1,81 @@ | ... | @@ -1,11 +1,81 @@ |
| 1 | const ErrorTrace = @This(); | ||
| 2 | |||
| 3 | const builtin = @import("builtin"); | ||
| 4 | |||
| 5 | const std = @import("std"); | ||
| 6 | const Step = std.Build.Step; | ||
| 7 | const OptimizeMode = std.lang.Optimize; | ||
| 8 | const mem = std.mem; | ||
| 9 | |||
| 10 | const error_traces_cases = @import("../error_traces.zig"); | ||
| 11 | |||
| 1 | b: *std.Build, | 12 | b: *std.Build, |
| 2 | step: *Step, | 13 | step: *Step, |
| 3 | test_filters: []const []const u8, | 14 | test_filters: []const []const u8, |
| 4 | targets: []const std.Build.ResolvedTarget, | 15 | skip_non_native: bool, |
| 5 | optimize_modes: []const OptimizeMode, | 16 | optimize_modes: []const OptimizeMode, |
| 6 | convert_exe: *std.Build.Step.Compile, | 17 | convert_exe: *std.Build.Step.Compile, |
| 7 | 18 | ||
| 19 | pub const CaseParameters = @import("StackTrace.zig").CaseParameters; | ||
| 20 | |||
| 21 | const param_sets = [_]CaseParameters{ | ||
| 22 | .{}, | ||
| 23 | .{ | ||
| 24 | .link_libc = true, | ||
| 25 | }, | ||
| 26 | .{ | ||
| 27 | .use_llvm = true, | ||
| 28 | .use_lld = true, | ||
| 29 | }, | ||
| 30 | .{ | ||
| 31 | .pie = true, | ||
| 32 | }, | ||
| 33 | .{ | ||
| 34 | .target = .{ | ||
| 35 | .cpu_arch = .aarch64, | ||
| 36 | .os_tag = .windows, | ||
| 37 | .abi = .msvc, | ||
| 38 | }, | ||
| 39 | }, | ||
| 40 | .{ | ||
| 41 | .target = .{ | ||
| 42 | .cpu_arch = .x86_64, | ||
| 43 | .os_tag = .windows, | ||
| 44 | .abi = .gnu, | ||
| 45 | }, | ||
| 46 | }, | ||
| 47 | .{ | ||
| 48 | .target = .{ | ||
| 49 | .cpu_arch = .x86, | ||
| 50 | .os_tag = .windows, | ||
| 51 | .abi = .msvc, | ||
| 52 | }, | ||
| 53 | }, | ||
| 54 | .{ | ||
| 55 | .target = .{ | ||
| 56 | .cpu_arch = .aarch64, | ||
| 57 | .os_tag = .macos, | ||
| 58 | }, | ||
| 59 | }, | ||
| 60 | .{ | ||
| 61 | .target = .{ | ||
| 62 | .cpu_arch = .s390x, | ||
| 63 | .os_tag = .linux, | ||
| 64 | .abi = .none, | ||
| 65 | }, | ||
| 66 | }, | ||
| 67 | .{ | ||
| 68 | .target = .{ | ||
| 69 | .cpu_arch = .loongarch32, | ||
| 70 | .os_tag = .linux, | ||
| 71 | .abi = .none, | ||
| 72 | }, | ||
| 73 | }, | ||
| 74 | }; | ||
| 75 | |||
| 8 | pub const Case = struct { | 76 | pub const Case = struct { |
| 77 | params: *const CaseParameters, | ||
| 78 | target: *const std.Target, | ||
| 9 | name: []const u8, | 79 | name: []const u8, |
| 10 | source: []const u8, | 80 | source: []const u8, |
| 11 | expect_error: []const u8, | 81 | expect_error: []const u8, |
| ... | @@ -22,50 +92,47 @@ pub const Case = struct { | ... | @@ -22,50 +92,47 @@ pub const Case = struct { |
| 22 | pub const Backend = enum { llvm, selfhosted }; | 92 | pub const Backend = enum { llvm, selfhosted }; |
| 23 | }; | 93 | }; |
| 24 | 94 | ||
| 25 | pub fn addCase(self: *ErrorTrace, case: Case) void { | 95 | pub fn addCases(self: *ErrorTrace) void { |
| 26 | for (self.targets) |*target| { | 96 | const b = self.b; |
| 27 | const triple: ?[]const u8 = if (target.query.isNative()) null else t: { | 97 | |
| 28 | break :t target.query.zigTriple(self.b.graph.arena) catch @panic("OOM"); | 98 | for (&param_sets) |*params| { |
| 29 | }; | 99 | const resolved_target = b.resolveTargetQuery(params.target); |
| 30 | for (self.optimize_modes) |optimize| { | 100 | |
| 31 | self.addCaseConfig(case, target, triple, optimize, .llvm); | 101 | if (self.skip_non_native and !resolved_target.query.isNative()) continue; |
| 32 | } | 102 | |
| 33 | if (shouldTestNonLlvm(&target.result)) { | 103 | // To avoid redundant testing, skip cross-compilation targets matching the host. |
| 34 | for (self.optimize_modes) |optimize| { | 104 | if (resolved_target.result.os.tag == builtin.target.os.tag and |
| 35 | self.addCaseConfig(case, target, triple, optimize, .selfhosted); | 105 | resolved_target.result.cpu.arch == builtin.target.cpu.arch) |
| 36 | } | 106 | { |
| 107 | continue; | ||
| 37 | } | 108 | } |
| 38 | } | ||
| 39 | } | ||
| 40 | 109 | ||
| 41 | fn shouldTestNonLlvm(target: *const std.Target) bool { | 110 | for (self.optimize_modes) |optimize| { |
| 42 | if (comptime builtin.cpu.arch.endian() == .big) return false; // https://github.com/ziglang/zig/issues/25961 | 111 | if (optimize == params.optimize) break; |
| 43 | return switch (target.cpu.arch) { | 112 | } else return; |
| 44 | .x86_64 => switch (target.ofmt) { | 113 | |
| 45 | .elf => !target.os.tag.isBSD() and target.os.tag != .illumos, | 114 | error_traces_cases.addCases(self, params, &resolved_target.result); |
| 46 | else => false, | 115 | } |
| 47 | }, | ||
| 48 | else => false, | ||
| 49 | }; | ||
| 50 | } | 116 | } |
| 51 | 117 | ||
| 52 | fn addCaseConfig( | 118 | /// Called from test/error_traces.zig |
| 53 | self: *ErrorTrace, | 119 | pub fn addCase(self: *ErrorTrace, case: Case) void { |
| 54 | case: Case, | ||
| 55 | target: *const std.Build.ResolvedTarget, | ||
| 56 | triple: ?[]const u8, | ||
| 57 | optimize: OptimizeMode, | ||
| 58 | backend: Case.Backend, | ||
| 59 | ) void { | ||
| 60 | const b = self.b; | 120 | const b = self.b; |
| 121 | const params = case.params; | ||
| 122 | const target = case.target; | ||
| 123 | const target_query = params.target; | ||
| 124 | |||
| 125 | const triple: ?[]const u8 = if (target_query.isNative()) null else t: { | ||
| 126 | break :t target_query.zigTriple(self.b.graph.arena) catch @panic("OOM"); | ||
| 127 | }; | ||
| 61 | 128 | ||
| 62 | const error_tracing: bool = tracing: { | 129 | const error_tracing: bool = tracing: { |
| 63 | if (optimize == .Debug) break :tracing true; | 130 | if (params.optimize == .debug) break :tracing true; |
| 64 | if (backend != .llvm) break :tracing true; | 131 | if (params.use_llvm == false) break :tracing true; |
| 65 | if (optimize == .ReleaseSmall) break :tracing false; | 132 | if (params.optimize == .small) break :tracing false; |
| 66 | for (case.disable_trace_optimized) |disable| { | 133 | for (case.disable_trace_optimized) |disable| { |
| 67 | const d_arch, const d_os = disable; | 134 | const d_arch, const d_os = disable; |
| 68 | if (target.result.cpu.arch == d_arch and target.result.os.tag == d_os) { | 135 | if (target.cpu.arch == d_arch and target.os.tag == d_os) { |
| 69 | // This particular configuration cannot do error tracing in optimized LLVM builds. | 136 | // This particular configuration cannot do error tracing in optimized LLVM builds. |
| 70 | break :tracing false; | 137 | break :tracing false; |
| 71 | } | 138 | } |
| ... | @@ -73,16 +140,23 @@ fn addCaseConfig( | ... | @@ -73,16 +140,23 @@ fn addCaseConfig( |
| 73 | break :tracing true; | 140 | break :tracing true; |
| 74 | }; | 141 | }; |
| 75 | 142 | ||
| 76 | const annotated_case_name = b.fmt("check {s} ({s}{s}{s} {s})", .{ | 143 | const backend_string = if (params.use_llvm == true) |
| 144 | "-llvm" | ||
| 145 | else if (params.use_llvm == false) | ||
| 146 | "-selfhosted" | ||
| 147 | else | ||
| 148 | ""; | ||
| 149 | |||
| 150 | const annotated_case_name = b.fmt("check {s} ({s}{s}{t}{s})", .{ | ||
| 77 | case.name, | 151 | case.name, |
| 78 | triple orelse "", | 152 | triple orelse "", |
| 79 | if (triple != null) " " else "", | 153 | if (triple != null) " " else "", |
| 80 | @tagName(optimize), | 154 | params.optimize, |
| 81 | @tagName(backend), | 155 | backend_string, |
| 82 | }); | 156 | }); |
| 83 | if (self.test_filters.len > 0) { | 157 | if (self.test_filters.len > 0) { |
| 84 | for (self.test_filters) |test_filter| { | 158 | for (self.test_filters) |test_filter| { |
| 85 | if (mem.indexOf(u8, annotated_case_name, test_filter)) |_| break; | 159 | if (mem.find(u8, annotated_case_name, test_filter)) |_| break; |
| 86 | } else return; | 160 | } else return; |
| 87 | } | 161 | } |
| 88 | 162 | ||
| ... | @@ -92,19 +166,18 @@ fn addCaseConfig( | ... | @@ -92,19 +166,18 @@ fn addCaseConfig( |
| 92 | .name = "test", | 166 | .name = "test", |
| 93 | .root_module = b.createModule(.{ | 167 | .root_module = b.createModule(.{ |
| 94 | .root_source_file = source_zig, | 168 | .root_source_file = source_zig, |
| 95 | .optimize = optimize, | 169 | .optimize = params.optimize, |
| 96 | .target = target.*, | 170 | .target = .{ .result = target.*, .query = target_query }, |
| 97 | .error_tracing = error_tracing, | 171 | .error_tracing = error_tracing, |
| 98 | .strip = false, | 172 | .strip = false, |
| 99 | }), | 173 | }), |
| 100 | .use_llvm = switch (backend) { | 174 | .use_llvm = params.use_llvm, |
| 101 | .llvm => true, | 175 | .use_lld = params.use_lld, |
| 102 | .selfhosted => false, | ||
| 103 | }, | ||
| 104 | }); | 176 | }); |
| 105 | exe.bundle_ubsan_rt = false; | 177 | exe.bundle_ubsan_rt = false; |
| 106 | 178 | ||
| 107 | const run = b.addRunArtifact(exe); | 179 | const run = b.addRunArtifact(exe); |
| 180 | run.skip_foreign_checks = true; | ||
| 108 | run.removeEnvironmentVariable("CLICOLOR_FORCE"); | 181 | run.removeEnvironmentVariable("CLICOLOR_FORCE"); |
| 109 | run.setEnvironmentVariable("NO_COLOR", "1"); | 182 | run.setEnvironmentVariable("NO_COLOR", "1"); |
| 110 | run.expectExitCode(1); | 183 | run.expectExitCode(1); |
| ... | @@ -116,16 +189,10 @@ fn addCaseConfig( | ... | @@ -116,16 +189,10 @@ fn addCaseConfig( |
| 116 | }; | 189 | }; |
| 117 | 190 | ||
| 118 | const check_run = b.addRunArtifact(self.convert_exe); | 191 | const check_run = b.addRunArtifact(self.convert_exe); |
| 192 | check_run.skip_foreign_checks = true; | ||
| 119 | check_run.setName(annotated_case_name); | 193 | check_run.setName(annotated_case_name); |
| 120 | check_run.addFileArg(run.captureStdErr(.{})); | 194 | check_run.addFileArg(run.captureStdErr(.{})); |
| 121 | check_run.expectStdOutEqual(expected_stderr); | 195 | check_run.expectStdOutEqual(expected_stderr); |
| 122 | 196 | ||
| 123 | self.step.dependOn(&check_run.step); | 197 | self.step.dependOn(&check_run.step); |
| 124 | } | 198 | } |
| 125 | |||
| 126 | const ErrorTrace = @This(); | ||
| 127 | const std = @import("std"); | ||
| 128 | const builtin = @import("builtin"); | ||
| 129 | const Step = std.Build.Step; | ||
| 130 | const OptimizeMode = std.builtin.OptimizeMode; | ||
| 131 | const mem = std.mem; |
test/src/Libc.zig+2-2| ... | @@ -49,7 +49,7 @@ pub fn addTarget(libc: *const Libc, target: std.Build.ResolvedTarget) void { | ... | @@ -49,7 +49,7 @@ pub fn addTarget(libc: *const Libc, target: std.Build.ResolvedTarget) void { |
| 49 | if (libc.options.test_target_filters.len > 0) { | 49 | if (libc.options.test_target_filters.len > 0) { |
| 50 | const triple_txt = target.query.zigTriple(libc.b.allocator) catch @panic("OOM"); | 50 | const triple_txt = target.query.zigTriple(libc.b.allocator) catch @panic("OOM"); |
| 51 | for (libc.options.test_target_filters) |filter| { | 51 | for (libc.options.test_target_filters) |filter| { |
| 52 | if (std.mem.indexOf(u8, triple_txt, filter)) |_| break; | 52 | if (std.mem.find(u8, triple_txt, filter)) |_| break; |
| 53 | } else return; | 53 | } else return; |
| 54 | } | 54 | } |
| 55 | 55 | ||
| ... | @@ -82,7 +82,7 @@ pub fn addTarget(libc: *const Libc, target: std.Build.ResolvedTarget) void { | ... | @@ -82,7 +82,7 @@ pub fn addTarget(libc: *const Libc, target: std.Build.ResolvedTarget) void { |
| 82 | 82 | ||
| 83 | const annotated_case_name = libc.b.fmt("run libc-test {s} ({t})", .{ test_case.name, optimize }); | 83 | const annotated_case_name = libc.b.fmt("run libc-test {s} ({t})", .{ test_case.name, optimize }); |
| 84 | for (libc.options.test_filters) |test_filter| { | 84 | for (libc.options.test_filters) |test_filter| { |
| 85 | if (std.mem.indexOf(u8, annotated_case_name, test_filter)) |_| break; | 85 | if (std.mem.find(u8, annotated_case_name, test_filter)) |_| break; |
| 86 | } else if (libc.options.test_filters.len > 0) continue; | 86 | } else if (libc.options.test_filters.len > 0) continue; |
| 87 | 87 | ||
| 88 | const mod = libc.b.createModule(.{ | 88 | const mod = libc.b.createModule(.{ |
test/src/Link.zig+1-1| ... | @@ -8,7 +8,7 @@ use_lld: bool, | ... | @@ -8,7 +8,7 @@ use_lld: bool, |
| 8 | link_libc: bool, | 8 | link_libc: bool, |
| 9 | test_filters: []const []const u8, | 9 | test_filters: []const []const u8, |
| 10 | update_step: ?*Step.UpdateSourceFiles, | 10 | update_step: ?*Step.UpdateSourceFiles, |
| 11 | updated_snapshots: std.StringArrayHashMapUnmanaged(void), | 11 | updated_snapshots: std.array_hash_map.String(void), |
| 12 | max_rss: usize, | 12 | max_rss: usize, |
| 13 | 13 | ||
| 14 | pub fn includeTest(self: *Link, prefix: []const u8) ?Case { | 14 | pub fn includeTest(self: *Link, prefix: []const u8) ?Case { |
test/src/LlvmIr.zig+2-2| ... | @@ -77,14 +77,14 @@ pub fn addCase(self: *LlvmIr, case: TestCase) void { | ... | @@ -77,14 +77,14 @@ pub fn addCase(self: *LlvmIr, case: TestCase) void { |
| 77 | if (self.options.test_target_filters.len > 0) { | 77 | if (self.options.test_target_filters.len > 0) { |
| 78 | const triple_txt = target.query.zigTriple(self.b.allocator) catch @panic("OOM"); | 78 | const triple_txt = target.query.zigTriple(self.b.allocator) catch @panic("OOM"); |
| 79 | for (self.options.test_target_filters) |filter| { | 79 | for (self.options.test_target_filters) |filter| { |
| 80 | if (std.mem.indexOf(u8, triple_txt, filter) != null) break; | 80 | if (std.mem.find(u8, triple_txt, filter) != null) break; |
| 81 | } else return; | 81 | } else return; |
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | const name = std.fmt.allocPrint(self.b.allocator, "check llvm-ir {s}", .{case.name}) catch @panic("OOM"); | 84 | const name = std.fmt.allocPrint(self.b.allocator, "check llvm-ir {s}", .{case.name}) catch @panic("OOM"); |
| 85 | if (self.options.test_filters.len > 0) { | 85 | if (self.options.test_filters.len > 0) { |
| 86 | for (self.options.test_filters) |filter| { | 86 | for (self.options.test_filters) |filter| { |
| 87 | if (std.mem.indexOf(u8, name, filter) != null) break; | 87 | if (std.mem.find(u8, name, filter) != null) break; |
| 88 | } else return; | 88 | } else return; |
| 89 | } | 89 | } |
| 90 | 90 |
test/src/RunTranslatedC.zig+1-1| ... | @@ -68,7 +68,7 @@ pub fn addCase(self: *RunTranslatedCContext, case: *const TestCase) void { | ... | @@ -68,7 +68,7 @@ pub fn addCase(self: *RunTranslatedCContext, case: *const TestCase) void { |
| 68 | 68 | ||
| 69 | const annotated_case_name = fmt.allocPrint(self.b.allocator, "run-translated-c {s}", .{case.name}) catch unreachable; | 69 | const annotated_case_name = fmt.allocPrint(self.b.allocator, "run-translated-c {s}", .{case.name}) catch unreachable; |
| 70 | for (self.test_filters) |test_filter| { | 70 | for (self.test_filters) |test_filter| { |
| 71 | if (mem.indexOf(u8, annotated_case_name, test_filter)) |_| break; | 71 | if (mem.find(u8, annotated_case_name, test_filter)) |_| break; |
| 72 | } else if (self.test_filters.len > 0) return; | 72 | } else if (self.test_filters.len > 0) return; |
| 73 | 73 | ||
| 74 | const write_src = b.addWriteFiles(); | 74 | const write_src = b.addWriteFiles(); |
test/src/StackTrace.zig+156-93| ... | @@ -1,10 +1,91 @@ | ... | @@ -1,10 +1,91 @@ |
| 1 | const StackTrace = @This(); | ||
| 2 | |||
| 3 | const builtin = @import("builtin"); | ||
| 4 | |||
| 5 | const std = @import("std"); | ||
| 6 | const Step = std.Build.Step; | ||
| 7 | const OptimizeMode = std.lang.Optimize; | ||
| 8 | const mem = std.mem; | ||
| 9 | |||
| 10 | const stack_traces_cases = @import("../stack_traces.zig"); | ||
| 11 | |||
| 1 | b: *std.Build, | 12 | b: *std.Build, |
| 2 | step: *Step, | 13 | step: *Step, |
| 3 | test_filters: []const []const u8, | 14 | test_filters: []const []const u8, |
| 4 | targets: []const std.Build.ResolvedTarget, | 15 | skip_non_native: bool, |
| 5 | convert_exe: *std.Build.Step.Compile, | 16 | convert_exe: *std.Build.Step.Compile, |
| 6 | 17 | ||
| 18 | pub const CaseParameters = struct { | ||
| 19 | target: std.Target.Query = .{}, | ||
| 20 | optimize: std.builtin.OptimizeMode = .debug, | ||
| 21 | link_libc: ?bool = null, | ||
| 22 | use_llvm: ?bool = null, | ||
| 23 | use_lld: ?bool = null, | ||
| 24 | pie: ?bool = null, | ||
| 25 | /// To enable this coverage, one of two things needs to happen: | ||
| 26 | /// * The compiler needs to gain the ability to strip only debug info (not symbols) | ||
| 27 | /// * `std.Build.Step.ObjCopy` needs to be un-regressed | ||
| 28 | strip: ?bool = false, | ||
| 29 | }; | ||
| 30 | |||
| 31 | const param_sets = [_]CaseParameters{ | ||
| 32 | .{}, | ||
| 33 | .{ | ||
| 34 | .link_libc = true, | ||
| 35 | }, | ||
| 36 | .{ | ||
| 37 | .use_llvm = true, | ||
| 38 | .use_lld = true, | ||
| 39 | }, | ||
| 40 | .{ | ||
| 41 | .pie = true, | ||
| 42 | }, | ||
| 43 | .{ | ||
| 44 | .target = .{ | ||
| 45 | .cpu_arch = .aarch64, | ||
| 46 | .os_tag = .windows, | ||
| 47 | .abi = .msvc, | ||
| 48 | }, | ||
| 49 | }, | ||
| 50 | .{ | ||
| 51 | .target = .{ | ||
| 52 | .cpu_arch = .x86_64, | ||
| 53 | .os_tag = .windows, | ||
| 54 | .abi = .gnu, | ||
| 55 | }, | ||
| 56 | }, | ||
| 57 | .{ | ||
| 58 | .target = .{ | ||
| 59 | .cpu_arch = .x86, | ||
| 60 | .os_tag = .windows, | ||
| 61 | .abi = .msvc, | ||
| 62 | }, | ||
| 63 | }, | ||
| 64 | .{ | ||
| 65 | .target = .{ | ||
| 66 | .cpu_arch = .aarch64, | ||
| 67 | .os_tag = .macos, | ||
| 68 | }, | ||
| 69 | }, | ||
| 70 | .{ | ||
| 71 | .target = .{ | ||
| 72 | .cpu_arch = .s390x, | ||
| 73 | .os_tag = .linux, | ||
| 74 | .abi = .none, | ||
| 75 | }, | ||
| 76 | }, | ||
| 77 | .{ | ||
| 78 | .target = .{ | ||
| 79 | .cpu_arch = .loongarch32, | ||
| 80 | .os_tag = .linux, | ||
| 81 | .abi = .none, | ||
| 82 | }, | ||
| 83 | }, | ||
| 84 | }; | ||
| 85 | |||
| 7 | const Config = struct { | 86 | const Config = struct { |
| 87 | params: *const CaseParameters, | ||
| 88 | target: *const std.Target, | ||
| 8 | name: []const u8, | 89 | name: []const u8, |
| 9 | source: []const u8, | 90 | source: []const u8, |
| 10 | /// Whether this test case expects to have unwind tables / frame pointers. | 91 | /// Whether this test case expects to have unwind tables / frame pointers. |
| ... | @@ -26,42 +107,37 @@ const Config = struct { | ... | @@ -26,42 +107,37 @@ const Config = struct { |
| 26 | expect_strip: []const u8, | 107 | expect_strip: []const u8, |
| 27 | }; | 108 | }; |
| 28 | 109 | ||
| 29 | pub fn addCase(self: *StackTrace, config: Config) void { | 110 | pub fn addCases(self: *StackTrace) void { |
| 30 | for (self.targets) |*target| { | 111 | const b = self.b; |
| 31 | addCaseTarget( | 112 | |
| 32 | self, | 113 | for (&param_sets) |*params| { |
| 33 | config, | 114 | const resolved_target = b.resolveTargetQuery(params.target); |
| 34 | target, | 115 | |
| 35 | if (target.query.isNative()) null else t: { | 116 | if (self.skip_non_native and !resolved_target.query.isNative()) continue; |
| 36 | break :t target.query.zigTriple(self.b.graph.arena) catch @panic("OOM"); | 117 | |
| 37 | }, | 118 | // To avoid redundant testing, skip cross-compilation targets matching the host. |
| 38 | ); | 119 | if (resolved_target.result.os.tag == builtin.target.os.tag and |
| 120 | resolved_target.result.cpu.arch == builtin.target.cpu.arch) | ||
| 121 | { | ||
| 122 | continue; | ||
| 123 | } | ||
| 124 | |||
| 125 | stack_traces_cases.addCases(self, params, &resolved_target.result); | ||
| 39 | } | 126 | } |
| 40 | } | 127 | } |
| 41 | fn addCaseTarget( | 128 | |
| 42 | self: *StackTrace, | 129 | /// Called from test/stack_traces.zig |
| 43 | config: Config, | 130 | pub fn addCase(self: *StackTrace, config: Config) void { |
| 44 | target: *const std.Build.ResolvedTarget, | 131 | const params = config.params; |
| 45 | triple: ?[]const u8, | 132 | const target = config.target; |
| 46 | ) void { | 133 | const target_query = config.params.target; |
| 47 | const both_backends = b: { | 134 | |
| 48 | if (comptime builtin.cpu.arch.endian() == .big) break :b false; // https://github.com/ziglang/zig/issues/25961 | 135 | const triple: ?[]const u8 = if (target_query.isNative()) null else t: { |
| 49 | break :b switch (target.result.cpu.arch) { | 136 | break :t target_query.zigTriple(self.b.graph.arena) catch @panic("OOM"); |
| 50 | .x86_64 => switch (target.result.ofmt) { | ||
| 51 | .elf => !target.result.os.tag.isBSD() and target.result.os.tag != .illumos, | ||
| 52 | else => false, | ||
| 53 | }, | ||
| 54 | else => false, | ||
| 55 | }; | ||
| 56 | }; | ||
| 57 | const both_pie = switch (target.result.os.tag) { | ||
| 58 | .fuchsia => false, | ||
| 59 | else => true, | ||
| 60 | }; | 137 | }; |
| 61 | const both_libc = !std.os.targetRequiresLibC(&target.result); | ||
| 62 | 138 | ||
| 63 | // See `std.debug.StackIterator.fp_usability` logic. | 139 | // See `std.debug.StackIterator.fp_usability` logic. |
| 64 | const fp_usability: enum { useless, unsafe, safe, ideal } = switch (target.result.cpu.arch) { | 140 | const fp_usability: enum { useless, unsafe, safe, ideal } = switch (target.cpu.arch) { |
| 65 | .alpha, | 141 | .alpha, |
| 66 | .csky, | 142 | .csky, |
| 67 | .microblaze, | 143 | .microblaze, |
| ... | @@ -83,20 +159,15 @@ fn addCaseTarget( | ... | @@ -83,20 +159,15 @@ fn addCaseTarget( |
| 83 | .sparc, | 159 | .sparc, |
| 84 | .sparc64, | 160 | .sparc64, |
| 85 | => .ideal, | 161 | => .ideal, |
| 86 | .aarch64 => if (target.result.os.tag.isDarwin()) .safe else .unsafe, | 162 | .aarch64 => if (target.os.tag.isDarwin()) .safe else .unsafe, |
| 87 | else => .unsafe, | 163 | else => .unsafe, |
| 88 | }; | 164 | }; |
| 89 | const supports_unwind_tables = switch (target.result.os.tag) { | 165 | const supports_unwind_tables = switch (target.os.tag) { |
| 90 | // x86-windows just has no way to do stack unwinding other then using frame pointers. | 166 | // x86-windows just has no way to do stack unwinding other then using frame pointers. |
| 91 | .windows => target.result.cpu.arch != .x86, | 167 | .windows => target.cpu.arch != .x86, |
| 92 | else => true, | 168 | else => true, |
| 93 | }; | 169 | }; |
| 94 | 170 | ||
| 95 | const use_llvm_vals: []const bool = if (both_backends) &.{ true, false } else &.{true}; | ||
| 96 | const pie_vals: []const ?bool = if (both_pie) &.{ true, false } else &.{null}; | ||
| 97 | const link_libc_vals: []const ?bool = if (both_libc) &.{ true, false } else &.{null}; | ||
| 98 | const strip_debug_vals: []const bool = &.{ true, false }; | ||
| 99 | |||
| 100 | const UnwindInfo = packed struct(u2) { | 171 | const UnwindInfo = packed struct(u2) { |
| 101 | tables: bool, | 172 | tables: bool, |
| 102 | fp: bool, | 173 | fp: bool, |
| ... | @@ -126,43 +197,33 @@ fn addCaseTarget( | ... | @@ -126,43 +197,33 @@ fn addCaseTarget( |
| 126 | }, | 197 | }, |
| 127 | }; | 198 | }; |
| 128 | 199 | ||
| 129 | for (use_llvm_vals) |use_llvm| { | 200 | for (unwind_info_vals) |unwind_info| { |
| 130 | for (pie_vals) |pie| { | 201 | if (unwind_info.tables and !supports_unwind_tables) continue; |
| 131 | for (link_libc_vals) |link_libc| { | 202 | const strip = params.strip orelse switch (params.optimize) { |
| 132 | for (strip_debug_vals) |strip_debug| { | 203 | .debug, .fast, .safe => false, |
| 133 | for (unwind_info_vals) |unwind_info| { | 204 | .small => true, |
| 134 | if (unwind_info.tables and !supports_unwind_tables) continue; | 205 | }; |
| 135 | self.addCaseInstance( | 206 | self.addCaseInstance( |
| 136 | target, | 207 | .{ .result = target.*, .query = target_query }, |
| 137 | triple, | 208 | triple, |
| 138 | config.name, | 209 | config.name, |
| 139 | config.source, | 210 | config.source, |
| 140 | use_llvm, | 211 | params, |
| 141 | pie, | 212 | !unwind_info.tables and supports_unwind_tables, |
| 142 | link_libc, | 213 | !unwind_info.fp, |
| 143 | strip_debug, | 214 | config.expect_panic, |
| 144 | !unwind_info.tables and supports_unwind_tables, | 215 | if (strip) config.expect_strip else config.expect, |
| 145 | !unwind_info.fp, | 216 | ); |
| 146 | config.expect_panic, | ||
| 147 | if (strip_debug) config.expect_strip else config.expect, | ||
| 148 | ); | ||
| 149 | } | ||
| 150 | } | ||
| 151 | } | ||
| 152 | } | ||
| 153 | } | 217 | } |
| 154 | } | 218 | } |
| 155 | 219 | ||
| 156 | fn addCaseInstance( | 220 | fn addCaseInstance( |
| 157 | self: *StackTrace, | 221 | self: *StackTrace, |
| 158 | target: *const std.Build.ResolvedTarget, | 222 | resolved_target: std.Build.ResolvedTarget, |
| 159 | triple: ?[]const u8, | 223 | triple: ?[]const u8, |
| 160 | name: []const u8, | 224 | name: []const u8, |
| 161 | source: []const u8, | 225 | source: []const u8, |
| 162 | use_llvm: bool, | 226 | params: *const CaseParameters, |
| 163 | pie: ?bool, | ||
| 164 | link_libc: ?bool, | ||
| 165 | strip_debug: bool, | ||
| 166 | strip_unwind: bool, | 227 | strip_unwind: bool, |
| 167 | omit_frame_pointer: bool, | 228 | omit_frame_pointer: bool, |
| 168 | expect_panic: bool, | 229 | expect_panic: bool, |
| ... | @@ -170,13 +231,6 @@ fn addCaseInstance( | ... | @@ -170,13 +231,6 @@ fn addCaseInstance( |
| 170 | ) void { | 231 | ) void { |
| 171 | const b = self.b; | 232 | const b = self.b; |
| 172 | 233 | ||
| 173 | if (strip_debug) { | ||
| 174 | // To enable this coverage, one of two things needs to happen: | ||
| 175 | // * The compiler needs to gain the ability to strip only debug info (not symbols) | ||
| 176 | // * `std.Build.Step.ObjCopy` needs to be un-regressed | ||
| 177 | return; | ||
| 178 | } | ||
| 179 | |||
| 180 | if (strip_unwind) { | 234 | if (strip_unwind) { |
| 181 | // To enable this coverage, `std.Build.Step.ObjCopy` needs to be un-regressed and gain the | 235 | // To enable this coverage, `std.Build.Step.ObjCopy` needs to be un-regressed and gain the |
| 182 | // ability to remove individual sections. `-fno-unwind-tables` is insufficient because it | 236 | // ability to remove individual sections. `-fno-unwind-tables` is insufficient because it |
| ... | @@ -187,20 +241,34 @@ fn addCaseInstance( | ... | @@ -187,20 +241,34 @@ fn addCaseInstance( |
| 187 | return; | 241 | return; |
| 188 | } | 242 | } |
| 189 | 243 | ||
| 244 | const backend_string = if (params.use_llvm == true) | ||
| 245 | " llvm" | ||
| 246 | else if (params.use_llvm == false) | ||
| 247 | " selfhosted" | ||
| 248 | else | ||
| 249 | ""; | ||
| 250 | |||
| 251 | const strip_string = if (params.strip == true) | ||
| 252 | " strip" | ||
| 253 | else if (params.strip == false) | ||
| 254 | " unstripped" | ||
| 255 | else | ||
| 256 | ""; | ||
| 257 | |||
| 190 | const annotated_case_name = b.fmt("check {s} ({s}{s}{s}{s}{s}{s}{s}{s})", .{ | 258 | const annotated_case_name = b.fmt("check {s} ({s}{s}{s}{s}{s}{s}{s}{s})", .{ |
| 191 | name, | 259 | name, |
| 192 | triple orelse "", | 260 | triple orelse "", |
| 193 | if (triple != null) " " else "", | 261 | if (triple != null) " " else "", |
| 194 | if (use_llvm) "llvm" else "selfhosted", | 262 | backend_string, |
| 195 | if (pie == true) " pie" else "", | 263 | if (params.pie == true) " pie" else "", |
| 196 | if (link_libc == true) " libc" else "", | 264 | if (params.link_libc == true) " libc" else "", |
| 197 | if (strip_debug) " strip" else "", | 265 | strip_string, |
| 198 | if (strip_unwind) " no_unwind" else "", | 266 | if (strip_unwind) " no_unwind" else "", |
| 199 | if (omit_frame_pointer) " no_fp" else "", | 267 | if (omit_frame_pointer) " no_fp" else "", |
| 200 | }); | 268 | }); |
| 201 | if (self.test_filters.len > 0) { | 269 | if (self.test_filters.len > 0) { |
| 202 | for (self.test_filters) |test_filter| { | 270 | for (self.test_filters) |test_filter| { |
| 203 | if (mem.indexOf(u8, annotated_case_name, test_filter)) |_| break; | 271 | if (mem.find(u8, annotated_case_name, test_filter)) |_| break; |
| 204 | } else return; | 272 | } else return; |
| 205 | } | 273 | } |
| 206 | 274 | ||
| ... | @@ -211,24 +279,26 @@ fn addCaseInstance( | ... | @@ -211,24 +279,26 @@ fn addCaseInstance( |
| 211 | .root_module = b.createModule(.{ | 279 | .root_module = b.createModule(.{ |
| 212 | .root_source_file = source_zig, | 280 | .root_source_file = source_zig, |
| 213 | .optimize = .Debug, | 281 | .optimize = .Debug, |
| 214 | .target = target.*, | 282 | .target = resolved_target, |
| 215 | .omit_frame_pointer = omit_frame_pointer, | 283 | .omit_frame_pointer = omit_frame_pointer, |
| 216 | .link_libc = link_libc, | 284 | .link_libc = params.link_libc, |
| 217 | .unwind_tables = if (strip_unwind) .none else null, | 285 | .unwind_tables = if (strip_unwind) .none else null, |
| 218 | // make panics single-threaded so that they don't include a thread ID | 286 | // make panics single-threaded so that they don't include a thread ID |
| 219 | .single_threaded = expect_panic, | 287 | .single_threaded = expect_panic, |
| 220 | }), | 288 | }), |
| 221 | .use_llvm = use_llvm, | 289 | .use_llvm = params.use_llvm, |
| 290 | .use_lld = params.use_lld, | ||
| 222 | }); | 291 | }); |
| 223 | exe.pie = pie; | 292 | exe.pie = params.pie; |
| 224 | exe.bundle_ubsan_rt = false; | 293 | exe.bundle_ubsan_rt = false; |
| 225 | 294 | ||
| 226 | const run = b.addRunArtifact(exe); | 295 | const run = b.addRunArtifact(exe); |
| 296 | run.skip_foreign_checks = true; | ||
| 227 | run.removeEnvironmentVariable("CLICOLOR_FORCE"); | 297 | run.removeEnvironmentVariable("CLICOLOR_FORCE"); |
| 228 | run.setEnvironmentVariable("NO_COLOR", "1"); | 298 | run.setEnvironmentVariable("NO_COLOR", "1"); |
| 229 | run.addCheck(.{ .expect_term = term: { | 299 | run.addCheck(.{ .expect_term = term: { |
| 230 | if (!expect_panic) break :term .{ .exited = 0 }; | 300 | if (!expect_panic) break :term .{ .exited = 0 }; |
| 231 | if (target.result.os.tag == .windows) break :term .{ .exited = 3 }; | 301 | if (resolved_target.result.os.tag == .windows) break :term .{ .exited = 3 }; |
| 232 | break :term .{ .signal = @fromBackingInt(@intCast(6)) }; | 302 | break :term .{ .signal = @fromBackingInt(@intCast(6)) }; |
| 233 | } }); | 303 | } }); |
| 234 | run.expectStdOutEqual(""); | 304 | run.expectStdOutEqual(""); |
| ... | @@ -241,10 +311,3 @@ fn addCaseInstance( | ... | @@ -241,10 +311,3 @@ fn addCaseInstance( |
| 241 | 311 | ||
| 242 | self.step.dependOn(&check_run.step); | 312 | self.step.dependOn(&check_run.step); |
| 243 | } | 313 | } |
| 244 | |||
| 245 | const StackTrace = @This(); | ||
| 246 | const std = @import("std"); | ||
| 247 | const builtin = @import("builtin"); | ||
| 248 | const Step = std.Build.Step; | ||
| 249 | const OptimizeMode = std.builtin.OptimizeMode; | ||
| 250 | const mem = std.mem; |
test/src/TranslateC.zig+2-2| ... | @@ -90,7 +90,7 @@ pub fn addCase(self: *TranslateCContext, case: *const TestCase) void { | ... | @@ -90,7 +90,7 @@ pub fn addCase(self: *TranslateCContext, case: *const TestCase) void { |
| 90 | const translate_c_cmd = "translate-c"; | 90 | const translate_c_cmd = "translate-c"; |
| 91 | const annotated_case_name = fmt.allocPrint(self.b.allocator, "{s} {s}", .{ translate_c_cmd, case.name }) catch unreachable; | 91 | const annotated_case_name = fmt.allocPrint(self.b.allocator, "{s} {s}", .{ translate_c_cmd, case.name }) catch unreachable; |
| 92 | for (self.test_filters) |test_filter| { | 92 | for (self.test_filters) |test_filter| { |
| 93 | if (mem.indexOf(u8, annotated_case_name, test_filter)) |_| break; | 93 | if (mem.find(u8, annotated_case_name, test_filter)) |_| break; |
| 94 | } else if (self.test_filters.len > 0) return; | 94 | } else if (self.test_filters.len > 0) return; |
| 95 | 95 | ||
| 96 | const target = b.resolveTargetQuery(case.target); | 96 | const target = b.resolveTargetQuery(case.target); |
| ... | @@ -99,7 +99,7 @@ pub fn addCase(self: *TranslateCContext, case: *const TestCase) void { | ... | @@ -99,7 +99,7 @@ pub fn addCase(self: *TranslateCContext, case: *const TestCase) void { |
| 99 | const triple_txt = target.query.zigTriple(b.allocator) catch @panic("OOM"); | 99 | const triple_txt = target.query.zigTriple(b.allocator) catch @panic("OOM"); |
| 100 | 100 | ||
| 101 | for (self.test_target_filters) |filter| { | 101 | for (self.test_target_filters) |filter| { |
| 102 | if (std.mem.indexOf(u8, triple_txt, filter) != null) break; | 102 | if (std.mem.find(u8, triple_txt, filter) != null) break; |
| 103 | } else return; | 103 | } else return; |
| 104 | } | 104 | } |
| 105 | 105 |
test/src/convert-stack-trace.zig+3-3| ... | @@ -52,13 +52,13 @@ pub fn main(init: std.process.Init) !void { | ... | @@ -52,13 +52,13 @@ pub fn main(init: std.process.Init) !void { |
| 52 | continue; | 52 | continue; |
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | const src_pos_end = std.mem.indexOf(u8, in_line, ": 0x") orelse { | 55 | const src_pos_end = std.mem.find(u8, in_line, ": 0x") orelse { |
| 56 | try w.writeAll(in_line); | 56 | try w.writeAll(in_line); |
| 57 | continue; | 57 | continue; |
| 58 | }; | 58 | }; |
| 59 | const src_pos_start = b: { | 59 | const src_pos_start = b: { |
| 60 | const postfix = ".zig:"; | 60 | const postfix = ".zig:"; |
| 61 | const postfix_index = std.mem.lastIndexOf(u8, in_line[0..src_pos_end], postfix) orelse { | 61 | const postfix_index = std.mem.findLast(u8, in_line[0..src_pos_end], postfix) orelse { |
| 62 | try w.writeAll(in_line); | 62 | try w.writeAll(in_line); |
| 63 | continue; | 63 | continue; |
| 64 | }; | 64 | }; |
| ... | @@ -89,7 +89,7 @@ pub fn main(init: std.process.Init) !void { | ... | @@ -89,7 +89,7 @@ pub fn main(init: std.process.Init) !void { |
| 89 | // ...with that first '_' being replaced by its basename. | 89 | // ...with that first '_' being replaced by its basename. |
| 90 | 90 | ||
| 91 | const src_path = in_line[0..src_pos_start]; | 91 | const src_path = in_line[0..src_pos_start]; |
| 92 | const basename_start = if (std.mem.lastIndexOfAny(u8, src_path, "/\\")) |i| i + 1 else 0; | 92 | const basename_start = if (std.mem.findLastAny(u8, src_path, "/\\")) |i| i + 1 else 0; |
| 93 | const symbol_start = addr_end + " in ".len; | 93 | const symbol_start = addr_end + " in ".len; |
| 94 | try w.writeAll(in_line[basename_start..src_pos_end]); | 94 | try w.writeAll(in_line[basename_start..src_pos_end]); |
| 95 | try w.writeAll(": [address] in "); | 95 | try w.writeAll(": [address] in "); |
test/stack_traces.zig+24-5| ... | @@ -1,7 +1,10 @@ | ... | @@ -1,7 +1,10 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const Context = @import("tests.zig").StackTracesContext; | ||
| 2 | 3 | ||
| 3 | pub fn addCases(cases: *@import("tests.zig").StackTracesContext, os: std.Target.Os.Tag) void { | 4 | pub fn addCases(cases: *Context, params: *const Context.CaseParameters, target: *const std.Target) void { |
| 4 | cases.addCase(.{ | 5 | cases.addCase(.{ |
| 6 | .params = params, | ||
| 7 | .target = target, | ||
| 5 | .name = "simple panic", | 8 | .name = "simple panic", |
| 6 | .source = | 9 | .source = |
| 7 | \\pub fn main() void { | 10 | \\pub fn main() void { |
| ... | @@ -33,6 +36,8 @@ pub fn addCases(cases: *@import("tests.zig").StackTracesContext, os: std.Target. | ... | @@ -33,6 +36,8 @@ pub fn addCases(cases: *@import("tests.zig").StackTracesContext, os: std.Target. |
| 33 | }); | 36 | }); |
| 34 | 37 | ||
| 35 | cases.addCase(.{ | 38 | cases.addCase(.{ |
| 39 | .params = params, | ||
| 40 | .target = target, | ||
| 36 | .name = "simple panic with no unwind strategy", | 41 | .name = "simple panic with no unwind strategy", |
| 37 | .source = | 42 | .source = |
| 38 | \\pub fn main() void { | 43 | \\pub fn main() void { |
| ... | @@ -50,6 +55,8 @@ pub fn addCases(cases: *@import("tests.zig").StackTracesContext, os: std.Target. | ... | @@ -50,6 +55,8 @@ pub fn addCases(cases: *@import("tests.zig").StackTracesContext, os: std.Target. |
| 50 | }); | 55 | }); |
| 51 | 56 | ||
| 52 | cases.addCase(.{ | 57 | cases.addCase(.{ |
| 58 | .params = params, | ||
| 59 | .target = target, | ||
| 53 | .name = "dump current trace", | 60 | .name = "dump current trace", |
| 54 | .source = | 61 | .source = |
| 55 | \\pub fn main() void { | 62 | \\pub fn main() void { |
| ... | @@ -89,6 +96,8 @@ pub fn addCases(cases: *@import("tests.zig").StackTracesContext, os: std.Target. | ... | @@ -89,6 +96,8 @@ pub fn addCases(cases: *@import("tests.zig").StackTracesContext, os: std.Target. |
| 89 | }); | 96 | }); |
| 90 | 97 | ||
| 91 | cases.addCase(.{ | 98 | cases.addCase(.{ |
| 99 | .params = params, | ||
| 100 | .target = target, | ||
| 92 | .name = "dump current trace with no unwind strategy", | 101 | .name = "dump current trace with no unwind strategy", |
| 93 | .source = | 102 | .source = |
| 94 | \\pub fn main() void { | 103 | \\pub fn main() void { |
| ... | @@ -114,6 +123,8 @@ pub fn addCases(cases: *@import("tests.zig").StackTracesContext, os: std.Target. | ... | @@ -114,6 +123,8 @@ pub fn addCases(cases: *@import("tests.zig").StackTracesContext, os: std.Target. |
| 114 | }); | 123 | }); |
| 115 | 124 | ||
| 116 | cases.addCase(.{ | 125 | cases.addCase(.{ |
| 126 | .params = params, | ||
| 127 | .target = target, | ||
| 117 | .name = "dump captured trace", | 128 | .name = "dump captured trace", |
| 118 | .source = | 129 | .source = |
| 119 | \\pub fn main() void { | 130 | \\pub fn main() void { |
| ... | @@ -155,6 +166,8 @@ pub fn addCases(cases: *@import("tests.zig").StackTracesContext, os: std.Target. | ... | @@ -155,6 +166,8 @@ pub fn addCases(cases: *@import("tests.zig").StackTracesContext, os: std.Target. |
| 155 | }); | 166 | }); |
| 156 | 167 | ||
| 157 | cases.addCase(.{ | 168 | cases.addCase(.{ |
| 169 | .params = params, | ||
| 170 | .target = target, | ||
| 158 | .name = "dump captured trace with no unwind strategy", | 171 | .name = "dump captured trace with no unwind strategy", |
| 159 | .source = | 172 | .source = |
| 160 | \\pub fn main() void { | 173 | \\pub fn main() void { |
| ... | @@ -180,6 +193,8 @@ pub fn addCases(cases: *@import("tests.zig").StackTracesContext, os: std.Target. | ... | @@ -180,6 +193,8 @@ pub fn addCases(cases: *@import("tests.zig").StackTracesContext, os: std.Target. |
| 180 | }); | 193 | }); |
| 181 | 194 | ||
| 182 | cases.addCase(.{ | 195 | cases.addCase(.{ |
| 196 | .params = params, | ||
| 197 | .target = target, | ||
| 183 | .name = "dump captured trace on thread", | 198 | .name = "dump captured trace on thread", |
| 184 | .source = | 199 | .source = |
| 185 | \\pub fn main() !void { | 200 | \\pub fn main() !void { |
| ... | @@ -225,6 +240,8 @@ pub fn addCases(cases: *@import("tests.zig").StackTracesContext, os: std.Target. | ... | @@ -225,6 +240,8 @@ pub fn addCases(cases: *@import("tests.zig").StackTracesContext, os: std.Target. |
| 225 | }); | 240 | }); |
| 226 | 241 | ||
| 227 | cases.addCase(.{ | 242 | cases.addCase(.{ |
| 243 | .params = params, | ||
| 244 | .target = target, | ||
| 228 | .name = "simple inline panic", | 245 | .name = "simple inline panic", |
| 229 | // The main function has two inline calls to ensure | 246 | // The main function has two inline calls to ensure |
| 230 | // that inlinees in PDBs are properly deduplicated. | 247 | // that inlinees in PDBs are properly deduplicated. |
| ... | @@ -240,7 +257,7 @@ pub fn addCases(cases: *@import("tests.zig").StackTracesContext, os: std.Target. | ... | @@ -240,7 +257,7 @@ pub fn addCases(cases: *@import("tests.zig").StackTracesContext, os: std.Target. |
| 240 | , | 257 | , |
| 241 | .unwind = .any, | 258 | .unwind = .any, |
| 242 | .expect_panic = true, | 259 | .expect_panic = true, |
| 243 | .expect = switch (os) { | 260 | .expect = switch (target.os.tag) { |
| 244 | // LLVM doesn't emit column info in the binary annotations for inlinee callees in PDBs, | 261 | // LLVM doesn't emit column info in the binary annotations for inlinee callees in PDBs, |
| 245 | // so the first location has only a row. | 262 | // so the first location has only a row. |
| 246 | .windows => | 263 | .windows => |
| ... | @@ -262,7 +279,7 @@ pub fn addCases(cases: *@import("tests.zig").StackTracesContext, os: std.Target. | ... | @@ -262,7 +279,7 @@ pub fn addCases(cases: *@import("tests.zig").StackTracesContext, os: std.Target. |
| 262 | \\ ^ | 279 | \\ ^ |
| 263 | , | 280 | , |
| 264 | }, | 281 | }, |
| 265 | .expect_strip = switch (os) { | 282 | .expect_strip = switch (target.os.tag) { |
| 266 | .windows => | 283 | .windows => |
| 267 | \\panic: oh no | 284 | \\panic: oh no |
| 268 | \\???:?:?: [address] in source.foo | 285 | \\???:?:?: [address] in source.foo |
| ... | @@ -279,6 +296,8 @@ pub fn addCases(cases: *@import("tests.zig").StackTracesContext, os: std.Target. | ... | @@ -279,6 +296,8 @@ pub fn addCases(cases: *@import("tests.zig").StackTracesContext, os: std.Target. |
| 279 | 296 | ||
| 280 | // Make sure all inline calls are resolved and in the right order! | 297 | // Make sure all inline calls are resolved and in the right order! |
| 281 | cases.addCase(.{ | 298 | cases.addCase(.{ |
| 299 | .params = params, | ||
| 300 | .target = target, | ||
| 282 | .name = "nested inline panic", | 301 | .name = "nested inline panic", |
| 283 | .source = | 302 | .source = |
| 284 | \\pub fn main() void { | 303 | \\pub fn main() void { |
| ... | @@ -298,7 +317,7 @@ pub fn addCases(cases: *@import("tests.zig").StackTracesContext, os: std.Target. | ... | @@ -298,7 +317,7 @@ pub fn addCases(cases: *@import("tests.zig").StackTracesContext, os: std.Target. |
| 298 | .unwind = .any, | 317 | .unwind = .any, |
| 299 | .expect_panic = true, | 318 | .expect_panic = true, |
| 300 | // This switch serves a similar purpose as in "inline panic". | 319 | // This switch serves a similar purpose as in "inline panic". |
| 301 | .expect = switch (os) { | 320 | .expect = switch (target.os.tag) { |
| 302 | .windows => | 321 | .windows => |
| 303 | \\panic: oh no | 322 | \\panic: oh no |
| 304 | \\source.zig:11: [address] in baz | 323 | \\source.zig:11: [address] in baz |
| ... | @@ -322,7 +341,7 @@ pub fn addCases(cases: *@import("tests.zig").StackTracesContext, os: std.Target. | ... | @@ -322,7 +341,7 @@ pub fn addCases(cases: *@import("tests.zig").StackTracesContext, os: std.Target. |
| 322 | \\ ^ | 341 | \\ ^ |
| 323 | , | 342 | , |
| 324 | }, | 343 | }, |
| 325 | .expect_strip = switch (os) { | 344 | .expect_strip = switch (target.os.tag) { |
| 326 | .windows => | 345 | .windows => |
| 327 | \\panic: oh no | 346 | \\panic: oh no |
| 328 | \\???:?:?: [address] in baz | 347 | \\???:?:?: [address] in baz |
test/standalone/build.zig+1-1| ... | @@ -31,6 +31,7 @@ pub fn build(b: *std.Build) void { | ... | @@ -31,6 +31,7 @@ pub fn build(b: *std.Build) void { |
| 31 | const tools_target = b.resolveTargetQuery(.{}); | 31 | const tools_target = b.resolveTargetQuery(.{}); |
| 32 | for ([_][]const u8{ | 32 | for ([_][]const u8{ |
| 33 | // Alphabetically sorted. No need to build `tools/spirv/grammar.zig`. | 33 | // Alphabetically sorted. No need to build `tools/spirv/grammar.zig`. |
| 34 | "../../tools/bsp.zig", | ||
| 34 | "../../tools/check_mingw.zig", | 35 | "../../tools/check_mingw.zig", |
| 35 | "../../tools/dump-cov.zig", | 36 | "../../tools/dump-cov.zig", |
| 36 | "../../tools/fetch_them_macos_headers.zig", | 37 | "../../tools/fetch_them_macos_headers.zig", |
| ... | @@ -39,7 +40,6 @@ pub fn build(b: *std.Build) void { | ... | @@ -39,7 +40,6 @@ pub fn build(b: *std.Build) void { |
| 39 | "../../tools/gen_parser_oracle.zig", | 40 | "../../tools/gen_parser_oracle.zig", |
| 40 | "../../tools/gen_spirv_spec.zig", | 41 | "../../tools/gen_spirv_spec.zig", |
| 41 | "../../tools/gen_stubs.zig", | 42 | "../../tools/gen_stubs.zig", |
| 42 | "../../tools/generate_c_size_and_align_checks.zig", | ||
| 43 | "../../tools/generate_JSONTestSuite.zig", | 43 | "../../tools/generate_JSONTestSuite.zig", |
| 44 | "../../tools/generate_linux_syscalls.zig", | 44 | "../../tools/generate_linux_syscalls.zig", |
| 45 | "../../tools/process_headers.zig", | 45 | "../../tools/process_headers.zig", |
test/standalone/build.zig.zon-3| ... | @@ -187,9 +187,6 @@ | ... | @@ -187,9 +187,6 @@ |
| 187 | .posix = .{ | 187 | .posix = .{ |
| 188 | .path = "posix", | 188 | .path = "posix", |
| 189 | }, | 189 | }, |
| 190 | .debug_io_color = .{ | ||
| 191 | .path = "debug_io_color", | ||
| 192 | }, | ||
| 193 | .elf2 = .{ | 190 | .elf2 = .{ |
| 194 | .path = "elf2", | 191 | .path = "elf2", |
| 195 | }, | 192 | }, |
test/standalone/compiler_rt_panic/main.c+2-2| ... | @@ -1,11 +1,11 @@ | ... | @@ -1,11 +1,11 @@ |
| 1 | #include <stddef.h> | 1 | #include <stddef.h> |
| 2 | 2 | ||
| 3 | void* __memset(void* dest, char c, size_t n, size_t dest_n); | 3 | void *__memset_chk(void *dest, int c, size_t n, size_t dest_n); |
| 4 | 4 | ||
| 5 | char foo[128]; | 5 | char foo[128]; |
| 6 | 6 | ||
| 7 | int main() { | 7 | int main() { |
| 8 | __memset(&foo[0], 0xff, 128, 128); | 8 | __memset_chk(&foo[0], 0xff, 128, 128); |
| 9 | return foo[64]; | 9 | return foo[64]; |
| 10 | } | 10 | } |
| 11 | 11 |
test/standalone/config_header/build.zig+21| ... | @@ -51,6 +51,27 @@ pub fn build(b: *std.Build) void { | ... | @@ -51,6 +51,27 @@ pub fn build(b: *std.Build) void { |
| 51 | }); | 51 | }); |
| 52 | test_step.dependOn(&check_config_header_autoconf_at.step); | 52 | test_step.dependOn(&check_config_header_autoconf_at.step); |
| 53 | 53 | ||
| 54 | const config_header_meson = b.addConfigHeader( | ||
| 55 | .{ .style = .{ | ||
| 56 | .meson = b.path("meson/mesondefine.h.in"), | ||
| 57 | } }, | ||
| 58 | .{ | ||
| 59 | .version = "1.2.3", | ||
| 60 | .boolean_true = true, | ||
| 61 | .boolean_false = false, | ||
| 62 | .uint_64 = 42, | ||
| 63 | .int_64 = -42, | ||
| 64 | .string = "meson", | ||
| 65 | .ident = .meson, | ||
| 66 | .not_defined = null, | ||
| 67 | .is_defined = {}, | ||
| 68 | }, | ||
| 69 | ); | ||
| 70 | const check_config_header_meson = b.addCheckFile(config_header_meson.getOutputFile(), .{ | ||
| 71 | .expected_exact = @embedFile("meson/mesondefine.h"), | ||
| 72 | }); | ||
| 73 | test_step.dependOn(&check_config_header_meson.step); | ||
| 74 | |||
| 54 | const config_header_blank = b.addConfigHeader( | 75 | const config_header_blank = b.addConfigHeader( |
| 55 | .{ | 76 | .{ |
| 56 | .style = .blank, | 77 | .style = .blank, |
test/standalone/config_header/meson/mesondefine.h created+22| ... | @@ -0,0 +1,22 @@ | ||
| 1 | /* This file was generated by ConfigHeader using the Zig Build System. */ | ||
| 2 | // comments are preserved | ||
| 3 | |||
| 4 | // empty lines are preserved | ||
| 5 | |||
| 6 | #define VERSION_STR "1.2.3" | ||
| 7 | |||
| 8 | #define boolean_true /* comment after define is okay */ | ||
| 9 | |||
| 10 | #undef boolean_false // same for line comment | ||
| 11 | |||
| 12 | #define uint_64 42 | ||
| 13 | |||
| 14 | #define int_64 -42 | ||
| 15 | |||
| 16 | #define string "meson" | ||
| 17 | |||
| 18 | #define ident meson | ||
| 19 | |||
| 20 | /* #undef not_defined */ | ||
| 21 | |||
| 22 | #define is_defined | ||
test/standalone/config_header/meson/mesondefine.h.in created+21| ... | @@ -0,0 +1,21 @@ | ||
| 1 | // comments are preserved | ||
| 2 | |||
| 3 | // empty lines are preserved | ||
| 4 | |||
| 5 | #define VERSION_STR "@version@" | ||
| 6 | |||
| 7 | #mesondefine boolean_true /* comment after define is okay */ | ||
| 8 | |||
| 9 | #mesondefine boolean_false // same for line comment | ||
| 10 | |||
| 11 | #mesondefine uint_64 | ||
| 12 | |||
| 13 | #mesondefine int_64 | ||
| 14 | |||
| 15 | #mesondefine string | ||
| 16 | |||
| 17 | #mesondefine ident | ||
| 18 | |||
| 19 | #mesondefine not_defined | ||
| 20 | |||
| 21 | #mesondefine is_defined | ||
test/standalone/debug_io_color/build.zig deleted-95| ... | @@ -1,95 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | |||
| 3 | pub fn build(b: *std.Build) void { | ||
| 4 | const test_step = b.step("test", "Test"); | ||
| 5 | b.default_step = test_step; | ||
| 6 | |||
| 7 | // Most targets handle color the same way, regardless of whether libc is linked. | ||
| 8 | const native_target = b.graph.host; | ||
| 9 | addTestCases(test_step, native_target, false); | ||
| 10 | addTestCases(test_step, native_target, true); | ||
| 11 | |||
| 12 | // WASI behaves differently depending on whether libc is linked. | ||
| 13 | if (b.enable_wasmtime) { | ||
| 14 | const wasi_target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .wasi }); | ||
| 15 | addTestCases(test_step, wasi_target, false); | ||
| 16 | addTestCases(test_step, wasi_target, true); | ||
| 17 | } | ||
| 18 | } | ||
| 19 | |||
| 20 | fn addTestCases( | ||
| 21 | test_step: *std.Build.Step, | ||
| 22 | target: std.Build.ResolvedTarget, | ||
| 23 | link_libc: bool, | ||
| 24 | ) void { | ||
| 25 | const b = test_step.owner; | ||
| 26 | const exe = b.addExecutable(.{ | ||
| 27 | .name = b.fmt("{s}{s}", .{ @tagName(target.result.os.tag), if (link_libc) "-libc" else "" }), | ||
| 28 | .root_module = b.createModule(.{ | ||
| 29 | .root_source_file = b.path("main.zig"), | ||
| 30 | .target = target, | ||
| 31 | .link_libc = link_libc, | ||
| 32 | }), | ||
| 33 | }); | ||
| 34 | |||
| 35 | // Should reflect 'std.process.Environ.Block' and 'std.Io.Threaded.init_single_threaded'. | ||
| 36 | const debug_io_can_read_environ = switch (target.result.os.tag) { | ||
| 37 | .windows => true, | ||
| 38 | .wasi, .emscripten => link_libc, | ||
| 39 | .freestanding, .other => false, | ||
| 40 | else => true, | ||
| 41 | }; | ||
| 42 | |||
| 43 | // Don't forget to account for whether the build process's stderr supports color. | ||
| 44 | const parent_stderr_color_enabled = (std.Io.Terminal.Mode.detect(b.graph.io, .stderr(), false, false) catch unreachable) != .no_color; | ||
| 45 | |||
| 46 | _ = addTestCase(test_step, exe, "neither", .inherit, .manual, parent_stderr_color_enabled); | ||
| 47 | _ = addTestCase(test_step, exe, "neither", .redirect, .manual, false); | ||
| 48 | _ = addTestCase(test_step, exe, "no_color", .inherit, .disable, if (debug_io_can_read_environ) false else parent_stderr_color_enabled); | ||
| 49 | _ = addTestCase(test_step, exe, "no_color", .redirect, .disable, false); | ||
| 50 | _ = addTestCase(test_step, exe, "clicolor_force", .inherit, .enable, if (debug_io_can_read_environ) true else parent_stderr_color_enabled); | ||
| 51 | _ = addTestCase(test_step, exe, "clicolor_force", .redirect, .enable, debug_io_can_read_environ); | ||
| 52 | |||
| 53 | const both = addTestCase(test_step, exe, "both", .inherit, .manual, if (debug_io_can_read_environ) false else parent_stderr_color_enabled); | ||
| 54 | both.setEnvironmentVariable("NO_COLOR", "1"); | ||
| 55 | both.setEnvironmentVariable("CLICOLOR_FORCE", "1"); | ||
| 56 | |||
| 57 | const both_redirected = addTestCase(test_step, exe, "both", .redirect, .manual, false); | ||
| 58 | both_redirected.setEnvironmentVariable("NO_COLOR", "1"); | ||
| 59 | both_redirected.setEnvironmentVariable("CLICOLOR_FORCE", "1"); | ||
| 60 | } | ||
| 61 | |||
| 62 | fn addTestCase( | ||
| 63 | test_step: *std.Build.Step, | ||
| 64 | exe: *std.Build.Step.Compile, | ||
| 65 | test_case_name: []const u8, | ||
| 66 | stderr: enum { inherit, redirect }, | ||
| 67 | run_step_color: std.Build.Step.Run.Color, | ||
| 68 | expected_color_enabled: bool, | ||
| 69 | ) *std.Build.Step.Run { | ||
| 70 | const b = test_step.owner; | ||
| 71 | const step_name = b.fmt("{s} {s}{s}", .{ | ||
| 72 | exe.name, | ||
| 73 | test_case_name, | ||
| 74 | if (stderr == .redirect) "-redirect" else "", | ||
| 75 | }); | ||
| 76 | const run_exe = b.addRunArtifact(exe); | ||
| 77 | run_exe.setName(b.fmt("run {s}", .{step_name})); | ||
| 78 | |||
| 79 | run_exe.failing_to_execute_foreign_is_an_error = false; | ||
| 80 | if (stderr == .redirect) run_exe.expectStdErrMatch(""); | ||
| 81 | |||
| 82 | run_exe.clearEnvironment(); | ||
| 83 | run_exe.color = run_step_color; | ||
| 84 | |||
| 85 | // Build system quirk: Currently, Run step stdout checks will also redirect stderr, so as a | ||
| 86 | // workaround we use a CheckFile step instead. We must also mark the Run step as having side | ||
| 87 | // effects, to ensure the parent stderr is inherited when not explicitly redirected. | ||
| 88 | run_exe.has_side_effects = true; | ||
| 89 | const stdout = run_exe.captureStdOut(.{}); | ||
| 90 | const check_file = b.addCheckFile(stdout, .{ .expected_exact = if (expected_color_enabled) "true" else "false" }); | ||
| 91 | check_file.setName(b.fmt("check {s}", .{step_name})); | ||
| 92 | test_step.dependOn(&check_file.step); | ||
| 93 | |||
| 94 | return run_exe; | ||
| 95 | } | ||
test/standalone/debug_io_color/main.zig deleted-7| ... | @@ -1,7 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | |||
| 3 | pub fn main() !void { | ||
| 4 | const stderr = std.debug.lockStderr(&.{}); | ||
| 5 | defer std.debug.unlockStderr(); | ||
| 6 | try std.Io.File.stdout().writeStreamingAll(std.Options.debug_io, if (stderr.terminal_mode != .no_color) "true" else "false"); | ||
| 7 | } | ||
test/standalone/dependency_options/build.zig+9-9| ... | @@ -11,11 +11,11 @@ pub fn build(b: *std.Build) !void { | ... | @@ -11,11 +11,11 @@ pub fn build(b: *std.Build) !void { |
| 11 | const none_specified_mod = none_specified.module("dummy"); | 11 | const none_specified_mod = none_specified.module("dummy"); |
| 12 | if (!none_specified_mod.resolved_target.?.query.eql(b.graph.host.query)) return error.TestFailed; | 12 | if (!none_specified_mod.resolved_target.?.query.eql(b.graph.host.query)) return error.TestFailed; |
| 13 | const expected_optimize: std.builtin.OptimizeMode = switch (b.graph.release_mode) { | 13 | const expected_optimize: std.builtin.OptimizeMode = switch (b.graph.release_mode) { |
| 14 | .off => .Debug, | 14 | .off => .debug, |
| 15 | .any => unreachable, | 15 | .any => unreachable, |
| 16 | .fast => .ReleaseFast, | 16 | .fast => .fast, |
| 17 | .safe => .ReleaseSafe, | 17 | .safe => .safe, |
| 18 | .small => .ReleaseSmall, | 18 | .small => .small, |
| 19 | }; | 19 | }; |
| 20 | if (none_specified_mod.optimize.? != expected_optimize) return error.TestFailed; | 20 | if (none_specified_mod.optimize.? != expected_optimize) return error.TestFailed; |
| 21 | 21 | ||
| ... | @@ -44,7 +44,7 @@ pub fn build(b: *std.Build) !void { | ... | @@ -44,7 +44,7 @@ pub fn build(b: *std.Build) !void { |
| 44 | 44 | ||
| 45 | const all_specified = b.dependency("other", .{ | 45 | const all_specified = b.dependency("other", .{ |
| 46 | .target = b.resolveTargetQuery(.{ .cpu_arch = .x86_64, .os_tag = .windows, .abi = .gnu }), | 46 | .target = b.resolveTargetQuery(.{ .cpu_arch = .x86_64, .os_tag = .windows, .abi = .gnu }), |
| 47 | .optimize = @as(std.builtin.OptimizeMode, .ReleaseSafe), | 47 | .optimize = @as(std.builtin.OptimizeMode, .safe), |
| 48 | .bool = @as(bool, true), | 48 | .bool = @as(bool, true), |
| 49 | .int = @as(i64, 123), | 49 | .int = @as(i64, 123), |
| 50 | .float = @as(f64, 0.5), | 50 | .float = @as(f64, 0.5), |
| ... | @@ -66,11 +66,11 @@ pub fn build(b: *std.Build) !void { | ... | @@ -66,11 +66,11 @@ pub fn build(b: *std.Build) !void { |
| 66 | if (all_specified_mod.resolved_target.?.result.cpu.arch != .x86_64) return error.TestFailed; | 66 | if (all_specified_mod.resolved_target.?.result.cpu.arch != .x86_64) return error.TestFailed; |
| 67 | if (all_specified_mod.resolved_target.?.result.os.tag != .windows) return error.TestFailed; | 67 | if (all_specified_mod.resolved_target.?.result.os.tag != .windows) return error.TestFailed; |
| 68 | if (all_specified_mod.resolved_target.?.result.abi != .gnu) return error.TestFailed; | 68 | if (all_specified_mod.resolved_target.?.result.abi != .gnu) return error.TestFailed; |
| 69 | if (all_specified_mod.optimize.? != .ReleaseSafe) return error.TestFailed; | 69 | if (all_specified_mod.optimize.? != .safe) return error.TestFailed; |
| 70 | 70 | ||
| 71 | const all_specified_optional = b.dependency("other", .{ | 71 | const all_specified_optional = b.dependency("other", .{ |
| 72 | .target = @as(?std.Build.ResolvedTarget, b.resolveTargetQuery(.{ .cpu_arch = .x86_64, .os_tag = .windows, .abi = .gnu })), | 72 | .target = @as(?std.Build.ResolvedTarget, b.resolveTargetQuery(.{ .cpu_arch = .x86_64, .os_tag = .windows, .abi = .gnu })), |
| 73 | .optimize = @as(?std.builtin.OptimizeMode, .ReleaseSafe), | 73 | .optimize = @as(?std.builtin.OptimizeMode, .safe), |
| 74 | .bool = @as(?bool, true), | 74 | .bool = @as(?bool, true), |
| 75 | .int = @as(?i64, 123), | 75 | .int = @as(?i64, 123), |
| 76 | .float = @as(?f64, 0.5), | 76 | .float = @as(?f64, 0.5), |
| ... | @@ -92,7 +92,7 @@ pub fn build(b: *std.Build) !void { | ... | @@ -92,7 +92,7 @@ pub fn build(b: *std.Build) !void { |
| 92 | 92 | ||
| 93 | const all_specified_literal = b.dependency("other", .{ | 93 | const all_specified_literal = b.dependency("other", .{ |
| 94 | .target = b.resolveTargetQuery(.{ .cpu_arch = .x86_64, .os_tag = .windows, .abi = .gnu }), | 94 | .target = b.resolveTargetQuery(.{ .cpu_arch = .x86_64, .os_tag = .windows, .abi = .gnu }), |
| 95 | .optimize = .ReleaseSafe, | 95 | .optimize = .safe, |
| 96 | .bool = true, | 96 | .bool = true, |
| 97 | .int = 123, | 97 | .int = 123, |
| 98 | .float = 0.5, | 98 | .float = 0.5, |
| ... | @@ -130,7 +130,7 @@ pub fn build(b: *std.Build) !void { | ... | @@ -130,7 +130,7 @@ pub fn build(b: *std.Build) !void { |
| 130 | // to the same cached dependency instance. | 130 | // to the same cached dependency instance. |
| 131 | const all_specified_alt = b.dependency("other", .{ | 131 | const all_specified_alt = b.dependency("other", .{ |
| 132 | .target = @as(std.Target.Query, .{ .cpu_arch = .x86_64, .os_tag = .windows, .abi = .gnu }), | 132 | .target = @as(std.Target.Query, .{ .cpu_arch = .x86_64, .os_tag = .windows, .abi = .gnu }), |
| 133 | .optimize = "ReleaseSafe", | 133 | .optimize = "safe", |
| 134 | .bool = .true, | 134 | .bool = .true, |
| 135 | .int = "123", | 135 | .int = "123", |
| 136 | .float = @as(f16, 0.5), | 136 | .float = @as(f16, 0.5), |
test/standalone/glibc_compat/build.zig+2| ... | @@ -103,6 +103,8 @@ pub fn build(b: *std.Build) void { | ... | @@ -103,6 +103,8 @@ pub fn build(b: *std.Build) void { |
| 103 | .{ .arch_os_abi = t }, | 103 | .{ .arch_os_abi = t }, |
| 104 | ) catch unreachable); | 104 | ) catch unreachable); |
| 105 | 105 | ||
| 106 | if (target.result.cpu.arch.isLoongArch()) continue; // https://github.com/Vexu/arocc/issues/1096 | ||
| 107 | |||
| 106 | const glibc_ver = target.result.os.version_range.linux.glibc; | 108 | const glibc_ver = target.result.os.version_range.linux.glibc; |
| 107 | 109 | ||
| 108 | // only build test if glibc version supports the architecture | 110 | // only build test if glibc version supports the architecture |
test/standalone/simple/build.zig+5-5| ... | @@ -13,26 +13,26 @@ pub fn build(b: *std.Build) void { | ... | @@ -13,26 +13,26 @@ pub fn build(b: *std.Build) void { |
| 13 | var optimize_modes_buf: [4]std.builtin.OptimizeMode = undefined; | 13 | var optimize_modes_buf: [4]std.builtin.OptimizeMode = undefined; |
| 14 | var optimize_modes_len: usize = 0; | 14 | var optimize_modes_len: usize = 0; |
| 15 | if (!skip_debug) { | 15 | if (!skip_debug) { |
| 16 | optimize_modes_buf[optimize_modes_len] = .Debug; | 16 | optimize_modes_buf[optimize_modes_len] = .debug; |
| 17 | optimize_modes_len += 1; | 17 | optimize_modes_len += 1; |
| 18 | } | 18 | } |
| 19 | if (!skip_release_safe) { | 19 | if (!skip_release_safe) { |
| 20 | optimize_modes_buf[optimize_modes_len] = .ReleaseSafe; | 20 | optimize_modes_buf[optimize_modes_len] = .safe; |
| 21 | optimize_modes_len += 1; | 21 | optimize_modes_len += 1; |
| 22 | } | 22 | } |
| 23 | if (!skip_release_fast) { | 23 | if (!skip_release_fast) { |
| 24 | optimize_modes_buf[optimize_modes_len] = .ReleaseFast; | 24 | optimize_modes_buf[optimize_modes_len] = .fast; |
| 25 | optimize_modes_len += 1; | 25 | optimize_modes_len += 1; |
| 26 | } | 26 | } |
| 27 | if (!skip_release_small) { | 27 | if (!skip_release_small) { |
| 28 | optimize_modes_buf[optimize_modes_len] = .ReleaseSmall; | 28 | optimize_modes_buf[optimize_modes_len] = .small; |
| 29 | optimize_modes_len += 1; | 29 | optimize_modes_len += 1; |
| 30 | } | 30 | } |
| 31 | const optimize_modes = optimize_modes_buf[0..optimize_modes_len]; | 31 | const optimize_modes = optimize_modes_buf[0..optimize_modes_len]; |
| 32 | 32 | ||
| 33 | for (cases) |case| { | 33 | for (cases) |case| { |
| 34 | for (optimize_modes) |optimize| { | 34 | for (optimize_modes) |optimize| { |
| 35 | if (!case.all_modes and optimize != .Debug) continue; | 35 | if (!case.all_modes and optimize != .debug) continue; |
| 36 | if (case.os_filter) |os_tag| { | 36 | if (case.os_filter) |os_tag| { |
| 37 | if (os_tag != builtin.os.tag) continue; | 37 | if (os_tag != builtin.os.tag) continue; |
| 38 | } | 38 | } |
test/standalone/windows_argv/fuzz.zig+1-2| ... | @@ -147,8 +147,7 @@ fn spawnVerify(verify_path: [:0]const u16, cmd_line: [:0]const u16) !windows.DWO | ... | @@ -147,8 +147,7 @@ fn spawnVerify(verify_path: [:0]const u16, cmd_line: [:0]const u16) !windows.DWO |
| 147 | break :spawn proc_info.hProcess; | 147 | break :spawn proc_info.hProcess; |
| 148 | }; | 148 | }; |
| 149 | defer windows.CloseHandle(child_proc); | 149 | defer windows.CloseHandle(child_proc); |
| 150 | const infinite_timeout: windows.LARGE_INTEGER = std.math.minInt(windows.LARGE_INTEGER); | 150 | switch (windows.ntdll.NtWaitForSingleObject(child_proc, .FALSE, null)) { |
| 151 | switch (windows.ntdll.NtWaitForSingleObject(child_proc, .FALSE, &infinite_timeout)) { | ||
| 152 | windows.NTSTATUS.WAIT_0 => {}, | 151 | windows.NTSTATUS.WAIT_0 => {}, |
| 153 | .TIMEOUT => return error.WaitTimeOut, | 152 | .TIMEOUT => return error.WaitTimeOut, |
| 154 | else => |status| return windows.unexpectedStatus(status), | 153 | else => |status| return windows.unexpectedStatus(status), |
test/tests.zig+129-177| ... | @@ -6,8 +6,6 @@ const OptimizeMode = std.builtin.OptimizeMode; | ... | @@ -6,8 +6,6 @@ const OptimizeMode = std.builtin.OptimizeMode; |
| 6 | const Step = std.Build.Step; | 6 | const Step = std.Build.Step; |
| 7 | 7 | ||
| 8 | // Cases | 8 | // Cases |
| 9 | const error_traces = @import("error_traces.zig"); | ||
| 10 | const stack_traces = @import("stack_traces.zig"); | ||
| 11 | const llvm_ir = @import("llvm_ir.zig"); | 9 | const llvm_ir = @import("llvm_ir.zig"); |
| 12 | const libc = @import("libc.zig"); | 10 | const libc = @import("libc.zig"); |
| 13 | const link = @import("link.zig"); | 11 | const link = @import("link.zig"); |
| ... | @@ -23,7 +21,7 @@ pub const LinkContext = @import("src/Link.zig"); | ... | @@ -23,7 +21,7 @@ pub const LinkContext = @import("src/Link.zig"); |
| 23 | const ModuleTestTarget = struct { | 21 | const ModuleTestTarget = struct { |
| 24 | linkage: ?std.builtin.LinkMode = null, | 22 | linkage: ?std.builtin.LinkMode = null, |
| 25 | target: std.Target.Query = .{}, | 23 | target: std.Target.Query = .{}, |
| 26 | optimize_mode: std.builtin.OptimizeMode = .Debug, | 24 | optimize_mode: std.builtin.OptimizeMode = .debug, |
| 27 | link_libc: ?bool = null, | 25 | link_libc: ?bool = null, |
| 28 | single_threaded: ?bool = null, | 26 | single_threaded: ?bool = null, |
| 29 | use_llvm: ?bool = null, | 27 | use_llvm: ?bool = null, |
| ... | @@ -57,38 +55,38 @@ const module_test_targets = blk: { | ... | @@ -57,38 +55,38 @@ const module_test_targets = blk: { |
| 57 | }, | 55 | }, |
| 58 | 56 | ||
| 59 | .{ | 57 | .{ |
| 60 | .optimize_mode = .ReleaseFast, | 58 | .optimize_mode = .fast, |
| 61 | }, | 59 | }, |
| 62 | .{ | 60 | .{ |
| 63 | .link_libc = true, | 61 | .link_libc = true, |
| 64 | .optimize_mode = .ReleaseFast, | 62 | .optimize_mode = .fast, |
| 65 | }, | 63 | }, |
| 66 | .{ | 64 | .{ |
| 67 | .optimize_mode = .ReleaseFast, | 65 | .optimize_mode = .fast, |
| 68 | .single_threaded = true, | 66 | .single_threaded = true, |
| 69 | }, | 67 | }, |
| 70 | 68 | ||
| 71 | .{ | 69 | .{ |
| 72 | .optimize_mode = .ReleaseSafe, | 70 | .optimize_mode = .safe, |
| 73 | }, | 71 | }, |
| 74 | .{ | 72 | .{ |
| 75 | .link_libc = true, | 73 | .link_libc = true, |
| 76 | .optimize_mode = .ReleaseSafe, | 74 | .optimize_mode = .safe, |
| 77 | }, | 75 | }, |
| 78 | .{ | 76 | .{ |
| 79 | .optimize_mode = .ReleaseSafe, | 77 | .optimize_mode = .safe, |
| 80 | .single_threaded = true, | 78 | .single_threaded = true, |
| 81 | }, | 79 | }, |
| 82 | 80 | ||
| 83 | .{ | 81 | .{ |
| 84 | .optimize_mode = .ReleaseSmall, | 82 | .optimize_mode = .small, |
| 85 | }, | 83 | }, |
| 86 | .{ | 84 | .{ |
| 87 | .link_libc = true, | 85 | .link_libc = true, |
| 88 | .optimize_mode = .ReleaseSmall, | 86 | .optimize_mode = .small, |
| 89 | }, | 87 | }, |
| 90 | .{ | 88 | .{ |
| 91 | .optimize_mode = .ReleaseSmall, | 89 | .optimize_mode = .small, |
| 92 | .single_threaded = true, | 90 | .single_threaded = true, |
| 93 | }, | 91 | }, |
| 94 | 92 | ||
| ... | @@ -200,7 +198,7 @@ const module_test_targets = blk: { | ... | @@ -200,7 +198,7 @@ const module_test_targets = blk: { |
| 200 | // }, | 198 | // }, |
| 201 | // .use_llvm = false, | 199 | // .use_llvm = false, |
| 202 | // .use_lld = false, | 200 | // .use_lld = false, |
| 203 | // .optimize_mode = .ReleaseFast, | 201 | // .optimize_mode = .fast, |
| 204 | // .strip = true, | 202 | // .strip = true, |
| 205 | // .skip_modules = &.{"std"}, // TODO get these passing | 203 | // .skip_modules = &.{"std"}, // TODO get these passing |
| 206 | //}, | 204 | //}, |
| ... | @@ -213,7 +211,7 @@ const module_test_targets = blk: { | ... | @@ -213,7 +211,7 @@ const module_test_targets = blk: { |
| 213 | // }, | 211 | // }, |
| 214 | // .use_llvm = false, | 212 | // .use_llvm = false, |
| 215 | // .use_lld = false, | 213 | // .use_lld = false, |
| 216 | // .optimize_mode = .ReleaseFast, | 214 | // .optimize_mode = .fast, |
| 217 | // .strip = true, | 215 | // .strip = true, |
| 218 | // .skip_modules = &.{"std"}, // TODO get these passing | 216 | // .skip_modules = &.{"std"}, // TODO get these passing |
| 219 | //}, | 217 | //}, |
| ... | @@ -274,6 +272,15 @@ const module_test_targets = blk: { | ... | @@ -274,6 +272,15 @@ const module_test_targets = blk: { |
| 274 | }, | 272 | }, |
| 275 | .link_libc = true, | 273 | .link_libc = true, |
| 276 | }, | 274 | }, |
| 275 | .{ | ||
| 276 | .target = .{ | ||
| 277 | .cpu_arch = .arm, | ||
| 278 | .os_tag = .linux, | ||
| 279 | .abi = .musleabi, | ||
| 280 | .ofmt = .c, | ||
| 281 | }, | ||
| 282 | .link_libc = true, | ||
| 283 | }, | ||
| 277 | .{ | 284 | .{ |
| 278 | .target = .{ | 285 | .target = .{ |
| 279 | .cpu_arch = .arm, | 286 | .cpu_arch = .arm, |
| ... | @@ -292,6 +299,15 @@ const module_test_targets = blk: { | ... | @@ -292,6 +299,15 @@ const module_test_targets = blk: { |
| 292 | }, | 299 | }, |
| 293 | .link_libc = true, | 300 | .link_libc = true, |
| 294 | }, | 301 | }, |
| 302 | .{ | ||
| 303 | .target = .{ | ||
| 304 | .cpu_arch = .arm, | ||
| 305 | .os_tag = .linux, | ||
| 306 | .abi = .musleabihf, | ||
| 307 | .ofmt = .c, | ||
| 308 | }, | ||
| 309 | .link_libc = true, | ||
| 310 | }, | ||
| 295 | .{ | 311 | .{ |
| 296 | .target = .{ | 312 | .target = .{ |
| 297 | .cpu_arch = .arm, | 313 | .cpu_arch = .arm, |
| ... | @@ -341,6 +357,15 @@ const module_test_targets = blk: { | ... | @@ -341,6 +357,15 @@ const module_test_targets = blk: { |
| 341 | }, | 357 | }, |
| 342 | .link_libc = true, | 358 | .link_libc = true, |
| 343 | }, | 359 | }, |
| 360 | .{ | ||
| 361 | .target = .{ | ||
| 362 | .cpu_arch = .armeb, | ||
| 363 | .os_tag = .linux, | ||
| 364 | .abi = .musleabi, | ||
| 365 | .ofmt = .c, | ||
| 366 | }, | ||
| 367 | .link_libc = true, | ||
| 368 | }, | ||
| 344 | // Crashes in weird ways when applying relocations. | 369 | // Crashes in weird ways when applying relocations. |
| 345 | // .{ | 370 | // .{ |
| 346 | // .target = .{ | 371 | // .target = .{ |
| ... | @@ -360,6 +385,15 @@ const module_test_targets = blk: { | ... | @@ -360,6 +385,15 @@ const module_test_targets = blk: { |
| 360 | }, | 385 | }, |
| 361 | .link_libc = true, | 386 | .link_libc = true, |
| 362 | }, | 387 | }, |
| 388 | .{ | ||
| 389 | .target = .{ | ||
| 390 | .cpu_arch = .armeb, | ||
| 391 | .os_tag = .linux, | ||
| 392 | .abi = .musleabihf, | ||
| 393 | .ofmt = .c, | ||
| 394 | }, | ||
| 395 | .link_libc = true, | ||
| 396 | }, | ||
| 363 | // Crashes in weird ways when applying relocations. | 397 | // Crashes in weird ways when applying relocations. |
| 364 | // .{ | 398 | // .{ |
| 365 | // .target = .{ | 399 | // .target = .{ |
| ... | @@ -419,6 +453,23 @@ const module_test_targets = blk: { | ... | @@ -419,6 +453,23 @@ const module_test_targets = blk: { |
| 419 | .abi = .none, | 453 | .abi = .none, |
| 420 | }, | 454 | }, |
| 421 | }, | 455 | }, |
| 456 | .{ | ||
| 457 | .target = .{ | ||
| 458 | .cpu_arch = .loongarch32, | ||
| 459 | .os_tag = .linux, | ||
| 460 | .abi = .gnu, | ||
| 461 | }, | ||
| 462 | .link_libc = true, | ||
| 463 | }, | ||
| 464 | .{ | ||
| 465 | .target = .{ | ||
| 466 | .cpu_arch = .loongarch32, | ||
| 467 | .os_tag = .linux, | ||
| 468 | .abi = .gnusf, | ||
| 469 | }, | ||
| 470 | .link_libc = true, | ||
| 471 | .extra_target = true, | ||
| 472 | }, | ||
| 422 | 473 | ||
| 423 | .{ | 474 | .{ |
| 424 | .target = .{ | 475 | .target = .{ |
| ... | @@ -1107,6 +1158,15 @@ const module_test_targets = blk: { | ... | @@ -1107,6 +1158,15 @@ const module_test_targets = blk: { |
| 1107 | }, | 1158 | }, |
| 1108 | .link_libc = true, | 1159 | .link_libc = true, |
| 1109 | }, | 1160 | }, |
| 1161 | .{ | ||
| 1162 | .target = .{ | ||
| 1163 | .cpu_arch = .x86, | ||
| 1164 | .os_tag = .linux, | ||
| 1165 | .abi = .musl, | ||
| 1166 | .ofmt = .c, | ||
| 1167 | }, | ||
| 1168 | .link_libc = true, | ||
| 1169 | }, | ||
| 1110 | .{ | 1170 | .{ |
| 1111 | .target = .{ | 1171 | .target = .{ |
| 1112 | .cpu_arch = .x86, | 1172 | .cpu_arch = .x86, |
| ... | @@ -1257,7 +1317,7 @@ const module_test_targets = blk: { | ... | @@ -1257,7 +1317,7 @@ const module_test_targets = blk: { |
| 1257 | // }, | 1317 | // }, |
| 1258 | // .use_llvm = false, | 1318 | // .use_llvm = false, |
| 1259 | // .use_lld = false, | 1319 | // .use_lld = false, |
| 1260 | // .optimize_mode = .ReleaseFast, | 1320 | // .optimize_mode = .fast, |
| 1261 | // .strip = true, | 1321 | // .strip = true, |
| 1262 | //}, | 1322 | //}, |
| 1263 | 1323 | ||
| ... | @@ -1523,7 +1583,6 @@ const module_test_targets = blk: { | ... | @@ -1523,7 +1583,6 @@ const module_test_targets = blk: { |
| 1523 | .os_tag = .wasi, | 1583 | .os_tag = .wasi, |
| 1524 | .abi = .none, | 1584 | .abi = .none, |
| 1525 | }, | 1585 | }, |
| 1526 | .skip_modules = &.{"compiler-rt"}, | ||
| 1527 | .use_llvm = false, | 1586 | .use_llvm = false, |
| 1528 | .use_lld = false, | 1587 | .use_lld = false, |
| 1529 | }, | 1588 | }, |
| ... | @@ -1645,6 +1704,15 @@ const module_test_targets = blk: { | ... | @@ -1645,6 +1704,15 @@ const module_test_targets = blk: { |
| 1645 | }, | 1704 | }, |
| 1646 | .link_libc = true, | 1705 | .link_libc = true, |
| 1647 | }, | 1706 | }, |
| 1707 | .{ | ||
| 1708 | .target = .{ | ||
| 1709 | .cpu_arch = .x86, | ||
| 1710 | .os_tag = .windows, | ||
| 1711 | .abi = .gnu, | ||
| 1712 | .ofmt = .c, | ||
| 1713 | }, | ||
| 1714 | .link_libc = true, | ||
| 1715 | }, | ||
| 1648 | 1716 | ||
| 1649 | .{ | 1717 | .{ |
| 1650 | .target = .{ | 1718 | .target = .{ |
| ... | @@ -1961,7 +2029,6 @@ const c_abi_targets = blk: { | ... | @@ -1961,7 +2029,6 @@ const c_abi_targets = blk: { |
| 1961 | .abi = .musl, | 2029 | .abi = .musl, |
| 1962 | }, | 2030 | }, |
| 1963 | .use_llvm = false, | 2031 | .use_llvm = false, |
| 1964 | .c_defines = &.{"ZIG_BACKEND_STAGE2_X86_64"}, | ||
| 1965 | }, | 2032 | }, |
| 1966 | .{ | 2033 | .{ |
| 1967 | .target = .{ | 2034 | .target = .{ |
| ... | @@ -1972,7 +2039,6 @@ const c_abi_targets = blk: { | ... | @@ -1972,7 +2039,6 @@ const c_abi_targets = blk: { |
| 1972 | }, | 2039 | }, |
| 1973 | .use_llvm = false, | 2040 | .use_llvm = false, |
| 1974 | .strip = true, | 2041 | .strip = true, |
| 1975 | .c_defines = &.{"ZIG_BACKEND_STAGE2_X86_64"}, | ||
| 1976 | }, | 2042 | }, |
| 1977 | .{ | 2043 | .{ |
| 1978 | .target = .{ | 2044 | .target = .{ |
| ... | @@ -1983,7 +2049,6 @@ const c_abi_targets = blk: { | ... | @@ -1983,7 +2049,6 @@ const c_abi_targets = blk: { |
| 1983 | }, | 2049 | }, |
| 1984 | .use_llvm = false, | 2050 | .use_llvm = false, |
| 1985 | .pic = true, | 2051 | .pic = true, |
| 1986 | .c_defines = &.{"ZIG_BACKEND_STAGE2_X86_64"}, | ||
| 1987 | }, | 2052 | }, |
| 1988 | .{ | 2053 | .{ |
| 1989 | .target = .{ | 2054 | .target = .{ |
| ... | @@ -2010,6 +2075,15 @@ const c_abi_targets = blk: { | ... | @@ -2010,6 +2075,15 @@ const c_abi_targets = blk: { |
| 2010 | .abi = .musl, | 2075 | .abi = .musl, |
| 2011 | }, | 2076 | }, |
| 2012 | }, | 2077 | }, |
| 2078 | .{ | ||
| 2079 | .target = .{ | ||
| 2080 | .cpu_arch = .wasm32, | ||
| 2081 | .os_tag = .wasi, | ||
| 2082 | .abi = .musl, | ||
| 2083 | }, | ||
| 2084 | .use_llvm = false, | ||
| 2085 | .use_lld = false, | ||
| 2086 | }, | ||
| 2013 | 2087 | ||
| 2014 | // Windows Targets | 2088 | // Windows Targets |
| 2015 | 2089 | ||
| ... | @@ -2028,7 +2102,6 @@ const c_abi_targets = blk: { | ... | @@ -2028,7 +2102,6 @@ const c_abi_targets = blk: { |
| 2028 | .abi = .gnu, | 2102 | .abi = .gnu, |
| 2029 | }, | 2103 | }, |
| 2030 | .use_llvm = false, | 2104 | .use_llvm = false, |
| 2031 | .c_defines = &.{"ZIG_BACKEND_STAGE2_X86_64"}, | ||
| 2032 | }, | 2105 | }, |
| 2033 | .{ | 2106 | .{ |
| 2034 | .target = .{ | 2107 | .target = .{ |
| ... | @@ -2038,7 +2111,6 @@ const c_abi_targets = blk: { | ... | @@ -2038,7 +2111,6 @@ const c_abi_targets = blk: { |
| 2038 | .abi = .gnu, | 2111 | .abi = .gnu, |
| 2039 | }, | 2112 | }, |
| 2040 | .use_llvm = false, | 2113 | .use_llvm = false, |
| 2041 | .c_defines = &.{"ZIG_BACKEND_STAGE2_X86_64"}, | ||
| 2042 | }, | 2114 | }, |
| 2043 | .{ | 2115 | .{ |
| 2044 | .target = .{ | 2116 | .target = .{ |
| ... | @@ -2048,7 +2120,6 @@ const c_abi_targets = blk: { | ... | @@ -2048,7 +2120,6 @@ const c_abi_targets = blk: { |
| 2048 | .abi = .gnu, | 2120 | .abi = .gnu, |
| 2049 | }, | 2121 | }, |
| 2050 | .use_llvm = false, | 2122 | .use_llvm = false, |
| 2051 | .c_defines = &.{"ZIG_BACKEND_STAGE2_X86_64"}, | ||
| 2052 | }, | 2123 | }, |
| 2053 | .{ | 2124 | .{ |
| 2054 | .target = .{ | 2125 | .target = .{ |
| ... | @@ -2063,7 +2134,7 @@ const c_abi_targets = blk: { | ... | @@ -2063,7 +2134,7 @@ const c_abi_targets = blk: { |
| 2063 | 2134 | ||
| 2064 | const LinkTarget = struct { | 2135 | const LinkTarget = struct { |
| 2065 | target: std.Target.Query = .{}, | 2136 | target: std.Target.Query = .{}, |
| 2066 | optimize_mode: std.builtin.OptimizeMode = .Debug, | 2137 | optimize_mode: std.builtin.OptimizeMode = .debug, |
| 2067 | link_libc: bool = false, | 2138 | link_libc: bool = false, |
| 2068 | use_llvm: bool = false, | 2139 | use_llvm: bool = false, |
| 2069 | use_lld: bool = false, | 2140 | use_lld: bool = false, |
| ... | @@ -2308,59 +2379,7 @@ pub fn isNative(actual_target: *const std.Build.ResolvedTarget, host: *const std | ... | @@ -2308,59 +2379,7 @@ pub fn isNative(actual_target: *const std.Build.ResolvedTarget, host: *const std |
| 2308 | return true; | 2379 | return true; |
| 2309 | } | 2380 | } |
| 2310 | 2381 | ||
| 2311 | /// For stack trace tests, we only test native by default, because external executors are pretty | 2382 | pub fn addStackTraceTests(b: *std.Build, test_filters: []const []const u8, skip_non_native: bool) *Step { |
| 2312 | /// unreliable at stack tracing. However, if there's a 32-bit equivalent target which the host can | ||
| 2313 | /// trivially run, we may as well at least test that! | ||
| 2314 | fn nativeAndCompatible32bit(b: *std.Build, skip_non_native: bool) []const std.Build.ResolvedTarget { | ||
| 2315 | const host = b.graph.host.result; | ||
| 2316 | const only_native = (&b.graph.host)[0..1]; | ||
| 2317 | if (skip_non_native) return only_native; | ||
| 2318 | const arch32 = compatible32bitArch(&b.graph.host.result) orelse return only_native; | ||
| 2319 | return b.graph.arena.dupe(std.Build.ResolvedTarget, &.{ | ||
| 2320 | b.graph.host, | ||
| 2321 | b.resolveTargetQuery(.{ .cpu_arch = arch32, .os_tag = host.os.tag }), | ||
| 2322 | }) catch @panic("OOM"); | ||
| 2323 | } | ||
| 2324 | |||
| 2325 | fn wineAndCompatible32bit(b: *std.Build, skip_non_native: bool) []const std.Build.ResolvedTarget { | ||
| 2326 | var targets: std.ArrayList(std.Build.ResolvedTarget) = .empty; | ||
| 2327 | |||
| 2328 | const host = b.graph.host.result; | ||
| 2329 | |||
| 2330 | targets.append(b.graph.arena, b.resolveTargetQuery(.{ | ||
| 2331 | .cpu_arch = host.cpu.arch, | ||
| 2332 | .os_tag = .windows, | ||
| 2333 | })) catch @panic("OOM"); | ||
| 2334 | if (!skip_non_native) { | ||
| 2335 | if (compatible32bitArch(&b.graph.host.result)) |arch| { | ||
| 2336 | targets.append(b.graph.arena, b.resolveTargetQuery(.{ | ||
| 2337 | .cpu_arch = arch, | ||
| 2338 | .os_tag = .windows, | ||
| 2339 | })) catch @panic("OOM"); | ||
| 2340 | } | ||
| 2341 | } | ||
| 2342 | |||
| 2343 | return targets.toOwnedSlice(b.graph.arena) catch @panic("OOM"); | ||
| 2344 | } | ||
| 2345 | |||
| 2346 | fn darlingTargets(b: *std.Build) []const std.Build.ResolvedTarget { | ||
| 2347 | var targets: std.ArrayList(std.Build.ResolvedTarget) = .empty; | ||
| 2348 | |||
| 2349 | const host = b.graph.host.result; | ||
| 2350 | |||
| 2351 | targets.append(b.graph.arena, b.resolveTargetQuery(.{ | ||
| 2352 | .cpu_arch = host.cpu.arch, | ||
| 2353 | .os_tag = .macos, | ||
| 2354 | })) catch @panic("OOM"); | ||
| 2355 | |||
| 2356 | return targets.toOwnedSlice(b.graph.arena) catch @panic("OOM"); | ||
| 2357 | } | ||
| 2358 | |||
| 2359 | pub fn addStackTraceTests( | ||
| 2360 | b: *std.Build, | ||
| 2361 | test_filters: []const []const u8, | ||
| 2362 | skip_non_native: bool, | ||
| 2363 | ) *Step { | ||
| 2364 | const step = b.step("test-stack-traces", "Run the stack trace tests"); | 2383 | const step = b.step("test-stack-traces", "Run the stack trace tests"); |
| 2365 | 2384 | ||
| 2366 | const convert_exe = b.addExecutable(.{ | 2385 | const convert_exe = b.addExecutable(.{ |
| ... | @@ -2368,43 +2387,19 @@ pub fn addStackTraceTests( | ... | @@ -2368,43 +2387,19 @@ pub fn addStackTraceTests( |
| 2368 | .root_module = b.createModule(.{ | 2387 | .root_module = b.createModule(.{ |
| 2369 | .root_source_file = b.path("test/src/convert-stack-trace.zig"), | 2388 | .root_source_file = b.path("test/src/convert-stack-trace.zig"), |
| 2370 | .target = b.graph.host, | 2389 | .target = b.graph.host, |
| 2371 | .optimize = .Debug, | 2390 | .optimize = .debug, |
| 2372 | }), | 2391 | }), |
| 2373 | }); | 2392 | }); |
| 2374 | 2393 | ||
| 2375 | const host_cases = b.allocator.create(StackTracesContext) catch @panic("OOM"); | 2394 | const stack_traces_context = b.allocator.create(StackTracesContext) catch @panic("OOM"); |
| 2376 | host_cases.* = .{ | 2395 | stack_traces_context.* = .{ |
| 2377 | .b = b, | 2396 | .b = b, |
| 2378 | .step = step, | 2397 | .step = step, |
| 2379 | .test_filters = test_filters, | 2398 | .test_filters = test_filters, |
| 2380 | .targets = nativeAndCompatible32bit(b, skip_non_native), | 2399 | .skip_non_native = skip_non_native, |
| 2381 | .convert_exe = convert_exe, | 2400 | .convert_exe = convert_exe, |
| 2382 | }; | 2401 | }; |
| 2383 | stack_traces.addCases(host_cases, b.graph.host.result.os.tag); | 2402 | stack_traces_context.addCases(); |
| 2384 | |||
| 2385 | if (b.enable_wine) { | ||
| 2386 | const wine_cases = b.allocator.create(StackTracesContext) catch @panic("OOM"); | ||
| 2387 | wine_cases.* = .{ | ||
| 2388 | .b = b, | ||
| 2389 | .step = step, | ||
| 2390 | .test_filters = test_filters, | ||
| 2391 | .targets = wineAndCompatible32bit(b, skip_non_native), | ||
| 2392 | .convert_exe = convert_exe, | ||
| 2393 | }; | ||
| 2394 | stack_traces.addCases(wine_cases, .windows); | ||
| 2395 | } | ||
| 2396 | |||
| 2397 | if (b.enable_darling) { | ||
| 2398 | const darling_cases = b.allocator.create(StackTracesContext) catch @panic("OOM"); | ||
| 2399 | darling_cases.* = .{ | ||
| 2400 | .b = b, | ||
| 2401 | .step = step, | ||
| 2402 | .test_filters = test_filters, | ||
| 2403 | .targets = darlingTargets(b), | ||
| 2404 | .convert_exe = convert_exe, | ||
| 2405 | }; | ||
| 2406 | stack_traces.addCases(darling_cases, .macos); | ||
| 2407 | } | ||
| 2408 | 2403 | ||
| 2409 | return step; | 2404 | return step; |
| 2410 | } | 2405 | } |
| ... | @@ -2422,56 +2417,24 @@ pub fn addErrorTraceTests( | ... | @@ -2422,56 +2417,24 @@ pub fn addErrorTraceTests( |
| 2422 | .root_module = b.createModule(.{ | 2417 | .root_module = b.createModule(.{ |
| 2423 | .root_source_file = b.path("test/src/convert-stack-trace.zig"), | 2418 | .root_source_file = b.path("test/src/convert-stack-trace.zig"), |
| 2424 | .target = b.graph.host, | 2419 | .target = b.graph.host, |
| 2425 | .optimize = .Debug, | 2420 | .optimize = .debug, |
| 2426 | }), | 2421 | }), |
| 2427 | }); | 2422 | }); |
| 2428 | 2423 | ||
| 2429 | const host_cases = b.allocator.create(ErrorTracesContext) catch @panic("OOM"); | 2424 | const error_traces_context = b.allocator.create(ErrorTracesContext) catch @panic("OOM"); |
| 2430 | host_cases.* = .{ | 2425 | error_traces_context.* = .{ |
| 2431 | .b = b, | 2426 | .b = b, |
| 2432 | .step = step, | 2427 | .step = step, |
| 2433 | .test_filters = test_filters, | 2428 | .test_filters = test_filters, |
| 2434 | .targets = nativeAndCompatible32bit(b, skip_non_native), | 2429 | .skip_non_native = skip_non_native, |
| 2435 | .optimize_modes = optimize_modes, | 2430 | .optimize_modes = optimize_modes, |
| 2436 | .convert_exe = convert_exe, | 2431 | .convert_exe = convert_exe, |
| 2437 | }; | 2432 | }; |
| 2438 | error_traces.addCases(host_cases, b.graph.host.result.os.tag); | 2433 | error_traces_context.addCases(); |
| 2439 | |||
| 2440 | if (b.enable_wine) { | ||
| 2441 | const wine_cases = b.allocator.create(ErrorTracesContext) catch @panic("OOM"); | ||
| 2442 | wine_cases.* = .{ | ||
| 2443 | .b = b, | ||
| 2444 | .step = step, | ||
| 2445 | .test_filters = test_filters, | ||
| 2446 | .targets = wineAndCompatible32bit(b, skip_non_native), | ||
| 2447 | .optimize_modes = optimize_modes, | ||
| 2448 | .convert_exe = convert_exe, | ||
| 2449 | }; | ||
| 2450 | error_traces.addCases(wine_cases, .windows); | ||
| 2451 | } | ||
| 2452 | |||
| 2453 | if (b.enable_darling) { | ||
| 2454 | const darling_cases = b.allocator.create(ErrorTracesContext) catch @panic("OOM"); | ||
| 2455 | darling_cases.* = .{ | ||
| 2456 | .b = b, | ||
| 2457 | .step = step, | ||
| 2458 | .test_filters = test_filters, | ||
| 2459 | .targets = darlingTargets(b), | ||
| 2460 | .optimize_modes = optimize_modes, | ||
| 2461 | .convert_exe = convert_exe, | ||
| 2462 | }; | ||
| 2463 | error_traces.addCases(darling_cases, .macos); | ||
| 2464 | } | ||
| 2465 | 2434 | ||
| 2466 | return step; | 2435 | return step; |
| 2467 | } | 2436 | } |
| 2468 | 2437 | ||
| 2469 | fn compilerHasPackageManager(b: *std.Build) bool { | ||
| 2470 | // We can only use dependencies if the compiler was built with support for package management. | ||
| 2471 | // (zig2 doesn't support it, but we still need to construct a build graph to build stage3.) | ||
| 2472 | return b.available_deps.len != 0; | ||
| 2473 | } | ||
| 2474 | |||
| 2475 | pub fn addStandaloneTests( | 2438 | pub fn addStandaloneTests( |
| 2476 | b: *std.Build, | 2439 | b: *std.Build, |
| 2477 | optimize_modes: []const OptimizeMode, | 2440 | optimize_modes: []const OptimizeMode, |
| ... | @@ -2480,21 +2443,19 @@ pub fn addStandaloneTests( | ... | @@ -2480,21 +2443,19 @@ pub fn addStandaloneTests( |
| 2480 | enable_symlinks_windows: bool, | 2443 | enable_symlinks_windows: bool, |
| 2481 | ) *Step { | 2444 | ) *Step { |
| 2482 | const step = b.step("test-standalone", "Run the standalone tests"); | 2445 | const step = b.step("test-standalone", "Run the standalone tests"); |
| 2483 | if (compilerHasPackageManager(b)) { | 2446 | const test_cases_dep_name = "standalone_test_cases"; |
| 2484 | const test_cases_dep_name = "standalone_test_cases"; | 2447 | const test_cases_dep = b.dependency(test_cases_dep_name, .{ |
| 2485 | const test_cases_dep = b.dependency(test_cases_dep_name, .{ | 2448 | .enable_ios_sdk = enable_ios_sdk, |
| 2486 | .enable_ios_sdk = enable_ios_sdk, | 2449 | .enable_macos_sdk = enable_macos_sdk, |
| 2487 | .enable_macos_sdk = enable_macos_sdk, | 2450 | .enable_symlinks_windows = enable_symlinks_windows, |
| 2488 | .enable_symlinks_windows = enable_symlinks_windows, | 2451 | .simple_skip_debug = mem.findScalar(OptimizeMode, optimize_modes, .debug) == null, |
| 2489 | .simple_skip_debug = mem.indexOfScalar(OptimizeMode, optimize_modes, .Debug) == null, | 2452 | .simple_skip_release_safe = mem.findScalar(OptimizeMode, optimize_modes, .safe) == null, |
| 2490 | .simple_skip_release_safe = mem.indexOfScalar(OptimizeMode, optimize_modes, .ReleaseSafe) == null, | 2453 | .simple_skip_release_fast = mem.findScalar(OptimizeMode, optimize_modes, .fast) == null, |
| 2491 | .simple_skip_release_fast = mem.indexOfScalar(OptimizeMode, optimize_modes, .ReleaseFast) == null, | 2454 | .simple_skip_release_small = mem.findScalar(OptimizeMode, optimize_modes, .small) == null, |
| 2492 | .simple_skip_release_small = mem.indexOfScalar(OptimizeMode, optimize_modes, .ReleaseSmall) == null, | 2455 | }); |
| 2493 | }); | 2456 | const test_cases_dep_step = test_cases_dep.builder.default_step; |
| 2494 | const test_cases_dep_step = test_cases_dep.builder.default_step; | 2457 | test_cases_dep_step.name = b.graph.dupeString(test_cases_dep_name); |
| 2495 | test_cases_dep_step.name = b.dupe(test_cases_dep_name); | 2458 | step.dependOn(test_cases_dep.builder.default_step); |
| 2496 | step.dependOn(test_cases_dep.builder.default_step); | ||
| 2497 | } | ||
| 2498 | return step; | 2459 | return step; |
| 2499 | } | 2460 | } |
| 2500 | 2461 | ||
| ... | @@ -2782,16 +2743,6 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { | ... | @@ -2782,16 +2743,6 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { |
| 2782 | 2743 | ||
| 2783 | const target = &resolved_target.result; | 2744 | const target = &resolved_target.result; |
| 2784 | 2745 | ||
| 2785 | if (target.cpu.arch == .s390x and target.ofmt == .c) { | ||
| 2786 | // https://codeberg.org/ziglang/zig/issues/35523 | ||
| 2787 | continue; | ||
| 2788 | } | ||
| 2789 | |||
| 2790 | if (target.cpu.arch == .riscv64 and target.ofmt == .c) { | ||
| 2791 | // https://codeberg.org/ziglang/zig/issues/30930 | ||
| 2792 | continue; | ||
| 2793 | } | ||
| 2794 | |||
| 2795 | if (std.mem.eql(u8, options.name, "libc")) { | 2746 | if (std.mem.eql(u8, options.name, "libc")) { |
| 2796 | // The libc API tests obviously need to link libc. So for test | 2747 | // The libc API tests obviously need to link libc. So for test |
| 2797 | // target entries where we wouldn't link libc by default, skip the | 2748 | // target entries where we wouldn't link libc by default, skip the |
| ... | @@ -2816,7 +2767,7 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { | ... | @@ -2816,7 +2767,7 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { |
| 2816 | 2767 | ||
| 2817 | if (options.test_target_filters.len > 0) { | 2768 | if (options.test_target_filters.len > 0) { |
| 2818 | for (options.test_target_filters) |filter| { | 2769 | for (options.test_target_filters) |filter| { |
| 2819 | if (std.mem.indexOf(u8, triple_txt, filter) != null) break; | 2770 | if (std.mem.find(u8, triple_txt, filter) != null) break; |
| 2820 | } else continue; | 2771 | } else continue; |
| 2821 | } | 2772 | } |
| 2822 | 2773 | ||
| ... | @@ -3057,7 +3008,7 @@ pub fn wouldUseLlvm(use_llvm: ?bool, query: std.Target.Query, optimize_mode: Opt | ... | @@ -3057,7 +3008,7 @@ pub fn wouldUseLlvm(use_llvm: ?bool, query: std.Target.Query, optimize_mode: Opt |
| 3057 | if (use_llvm) |x| return x; | 3008 | if (use_llvm) |x| return x; |
| 3058 | if (query.ofmt == .c) return false; | 3009 | if (query.ofmt == .c) return false; |
| 3059 | switch (optimize_mode) { | 3010 | switch (optimize_mode) { |
| 3060 | .Debug => {}, | 3011 | .debug => {}, |
| 3061 | else => return true, | 3012 | else => return true, |
| 3062 | } | 3013 | } |
| 3063 | const cpu_arch = query.cpu_arch orelse builtin.cpu.arch; | 3014 | const cpu_arch = query.cpu_arch orelse builtin.cpu.arch; |
| ... | @@ -3114,7 +3065,7 @@ pub fn addCAbiTests(b: *std.Build, options: CAbiTestOptions) *Step { | ... | @@ -3114,7 +3065,7 @@ pub fn addCAbiTests(b: *std.Build, options: CAbiTestOptions) *Step { |
| 3114 | 3065 | ||
| 3115 | if (options.test_target_filters.len > 0) { | 3066 | if (options.test_target_filters.len > 0) { |
| 3116 | for (options.test_target_filters) |filter| { | 3067 | for (options.test_target_filters) |filter| { |
| 3117 | if (std.mem.indexOf(u8, triple_txt, filter) != null) break; | 3068 | if (std.mem.find(u8, triple_txt, filter) != null) break; |
| 3118 | } else continue; | 3069 | } else continue; |
| 3119 | } | 3070 | } |
| 3120 | 3071 | ||
| ... | @@ -3203,7 +3154,7 @@ pub fn addLinkTests(b: *std.Build, options: LinkTestOptions) *Step { | ... | @@ -3203,7 +3154,7 @@ pub fn addLinkTests(b: *std.Build, options: LinkTestOptions) *Step { |
| 3203 | 3154 | ||
| 3204 | if (options.test_target_filters.len > 0) { | 3155 | if (options.test_target_filters.len > 0) { |
| 3205 | for (options.test_target_filters) |filter| { | 3156 | for (options.test_target_filters) |filter| { |
| 3206 | if (std.mem.indexOf(u8, triple_txt, filter) != null) break; | 3157 | if (std.mem.find(u8, triple_txt, filter) != null) break; |
| 3207 | } else continue; | 3158 | } else continue; |
| 3208 | } | 3159 | } |
| 3209 | 3160 | ||
| ... | @@ -3314,7 +3265,7 @@ pub fn addIncrementalTests(b: *std.Build, test_step: *Step, test_filters: []cons | ... | @@ -3314,7 +3265,7 @@ pub fn addIncrementalTests(b: *std.Build, test_step: *Step, test_filters: []cons |
| 3314 | .root_module = b.createModule(.{ | 3265 | .root_module = b.createModule(.{ |
| 3315 | .root_source_file = b.path("tools/incr-check.zig"), | 3266 | .root_source_file = b.path("tools/incr-check.zig"), |
| 3316 | .target = b.graph.host, | 3267 | .target = b.graph.host, |
| 3317 | .optimize = .Debug, | 3268 | .optimize = .debug, |
| 3318 | }), | 3269 | }), |
| 3319 | }); | 3270 | }); |
| 3320 | 3271 | ||
| ... | @@ -3328,7 +3279,7 @@ pub fn addIncrementalTests(b: *std.Build, test_step: *Step, test_filters: []cons | ... | @@ -3328,7 +3279,7 @@ pub fn addIncrementalTests(b: *std.Build, test_step: *Step, test_filters: []cons |
| 3328 | if (std.mem.endsWith(u8, entry.basename, ".swp")) continue; | 3279 | if (std.mem.endsWith(u8, entry.basename, ".swp")) continue; |
| 3329 | 3280 | ||
| 3330 | for (test_filters) |test_filter| { | 3281 | for (test_filters) |test_filter| { |
| 3331 | if (std.mem.indexOf(u8, entry.path, test_filter)) |_| break; | 3282 | if (std.mem.find(u8, entry.path, test_filter)) |_| break; |
| 3332 | } else if (test_filters.len > 0) continue; | 3283 | } else if (test_filters.len > 0) continue; |
| 3333 | 3284 | ||
| 3334 | switch (entry.kind) { | 3285 | switch (entry.kind) { |
| ... | @@ -3354,10 +3305,11 @@ pub fn addIncrementalTests(b: *std.Build, test_step: *Step, test_filters: []cons | ... | @@ -3354,10 +3305,11 @@ pub fn addIncrementalTests(b: *std.Build, test_step: *Step, test_filters: []cons |
| 3354 | 3305 | ||
| 3355 | run.addArg("--quiet"); // don't fill stderr telling us about skipped tests etc | 3306 | run.addArg("--quiet"); // don't fill stderr telling us about skipped tests etc |
| 3356 | 3307 | ||
| 3357 | if (b.enable_qemu) run.addArg("-fqemu"); | 3308 | run.addThirdPartyEnabledArgDarling(.{ .enabled = "-fdarling" }); |
| 3358 | if (b.enable_wine) run.addArg("-fwine"); | 3309 | run.addThirdPartyEnabledArgQemu(.{ .enabled = "-fqemu" }); |
| 3359 | if (b.enable_wasmtime) run.addArg("-fwasmtime"); | 3310 | run.addThirdPartyEnabledArgRosetta(.{ .enabled = "-frosetta" }); |
| 3360 | if (b.enable_darling) run.addArg("-fdarling"); | 3311 | run.addThirdPartyEnabledArgWasmtime(.{ .enabled = "-fwasmtime" }); |
| 3312 | run.addThirdPartyEnabledArgWine(.{ .enabled = "-fwine" }); | ||
| 3361 | 3313 | ||
| 3362 | run.addCheck(.{ .expect_term = .{ .exited = 0 } }); | 3314 | run.addCheck(.{ .expect_term = .{ .exited = 0 } }); |
| 3363 | test_step.dependOn(&run.step); | 3315 | test_step.dependOn(&run.step); |
tools/bsp.zig created+242| ... | @@ -0,0 +1,242 @@ | ||
| 1 | //! CLI tool to interface with the build system protocol (zig build --listen=-) | ||
| 2 | |||
| 3 | const std = @import("std"); | ||
| 4 | const Io = std.Io; | ||
| 5 | const Allocator = std.mem.Allocator; | ||
| 6 | const Configuration = std.Build.Configuration; | ||
| 7 | const Client = std.zig.Client; | ||
| 8 | const Server = std.zig.Server; | ||
| 9 | const log = std.log.scoped(.bsp); | ||
| 10 | |||
| 11 | pub fn main(init: std.process.Init) !void { | ||
| 12 | const io = init.io; | ||
| 13 | const gpa = init.gpa; | ||
| 14 | const arena = init.arena.allocator(); | ||
| 15 | |||
| 16 | var maker_args: std.ArrayList([]const u8) = .empty; | ||
| 17 | |||
| 18 | const args = try init.minimal.args.toSlice(arena); | ||
| 19 | for (args[1..]) |arg| { | ||
| 20 | try maker_args.append(arena, try arena.dupe(u8, arg)); | ||
| 21 | } | ||
| 22 | if (maker_args.items.len < 1) try maker_args.append(arena, "zig"); | ||
| 23 | if (maker_args.items.len < 2) try maker_args.append(arena, "build"); | ||
| 24 | if (!std.mem.eql(u8, maker_args.last().?, "--listen=-")) try maker_args.append(arena, "--listen=-"); | ||
| 25 | |||
| 26 | log.debug("cmd: {f}", .{std.zig.SubprocessCommand{ | ||
| 27 | .argv = maker_args.items, | ||
| 28 | }}); | ||
| 29 | |||
| 30 | var child_process = std.process.spawn(io, .{ | ||
| 31 | .argv = maker_args.items, | ||
| 32 | .stdin = .pipe, | ||
| 33 | .stdout = .pipe, | ||
| 34 | .stderr = .pipe, | ||
| 35 | }) catch |err| std.debug.panic("failed to spawn process: {}", .{err}); | ||
| 36 | errdefer child_process.kill(io); | ||
| 37 | |||
| 38 | var multi_reader_buffer: Io.File.MultiReader.Buffer(2) = undefined; | ||
| 39 | var multi_reader: Io.File.MultiReader = undefined; | ||
| 40 | defer multi_reader.deinit(); | ||
| 41 | multi_reader.init( | ||
| 42 | gpa, | ||
| 43 | io, | ||
| 44 | multi_reader_buffer.toStreams(), | ||
| 45 | &.{ child_process.stdout.?, child_process.stderr.? }, | ||
| 46 | ); | ||
| 47 | const client_stdout = multi_reader.reader(0); | ||
| 48 | const client_stderr = multi_reader.reader(1); | ||
| 49 | |||
| 50 | var client_stdout_buffer: [256]u8 = undefined; | ||
| 51 | var client_stdout_writer = child_process.stdin.?.writerStreaming(io, &client_stdout_buffer); | ||
| 52 | |||
| 53 | var client: Client = .{ | ||
| 54 | .in = client_stdout, | ||
| 55 | .out = &client_stdout_writer.interface, | ||
| 56 | }; | ||
| 57 | |||
| 58 | const err = blk: { | ||
| 59 | const handshake: Server.Message.Handshake = handshake: { | ||
| 60 | const header = client.receiveMessageWithMultiReader(&multi_reader, .none) catch |err| switch (err) { | ||
| 61 | error.Canceled, error.ConcurrencyUnavailable => |e| return e, | ||
| 62 | error.Timeout => unreachable, | ||
| 63 | else => |e| { | ||
| 64 | log.err("failed to receive message: {t}", .{err}); | ||
| 65 | break :blk e; | ||
| 66 | }, | ||
| 67 | }; | ||
| 68 | const body = client_stdout.take(header.bytes_len) catch unreachable; | ||
| 69 | log.debug("received {f} ({d} bytes)", .{ fmtEnum(header.tag), body.len }); | ||
| 70 | |||
| 71 | if (header.tag != .bsp_handshake) { | ||
| 72 | log.err("received unexpected message: {f}", .{fmtEnum(header.tag)}); | ||
| 73 | return error.UnexpectedMessage; | ||
| 74 | } | ||
| 75 | |||
| 76 | var r: Io.Reader = .fixed(body); | ||
| 77 | break :handshake try r.takeStruct(Server.Message.Handshake, .little); | ||
| 78 | }; | ||
| 79 | _ = handshake; | ||
| 80 | |||
| 81 | var conf_arena_allocator: std.heap.ArenaAllocator = .init(gpa); | ||
| 82 | defer conf_arena_allocator.deinit(); | ||
| 83 | const conf_arena = conf_arena_allocator.allocator(); | ||
| 84 | |||
| 85 | const configuration = configuration: { | ||
| 86 | const header = client.receiveMessageWithMultiReader(&multi_reader, .none) catch |err| switch (err) { | ||
| 87 | error.Canceled, error.ConcurrencyUnavailable => |e| return e, | ||
| 88 | error.Timeout => unreachable, | ||
| 89 | else => |e| { | ||
| 90 | log.err("failed to receive message: {t}", .{err}); | ||
| 91 | break :blk e; | ||
| 92 | }, | ||
| 93 | }; | ||
| 94 | const body = client_stdout.take(header.bytes_len) catch unreachable; | ||
| 95 | log.debug("received {t} ({d} bytes)", .{ header.tag, body.len }); | ||
| 96 | |||
| 97 | if (header.tag != .bsp_configuration) { | ||
| 98 | log.err("received unexpected message: {f}", .{fmtEnum(header.tag)}); | ||
| 99 | return error.UnexpectedMessage; | ||
| 100 | } | ||
| 101 | |||
| 102 | const configuration_path = body; | ||
| 103 | var file = Io.Dir.cwd().openFile(io, configuration_path, .{}) catch |err| | ||
| 104 | std.debug.panic("failed to open configuration file {q}: {t}", .{ configuration_path, err }); | ||
| 105 | defer file.close(io); | ||
| 106 | break :configuration Configuration.loadFile(conf_arena, io, file) catch |err| | ||
| 107 | std.debug.panic("failed to load configuration file {q}: {t}", .{ configuration_path, err }); | ||
| 108 | }; | ||
| 109 | const c = &configuration; | ||
| 110 | |||
| 111 | var top_level_steps: std.array_hash_map.String(Configuration.Step.Index) = .empty; | ||
| 112 | defer top_level_steps.deinit(gpa); | ||
| 113 | |||
| 114 | for (c.steps, 0..) |*conf_step, step_index_usize| { | ||
| 115 | if (conf_step.owner != .root) continue; | ||
| 116 | const step_index: Configuration.Step.Index = @fromBackingInt(@intCast(step_index_usize)); | ||
| 117 | const flags = conf_step.flags(c); | ||
| 118 | if (flags.tag != .top_level) continue; | ||
| 119 | const name = step_index.ptr(c).name.slice(c); | ||
| 120 | try top_level_steps.putNoClobber(gpa, name, step_index); | ||
| 121 | } | ||
| 122 | |||
| 123 | std.debug.print("Steps:\n", .{}); | ||
| 124 | for (top_level_steps.keys()) |name| { | ||
| 125 | std.debug.print(" - {q}\n", .{name}); | ||
| 126 | } | ||
| 127 | std.debug.print( | ||
| 128 | \\Available Commands: | ||
| 129 | \\ - build [step names / step indices] | ||
| 130 | \\ - watch [step names / step indices] | ||
| 131 | \\ - exit | ||
| 132 | \\ | ||
| 133 | , .{}); | ||
| 134 | |||
| 135 | var stdin_reader_buffer: [256]u8 = undefined; | ||
| 136 | var stdin_reader = Io.File.stdin().reader(io, &stdin_reader_buffer); | ||
| 137 | const stdin = &stdin_reader.interface; | ||
| 138 | |||
| 139 | while (true) { | ||
| 140 | try Io.File.stdout().writeStreamingAll(io, "> "); | ||
| 141 | const command = try stdin.takeDelimiterExclusive('\n'); | ||
| 142 | stdin.toss(1); | ||
| 143 | if (std.mem.startsWith(u8, command, "build") or | ||
| 144 | std.mem.startsWith(u8, command, "watch")) | ||
| 145 | { | ||
| 146 | var steps: std.ArrayList(Configuration.Step.Index) = .empty; | ||
| 147 | defer steps.deinit(gpa); | ||
| 148 | |||
| 149 | const watch = std.mem.startsWith(u8, command, "watch"); | ||
| 150 | |||
| 151 | if (std.mem.cutPrefix(u8, command, "build ") orelse | ||
| 152 | std.mem.cutPrefix(u8, command, "watch ")) |command_args| | ||
| 153 | { | ||
| 154 | var it = std.mem.tokenizeScalar(u8, command_args, ' '); | ||
| 155 | while (it.next()) |arg| { | ||
| 156 | const step: Configuration.Step.Index = | ||
| 157 | if (std.fmt.parseInt(u32, arg, 10)) |i| | ||
| 158 | @fromBackingInt(i) | ||
| 159 | else |_| | ||
| 160 | top_level_steps.get(arg) orelse std.debug.panic("unexpected step name or index", .{}); | ||
| 161 | try steps.append(gpa, step); | ||
| 162 | } | ||
| 163 | } | ||
| 164 | |||
| 165 | if (steps.items.len < 1) { | ||
| 166 | try steps.append(gpa, c.default_step); | ||
| 167 | } | ||
| 168 | |||
| 169 | try client.serveBuildSteps(steps.items, .{ .watch = watch }); | ||
| 170 | |||
| 171 | while (true) { | ||
| 172 | const header: Server.Message.Header = client.receiveMessageWithMultiReader(&multi_reader, .none) catch |err| switch (err) { | ||
| 173 | error.Canceled, error.ConcurrencyUnavailable => |e| return e, | ||
| 174 | error.Timeout => unreachable, | ||
| 175 | else => |e| { | ||
| 176 | log.err("failed to receive message: {t}", .{err}); | ||
| 177 | break :blk e; | ||
| 178 | }, | ||
| 179 | }; | ||
| 180 | const body = client_stdout.take(header.bytes_len) catch unreachable; | ||
| 181 | log.debug("received {f} ({d} bytes)", .{ fmtEnum(header.tag), body.len }); | ||
| 182 | |||
| 183 | switch (header.tag) { | ||
| 184 | .bsp_build_started => {}, | ||
| 185 | .bsp_build_completed => if (!watch) break, | ||
| 186 | .bsp_step_started => {}, | ||
| 187 | .bsp_step_completed => {}, | ||
| 188 | .bsp_configuration => @panic("TODO"), | ||
| 189 | else => std.debug.panic("received unexpected message: {f}", .{fmtEnum(header.tag)}), | ||
| 190 | } | ||
| 191 | } | ||
| 192 | continue; | ||
| 193 | } else if (std.mem.eql(u8, command, "exit")) { | ||
| 194 | try client.serveBodylessMessage(.exit); | ||
| 195 | break; | ||
| 196 | } else { | ||
| 197 | log.err("unknown command: {q}", .{command}); | ||
| 198 | continue; | ||
| 199 | } | ||
| 200 | } | ||
| 201 | }; | ||
| 202 | |||
| 203 | try multi_reader.fillRemaining(.none); | ||
| 204 | |||
| 205 | if (client_stderr.bufferedLen() > 0) { | ||
| 206 | log.err("stderr:\n{s}\n", .{client_stderr.buffered()}); | ||
| 207 | } | ||
| 208 | |||
| 209 | try err; | ||
| 210 | |||
| 211 | const term = try child_process.wait(io); | ||
| 212 | |||
| 213 | if (!term.success()) { | ||
| 214 | log.err("maker {f}", .{term}); | ||
| 215 | } | ||
| 216 | } | ||
| 217 | |||
| 218 | const FormatEnum = union(enum) { | ||
| 219 | named: []const u8, | ||
| 220 | unnamed: usize, | ||
| 221 | |||
| 222 | pub fn format( | ||
| 223 | e: FormatEnum, | ||
| 224 | writer: *std.Io.Writer, | ||
| 225 | ) std.Io.Writer.Error!void { | ||
| 226 | switch (e) { | ||
| 227 | .named => |name| { | ||
| 228 | try writer.writeByte('.'); | ||
| 229 | try writer.writeAll(name); | ||
| 230 | }, | ||
| 231 | .unnamed => |number| try writer.print("0x{x}", .{number}), | ||
| 232 | } | ||
| 233 | } | ||
| 234 | }; | ||
| 235 | |||
| 236 | fn fmtEnum(e: anytype) FormatEnum { | ||
| 237 | if (std.enums.tagName(@TypeOf(e), e)) |name| { | ||
| 238 | return .{ .named = name }; | ||
| 239 | } else { | ||
| 240 | return .{ .unnamed = @backingInt(e) }; | ||
| 241 | } | ||
| 242 | } | ||
tools/docgen.zig+2-2| ... | @@ -712,10 +712,10 @@ fn tokenizeAndPrintRaw( | ... | @@ -712,10 +712,10 @@ fn tokenizeAndPrintRaw( |
| 712 | next_tok_is_fn = false; | 712 | next_tok_is_fn = false; |
| 713 | 713 | ||
| 714 | const token = tokenizer.next(); | 714 | const token = tokenizer.next(); |
| 715 | if (mem.indexOf(u8, src[index..token.loc.start], "//")) |comment_start_off| { | 715 | if (mem.find(u8, src[index..token.loc.start], "//")) |comment_start_off| { |
| 716 | // render one comment | 716 | // render one comment |
| 717 | const comment_start = index + comment_start_off; | 717 | const comment_start = index + comment_start_off; |
| 718 | const comment_end_off = mem.indexOf(u8, src[comment_start..token.loc.start], "\n"); | 718 | const comment_end_off = mem.find(u8, src[comment_start..token.loc.start], "\n"); |
| 719 | const comment_end = if (comment_end_off) |o| comment_start + o else token.loc.start; | 719 | const comment_end = if (comment_end_off) |o| comment_start + o else token.loc.start; |
| 720 | 720 | ||
| 721 | try writeEscapedLines(out, src[index..comment_start]); | 721 | try writeEscapedLines(out, src[index..comment_start]); |
tools/doctest.zig+11-11| ... | @@ -383,7 +383,7 @@ fn printOutput( | ... | @@ -383,7 +383,7 @@ fn printOutput( |
| 383 | fatal("example compile crashed", .{}); | 383 | fatal("example compile crashed", .{}); |
| 384 | }, | 384 | }, |
| 385 | } | 385 | } |
| 386 | if (mem.indexOf(u8, result.stderr, error_match) == null) { | 386 | if (mem.find(u8, result.stderr, error_match) == null) { |
| 387 | print("{s}\nExpected to find '{s}' in stderr\n", .{ result.stderr, error_match }); | 387 | print("{s}\nExpected to find '{s}' in stderr\n", .{ result.stderr, error_match }); |
| 388 | fatal("example did not have expected compile error", .{}); | 388 | fatal("example did not have expected compile error", .{}); |
| 389 | } | 389 | } |
| ... | @@ -438,7 +438,7 @@ fn printOutput( | ... | @@ -438,7 +438,7 @@ fn printOutput( |
| 438 | fatal("example compile crashed", .{}); | 438 | fatal("example compile crashed", .{}); |
| 439 | }, | 439 | }, |
| 440 | } | 440 | } |
| 441 | if (mem.indexOf(u8, result.stderr, error_match) == null) { | 441 | if (mem.find(u8, result.stderr, error_match) == null) { |
| 442 | print("{s}\nExpected to find '{s}' in stderr\n", .{ result.stderr, error_match }); | 442 | print("{s}\nExpected to find '{s}' in stderr\n", .{ result.stderr, error_match }); |
| 443 | fatal("example did not have expected runtime safety error message", .{}); | 443 | fatal("example did not have expected runtime safety error message", .{}); |
| 444 | } | 444 | } |
| ... | @@ -513,7 +513,7 @@ fn printOutput( | ... | @@ -513,7 +513,7 @@ fn printOutput( |
| 513 | fatal("example compile crashed", .{}); | 513 | fatal("example compile crashed", .{}); |
| 514 | }, | 514 | }, |
| 515 | } | 515 | } |
| 516 | if (mem.indexOf(u8, result.stderr, error_match) == null) { | 516 | if (mem.find(u8, result.stderr, error_match) == null) { |
| 517 | print("{s}\nExpected to find '{s}' in stderr\n", .{ result.stderr, error_match }); | 517 | print("{s}\nExpected to find '{s}' in stderr\n", .{ result.stderr, error_match }); |
| 518 | fatal("example did not have expected compile error message", .{}); | 518 | fatal("example did not have expected compile error message", .{}); |
| 519 | } | 519 | } |
| ... | @@ -623,10 +623,10 @@ fn tokenizeAndPrint(arena: Allocator, out: *Writer, raw_src: []const u8) !void { | ... | @@ -623,10 +623,10 @@ fn tokenizeAndPrint(arena: Allocator, out: *Writer, raw_src: []const u8) !void { |
| 623 | next_tok_is_fn = false; | 623 | next_tok_is_fn = false; |
| 624 | 624 | ||
| 625 | const token = tokenizer.next(); | 625 | const token = tokenizer.next(); |
| 626 | if (mem.indexOf(u8, src[index..token.loc.start], "//")) |comment_start_off| { | 626 | if (mem.find(u8, src[index..token.loc.start], "//")) |comment_start_off| { |
| 627 | // render one comment | 627 | // render one comment |
| 628 | const comment_start = index + comment_start_off; | 628 | const comment_start = index + comment_start_off; |
| 629 | const comment_end_off = mem.indexOf(u8, src[comment_start..token.loc.start], "\n"); | 629 | const comment_end_off = mem.find(u8, src[comment_start..token.loc.start], "\n"); |
| 630 | const comment_end = if (comment_end_off) |o| comment_start + o else token.loc.start; | 630 | const comment_end = if (comment_end_off) |o| comment_start + o else token.loc.start; |
| 631 | 631 | ||
| 632 | try writeEscapedLines(out, src[index..comment_start]); | 632 | try writeEscapedLines(out, src[index..comment_start]); |
| ... | @@ -870,13 +870,13 @@ const Code = struct { | ... | @@ -870,13 +870,13 @@ const Code = struct { |
| 870 | }; | 870 | }; |
| 871 | 871 | ||
| 872 | fn stripManifest(source_bytes: []const u8) []const u8 { | 872 | fn stripManifest(source_bytes: []const u8) []const u8 { |
| 873 | const manifest_start = mem.lastIndexOf(u8, source_bytes, "\n\n// ") orelse | 873 | const manifest_start = mem.findLast(u8, source_bytes, "\n\n// ") orelse |
| 874 | fatal("missing manifest comment", .{}); | 874 | fatal("missing manifest comment", .{}); |
| 875 | return source_bytes[0 .. manifest_start + 1]; | 875 | return source_bytes[0 .. manifest_start + 1]; |
| 876 | } | 876 | } |
| 877 | 877 | ||
| 878 | fn parseManifest(arena: Allocator, source_bytes: []const u8) !Code { | 878 | fn parseManifest(arena: Allocator, source_bytes: []const u8) !Code { |
| 879 | const manifest_start = mem.lastIndexOf(u8, source_bytes, "\n\n// ") orelse | 879 | const manifest_start = mem.findLast(u8, source_bytes, "\n\n// ") orelse |
| 880 | fatal("missing manifest comment", .{}); | 880 | fatal("missing manifest comment", .{}); |
| 881 | var it = mem.tokenizeScalar(u8, source_bytes[manifest_start..], '\n'); | 881 | var it = mem.tokenizeScalar(u8, source_bytes[manifest_start..], '\n'); |
| 882 | const first_line = skipPrefix(it.next().?); | 882 | const first_line = skipPrefix(it.next().?); |
| ... | @@ -915,11 +915,11 @@ fn parseManifest(arena: Allocator, source_bytes: []const u8) !Code { | ... | @@ -915,11 +915,11 @@ fn parseManifest(arena: Allocator, source_bytes: []const u8) !Code { |
| 915 | while (it.next()) |prefixed_line| { | 915 | while (it.next()) |prefixed_line| { |
| 916 | const line = skipPrefix(prefixed_line); | 916 | const line = skipPrefix(prefixed_line); |
| 917 | if (mem.startsWith(u8, line, "optimize=")) { | 917 | if (mem.startsWith(u8, line, "optimize=")) { |
| 918 | mode = std.meta.stringToEnum(std.builtin.OptimizeMode, line["optimize=".len..]) orelse | 918 | mode = std.builtin.Optimize.fromString(line["optimize=".len..]) orelse |
| 919 | fatal("bad optimization mode line: '{s}'", .{line}); | 919 | fatal("bad optimization mode line: {q}", .{line}); |
| 920 | } else if (mem.startsWith(u8, line, "link_mode=")) { | 920 | } else if (mem.startsWith(u8, line, "link_mode=")) { |
| 921 | link_mode = std.meta.stringToEnum(std.builtin.LinkMode, line["link_mode=".len..]) orelse | 921 | link_mode = std.meta.stringToEnum(std.builtin.LinkMode, line["link_mode=".len..]) orelse |
| 922 | fatal("bad link mode line: '{s}'", .{line}); | 922 | fatal("bad link mode line: {q}", .{line}); |
| 923 | } else if (mem.startsWith(u8, line, "link_object=")) { | 923 | } else if (mem.startsWith(u8, line, "link_object=")) { |
| 924 | try link_objects.append(arena, line["link_object=".len..]); | 924 | try link_objects.append(arena, line["link_object=".len..]); |
| 925 | } else if (mem.startsWith(u8, line, "additional_option=")) { | 925 | } else if (mem.startsWith(u8, line, "additional_option=")) { |
| ... | @@ -1104,7 +1104,7 @@ fn termColor(allocator: Allocator, input: []const u8) ![]u8 { | ... | @@ -1104,7 +1104,7 @@ fn termColor(allocator: Allocator, input: []const u8) ![]u8 { |
| 1104 | 1104 | ||
| 1105 | // Returns true if number is in slice. | 1105 | // Returns true if number is in slice. |
| 1106 | fn in(slice: []const u8, number: u8) bool { | 1106 | fn in(slice: []const u8, number: u8) bool { |
| 1107 | return mem.indexOfScalar(u8, slice, number) != null; | 1107 | return mem.findScalar(u8, slice, number) != null; |
| 1108 | } | 1108 | } |
| 1109 | 1109 | ||
| 1110 | fn run( | 1110 | fn run( |
tools/fetch_them_macos_headers.zig+2-2| ... | @@ -187,8 +187,8 @@ fn fetchTarget( | ... | @@ -187,8 +187,8 @@ fn fetchTarget( |
| 187 | 187 | ||
| 188 | var it = mem.splitScalar(u8, headers_list_str, '\n'); | 188 | var it = mem.splitScalar(u8, headers_list_str, '\n'); |
| 189 | while (it.next()) |line| { | 189 | while (it.next()) |line| { |
| 190 | if (mem.lastIndexOf(u8, line, "clang") != null) continue; | 190 | if (mem.findLast(u8, line, "clang") != null) continue; |
| 191 | if (mem.lastIndexOf(u8, line, prefix[0..])) |idx| { | 191 | if (mem.findLast(u8, line, prefix[0..])) |idx| { |
| 192 | const out_rel_path = line[idx + prefix.len + 1 ..]; | 192 | const out_rel_path = line[idx + prefix.len + 1 ..]; |
| 193 | const out_rel_path_stripped = mem.trim(u8, out_rel_path, " \\"); | 193 | const out_rel_path_stripped = mem.trim(u8, out_rel_path, " \\"); |
| 194 | const dirname = Dir.path.dirname(out_rel_path_stripped) orelse "."; | 194 | const dirname = Dir.path.dirname(out_rel_path_stripped) orelse "."; |
tools/generate_c_size_and_align_checks.zig deleted-62| ... | @@ -1,62 +0,0 @@ | ||
| 1 | //! Usage: zig run tools/generate_c_size_and_align_checks.zig -- [target_triple] | ||
| 2 | //! e.g. zig run tools/generate_c_size_and_align_checks.zig -- x86_64-linux-gnu | ||
| 3 | //! | ||
| 4 | //! Prints _Static_asserts for the size and alignment of all the basic built-in C | ||
| 5 | //! types. The output can be run through a compiler for the specified target to | ||
| 6 | //! verify that Zig's values are the same as those used by a C compiler for the | ||
| 7 | //! target. | ||
| 8 | |||
| 9 | const std = @import("std"); | ||
| 10 | const Io = std.Io; | ||
| 11 | |||
| 12 | fn cName(ty: std.Target.CType) []const u8 { | ||
| 13 | return switch (ty) { | ||
| 14 | .char => "char", | ||
| 15 | .short => "short", | ||
| 16 | .ushort => "unsigned short", | ||
| 17 | .int => "int", | ||
| 18 | .uint => "unsigned int", | ||
| 19 | .long => "long", | ||
| 20 | .ulong => "unsigned long", | ||
| 21 | .longlong => "long long", | ||
| 22 | .ulonglong => "unsigned long long", | ||
| 23 | .float => "float", | ||
| 24 | .double => "double", | ||
| 25 | .longdouble => "long double", | ||
| 26 | }; | ||
| 27 | } | ||
| 28 | |||
| 29 | var general_purpose_allocator: std.heap.DebugAllocator(.{}) = .init; | ||
| 30 | |||
| 31 | pub fn main(init: std.process.Init) !void { | ||
| 32 | const args = try init.minimal.args.toSlice(init.arena.allocator()); | ||
| 33 | const io = init.io; | ||
| 34 | |||
| 35 | if (args.len != 2) { | ||
| 36 | std.debug.print("Usage: {s} [target_triple]\n", .{args[0]}); | ||
| 37 | std.process.exit(1); | ||
| 38 | } | ||
| 39 | |||
| 40 | const query = try std.Target.Query.parse(.{ .arch_os_abi = args[1] }); | ||
| 41 | const target = try std.zig.system.resolveTargetQuery(io, query); | ||
| 42 | |||
| 43 | var buffer: [2000]u8 = undefined; | ||
| 44 | var stdout_writer = Io.File.stdout().writerStreaming(io, &buffer); | ||
| 45 | const w = &stdout_writer.interface; | ||
| 46 | inline for (@typeInfo(std.Target.CType).@"enum".field_values) |field_value| { | ||
| 47 | const c_type: std.Target.CType = @fromBackingInt(@intCast(field_value)); | ||
| 48 | try w.print("_Static_assert(sizeof({0s}) == {1d}, \"sizeof({0s}) == {1d}\");\n", .{ | ||
| 49 | cName(c_type), | ||
| 50 | target.cTypeByteSize(c_type), | ||
| 51 | }); | ||
| 52 | try w.print("_Static_assert(_Alignof({0s}) == {1d}, \"_Alignof({0s}) == {1d}\");\n", .{ | ||
| 53 | cName(c_type), | ||
| 54 | target.cTypeAlignment(c_type), | ||
| 55 | }); | ||
| 56 | try w.print("_Static_assert(__alignof({0s}) == {1d}, \"__alignof({0s}) == {1d}\");\n\n", .{ | ||
| 57 | cName(c_type), | ||
| 58 | target.cTypePreferredAlignment(c_type), | ||
| 59 | }); | ||
| 60 | } | ||
| 61 | try w.flush(); | ||
| 62 | } | ||
tools/incr-check.zig+37-33| ... | @@ -305,21 +305,23 @@ const Eval = struct { | ... | @@ -305,21 +305,23 @@ const Eval = struct { |
| 305 | 305 | ||
| 306 | fn check(eval: *Eval, mr: *Io.File.MultiReader, update: Case.Update, prog_node: std.Progress.Node) !void { | 306 | fn check(eval: *Eval, mr: *Io.File.MultiReader, update: Case.Update, prog_node: std.Progress.Node) !void { |
| 307 | const arena = eval.arena; | 307 | const arena = eval.arena; |
| 308 | const stdout = mr.fileReader(0); | 308 | const stdout = mr.reader(0); |
| 309 | const stderr = &mr.fileReader(1).interface; | 309 | const stderr = mr.reader(1); |
| 310 | const Header = std.zig.Server.Message.Header; | 310 | |
| 311 | var client: std.zig.Client = .{ | ||
| 312 | .in = stdout, | ||
| 313 | .out = undefined, | ||
| 314 | }; | ||
| 311 | 315 | ||
| 312 | while (true) { | 316 | while (true) { |
| 313 | const header = stdout.interface.takeStruct(Header, .little) catch |err| switch (err) { | 317 | const header = client.receiveMessageWithMultiReader(mr, .none) catch |err| switch (err) { |
| 314 | error.EndOfStream => break, | 318 | error.Timeout => unreachable, |
| 315 | error.ReadFailed => return stdout.err.?, | ||
| 316 | }; | ||
| 317 | const body = stdout.interface.take(header.bytes_len) catch |err| switch (err) { | ||
| 318 | // If this panic triggers it might be helpful to rework this | 319 | // If this panic triggers it might be helpful to rework this |
| 319 | // code to print the stderr from the abnormally terminated child. | 320 | // code to print the stderr from the abnormally terminated child. |
| 320 | error.EndOfStream => @panic("unexpected mid-message end of stream"), | 321 | error.EndOfStream => @panic("unexpected mid-message end of stream"), |
| 321 | error.ReadFailed => return stdout.err.?, | 322 | else => |e| return e, |
| 322 | }; | 323 | }; |
| 324 | const body = client.in.take(header.bytes_len) catch unreachable; | ||
| 323 | 325 | ||
| 324 | switch (header.tag) { | 326 | switch (header.tag) { |
| 325 | .error_bundle => { | 327 | .error_bundle => { |
| ... | @@ -448,7 +450,7 @@ const Eval = struct { | ... | @@ -448,7 +450,7 @@ const Eval = struct { |
| 448 | const raw_filename = eb.nullTerminatedString(src.src_path); | 450 | const raw_filename = eb.nullTerminatedString(src.src_path); |
| 449 | // We need to replace backslashes for consistency between platforms. | 451 | // We need to replace backslashes for consistency between platforms. |
| 450 | const filename = name: { | 452 | const filename = name: { |
| 451 | if (std.mem.indexOfScalar(u8, raw_filename, '\\') == null) break :name raw_filename; | 453 | if (std.mem.findScalar(u8, raw_filename, '\\') == null) break :name raw_filename; |
| 452 | const copied = try eval.arena.dupe(u8, raw_filename); | 454 | const copied = try eval.arena.dupe(u8, raw_filename); |
| 453 | std.mem.replaceScalar(u8, copied, '\\', '/'); | 455 | std.mem.replaceScalar(u8, copied, '\\', '/'); |
| 454 | break :name copied; | 456 | break :name copied; |
| ... | @@ -605,12 +607,13 @@ const Eval = struct { | ... | @@ -605,12 +607,13 @@ const Eval = struct { |
| 605 | 607 | ||
| 606 | fn requestUpdate(eval: *Eval) !void { | 608 | fn requestUpdate(eval: *Eval) !void { |
| 607 | const io = eval.io; | 609 | const io = eval.io; |
| 608 | const header: std.zig.Client.Message.Header = .{ | 610 | |
| 609 | .tag = .update, | 611 | var w = eval.child.stdin.?.writerStreaming(io, &.{}); |
| 610 | .bytes_len = 0, | 612 | var client: std.zig.Client = .{ |
| 613 | .in = undefined, | ||
| 614 | .out = &w.interface, | ||
| 611 | }; | 615 | }; |
| 612 | var w = eval.child.stdin.?.writer(io, &.{}); | 616 | client.serveBodylessMessage(.update) catch |err| switch (err) { |
| 613 | w.interface.writeStruct(header, .little) catch |err| switch (err) { | ||
| 614 | error.WriteFailed => return w.err.?, | 617 | error.WriteFailed => return w.err.?, |
| 615 | }; | 618 | }; |
| 616 | } | 619 | } |
| ... | @@ -618,22 +621,23 @@ const Eval = struct { | ... | @@ -618,22 +621,23 @@ const Eval = struct { |
| 618 | fn end(eval: *Eval, mr: *Io.File.MultiReader) !void { | 621 | fn end(eval: *Eval, mr: *Io.File.MultiReader) !void { |
| 619 | requestExit(eval.child, eval); | 622 | requestExit(eval.child, eval); |
| 620 | 623 | ||
| 621 | const stdout = mr.fileReader(0); | 624 | var client: std.zig.Client = .{ |
| 622 | const Header = std.zig.Server.Message.Header; | 625 | .in = mr.reader(0), |
| 626 | .out = undefined, | ||
| 627 | }; | ||
| 623 | 628 | ||
| 624 | while (true) { | 629 | while (true) { |
| 625 | const header = stdout.interface.takeStruct(Header, .little) catch |err| switch (err) { | 630 | const header = client.receiveMessageWithMultiReader(mr, .none) catch |err| switch (err) { |
| 626 | error.EndOfStream => break, | 631 | error.Timeout => unreachable, |
| 627 | error.ReadFailed => return stdout.err.?, | 632 | error.EndOfStream => |e| { |
| 628 | }; | 633 | if (client.in.bufferedLen() == 0) break; |
| 629 | stdout.interface.discardAll(header.bytes_len) catch |err| switch (err) { | 634 | return e; |
| 630 | error.ReadFailed => return stdout.err.?, | 635 | }, |
| 631 | error.EndOfStream => |e| return e, | 636 | else => |e| return e, |
| 632 | }; | 637 | }; |
| 638 | try client.in.discardAll(header.bytes_len); | ||
| 633 | } | 639 | } |
| 634 | 640 | ||
| 635 | try mr.fillRemaining(.none); | ||
| 636 | |||
| 637 | const stderr = mr.reader(1).buffered(); | 641 | const stderr = mr.reader(1).buffered(); |
| 638 | if (stderr.len > 0) eval.fatal("unexpected stderr:\n{s}", .{stderr}); | 642 | if (stderr.len > 0) eval.fatal("unexpected stderr:\n{s}", .{stderr}); |
| 639 | } | 643 | } |
| ... | @@ -773,7 +777,7 @@ const Case = struct { | ... | @@ -773,7 +777,7 @@ const Case = struct { |
| 773 | .backend = backend, | 777 | .backend = backend, |
| 774 | }); | 778 | }); |
| 775 | } else if (std.mem.eql(u8, key, "module")) { | 779 | } else if (std.mem.eql(u8, key, "module")) { |
| 776 | const split_idx = std.mem.indexOfScalar(u8, val, '=') orelse | 780 | const split_idx = std.mem.findScalar(u8, val, '=') orelse |
| 777 | fatal("line {d}: module does not include file", .{line_n}); | 781 | fatal("line {d}: module does not include file", .{line_n}); |
| 778 | const name = val[0..split_idx]; | 782 | const name = val[0..split_idx]; |
| 779 | const file = val[split_idx + 1 ..]; | 783 | const file = val[split_idx + 1 ..]; |
| ... | @@ -899,12 +903,12 @@ fn requestExit(child: *std.process.Child, eval: *Eval) void { | ... | @@ -899,12 +903,12 @@ fn requestExit(child: *std.process.Child, eval: *Eval) void { |
| 899 | if (child.stdin == null) return; | 903 | if (child.stdin == null) return; |
| 900 | const io = eval.io; | 904 | const io = eval.io; |
| 901 | 905 | ||
| 902 | const header: std.zig.Client.Message.Header = .{ | 906 | var w = eval.child.stdin.?.writerStreaming(io, &.{}); |
| 903 | .tag = .exit, | 907 | var client: std.zig.Client = .{ |
| 904 | .bytes_len = 0, | 908 | .in = undefined, |
| 909 | .out = &w.interface, | ||
| 905 | }; | 910 | }; |
| 906 | var w = eval.child.stdin.?.writer(io, &.{}); | 911 | client.serveBodylessMessage(.exit) catch |err| switch (err) { |
| 907 | w.interface.writeStruct(header, .little) catch |err| switch (err) { | ||
| 908 | error.WriteFailed => switch (w.err.?) { | 912 | error.WriteFailed => switch (w.err.?) { |
| 909 | error.BrokenPipe => {}, | 913 | error.BrokenPipe => {}, |
| 910 | else => |e| eval.fatal("failed to send exit: {t}", .{e}), | 914 | else => |e| eval.fatal("failed to send exit: {t}", .{e}), |
| ... | @@ -979,7 +983,7 @@ fn rand64(io: Io) u64 { | ... | @@ -979,7 +983,7 @@ fn rand64(io: Io) u64 { |
| 979 | fn parseTargetQueryAndBackend(input_str: []const u8, err_prefix: []const u8) struct { std.Target.Query, Backend } { | 983 | fn parseTargetQueryAndBackend(input_str: []const u8, err_prefix: []const u8) struct { std.Target.Query, Backend } { |
| 980 | const fatal = std.process.fatal; | 984 | const fatal = std.process.fatal; |
| 981 | 985 | ||
| 982 | const split_idx = std.mem.lastIndexOfScalar(u8, input_str, '-') orelse | 986 | const split_idx = std.mem.findScalarLast(u8, input_str, '-') orelse |
| 983 | fatal("{s}target does not include backend", .{err_prefix}); | 987 | fatal("{s}target does not include backend", .{err_prefix}); |
| 984 | 988 | ||
| 985 | const query = input_str[0..split_idx]; | 989 | const query = input_str[0..split_idx]; |
tools/migrate_langref.zig+2-2| ... | @@ -319,7 +319,7 @@ fn walk(arena: Allocator, io: Io, tokenizer: *Tokenizer, out_dir: Dir, w: anytyp | ... | @@ -319,7 +319,7 @@ fn walk(arena: Allocator, io: Io, tokenizer: *Tokenizer, out_dir: Dir, w: anytyp |
| 319 | return parseError(tokenizer, code_kind_tok, "unrecognized code kind: {s}", .{code_kind_str}); | 319 | return parseError(tokenizer, code_kind_tok, "unrecognized code kind: {s}", .{code_kind_str}); |
| 320 | } | 320 | } |
| 321 | 321 | ||
| 322 | var mode: std.builtin.OptimizeMode = .Debug; | 322 | var mode: std.builtin.OptimizeMode = .debug; |
| 323 | var link_objects = std.array_list.Managed([]const u8).init(arena); | 323 | var link_objects = std.array_list.Managed([]const u8).init(arena); |
| 324 | var target_str: ?[]const u8 = null; | 324 | var target_str: ?[]const u8 = null; |
| 325 | var link_libc = false; | 325 | var link_libc = false; |
| ... | @@ -403,7 +403,7 @@ fn walk(arena: Allocator, io: Io, tokenizer: *Tokenizer, out_dir: Dir, w: anytyp | ... | @@ -403,7 +403,7 @@ fn walk(arena: Allocator, io: Io, tokenizer: *Tokenizer, out_dir: Dir, w: anytyp |
| 403 | }, | 403 | }, |
| 404 | } | 404 | } |
| 405 | 405 | ||
| 406 | if (mode != .Debug) | 406 | if (mode != .debug) |
| 407 | try code.print("// optimize={s}\n", .{@tagName(mode)}); | 407 | try code.print("// optimize={s}\n", .{@tagName(mode)}); |
| 408 | 408 | ||
| 409 | for (link_objects.items) |link_object| { | 409 | for (link_objects.items) |link_object| { |
tools/process_headers.zig+2| ... | @@ -36,6 +36,8 @@ const glibc_targets = [_]LibCTarget{ | ... | @@ -36,6 +36,8 @@ const glibc_targets = [_]LibCTarget{ |
| 36 | .{ .arch = .aarch64_be, .abi = .gnu, .dest = "aarch64-linux-gnu" }, | 36 | .{ .arch = .aarch64_be, .abi = .gnu, .dest = "aarch64-linux-gnu" }, |
| 37 | .{ .arch = .csky, .abi = .gnueabi, .dest = "csky-linux-gnu" }, | 37 | .{ .arch = .csky, .abi = .gnueabi, .dest = "csky-linux-gnu" }, |
| 38 | .{ .arch = .csky, .abi = .gnueabihf, .dest = "csky-linux-gnu" }, | 38 | .{ .arch = .csky, .abi = .gnueabihf, .dest = "csky-linux-gnu" }, |
| 39 | .{ .arch = .loongarch32, .abi = .gnu, .dest = "loongarch-linux-gnu" }, | ||
| 40 | .{ .arch = .loongarch32, .abi = .gnusf, .dest = "loongarch-linux-gnu" }, | ||
| 39 | .{ .arch = .loongarch64, .abi = .gnu, .dest = "loongarch-linux-gnu" }, | 41 | .{ .arch = .loongarch64, .abi = .gnu, .dest = "loongarch-linux-gnu" }, |
| 40 | .{ .arch = .loongarch64, .abi = .gnusf, .dest = "loongarch-linux-gnu" }, | 42 | .{ .arch = .loongarch64, .abi = .gnusf, .dest = "loongarch-linux-gnu" }, |
| 41 | .{ .arch = .m68k, .abi = .gnu }, | 43 | .{ .arch = .m68k, .abi = .gnu }, |
tools/update_clang_options.zig+1-1| ... | @@ -599,7 +599,7 @@ const known_options = [_]KnownOpt{ | ... | @@ -599,7 +599,7 @@ const known_options = [_]KnownOpt{ |
| 599 | const blacklisted_options = [_][]const u8{}; | 599 | const blacklisted_options = [_][]const u8{}; |
| 600 | 600 | ||
| 601 | fn knownOption(name: []const u8) ?[]const u8 { | 601 | fn knownOption(name: []const u8) ?[]const u8 { |
| 602 | const chopped_name = if (std.mem.indexOfScalar(u8, name, '=')) |idx| name[0..idx] else name; | 602 | const chopped_name = if (std.mem.findScalar(u8, name, '=')) |idx| name[0..idx] else name; |
| 603 | for (known_options) |item| { | 603 | for (known_options) |item| { |
| 604 | if (std.mem.eql(u8, chopped_name, item.name)) { | 604 | if (std.mem.eql(u8, chopped_name, item.name)) { |
| 605 | return item.ident; | 605 | return item.ident; |
tools/update_crc_catalog.zig+1-1| ... | @@ -99,7 +99,7 @@ fn @"i like cheese"(arena: std.mem.Allocator, io: Io, args: []const []const u8) | ... | @@ -99,7 +99,7 @@ fn @"i like cheese"(arena: std.mem.Allocator, io: Io, args: []const []const u8) |
| 99 | 99 | ||
| 100 | var it = mem.splitSequence(u8, line, " "); | 100 | var it = mem.splitSequence(u8, line, " "); |
| 101 | while (it.next()) |property| { | 101 | while (it.next()) |property| { |
| 102 | const i = mem.indexOf(u8, property, "=").?; | 102 | const i = mem.find(u8, property, "=").?; |
| 103 | const key = property[0..i]; | 103 | const key = property[0..i]; |
| 104 | const value = property[i + 1 ..]; | 104 | const value = property[i + 1 ..]; |
| 105 | if (mem.eql(u8, key, "width")) { | 105 | if (mem.eql(u8, key, "width")) { |
tools/update_glibc.zig+1| ... | @@ -36,6 +36,7 @@ const exempt_extensions = [_][]const u8{ | ... | @@ -36,6 +36,7 @@ const exempt_extensions = [_][]const u8{ |
| 36 | // These are the start files we use when targeting glibc <= 2.33. | 36 | // These are the start files we use when targeting glibc <= 2.33. |
| 37 | "-2.33.S", | 37 | "-2.33.S", |
| 38 | "-2.33.c", | 38 | "-2.33.c", |
| 39 | "-2.32.c", | ||
| 39 | }; | 40 | }; |
| 40 | 41 | ||
| 41 | pub fn main(init: std.process.Init) !void { | 42 | pub fn main(init: std.process.Init) !void { |